diff options
Diffstat (limited to 'src/tools.c')
-rw-r--r-- | src/tools.c | 249 |
1 files changed, 166 insertions, 83 deletions
diff --git a/src/tools.c b/src/tools.c index 2629fd3..fe1728d 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -42,6 +42,8 @@ THE SOFTWARE. | |||
42 | #include <ctype.h> | 42 | #include <ctype.h> |
43 | #include <stdlib.h> | 43 | #include <stdlib.h> |
44 | 44 | ||
45 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); | ||
46 | |||
45 | MUTEX_T deep_lock; | 47 | MUTEX_T deep_lock; |
46 | MUTEX_T mtid_lock; | 48 | MUTEX_T mtid_lock; |
47 | 49 | ||
@@ -94,45 +96,52 @@ void luaG_dump( lua_State* L ) { | |||
94 | 96 | ||
95 | /*---=== luaG_newstate ===---*/ | 97 | /*---=== luaG_newstate ===---*/ |
96 | 98 | ||
97 | static const luaL_Reg libs[] = { | 99 | static const luaL_Reg libs[] = |
98 | { LUA_LOADLIBNAME, luaopen_package }, | 100 | { |
99 | { LUA_TABLIBNAME, luaopen_table }, | 101 | { LUA_LOADLIBNAME, luaopen_package}, |
100 | { LUA_IOLIBNAME, luaopen_io }, | 102 | { LUA_TABLIBNAME, luaopen_table}, |
101 | { LUA_OSLIBNAME, luaopen_os }, | 103 | { LUA_IOLIBNAME, luaopen_io}, |
102 | { LUA_STRLIBNAME, luaopen_string }, | 104 | { LUA_OSLIBNAME, luaopen_os}, |
103 | { LUA_MATHLIBNAME, luaopen_math }, | 105 | { LUA_STRLIBNAME, luaopen_string}, |
104 | { LUA_DBLIBNAME, luaopen_debug }, | 106 | { LUA_MATHLIBNAME, luaopen_math}, |
105 | // | 107 | #if LUA_VERSION_NUM >= 502 |
106 | { "base", NULL }, // ignore "base" (already acquired it) | 108 | { LUA_BITLIBNAME, luaopen_bit32}, |
107 | { "coroutine", NULL }, // part of Lua 5.1 base package | 109 | #endif // LUA_VERSION_NUM |
108 | { NULL, NULL } | 110 | { LUA_DBLIBNAME, luaopen_debug}, |
111 | // | ||
112 | { "base", NULL }, // ignore "base" (already acquired it) | ||
113 | { LUA_COLIBNAME, NULL }, // part of Lua 5.[1|2] base package | ||
114 | { NULL, NULL } | ||
109 | }; | 115 | }; |
110 | 116 | ||
111 | static bool_t openlib( lua_State *L, const char *name, size_t len ) { | 117 | static void open1lib( lua_State* L, char const* name, size_t len) |
112 | 118 | { | |
113 | unsigned i; | 119 | int i; |
114 | bool_t all= strncmp( name, "*", len ) == 0; | 120 | for( i = 0; libs[i].name; ++ i) |
115 | |||
116 | for( i=0; libs[i].name; i++ ) | ||
117 | { | 121 | { |
118 | if (all || (strncmp(name, libs[i].name, len) ==0)) | 122 | if( strncmp( name, libs[i].name, len) == 0) |
119 | { | 123 | { |
120 | if (libs[i].func) | 124 | if( libs[i].func) |
121 | { | 125 | { |
122 | STACK_GROW(L,1); | 126 | DEBUGSPEW_CODE( fprintf( stderr, "opening %.*s library\n", len, name)); |
123 | STACK_CHECK(L) | 127 | STACK_GROW( L, 1); |
128 | STACK_CHECK( L) | ||
124 | lua_pushcfunction( L, libs[i].func); | 129 | lua_pushcfunction( L, libs[i].func); |
125 | // pushes the module table on the stack | 130 | // pushes the module table on the stack |
126 | lua_call( L, 0, 1); | 131 | lua_call( L, 0, 1); |
127 | populate_func_lookup_table( L, -1, libs[i].name); | 132 | populate_func_lookup_table( L, -1, libs[i].name); |
128 | // remove the module when we are done | 133 | #if LUA_VERSION_NUM >= 502 |
134 | // Lua 5.2: luaopen_x doesn't create the global, we have to do it ourselves! | ||
135 | lua_setglobal( L, libs[i].name); | ||
136 | #else // LUA_VERSION_NUM | ||
137 | // Lua 5.1: remove the module when we are done | ||
129 | lua_pop( L, 1); | 138 | lua_pop( L, 1); |
130 | STACK_END(L, 0) | 139 | #endif // LUA_VERSION_NUM |
140 | STACK_END( L, 0) | ||
131 | } | 141 | } |
132 | if (!all) return TRUE; | 142 | break; |
133 | } | 143 | } |
134 | } | 144 | } |
135 | return all; | ||
136 | } | 145 | } |
137 | 146 | ||
138 | static int dummy_writer(lua_State *L, const void* p, size_t sz, void* ud) | 147 | static int dummy_writer(lua_State *L, const void* p, size_t sz, void* ud) |
@@ -323,6 +332,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
323 | // remove table name from fqn stack | 332 | // remove table name from fqn stack |
324 | lua_pushnil( L); // ... {_i} {bfc} k nil | 333 | lua_pushnil( L); // ... {_i} {bfc} k nil |
325 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k | 334 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k |
335 | DEBUGSPEW_CODE( fprintf( stderr, "%.*spopulating: %s\n", _i, debugspew_indent, newName)); | ||
326 | -- _depth; | 336 | -- _depth; |
327 | } | 337 | } |
328 | else | 338 | else |
@@ -372,12 +382,12 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
372 | /* | 382 | /* |
373 | * create a "fully.qualified.name" <-> function equivalence database | 383 | * create a "fully.qualified.name" <-> function equivalence database |
374 | */ | 384 | */ |
375 | void populate_func_lookup_table( lua_State *L, int _i, char const *_name) | 385 | void populate_func_lookup_table( lua_State* L, int _i, char const* _name) |
376 | { | 386 | { |
377 | int const ctx_base = lua_gettop( L) + 1; | 387 | int const ctx_base = lua_gettop( L) + 1; |
378 | int const in_base = lua_absindex( L, _i); | 388 | int const in_base = lua_absindex( L, _i); |
379 | int const start_depth = _name ? 1 : 0; | 389 | int const start_depth = _name ? 1 : 0; |
380 | //printf( "%p: populate_func_lookup_table('%s')\n", L, _name ? _name : "NULL"); | 390 | DEBUGSPEW_CODE( fprintf( stderr, "%p: populate_func_lookup_table('%s')\n", L, _name ? _name : "NULL")); |
381 | STACK_GROW( L, 3); | 391 | STACK_GROW( L, 3); |
382 | STACK_CHECK( L) | 392 | STACK_CHECK( L) |
383 | lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // {}? | 393 | lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // {}? |
@@ -423,8 +433,6 @@ void populate_func_lookup_table( lua_State *L, int _i, char const *_name) | |||
423 | 433 | ||
424 | lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) | 434 | lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) |
425 | { | 435 | { |
426 | char const* p; | ||
427 | unsigned int len; | ||
428 | lua_State* const L = luaL_newstate(); | 436 | lua_State* const L = luaL_newstate(); |
429 | 437 | ||
430 | // no libs, or special init func (not even 'base') | 438 | // no libs, or special init func (not even 'base') |
@@ -447,31 +455,43 @@ lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) | |||
447 | { | 455 | { |
448 | if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility) | 456 | if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility) |
449 | { | 457 | { |
458 | DEBUGSPEW_CODE( fprintf( stderr, "opening ALL base libraries\n")); | ||
450 | luaL_openlibs( L); | 459 | luaL_openlibs( L); |
451 | libs = NULL; // done with libs | 460 | libs = NULL; // done with libs |
452 | } | 461 | } |
453 | else | 462 | else |
454 | { | 463 | { |
464 | DEBUGSPEW_CODE( fprintf( stderr, "opening base library\n")); | ||
455 | lua_pushcfunction( L, luaopen_base); | 465 | lua_pushcfunction( L, luaopen_base); |
456 | lua_call( L, 0, 0); | 466 | lua_call( L, 0, 0); |
457 | } | 467 | } |
458 | } | 468 | } |
469 | |||
459 | // after opening base, register the functions it exported in our name<->function database | 470 | // after opening base, register the functions it exported in our name<->function database |
460 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack | 471 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
461 | populate_func_lookup_table( L, -1, NULL); | 472 | populate_func_lookup_table( L, -1, NULL); |
462 | lua_pop( L, 1); | 473 | lua_pop( L, 1); |
474 | |||
463 | STACK_MID( L, 0); | 475 | STACK_MID( L, 0); |
464 | if( libs) | ||
465 | { | 476 | { |
466 | for( p = libs; *p; p += len) | 477 | char const* p; |
478 | unsigned int len = 0; | ||
479 | if( libs) | ||
467 | { | 480 | { |
468 | len=0; | 481 | for( p = libs; *p; p += len) |
469 | while (*p && !is_name_char(*p)) p++; // bypass delimiters | 482 | { |
470 | while (is_name_char(p[len])) len++; // bypass name | 483 | len = 0; |
471 | if (len && (!openlib( L, p, len ))) | 484 | // skip delimiters |
472 | break; | 485 | while( *p && !is_name_char( *p)) |
486 | ++ p; | ||
487 | // skip name | ||
488 | while( is_name_char( p[len])) | ||
489 | ++ len; | ||
490 | // open library | ||
491 | open1lib( L, p, len); | ||
492 | } | ||
493 | serialize_require( L); | ||
473 | } | 494 | } |
474 | serialize_require( L); | ||
475 | } | 495 | } |
476 | STACK_END(L,0) | 496 | STACK_END(L,0) |
477 | lua_gc( L, LUA_GCRESTART, 0); | 497 | lua_gc( L, LUA_GCRESTART, 0); |
@@ -1126,9 +1146,9 @@ static bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, | |||
1126 | * | 1146 | * |
1127 | * Always pushes a function to 'L2'. | 1147 | * Always pushes a function to 'L2'. |
1128 | */ | 1148 | */ |
1129 | static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ); | 1149 | static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i); |
1130 | 1150 | ||
1131 | static void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) | 1151 | static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i) |
1132 | { | 1152 | { |
1133 | void * const aspointer = (void*)lua_topointer( L, i); | 1153 | void * const aspointer = (void*)lua_topointer( L, i); |
1134 | // TBD: Merge this and same code for tables | 1154 | // TBD: Merge this and same code for tables |
@@ -1228,6 +1248,27 @@ int discover_object_name_recur( lua_State* L, int _shortest, int _length) | |||
1228 | else if( lua_istable( L, -1)) | 1248 | else if( lua_istable( L, -1)) |
1229 | { | 1249 | { |
1230 | _shortest = discover_object_name_recur( L, _shortest, _length); | 1250 | _shortest = discover_object_name_recur( L, _shortest, _length); |
1251 | // search in the table's metatable too | ||
1252 | if( lua_getmetatable( L, -1)) | ||
1253 | { | ||
1254 | if( lua_istable( L, -1)) | ||
1255 | { | ||
1256 | _shortest = discover_object_name_recur( L, _shortest, _length); | ||
1257 | } | ||
1258 | lua_pop( L, 1); | ||
1259 | } | ||
1260 | } | ||
1261 | else if( lua_isuserdata( L, -1)) | ||
1262 | { | ||
1263 | // search in the object's metatable (some modules are built that way) | ||
1264 | if( lua_getmetatable( L, -1)) | ||
1265 | { | ||
1266 | if( lua_istable( L, -1)) | ||
1267 | { | ||
1268 | _shortest = discover_object_name_recur( L, _shortest, _length); | ||
1269 | } | ||
1270 | lua_pop( L, 1); | ||
1271 | } | ||
1231 | } | 1272 | } |
1232 | // make ready for next iteration | 1273 | // make ready for next iteration |
1233 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k | 1274 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k |
@@ -1298,9 +1339,10 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | |||
1298 | if( !fqn) | 1339 | if( !fqn) |
1299 | { | 1340 | { |
1300 | char const* from; | 1341 | char const* from; |
1301 | lua_pushvalue( L, i); // ... f ... f | ||
1302 | // try to discover the name of the function we want to send | 1342 | // try to discover the name of the function we want to send |
1303 | luaG_nameof( L); // ... f ... "type" "name" | 1343 | lua_pushcfunction( L, luaG_nameof); // ... f ...luaG_nameof |
1344 | lua_pushvalue( L, i); // ... f ... luaG_nameof f | ||
1345 | lua_call( L, 1, 2); // ... f ... "type" "name" | ||
1304 | lua_getglobal( L, "decoda_name"); // ... f ... "type" "name" decoda_name | 1346 | lua_getglobal( L, "decoda_name"); // ... f ... "type" "name" decoda_name |
1305 | from = lua_tostring( L, -1); | 1347 | from = lua_tostring( L, -1); |
1306 | (void) luaL_error( L, "%s '%s' not found in %s origin transfer database.", lua_tostring( L, -3), lua_tostring( L, -2), from ? from : "main"); | 1348 | (void) luaL_error( L, "%s '%s' not found in %s origin transfer database.", lua_tostring( L, -3), lua_tostring( L, -2), from ? from : "main"); |
@@ -1327,15 +1369,6 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | |||
1327 | STACK_END( L2, 1) | 1369 | STACK_END( L2, 1) |
1328 | } | 1370 | } |
1329 | 1371 | ||
1330 | #define LOG_FUNC_INFO 0 | ||
1331 | #if LOG_FUNC_INFO | ||
1332 | #define LOG_FUNC_INFO_CODE(_code) _code | ||
1333 | #else // LOG_FUNC_INFO | ||
1334 | #define LOG_FUNC_INFO_CODE(_code) | ||
1335 | #endif // LOG_FUNC_INFO | ||
1336 | |||
1337 | LOG_FUNC_INFO_CODE( static char const* s_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); | ||
1338 | |||
1339 | /* | 1372 | /* |
1340 | * Copy a function over, which has not been found in the cache. | 1373 | * Copy a function over, which has not been found in the cache. |
1341 | * L2 has the cache key for this function at the top of the stack | 1374 | * L2 has the cache key for this function at the top of the stack |
@@ -1350,7 +1383,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1350 | FuncSubType funcSubType; | 1383 | FuncSubType funcSubType; |
1351 | lua_CFunction cfunc = luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions | 1384 | lua_CFunction cfunc = luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions |
1352 | 1385 | ||
1353 | ASSERT_L( L2_cache_i != 0); // ... {cache} ... p | 1386 | ASSERT_L( L2_cache_i != 0); // ... {cache} ... p |
1354 | STACK_GROW(L,2); | 1387 | STACK_GROW(L,2); |
1355 | STACK_CHECK(L) | 1388 | STACK_CHECK(L) |
1356 | 1389 | ||
@@ -1362,7 +1395,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1362 | // if already on top of the stack, no need to push again | 1395 | // if already on top of the stack, no need to push again |
1363 | int needToPush = (i != (uint_t)lua_gettop( L)); | 1396 | int needToPush = (i != (uint_t)lua_gettop( L)); |
1364 | if( needToPush) | 1397 | if( needToPush) |
1365 | lua_pushvalue( L, i); | 1398 | lua_pushvalue( L, i); // ... f |
1366 | 1399 | ||
1367 | luaL_buffinit( L, &b); | 1400 | luaL_buffinit( L, &b); |
1368 | // | 1401 | // |
@@ -1374,12 +1407,13 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1374 | luaL_error( L, "internal error: function dump failed."); | 1407 | luaL_error( L, "internal error: function dump failed."); |
1375 | } | 1408 | } |
1376 | 1409 | ||
1377 | luaL_pushresult( &b); // pushes dumped string on 'L' | 1410 | // pushes dumped string on 'L' |
1411 | luaL_pushresult( &b); // ... f b | ||
1378 | 1412 | ||
1379 | // if not pushed, no need to pop | 1413 | // if not pushed, no need to pop |
1380 | if( needToPush) | 1414 | if( needToPush) |
1381 | { | 1415 | { |
1382 | lua_remove( L, -2); | 1416 | lua_remove( L, -2); // ... b |
1383 | } | 1417 | } |
1384 | 1418 | ||
1385 | // transfer the bytecode, then the upvalues, to create a similar closure | 1419 | // transfer the bytecode, then the upvalues, to create a similar closure |
@@ -1392,15 +1426,16 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1392 | // | 1426 | // |
1393 | { | 1427 | { |
1394 | lua_Debug ar; | 1428 | lua_Debug ar; |
1395 | lua_pushvalue( L, i); | 1429 | lua_pushvalue( L, i); // ... b f |
1396 | lua_getinfo(L, ">nS", &ar); // fills 'name' 'namewhat' and 'linedefined', pops function | 1430 | // fills 'name' 'namewhat' and 'linedefined', pops function |
1431 | lua_getinfo(L, ">nS", &ar); // ... b | ||
1397 | name = ar.namewhat; | 1432 | name = ar.namewhat; |
1398 | fprintf( stderr, "%.*sFNAME: %s @ %d\n", i, s_indent, ar.short_src, ar.linedefined); // just gives NULL | 1433 | fprintf( stderr, "%.*sFNAME: %s @ %d\n", i, s_indent, ar.short_src, ar.linedefined); // just gives NULL |
1399 | } | 1434 | } |
1400 | #endif // LOG_FUNC_INFO | 1435 | #endif // LOG_FUNC_INFO |
1401 | { | 1436 | { |
1402 | size_t sz; | 1437 | size_t sz; |
1403 | char const* s = lua_tolstring( L, -1, &sz); | 1438 | char const* s = lua_tolstring( L, -1, &sz); // ... b |
1404 | ASSERT_L( s && sz); | 1439 | ASSERT_L( s && sz); |
1405 | STACK_GROW( L2, 2); | 1440 | STACK_GROW( L2, 2); |
1406 | // Note: Line numbers seem to be taken precisely from the | 1441 | // Note: Line numbers seem to be taken precisely from the |
@@ -1409,7 +1444,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1409 | // | 1444 | // |
1410 | // TBD: Can we get the function's original name through, as well? | 1445 | // TBD: Can we get the function's original name through, as well? |
1411 | // | 1446 | // |
1412 | if( luaL_loadbuffer( L2, s, sz, name) != 0) // ... {cache} ... p function | 1447 | if( luaL_loadbuffer( L2, s, sz, name) != 0) // ... {cache} ... p function |
1413 | { | 1448 | { |
1414 | // chunk is precompiled so only LUA_ERRMEM can happen | 1449 | // chunk is precompiled so only LUA_ERRMEM can happen |
1415 | // "Otherwise, it pushes an error message" | 1450 | // "Otherwise, it pushes an error message" |
@@ -1417,38 +1452,50 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1417 | STACK_GROW( L, 1); | 1452 | STACK_GROW( L, 1); |
1418 | luaL_error( L, "%s", lua_tostring( L2, -1)); | 1453 | luaL_error( L, "%s", lua_tostring( L2, -1)); |
1419 | } | 1454 | } |
1420 | lua_pop( L, 1); // remove the dumped string | 1455 | // remove the dumped string |
1456 | lua_pop( L, 1); // ... | ||
1421 | // now set the cache as soon as we can. | 1457 | // now set the cache as soon as we can. |
1422 | // this is necessary if one of the function's upvalues references it indirectly | 1458 | // this is necessary if one of the function's upvalues references it indirectly |
1423 | // we need to find it in the cache even if it isn't fully transfered yet | 1459 | // we need to find it in the cache even if it isn't fully transfered yet |
1424 | lua_insert( L2, -2); // ... {cache} ... function p | 1460 | lua_insert( L2, -2); // ... {cache} ... function p |
1425 | lua_pushvalue( L2, -2); // ... {cache} ... function p function | 1461 | lua_pushvalue( L2, -2); // ... {cache} ... function p function |
1426 | // cache[p] = function | 1462 | // cache[p] = function |
1427 | lua_rawset( L2, L2_cache_i); // ... {cache} ... function | 1463 | lua_rawset( L2, L2_cache_i); // ... {cache} ... function |
1428 | } | 1464 | } |
1429 | STACK_MID( L, 0) | 1465 | STACK_MID( L, 0) |
1430 | 1466 | ||
1431 | /* push over any upvalues; references to this function will come from | 1467 | /* push over any upvalues; references to this function will come from |
1432 | * cache so we don't end up in eternal loop. | 1468 | * cache so we don't end up in eternal loop. |
1469 | * Lua5.2: one of the upvalues is _ENV, which we don't want to copy! | ||
1470 | * instead, the function shall have LUA_RIDX_GLOBALS taken in the destination state! | ||
1433 | */ | 1471 | */ |
1434 | { | 1472 | { |
1435 | LOG_FUNC_INFO_CODE( char const* upname); | 1473 | DEBUGSPEW_CODE( char const* upname); |
1436 | for( n = 0; (LOG_FUNC_INFO_CODE( upname =) lua_getupvalue( L, i, 1 + n)) != NULL; ++ n) | 1474 | #if LUA_VERSION_NUM == 502 |
1437 | { | 1475 | // With Lua 5.2, each Lua function gets its environment as one of its upvalues (named LUA_ENV, aka "_ENV" by default) |
1438 | LOG_FUNC_INFO_CODE( fprintf( stderr, "%.*sUPNAME[%d]: %s\n", i, s_indent, n, upname)); | 1476 | // Generally this is LUA_RIDX_GLOBALS, which we don't want to copy from the source to the destination state... |
1439 | // v 3.4.2: we now longer need to handle this special case, because the general mechanism can take care of it just fine | 1477 | // -> if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table |
1440 | /*if( (!cfunc) && lua_equal( L, i, -1)) | 1478 | lua_pushglobaltable( L); // ... _G |
1479 | #endif // LUA_VERSION_NUM | ||
1480 | for( n = 0; (DEBUGSPEW_CODE( upname =) lua_getupvalue( L, i, 1 + n)) != NULL; ++ n) | ||
1481 | { // ... _G up[n] | ||
1482 | DEBUGSPEW_CODE( fprintf( stderr, "%.*sUPNAME[%d]: %s\n", i, debugspew_indent, n, upname)); | ||
1483 | #if LUA_VERSION_NUM == 502 | ||
1484 | if( lua_rawequal( L, -1, -2)) // is the upvalue equal to the global table? | ||
1441 | { | 1485 | { |
1442 | // Lua closure that has a (recursive) upvalue to itself | 1486 | lua_pushglobaltable( L2); // ... {cache} ... function <upvalues> |
1443 | lua_pushvalue( L2, -n - 1); // ... {cache} ... function upvalues... | ||
1444 | } | 1487 | } |
1445 | else*/ | 1488 | else |
1489 | #endif // LUA_VERSION_NUM | ||
1446 | { | 1490 | { |
1447 | if( !inter_copy_one_( L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL)) | 1491 | if( !inter_copy_one_( L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL)) // ... {cache} ... function <upvalues> |
1448 | luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); | 1492 | luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); |
1449 | } | 1493 | } |
1450 | lua_pop( L, 1); | 1494 | lua_pop( L, 1); // ... _G |
1451 | } | 1495 | } |
1496 | #if LUA_VERSION_NUM == 502 | ||
1497 | lua_pop( L, 1); // ... | ||
1498 | #endif // LUA_VERSION_NUM | ||
1452 | } | 1499 | } |
1453 | // L2: function + 'n' upvalues (>=0) | 1500 | // L2: function + 'n' upvalues (>=0) |
1454 | 1501 | ||
@@ -1459,7 +1506,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1459 | int func_index = lua_gettop( L2) - n; | 1506 | int func_index = lua_gettop( L2) - n; |
1460 | for( ; n > 0; -- n) | 1507 | for( ; n > 0; -- n) |
1461 | { | 1508 | { |
1462 | char const* rc = lua_setupvalue( L2, func_index, n); // ... {cache} ... function | 1509 | char const* rc = lua_setupvalue( L2, func_index, n); // ... {cache} ... function |
1463 | // | 1510 | // |
1464 | // "assigns the value at the top of the stack to the upvalue and returns its name. | 1511 | // "assigns the value at the top of the stack to the upvalue and returns its name. |
1465 | // It also pops the value from the stack." | 1512 | // It also pops the value from the stack." |
@@ -1467,16 +1514,16 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1467 | ASSERT_L( rc); // not having enough slots? | 1514 | ASSERT_L( rc); // not having enough slots? |
1468 | } | 1515 | } |
1469 | // once all upvalues have been set we are left | 1516 | // once all upvalues have been set we are left |
1470 | // with the function at the top of the stack // ... {cache} ... function | 1517 | // with the function at the top of the stack // ... {cache} ... function |
1471 | } | 1518 | } |
1472 | } | 1519 | } |
1473 | } | 1520 | } |
1474 | else // C function OR LuaJIT fast function!!! | 1521 | else // C function OR LuaJIT fast function!!! |
1475 | { | 1522 | { |
1476 | lua_pop( L2, 1); // ... {cache} ... | 1523 | lua_pop( L2, 1); // ... {cache} ... |
1477 | LOG_FUNC_INFO_CODE( fprintf( stderr, "%.*sFNAME: [C] function %p \n", i, s_indent, cfunc)); | 1524 | DEBUGSPEW_CODE( fprintf( stderr, "%.*sFNAME: [C] function %p \n", i, debugspew_indent, cfunc)); |
1478 | // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up | 1525 | // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up |
1479 | lookup_native_func( L2, L, i); // ... {cache} ... function | 1526 | lookup_native_func( L2, L, i); // ... {cache} ... function |
1480 | } | 1527 | } |
1481 | STACK_END( L, 0) | 1528 | STACK_END( L, 0) |
1482 | } | 1529 | } |
@@ -1518,8 +1565,8 @@ static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, u | |||
1518 | break; | 1565 | break; |
1519 | 1566 | ||
1520 | case LUA_TSTRING: { | 1567 | case LUA_TSTRING: { |
1521 | size_t len; const char *s = lua_tolstring( L, i, &len ); | 1568 | size_t len; const char* s = lua_tolstring( L, i, &len); |
1522 | LOG_FUNC_INFO_CODE( if( vt == VT_KEY) fprintf( stderr, "%.*sKEY: %s\n", i, s_indent, s)); | 1569 | DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, "%.*sKEY: %s\n", i, debugspew_indent, s)); |
1523 | lua_pushlstring( L2, s, len ); | 1570 | lua_pushlstring( L2, s, len ); |
1524 | } break; | 1571 | } break; |
1525 | 1572 | ||
@@ -1735,7 +1782,7 @@ int luaG_inter_copy( lua_State* L, lua_State *L2, uint_t n) | |||
1735 | } | 1782 | } |
1736 | 1783 | ||
1737 | /* | 1784 | /* |
1738 | * Remove the cache table. Persistant caching would cause i.e. multiple | 1785 | * Remove the cache table. Persistent caching would cause i.e. multiple |
1739 | * messages passed in the same table to use the same table also in receiving | 1786 | * messages passed in the same table to use the same table also in receiving |
1740 | * end. | 1787 | * end. |
1741 | */ | 1788 | */ |
@@ -1755,13 +1802,49 @@ int luaG_inter_copy( lua_State* L, lua_State *L2, uint_t n) | |||
1755 | } | 1802 | } |
1756 | 1803 | ||
1757 | 1804 | ||
1758 | int luaG_inter_move( lua_State* L, lua_State *L2, uint_t n ) | 1805 | int luaG_inter_move( lua_State* L, lua_State* L2, uint_t n) |
1759 | { | 1806 | { |
1760 | int ret = luaG_inter_copy( L, L2, n); | 1807 | int ret = luaG_inter_copy( L, L2, n); |
1761 | lua_pop( L, (int) n); | 1808 | lua_pop( L, (int) n); |
1762 | return ret; | 1809 | return ret; |
1763 | } | 1810 | } |
1764 | 1811 | ||
1812 | void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx) | ||
1813 | { | ||
1814 | // package | ||
1815 | STACK_CHECK( L) | ||
1816 | STACK_CHECK( L2) | ||
1817 | _idx = lua_absindex( L, _idx); | ||
1818 | if( lua_type( L, _idx) != LUA_TTABLE) | ||
1819 | { | ||
1820 | (void) luaL_error( L, "expected package as table, got %s", luaL_typename( L, _idx)); | ||
1821 | } | ||
1822 | lua_getglobal( L2, "package"); | ||
1823 | if( !lua_isnil( L2, -1)) // package library not loaded: do nothing | ||
1824 | { | ||
1825 | int i; | ||
1826 | // package.loaders is renamed package.searchers in Lua 5.2 | ||
1827 | char const* entries[] = { "path", "cpath", "preload", (LUA_VERSION_NUM == 501) ? "loaders" : "searchers", NULL}; | ||
1828 | for( i = 0; entries[i]; ++ i) | ||
1829 | { | ||
1830 | lua_getfield( L, _idx, entries[i]); | ||
1831 | if( lua_isnil( L, -1)) | ||
1832 | { | ||
1833 | lua_pop( L, 1); | ||
1834 | } | ||
1835 | else | ||
1836 | { | ||
1837 | luaG_inter_move( L, L2, 1); // moves the entry to L2 | ||
1838 | lua_setfield( L2, -2, entries[i]); // set package[entries[i]] | ||
1839 | } | ||
1840 | } | ||
1841 | } | ||
1842 | lua_pop( L2, 1); | ||
1843 | STACK_END( L2, 0) | ||
1844 | STACK_END( L, 0) | ||
1845 | } | ||
1846 | |||
1847 | |||
1765 | /*---=== Serialize require ===--- | 1848 | /*---=== Serialize require ===--- |
1766 | */ | 1849 | */ |
1767 | 1850 | ||