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;