webmcp

changeset 144:0690fe79b673

Improved macros for handling Lua registry in JSON library
author jbe
date Wed Jul 30 19:24:06 2014 +0200 (2014-07-30)
parents 6f723e60acdc
children 0edc2f05c66a
files libraries/json/json.c
line diff
     1.1 --- a/libraries/json/json.c	Wed Jul 30 02:36:37 2014 +0200
     1.2 +++ b/libraries/json/json.c	Wed Jul 30 19:24:06 2014 +0200
     1.3 @@ -3,20 +3,26 @@
     1.4  #include <stdlib.h>
     1.5  #include <string.h>
     1.6  
     1.7 +// maximum number of nested JSON values (objects and arrays):
     1.8  #define JSON_MAXDEPTH 100
     1.9  
    1.10 -#define JSON_REGENT static char
    1.11 +// macros for usage of Lua registry:
    1.12 +#define JSON_REGENT char
    1.13  #define JSON_REGREF void *
    1.14 +#define json_regref(x) (&json_registry.x)
    1.15 +#define json_regfetchref(L, x) (lua_pushlightuserdata((L), (x)), lua_rawget((L), LUA_REGISTRYINDEX))
    1.16 +#define json_regfetch(L, x) (json_regfetchref(L, json_regref(x)))
    1.17 +#define json_regstore(L, x) (lua_pushlightuserdata(L, json_regref(x)), lua_pushvalue(L, -2), lua_rawset(L, LUA_REGISTRYINDEX));
    1.18  
    1.19 -JSON_REGENT json_nullmark;
    1.20 -JSON_REGENT json_shadowtbl;
    1.21 -JSON_REGENT json_unknownmt;
    1.22 -JSON_REGENT json_objectmt;
    1.23 -JSON_REGENT json_arraymt;
    1.24 -
    1.25 -#define json_regfetch(L, x) (lua_pushlightuserdata((L), &(x)), lua_rawget((L), LUA_REGISTRYINDEX))
    1.26 -
    1.27 -#define json_regstore(L, x) (lua_pushlightuserdata(L, &(x)), lua_pushvalue(L, -2), lua_rawset(L, LUA_REGISTRYINDEX));
    1.28 +// generate dummy memory addresses that represent Lua objects
    1.29 +// (via lightuserdata keys and LUA_REGISTRYINDEX):
    1.30 +static struct {
    1.31 +  JSON_REGENT nullmark;
    1.32 +  JSON_REGENT shadowtbl;
    1.33 +  JSON_REGENT unknownmt;
    1.34 +  JSON_REGENT objectmt;
    1.35 +  JSON_REGENT arraymt;
    1.36 +} json_registry;
    1.37  
    1.38  // marks a table as JSON object or JSON array:
    1.39  // (returns its modified argument or a new table if argument is nil)
    1.40 @@ -26,13 +32,13 @@
    1.41      lua_settop(L, 0);
    1.42      lua_newtable(L);
    1.43      // set shadow table:
    1.44 -    json_regfetch(L, json_shadowtbl);
    1.45 +    json_regfetch(L, shadowtbl);
    1.46      lua_pushvalue(L, 1);
    1.47      lua_newtable(L);
    1.48      lua_rawset(L, -3);
    1.49    } else {
    1.50      // check if shadow table already exists:
    1.51 -    json_regfetch(L, json_shadowtbl);
    1.52 +    json_regfetch(L, shadowtbl);
    1.53      lua_pushvalue(L, 1);
    1.54      lua_rawget(L, -2);
    1.55      if (lua_isnil(L, -1)) {
    1.56 @@ -54,7 +60,7 @@
    1.57    // discard everything but table to return:
    1.58    lua_settop(L, 1);
    1.59    // set metatable:
    1.60 -  json_regfetch(L, *mt);
    1.61 +  json_regfetchref(L, mt);
    1.62    lua_setmetatable(L, 1);
    1.63    // return table:
    1.64    return 1;
    1.65 @@ -63,13 +69,13 @@
    1.66  // marks a table as JSON object:
    1.67  // (returns its modified argument or a new table if argument is nil)
    1.68  static int json_object(lua_State *L) {
    1.69 -  return json_mark(L, &json_objectmt);
    1.70 +  return json_mark(L, json_regref(objectmt));
    1.71  }
    1.72  
    1.73  // marks a table as JSON array:
    1.74  // (returns its modified argument or a new table if argument is nil)
    1.75  static int json_array(lua_State *L) {
    1.76 -  return json_mark(L, &json_arraymt);
    1.77 +  return json_mark(L, json_regref(arraymt));
    1.78  }
    1.79  
    1.80  #define JSON_STATE_VALUE 0
    1.81 @@ -100,13 +106,13 @@
    1.82    // limit stack to 1 element:
    1.83    lua_settop(L, 1);
    1.84    // push json_objectmt on stack position 2:
    1.85 -  json_regfetch(L, json_objectmt);
    1.86 +  json_regfetch(L, objectmt);
    1.87    // push json_arraymt on stack position 3:
    1.88 -  json_regfetch(L, json_arraymt);
    1.89 +  json_regfetch(L, arraymt);
    1.90    // push json_shadowtbl on stack position 4:
    1.91 -  json_regfetch(L, json_shadowtbl);
    1.92 +  json_regfetch(L, shadowtbl);
    1.93    // push json_nullmark on stack position 5:
    1.94 -  json_regfetch(L, json_nullmark);
    1.95 +  json_regfetch(L, nullmark);
    1.96    // require string as first argument:
    1.97    str = luaL_checklstring(L, 1, &total);
    1.98    // if string contains a NULL byte, this is a syntax error
    1.99 @@ -393,10 +399,10 @@
   1.100    int stacktop;
   1.101    int idx = 2 + json_path_idxshift;
   1.102    // insert json_shadowtbl on stack at position 1:
   1.103 -  json_regfetch(L, json_shadowtbl);
   1.104 +  json_regfetch(L, shadowtbl);
   1.105    lua_insert(L, 1);
   1.106    // insert json_nullmark on stack at position 2:
   1.107 -  json_regfetch(L, json_nullmark);
   1.108 +  json_regfetch(L, nullmark);
   1.109    lua_insert(L, 2);
   1.110    // store number of arguments:
   1.111    stacktop = lua_gettop(L);
   1.112 @@ -449,13 +455,13 @@
   1.113        // otherwise,
   1.114        // check if metatable indicates "object" or "array":
   1.115        if (lua_getmetatable(L, -1)) {
   1.116 -        json_regfetch(L, json_objectmt);
   1.117 +        json_regfetch(L, objectmt);
   1.118          if (lua_rawequal(L, -2, -1)) {
   1.119            // return string "object":
   1.120            lua_pushliteral(L, "object");
   1.121            return 1;
   1.122          }
   1.123 -        json_regfetch(L, json_arraymt);
   1.124 +        json_regfetch(L, arraymt);
   1.125          if (lua_rawequal(L, -3, -1)) {
   1.126            // return string "array":
   1.127            lua_pushliteral(L, "array");
   1.128 @@ -504,13 +510,13 @@
   1.129    // truncate stack to two elements:
   1.130    lua_settop(L, 2);
   1.131    // push json_unknownmt to stack position 3:
   1.132 -  json_regfetch(L, json_unknownmt);
   1.133 +  json_regfetch(L, unknownmt);
   1.134    // push json_objectmt to stack position 4:
   1.135 -  json_regfetch(L, json_objectmt);
   1.136 +  json_regfetch(L, objectmt);
   1.137    // push json_arraymt to stack position 5:
   1.138 -  json_regfetch(L, json_arraymt);
   1.139 +  json_regfetch(L, arraymt);
   1.140    // push json_shadowtbl to stack position 6:
   1.141 -  json_regfetch(L, json_shadowtbl);
   1.142 +  json_regfetch(L, shadowtbl);
   1.143    //
   1.144    lua_getmetatable(L, 1);
   1.145    if (
   1.146 @@ -530,14 +536,14 @@
   1.147      lua_rawset(L, json_setnull_shadowtbl_idx);
   1.148    }
   1.149    lua_pushvalue(L, 2);
   1.150 -  json_regfetch(L, json_nullmark);
   1.151 +  json_regfetch(L, nullmark);
   1.152    lua_rawset(L, -3);
   1.153    return 0;
   1.154  }
   1.155  
   1.156  static int json_len(lua_State *L) {
   1.157    lua_settop(L, 1);
   1.158 -  json_regfetch(L, json_shadowtbl);
   1.159 +  json_regfetch(L, shadowtbl);
   1.160    lua_pushvalue(L, 1);
   1.161    lua_rawget(L, -2);
   1.162    lua_pushinteger(L, lua_rawlen(L, lua_isnil(L, -1) ? 1 : -1));
   1.163 @@ -549,8 +555,8 @@
   1.164  
   1.165  static int json_index(lua_State *L) {
   1.166    lua_settop(L, 2);
   1.167 -  json_regfetch(L, json_nullmark);  // on stack position 3
   1.168 -  json_regfetch(L, json_shadowtbl);
   1.169 +  json_regfetch(L, nullmark);  // on stack position 3
   1.170 +  json_regfetch(L, shadowtbl);
   1.171    lua_pushvalue(L, 1);
   1.172    lua_rawget(L, json_index_shadowtbl_idx);
   1.173    if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   1.174 @@ -562,7 +568,7 @@
   1.175  
   1.176  static int json_newindex(lua_State *L) {
   1.177    lua_settop(L, 3);
   1.178 -  json_regfetch(L, json_shadowtbl);
   1.179 +  json_regfetch(L, shadowtbl);
   1.180    lua_pushvalue(L, 1);
   1.181    lua_rawget(L, -2);
   1.182    if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   1.183 @@ -577,8 +583,8 @@
   1.184  
   1.185  static int json_pairs_iterfunc(lua_State *L) {
   1.186    lua_settop(L, 2);
   1.187 -  json_regfetch(L, json_nullmark);  // on stack position 3
   1.188 -  json_regfetch(L, json_shadowtbl);
   1.189 +  json_regfetch(L, nullmark);  // on stack position 3
   1.190 +  json_regfetch(L, shadowtbl);
   1.191    lua_pushvalue(L, 1);
   1.192    lua_rawget(L, json_pairs_iterfunc_shadowtbl_idx);
   1.193    if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   1.194 @@ -604,8 +610,8 @@
   1.195  static int json_ipairs_iterfunc(lua_State *L) {
   1.196    int idx;
   1.197    lua_settop(L, 2);
   1.198 -  json_regfetch(L, json_nullmark);  // on stack position 3
   1.199 -  json_regfetch(L, json_shadowtbl);
   1.200 +  json_regfetch(L, nullmark);  // on stack position 3
   1.201 +  json_regfetch(L, shadowtbl);
   1.202    idx = lua_tointeger(L, 2) + 1;
   1.203    lua_pushvalue(L, 1);
   1.204    lua_rawget(L, json_ipairs_iterfunc_shadowtbl_idx);
   1.205 @@ -650,15 +656,15 @@
   1.206    lua_newtable(L);  // library
   1.207    lua_newtable(L);
   1.208    luaL_setfuncs(L, json_metatable_functions, 0);
   1.209 -  json_regstore(L, json_unknownmt);
   1.210 +  json_regstore(L, unknownmt);
   1.211    lua_setfield(L, 1, "ambiguous_mt");
   1.212    lua_newtable(L);
   1.213    luaL_setfuncs(L, json_metatable_functions, 0);
   1.214 -  json_regstore(L, json_objectmt);
   1.215 +  json_regstore(L, objectmt);
   1.216    lua_setfield(L, 1, "object_mt");
   1.217    lua_newtable(L);
   1.218    luaL_setfuncs(L, json_metatable_functions, 0);
   1.219 -  json_regstore(L, json_arraymt);
   1.220 +  json_regstore(L, arraymt);
   1.221    lua_setfield(L, 1, "array_mt");
   1.222    lua_newtable(L);  // ephemeron table to store shadow tables for each JSON object/array to allow NULL values returned as nil
   1.223    lua_newtable(L);  // metatable for ephemeron table
   1.224 @@ -666,9 +672,9 @@
   1.225    lua_pushliteral(L, "k");
   1.226    lua_rawset(L, -3);
   1.227    lua_setmetatable(L, -2);
   1.228 -  json_regstore(L, json_shadowtbl);
   1.229 +  json_regstore(L, shadowtbl);
   1.230    lua_newtable(L);
   1.231 -  json_regstore(L, json_nullmark);
   1.232 +  json_regstore(L, nullmark);
   1.233    lua_settop(L, 1);
   1.234    luaL_setfuncs(L, json_module_functions, 0);
   1.235    return 1;

Impressum / About Us