webmcp

changeset 155:185e944182cb

Better C macros for null-marker in JSON library
author jbe
date Thu Jul 31 03:18:04 2014 +0200 (2014-07-31)
parents c8669dde9ce2
children 88b613f5bc22
files libraries/json/json.c
line diff
     1.1 --- a/libraries/json/json.c	Thu Jul 31 03:01:53 2014 +0200
     1.2 +++ b/libraries/json/json.c	Thu Jul 31 03:18:04 2014 +0200
     1.3 @@ -14,21 +14,19 @@
     1.4  //       returning nil and an error string).
     1.5  #define JSON_MAXDEPTH 500
     1.6  
     1.7 +// generate dummy memory addresses that represents null values:
     1.8 +char json_nullmark;
     1.9 +#define json_isnullmark(L, i) (lua_touserdata((L), (i)) == &json_nullmark)
    1.10 +#define json_pushnullmark(L) lua_pushlightuserdata((L), &json_nullmark)
    1.11 +
    1.12  // macros for usage of Lua registry:
    1.13  #define JSON_REGENT char
    1.14  #define JSON_REGPOINTER void *
    1.15 -#define json_pushlightref(L, x) lua_pushlightuserdata((L), &json_reference.x)
    1.16 -#define json_islightref(L, i, x) (lua_touserdata((L), (i)) == &json_reference.x)
    1.17  #define json_regpointer(x) (&json_registry.x)
    1.18  #define json_regfetchpointer(L, x) lua_rawgetp((L), LUA_REGISTRYINDEX, (x))
    1.19  #define json_regfetch(L, x) json_regfetchpointer(L, json_regpointer(x))
    1.20  #define json_regstore(L, x) lua_rawsetp(L, LUA_REGISTRYINDEX, json_regpointer(x))
    1.21  
    1.22 -// generate dummy memory addresses that represent non-modifiable lightuserdata (dummy) objects:
    1.23 -static struct {
    1.24 -  JSON_REGENT nullmark;  // magic value to indicate JSON null value in shadow table
    1.25 -} json_reference;
    1.26 -
    1.27  // generate dummy memory addresses that represent Lua objects
    1.28  // via lightuserdata keys and LUA_REGISTRYINDEX:
    1.29  static struct {
    1.30 @@ -109,7 +107,6 @@
    1.31  #define json_import_objectmt_idx 2
    1.32  #define json_import_arraymt_idx 3
    1.33  #define json_import_shadowtbl_idx 4
    1.34 -#define json_import_nullmark_idx 5
    1.35  
    1.36  // decodes a JSON document:
    1.37  static int json_import(lua_State *L) {
    1.38 @@ -131,8 +128,6 @@
    1.39    json_regfetch(L, arraymt);
    1.40    // push shadowtbl onto stack position 4:
    1.41    json_regfetch(L, shadowtbl);
    1.42 -  // push nullmark onto stack position 5:
    1.43 -  json_pushlightref(L, nullmark);
    1.44    // require string as first argument:
    1.45    str = luaL_checklstring(L, 1, &total);
    1.46    // if string contains a NULL byte, this is a syntax error
    1.47 @@ -386,7 +381,7 @@
    1.48      if (level) {
    1.49        // if sub-level,
    1.50        // push special null-marker onto stack:
    1.51 -      lua_pushvalue(L, json_import_nullmark_idx);
    1.52 +      json_pushnullmark(L);
    1.53      } else {
    1.54        // if top-level,
    1.55        // push nil onto stack:
    1.56 @@ -446,10 +441,9 @@
    1.57  
    1.58  // special Lua stack indicies for json_path function:
    1.59  #define json_path_shadowtbl_idx 1
    1.60 -#define json_path_nullmark_idx 2
    1.61  
    1.62  // stack offset of arguments to json_path function:
    1.63 -#define json_path_idxshift 2
    1.64 +#define json_path_idxshift 1
    1.65  
    1.66  // gets a value or its type from a JSON document (passed as first argument)
    1.67  // using a path (passed as variable number of keys after first argument):
    1.68 @@ -459,9 +453,6 @@
    1.69    // insert shadowtbl into stack at position 1 (shifting the arguments):
    1.70    json_regfetch(L, shadowtbl);
    1.71    lua_insert(L, 1);
    1.72 -  // insert nullmark into stack at position 2 (shifting the arguments):
    1.73 -  json_pushlightref(L, nullmark);
    1.74 -  lua_insert(L, 2);
    1.75    // store stack index of top of stack:
    1.76    stacktop = lua_gettop(L);
    1.77    // use first argument as "current value" (stored on top of stack):
    1.78 @@ -501,11 +492,11 @@
    1.79    if (!type_mode) {
    1.80      // if a value (and not its type) was requested,
    1.81      // check if value is the null-marker, and store nil on top of Lua stack in that case:
    1.82 -    if (lua_rawequal(L, -1, json_path_nullmark_idx)) lua_pushnil(L);
    1.83 +    if (json_isnullmark(L, -1)) lua_pushnil(L);
    1.84    } else {
    1.85      // if the type was requested,
    1.86      // check if value is the null-marker:
    1.87 -    if (lua_rawequal(L, -1, json_path_nullmark_idx)) {
    1.88 +    if (json_isnullmark(L, -1)) {
    1.89        // if yes, store string "null" on top of Lua stack:
    1.90        lua_pushliteral(L, "null");
    1.91      } else {
    1.92 @@ -608,7 +599,7 @@
    1.93    }
    1.94    // push key (second argument) and null-marker after shadow table onto stack:
    1.95    lua_pushvalue(L, 2);
    1.96 -  json_pushlightref(L, nullmark);
    1.97 +  json_pushnullmark(L);
    1.98    // store key and null-marker in shadow table:
    1.99    lua_rawset(L, -3);
   1.100    // return nothing:
   1.101 @@ -628,27 +619,20 @@
   1.102    return 1;
   1.103  }
   1.104  
   1.105 -// special Lua stack indicies for json_index function:
   1.106 -#define json_index_nullmark_idx 3
   1.107 -#define json_index_shadowtbl_idx 4
   1.108 -
   1.109  static int json_index(lua_State *L) {
   1.110    // stack shall contain two function arguments:
   1.111    lua_settop(L, 2);
   1.112 -  // push nullmark onto stack position 3:
   1.113 -  json_pushlightref(L, nullmark);
   1.114 -  // push shadowtbl onto stack position 4:
   1.115 +  // get corresponding shadow table for first argument:
   1.116    json_regfetch(L, shadowtbl);
   1.117 -  // get corresponding shadow table for first argument:
   1.118    lua_pushvalue(L, 1);
   1.119 -  lua_rawget(L, json_index_shadowtbl_idx);
   1.120 +  lua_rawget(L, -2);
   1.121    // throw error if no shadow table was found:
   1.122    if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   1.123    // use key passed as second argument to lookup value in shadow table:
   1.124    lua_pushvalue(L, 2);
   1.125    lua_rawget(L, -2);
   1.126    // if value is null-marker, then push nil onto stack:
   1.127 -  if (lua_rawequal(L, -1, json_index_nullmark_idx)) lua_pushnil(L);
   1.128 +  if (json_isnullmark(L, -1)) lua_pushnil(L);
   1.129    // return either looked up value, or nil
   1.130    return 1;
   1.131  }
   1.132 @@ -671,20 +655,13 @@
   1.133    return 0;
   1.134  }
   1.135  
   1.136 -// special Lua stack indicies for json_pairs_iterfunc function:
   1.137 -#define json_pairs_iterfunc_nullmark_idx 3
   1.138 -#define json_pairs_iterfunc_shadowtbl_idx 4
   1.139 -
   1.140  static int json_pairs_iterfunc(lua_State *L) {
   1.141    // stack shall contain two function arguments:
   1.142    lua_settop(L, 2);
   1.143 -  // push nullmark onto stack position 3:
   1.144 -  json_pushlightref(L, nullmark);
   1.145 -  // push shadowtbl onto stack position 4:
   1.146 +  // get corresponding shadow table for first argument:
   1.147    json_regfetch(L, shadowtbl);
   1.148 -  // get corresponding shadow table for first argument:
   1.149    lua_pushvalue(L, 1);
   1.150 -  lua_rawget(L, json_pairs_iterfunc_shadowtbl_idx);
   1.151 +  lua_rawget(L, -2);
   1.152    // throw error if no shadow table was found:
   1.153    if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   1.154    // get next key value pair from shadow table (using previous key from argument 2)
   1.155 @@ -692,7 +669,7 @@
   1.156    lua_pushvalue(L, 2);
   1.157    if (!lua_next(L, -2)) return 0;
   1.158    // replace null-marker with nil:
   1.159 -  if (lua_rawequal(L, -1, json_pairs_iterfunc_nullmark_idx)) {
   1.160 +  if (json_isnullmark(L, -1)) {
   1.161      lua_pop(L, 1);
   1.162      lua_pushnil(L);
   1.163    }
   1.164 @@ -710,23 +687,16 @@
   1.165    return 3;
   1.166  }
   1.167  
   1.168 -// special Lua stack indicies for json_ipairs_iterfunc function:
   1.169 -#define json_ipairs_iterfunc_nullmark_idx 3
   1.170 -#define json_ipairs_iterfunc_shadowtbl_idx 4
   1.171 -
   1.172  static int json_ipairs_iterfunc(lua_State *L) {
   1.173    lua_Integer idx;
   1.174    // stack shall contain two function arguments:
   1.175    lua_settop(L, 2);
   1.176 -  // push nullmark onto stack position 3:
   1.177 -  json_pushlightref(L, nullmark);
   1.178 -  // push shadowtbl onto stack position 4:
   1.179 -  json_regfetch(L, shadowtbl);
   1.180    // calculate new index by incrementing second argument:
   1.181    idx = lua_tointeger(L, 2) + 1;
   1.182    // get corresponding shadow table for first argument:
   1.183 +  json_regfetch(L, shadowtbl);
   1.184    lua_pushvalue(L, 1);
   1.185 -  lua_rawget(L, json_ipairs_iterfunc_shadowtbl_idx);
   1.186 +  lua_rawget(L, -2);
   1.187    // throw error if no shadow table was found:
   1.188    if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   1.189    // do integer lookup in shadow table:
   1.190 @@ -737,7 +707,7 @@
   1.191    // either the looked up value if it is not equal to the null-marker
   1.192    // or nil instead of null-marker:
   1.193    lua_pushinteger(L, idx);
   1.194 -  if (lua_rawequal(L, -2, json_ipairs_iterfunc_nullmark_idx)) lua_pushnil(L);
   1.195 +  if (json_isnullmark(L, -2)) lua_pushnil(L);
   1.196    else lua_pushvalue(L, -2);
   1.197    return 2;
   1.198  }
   1.199 @@ -852,7 +822,7 @@
   1.200            lua_call(L, 1, 1);
   1.201            luaL_addvalue(&buf);
   1.202            luaL_addchar(&buf, ':');
   1.203 -          if (json_islightref(L, 3, nullmark)) {
   1.204 +          if (json_isnullmark(L, 3)) {
   1.205              luaL_addstring(&buf, "null");
   1.206            } else {
   1.207              lua_pushcfunction(L, json_export);

Impressum / About Us