aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools.c123
1 files changed, 55 insertions, 68 deletions
diff --git a/src/tools.c b/src/tools.c
index 0206897..2629fd3 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -8,6 +8,7 @@
8=============================================================================== 8===============================================================================
9 9
10Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> 10Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com>
11 2011-13 benoit Germain <bnt.germain@gmail.com>
11 12
12Permission is hereby granted, free of charge, to any person obtaining a copy 13Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal 14of this software and associated documentation files (the "Software"), to deal
@@ -1129,74 +1130,47 @@ static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uin
1129 1130
1130static void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) 1131static void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i )
1131{ 1132{
1132 void * const aspointer = (void*)lua_topointer( L, i ); 1133 void * const aspointer = (void*)lua_topointer( L, i);
1133 // TBD: Merge this and same code for tables 1134 // TBD: Merge this and same code for tables
1134 ASSERT_L( L2_cache_i != 0 ); 1135 ASSERT_L( L2_cache_i != 0 );
1135 1136
1136 STACK_GROW(L2,3); 1137 STACK_GROW( L2, 2);
1137 1138
1138 // L2_cache[id_str]= function 1139 // L2_cache[id_str]= function
1139 // 1140 //
1140 STACK_CHECK(L2) 1141 STACK_CHECK( L2)
1141 1142
1142 // We don't need to use the from state ('L') in ID since the life span 1143 // We don't need to use the from state ('L') in ID since the life span
1143 // is only for the duration of a copy (both states are locked). 1144 // is only for the duration of a copy (both states are locked).
1144 // 1145 //
1145 lua_pushlightuserdata( L2, aspointer); // push a light userdata uniquely representing the function 1146
1147 // push a light userdata uniquely representing the function
1148 lua_pushlightuserdata( L2, aspointer); // ... {cache} ... p
1146 1149
1147 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); 1150 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) );
1148 1151
1149 lua_pushvalue( L2, -1 ); 1152 lua_pushvalue( L2, -1 ); // ... {cache} ... p p
1150 lua_rawget( L2, L2_cache_i ); 1153 lua_rawget( L2, L2_cache_i ); // ... {cache} ... p function|nil|true
1151 //
1152 // [-2]: identity lightuserdata function pointer
1153 // [-1]: function|nil|true (true means: we're working on it; recursive)
1154 1154
1155 if (lua_isnil(L2,-1)) 1155 if( lua_isnil(L2,-1)) // function is unknown
1156 { 1156 {
1157 lua_pop(L2,1); 1157 lua_pop( L2, 1); // ... {cache} ... p
1158 1158
1159 // Set to 'true' for the duration of creation; need to find self-references 1159 // Set to 'true' for the duration of creation; need to find self-references
1160 // via upvalues 1160 // via upvalues
1161 // 1161 //
1162 lua_pushvalue( L2, -1); 1162 // pushes a copy of the func, a stores a reference in the cache
1163 lua_pushboolean(L2,TRUE); 1163 inter_copy_func( L2, L2_cache_i, L, i); // ... {cache} ... function
1164 lua_rawset( L2, L2_cache_i);
1165
1166 inter_copy_func( L2, L2_cache_i, L, i ); // pushes a copy of the func
1167
1168 lua_pushvalue(L2,-1);
1169 lua_insert(L2,-3);
1170 //
1171 // [-3]: function (2nd ref)
1172 // [-2]: identity lightuserdata function pointer
1173 // [-1]: function
1174
1175 lua_rawset(L2,L2_cache_i);
1176 //
1177 // [-1]: function (tied to 'L2_cache' table')
1178
1179 }
1180 else if (lua_isboolean(L2,-1))
1181 {
1182 // Loop in preparing upvalues; either direct or via a table
1183 //
1184 // Note: This excludes the case where a function directly addresses
1185 // itself as an upvalue (recursive lane creation).
1186 //
1187 STACK_GROW(L,1);
1188 luaL_error( L, "Recursive use of upvalues; cannot copy the function" );
1189
1190 } 1164 }
1191 else 1165 else // found function in the cache
1192 { 1166 {
1193 lua_remove(L2,-2); 1167 lua_remove( L2, -2); // ... {cache} ... function
1194 } 1168 }
1195 STACK_END(L2,1) 1169 STACK_END( L2, 1)
1196 // 1170 //
1197 // L2 [-1]: function 1171 // L2 [-1]: function
1198 1172
1199 ASSERT_L( lua_isfunction(L2,-1)); 1173 ASSERT_L( lua_isfunction( L2, -1));
1200} 1174}
1201 1175
1202/* 1176/*
@@ -1360,20 +1334,23 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i)
1360#define LOG_FUNC_INFO_CODE(_code) 1334#define LOG_FUNC_INFO_CODE(_code)
1361#endif // LOG_FUNC_INFO 1335#endif // LOG_FUNC_INFO
1362 1336
1337LOG_FUNC_INFO_CODE( static char const* s_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+");
1338
1363/* 1339/*
1364* Copy a function over, which has not been found in the cache. 1340 * 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
1365*/ 1342*/
1366enum e_vt { 1343enum e_vt {
1367 VT_NORMAL, VT_KEY, VT_METATABLE 1344 VT_NORMAL, VT_KEY, VT_METATABLE
1368}; 1345};
1369static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i, enum e_vt value_type ); 1346static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i, enum e_vt value_type );
1370 1347
1371static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) 1348static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i)
1372{ 1349{
1373 FuncSubType funcSubType; 1350 FuncSubType funcSubType;
1374 lua_CFunction cfunc = luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions 1351 lua_CFunction cfunc = luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions
1375 1352
1376 ASSERT_L( L2_cache_i != 0 ); 1353 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p
1377 STACK_GROW(L,2); 1354 STACK_GROW(L,2);
1378 STACK_CHECK(L) 1355 STACK_CHECK(L)
1379 1356
@@ -1407,41 +1384,47 @@ static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uin
1407 1384
1408 // transfer the bytecode, then the upvalues, to create a similar closure 1385 // transfer the bytecode, then the upvalues, to create a similar closure
1409 { 1386 {
1410 const char *name= NULL; 1387 char const* name = NULL;
1411 1388
1412 #if LOG_FUNC_INFO 1389 #if LOG_FUNC_INFO
1413 // "To get information about a function you push it onto the 1390 // "To get information about a function you push it onto the
1414 // stack and start the what string with the character '>'." 1391 // stack and start the what string with the character '>'."
1415 // 1392 //
1416 { 1393 {
1417 lua_Debug ar; 1394 lua_Debug ar;
1418 lua_pushvalue( L, i ); 1395 lua_pushvalue( L, i);
1419 lua_getinfo(L, ">nS", &ar); // fills 'name' 'namewhat' and 'linedefined', pops function 1396 lua_getinfo(L, ">nS", &ar); // fills 'name' 'namewhat' and 'linedefined', pops function
1420 name= ar.namewhat; 1397 name = ar.namewhat;
1421 fprintf( stderr, "NAME: %s @ %d\n", ar.short_src, ar.linedefined); // just gives NULL 1398 fprintf( stderr, "%.*sFNAME: %s @ %d\n", i, s_indent, ar.short_src, ar.linedefined); // just gives NULL
1422 } 1399 }
1423 #endif // LOG_FUNC_INFO 1400 #endif // LOG_FUNC_INFO
1424 { 1401 {
1425 const char *s;
1426 size_t sz; 1402 size_t sz;
1427 s = lua_tolstring( L, -1, &sz); 1403 char const* s = lua_tolstring( L, -1, &sz);
1428 ASSERT_L( s && sz); 1404 ASSERT_L( s && sz);
1429 1405 STACK_GROW( L2, 2);
1430 // Note: Line numbers seem to be taken precisely from the 1406 // Note: Line numbers seem to be taken precisely from the
1431 // original function. 'name' is not used since the chunk 1407 // original function. 'name' is not used since the chunk
1432 // is precompiled (it seems...). 1408 // is precompiled (it seems...).
1433 // 1409 //
1434 // TBD: Can we get the function's original name through, as well? 1410 // TBD: Can we get the function's original name through, as well?
1435 // 1411 //
1436 if (luaL_loadbuffer(L2, s, sz, name) != 0) 1412 if( luaL_loadbuffer( L2, s, sz, name) != 0) // ... {cache} ... p function
1437 { 1413 {
1438 // chunk is precompiled so only LUA_ERRMEM can happen 1414 // chunk is precompiled so only LUA_ERRMEM can happen
1439 // "Otherwise, it pushes an error message" 1415 // "Otherwise, it pushes an error message"
1440 // 1416 //
1441 STACK_GROW( L,1); 1417 STACK_GROW( L, 1);
1442 luaL_error( L, "%s", lua_tostring(L2,-1)); 1418 luaL_error( L, "%s", lua_tostring( L2, -1));
1443 } 1419 }
1444 lua_pop( L, 1); // remove the dumped string 1420 lua_pop( L, 1); // remove the dumped string
1421 // now set the cache as soon as we can.
1422 // 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
1424 lua_insert( L2, -2); // ... {cache} ... function p
1425 lua_pushvalue( L2, -2); // ... {cache} ... function p function
1426 // cache[p] = function
1427 lua_rawset( L2, L2_cache_i); // ... {cache} ... function
1445 } 1428 }
1446 STACK_MID( L, 0) 1429 STACK_MID( L, 0)
1447 1430
@@ -1452,16 +1435,16 @@ static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uin
1452 LOG_FUNC_INFO_CODE( char const* upname); 1435 LOG_FUNC_INFO_CODE( char const* upname);
1453 for( n = 0; (LOG_FUNC_INFO_CODE( upname =) lua_getupvalue( L, i, 1 + n)) != NULL; ++ n) 1436 for( n = 0; (LOG_FUNC_INFO_CODE( upname =) lua_getupvalue( L, i, 1 + n)) != NULL; ++ n)
1454 { 1437 {
1455 LOG_FUNC_INFO_CODE( fprintf( stderr, "UPNAME: %s\n", upname)); 1438 LOG_FUNC_INFO_CODE( fprintf( stderr, "%.*sUPNAME[%d]: %s\n", i, s_indent, n, upname));
1456 if( (!cfunc) && lua_equal( L, i, -1)) 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
1440 /*if( (!cfunc) && lua_equal( L, i, -1))
1457 { 1441 {
1458 /* Lua closure that has a (recursive) upvalue to itself 1442 // Lua closure that has a (recursive) upvalue to itself
1459 */ 1443 lua_pushvalue( L2, -n - 1); // ... {cache} ... function upvalues...
1460 lua_pushvalue( L2, -n - 1);
1461 } 1444 }
1462 else 1445 else*/
1463 { 1446 {
1464 if( !inter_copy_one_( L2, L2_cache_i, L, lua_gettop(L), VT_NORMAL)) 1447 if( !inter_copy_one_( L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL))
1465 luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); 1448 luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1));
1466 } 1449 }
1467 lua_pop( L, 1); 1450 lua_pop( L, 1);
@@ -1476,21 +1459,24 @@ static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uin
1476 int func_index = lua_gettop( L2) - n; 1459 int func_index = lua_gettop( L2) - n;
1477 for( ; n > 0; -- n) 1460 for( ; n > 0; -- n)
1478 { 1461 {
1479 char const* rc = lua_setupvalue( L2, func_index, n); 1462 char const* rc = lua_setupvalue( L2, func_index, n); // ... {cache} ... function
1480 // 1463 //
1481 // "assigns the value at the top of the stack to the upvalue and returns its name. 1464 // "assigns the value at the top of the stack to the upvalue and returns its name.
1482 // It also pops the value from the stack." 1465 // It also pops the value from the stack."
1483 1466
1484 ASSERT_L( rc); // not having enough slots? 1467 ASSERT_L( rc); // not having enough slots?
1485 } 1468 }
1469 // once all upvalues have been set we are left
1470 // with the function at the top of the stack // ... {cache} ... function
1486 } 1471 }
1487 } 1472 }
1488 } 1473 }
1489 else // C function OR LuaJIT fast function!!! 1474 else // C function OR LuaJIT fast function!!!
1490 { 1475 {
1491 LOG_FUNC_INFO_CODE( fprintf( stderr, "NAME: [C] function %p \n", cfunc)); 1476 lua_pop( L2, 1); // ... {cache} ...
1477 LOG_FUNC_INFO_CODE( fprintf( stderr, "%.*sFNAME: [C] function %p \n", i, s_indent, cfunc));
1492 // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up 1478 // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up
1493 lookup_native_func( L2, L, i); 1479 lookup_native_func( L2, L, i); // ... {cache} ... function
1494 } 1480 }
1495 STACK_END( L, 0) 1481 STACK_END( L, 0)
1496} 1482}
@@ -1533,6 +1519,7 @@ static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, u
1533 1519
1534 case LUA_TSTRING: { 1520 case LUA_TSTRING: {
1535 size_t len; const char *s = lua_tolstring( L, i, &len ); 1521 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));
1536 lua_pushlstring( L2, s, len ); 1523 lua_pushlstring( L2, s, len );
1537 } break; 1524 } break;
1538 1525