aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools.c84
1 files changed, 41 insertions, 43 deletions
diff --git a/src/tools.c b/src/tools.c
index 2fc7b58..e89b340 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -202,19 +202,19 @@ static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out)
202 202
203 203
204// inspired from tconcat() in ltablib.c 204// inspired from tconcat() in ltablib.c
205static char const * luaG_pushFQN(lua_State *L, int t, int last) 205static char const* luaG_pushFQN(lua_State *L, int t, int last)
206{ 206{
207 int i = 1; 207 int i = 1;
208 luaL_Buffer b; 208 luaL_Buffer b;
209 STACK_CHECK( L) 209 STACK_CHECK( L)
210 luaL_buffinit(L, &b); 210 luaL_buffinit(L, &b);
211 for( ; i < last; i++) 211 for( ; i < last; ++ i)
212 { 212 {
213 lua_rawgeti( L, t, i); 213 lua_rawgeti( L, t, i);
214 luaL_addvalue( &b); 214 luaL_addvalue( &b);
215 luaL_addlstring(&b, ".", 1); 215 luaL_addlstring(&b, ".", 1);
216 } 216 }
217 if (i == last) /* add last value (if interval was not empty) */ 217 if( i == last) // add last value (if interval was not empty)
218 { 218 {
219 lua_rawgeti( L, t, i); 219 lua_rawgeti( L, t, i);
220 luaL_addvalue( &b); 220 luaL_addvalue( &b);
@@ -225,7 +225,7 @@ static char const * luaG_pushFQN(lua_State *L, int t, int last)
225} 225}
226 226
227 227
228static void populate_func_lookup_table_recur( lua_State *L, int _ctx_base, int _i, int _depth) 228static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _i, int _depth)
229{ 229{
230 lua_Integer visit_count; 230 lua_Integer visit_count;
231 // slot 1 in the stack contains the table that receives everything we found 231 // slot 1 in the stack contains the table that receives everything we found
@@ -282,49 +282,47 @@ static void populate_func_lookup_table_recur( lua_State *L, int _ctx_base, int _
282 lua_pushvalue( L, -2); // ... {_i} {bfc} k {} k 282 lua_pushvalue( L, -2); // ... {_i} {bfc} k {} k
283 lua_insert( L, -2); // ... {_i} {bfc} k k {} 283 lua_insert( L, -2); // ... {_i} {bfc} k k {}
284 lua_rawset( L, breadth_first_cache); // ... {_i} {bfc} k 284 lua_rawset( L, breadth_first_cache); // ... {_i} {bfc} k
285 STACK_MID( L, 2)
286 } 285 }
287 else if( lua_isfunction( L, -1)) // ... {_i} {bfc} k func 286 else if( lua_isfunction( L, -1) && (luaG_getfuncsubtype( L, -1) != FST_Bytecode)) // ... {_i} {bfc} k func
288 { 287 {
289 if( luaG_getfuncsubtype( L, -1) != FST_Bytecode) 288 char const* prevName, * newName;
289 // first, raise an error if the function is already known
290 lua_pushvalue( L, -1); // ... {_i} {bfc} k func func
291 lua_rawget( L, dest); // ... {_i} {bfc} k func name?
292 prevName = lua_tostring( L, -1); // NULL if we got nil (first encounter of this function)
293 // push function name in fqn stack (note that concatenation will crash if name is a not string or a number)
294 lua_pushvalue( L, -3); // ... {_i} {bfc} k func name? k
295 ++ _depth;
296 lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k func name?
297 // generate name
298 newName = luaG_pushFQN( L, fqn, _depth); // ... {_i} {bfc} k func name? "f.q.n"
299 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order
300 // on different VMs even when the tables are populated the exact same way.
301 // When Lua is built with compatibility options (such as LUA_COMPAT_ALL),
302 // this causes several base libraries to register functions under multiple names.
303 // This, with the randomizer, can cause the first name of a function to be different on different VMs,
304 // which breaks function transfer.
305 // This means that Lua 5.2 must be built with compatibility off to be able to use Lanes.
306 // Even under Lua 5.1, this may cause trouble (even if this would be much less frequent)
307 // Unfortunately, this fails with string.gfind/string.gmatch when Lua 5.1 is built with LUA_COMPAT_GFIND (which is the case of LuaBinaries),
308 // so for the time being, fail only for Lua 5.2 as the randomizer is the real show breaker here.
309 if( (LUA_VERSION_NUM > 501) && (prevName != NULL))
290 { 310 {
291 //char const *fqnString; for debugging 311 (void) luaL_error( L, "multiple names detected (%s and %s)", prevName, newName);
292 bool_t not_registered; 312 return;
293 // first, skip everything if the function is already known
294 lua_pushvalue( L, -1); // ... {_i} {bfc} k func func
295 lua_rawget( L, dest); // ... {_i} {bfc} k func name?
296 not_registered = lua_isnil( L, -1);
297 lua_pop( L, 1); // ... {_i} {bfc} k func
298 if( not_registered)
299 {
300 ++ _depth;
301 // push function name in fqn stack (note that concatenation will crash if name is a not string!)
302 lua_pushvalue( L, -2); // ... {_i} {bfc} k func k
303 lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k func
304 // generate name
305 /*fqnString =*/ (void) luaG_pushFQN( L, fqn, _depth); // ... {_i} {bfc} k func "f.q.n"
306 //puts( fqnString);
307 // prepare the stack for database feed
308 lua_pushvalue( L, -1); // ... {_i} {bfc} k func "f.q.n" "f.q.n"
309 lua_pushvalue( L, -3); // ... {_i} {bfc} k func "f.q.n" "f.q.n" func
310 // t["f.q.n"] = func
311 lua_rawset( L, dest); // ... {_i} {bfc} k func "f.q.n"
312 // t[func] = "f.q.n"
313 lua_rawset( L, dest); // ... {_i} {bfc} k
314 // remove table name from fqn stack
315 lua_pushnil( L); // ... {_i} {bfc} k nil
316 lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k
317 -- _depth;
318 }
319 else
320 {
321 lua_pop( L, 1); // ... {_i} {bfc} k
322 }
323 }
324 else
325 {
326 lua_pop( L, 1); // ... {_i} {bfc} k
327 } 313 }
314 // prepare the stack for database feed
315 lua_remove( L, -2); // ... {_i} {bfc} k func "f.q.n"
316 lua_pushvalue( L, -1); // ... {_i} {bfc} k func "f.q.n" "f.q.n"
317 lua_pushvalue( L, -3); // ... {_i} {bfc} k func "f.q.n" "f.q.n" func
318 // t["f.q.n"] = func
319 lua_rawset( L, dest); // ... {_i} {bfc} k func "f.q.n"
320 // t[func] = "f.q.n"
321 lua_rawset( L, dest); // ... {_i} {bfc} k
322 // remove table name from fqn stack
323 lua_pushnil( L); // ... {_i} {bfc} k nil
324 lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k
325 -- _depth;
328 } 326 }
329 else 327 else
330 { 328 {