aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c172
1 files changed, 94 insertions, 78 deletions
diff --git a/src/tools.c b/src/tools.c
index fe1728d..ade8cb8 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -100,17 +100,19 @@ static const luaL_Reg libs[] =
100{ 100{
101 { LUA_LOADLIBNAME, luaopen_package}, 101 { LUA_LOADLIBNAME, luaopen_package},
102 { LUA_TABLIBNAME, luaopen_table}, 102 { LUA_TABLIBNAME, luaopen_table},
103 { LUA_IOLIBNAME, luaopen_io},
104 { LUA_OSLIBNAME, luaopen_os},
105 { LUA_STRLIBNAME, luaopen_string}, 103 { LUA_STRLIBNAME, luaopen_string},
106 { LUA_MATHLIBNAME, luaopen_math}, 104 { LUA_MATHLIBNAME, luaopen_math},
105 { LUA_OSLIBNAME, luaopen_os},
106 { LUA_IOLIBNAME, luaopen_io},
107#if LUA_VERSION_NUM >= 502 107#if LUA_VERSION_NUM >= 502
108 { LUA_BITLIBNAME, luaopen_bit32}, 108 { LUA_BITLIBNAME, luaopen_bit32},
109 { LUA_COLIBNAME, luaopen_coroutine}, // Lua 5.2: coroutine is no longer a part of base!
110#else // LUA_VERSION_NUM
111 { LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package
109#endif // LUA_VERSION_NUM 112#endif // LUA_VERSION_NUM
110 { LUA_DBLIBNAME, luaopen_debug}, 113 { LUA_DBLIBNAME, luaopen_debug},
111 // 114 //
112 { "base", NULL }, // ignore "base" (already acquired it) 115 { "base", NULL}, // ignore "base" (already acquired it)
113 { LUA_COLIBNAME, NULL }, // part of Lua 5.[1|2] base package
114 { NULL, NULL } 116 { NULL, NULL }
115}; 117};
116 118
@@ -124,18 +126,16 @@ static void open1lib( lua_State* L, char const* name, size_t len)
124 if( libs[i].func) 126 if( libs[i].func)
125 { 127 {
126 DEBUGSPEW_CODE( fprintf( stderr, "opening %.*s library\n", len, name)); 128 DEBUGSPEW_CODE( fprintf( stderr, "opening %.*s library\n", len, name));
127 STACK_GROW( L, 1);
128 STACK_CHECK( L) 129 STACK_CHECK( L)
129 lua_pushcfunction( L, libs[i].func);
130 // pushes the module table on the stack
131 lua_call( L, 0, 1);
132 populate_func_lookup_table( L, -1, libs[i].name);
133#if LUA_VERSION_NUM >= 502 130#if LUA_VERSION_NUM >= 502
134 // Lua 5.2: luaopen_x doesn't create the global, we have to do it ourselves! 131 // open the library as if through require(), and create a global as well (the library table is left on the stack)
135 lua_setglobal( L, libs[i].name); 132 luaL_requiref( L, libs[i].name, libs[i].func, 1);
136#else // LUA_VERSION_NUM
137 // Lua 5.1: remove the module when we are done
138 lua_pop( L, 1); 133 lua_pop( L, 1);
134#else // LUA_VERSION_NUM
135 STACK_GROW( L, 1);
136 lua_pushcfunction( L, libs[i].func);
137 // pushes the module table on the stack
138 lua_call( L, 0, 0);
139#endif // LUA_VERSION_NUM 139#endif // LUA_VERSION_NUM
140 STACK_END( L, 0) 140 STACK_END( L, 0)
141 } 141 }
@@ -427,75 +427,93 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* _name)
427* 427*
428* Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. 428* Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL.
429* 429*
430* Returns NULL for ok, position of error within 'libs' on failure.
431*/ 430*/
432#define is_name_char(c) (isalpha(c) || (c)=='*')
433 431
434lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) 432lua_State* luaG_newstate( lua_State* _from, char const* libs, lua_CFunction _on_state_create)
435{ 433{
436 lua_State* const L = luaL_newstate(); 434 // reuse alloc function from the originating state
435 void* allocUD;
436 lua_Alloc allocF = lua_getallocf( _from, &allocUD);
437 lua_State* L = lua_newstate( allocF, allocUD);
437 438
438 // no libs, or special init func (not even 'base') 439 if( !L)
439 if (libs || _on_state_create)
440 { 440 {
441 // 'lua.c' stops GC during initialization so perhaps its a good idea. :) 441 luaL_error( _from, "'lua_newstate()' failed; out of memory");
442 // 442 }
443 lua_gc( L, LUA_GCSTOP, 0);
444 443
445 // Anything causes 'base' to be taken in 444 // neither libs (not even 'base') nor special init func: we are done
446 // 445 if( !libs && !_on_state_create)
447 STACK_GROW( L, 2); 446 {
448 STACK_CHECK( L) 447 return L;
449 if( _on_state_create) 448 }
449
450 STACK_GROW( L, 2);
451 STACK_CHECK( L)
452 if( _on_state_create)
453 {
454 DEBUGSPEW_CODE( fprintf( stderr, "calling on_state_create()\n"));
455 lua_pushcfunction( L, _on_state_create);
456 lua_call( L, 0, 0);
457 }
458
459 // 'lua.c' stops GC during initialization so perhaps its a good idea. :)
460 // but do it after _on_state_create in case it does a lot of stuff...
461 lua_gc( L, LUA_GCSTOP, 0);
462
463 // Anything causes 'base' to be taken in
464 //
465 if( libs)
466 {
467 if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility)
450 { 468 {
451 lua_pushcfunction( L, _on_state_create); 469 DEBUGSPEW_CODE( fprintf( stderr, "opening ALL standard libraries\n"));
452 lua_call( L, 0, 0); 470 luaL_openlibs( L);
471 libs = NULL; // done with libs
453 } 472 }
454 if( libs) 473 else
455 { 474 {
456 if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility) 475 DEBUGSPEW_CODE( fprintf( stderr, "opening base library\n"));
457 { 476#if LUA_VERSION_NUM >= 502
458 DEBUGSPEW_CODE( fprintf( stderr, "opening ALL base libraries\n")); 477 // open base library the same way as in luaL_openlibs()
459 luaL_openlibs( L); 478 luaL_requiref( L, "_G", luaopen_base, 1);
460 libs = NULL; // done with libs 479 lua_pop( L, 1);
461 } 480#else // LUA_VERSION_NUM
462 else 481 lua_pushcfunction( L, luaopen_base);
463 { 482 lua_pushstring( L, "");
464 DEBUGSPEW_CODE( fprintf( stderr, "opening base library\n")); 483 lua_call( L, 1, 0);
465 lua_pushcfunction( L, luaopen_base); 484#endif // LUA_VERSION_NUM
466 lua_call( L, 0, 0);
467 }
468 } 485 }
486 }
487 STACK_END( L, 0)
469 488
470 // after opening base, register the functions it exported in our name<->function database 489 // scan all libraries, open them one by one
471 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack 490 if( libs)
472 populate_func_lookup_table( L, -1, NULL); 491 {
473 lua_pop( L, 1); 492 char const* p;
474 493 unsigned int len = 0;
475 STACK_MID( L, 0); 494 for( p = libs; *p; p += len)
476 { 495 {
477 char const* p; 496 len = 0;
478 unsigned int len = 0; 497 // skip delimiters
479 if( libs) 498 while( *p && !isalnum( *p))
480 { 499 ++ p;
481 for( p = libs; *p; p += len) 500 // skip name
482 { 501 while( isalnum( p[len]))
483 len = 0; 502 ++ len;
484 // skip delimiters 503 // open library
485 while( *p && !is_name_char( *p)) 504 open1lib( L, p, len);
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);
494 }
495 } 505 }
496 STACK_END(L,0) 506 serialize_require( L);
497 lua_gc( L, LUA_GCRESTART, 0);
498 } 507 }
508
509 lua_gc( L, LUA_GCRESTART, 0);
510
511 STACK_CHECK( L)
512 // after opening base, register the functions it exported in our name<->function database
513 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack
514 populate_func_lookup_table( L, -1, NULL);
515 lua_pop( L, 1);
516 STACK_END( L, 0)
499 return L; 517 return L;
500} 518}
501 519
@@ -1895,25 +1913,23 @@ static int new_require( lua_State *L)
1895*/ 1913*/
1896void serialize_require( lua_State *L ) 1914void serialize_require( lua_State *L )
1897{ 1915{
1898 STACK_GROW(L,1); 1916 STACK_GROW( L, 1);
1899 STACK_CHECK(L) 1917 STACK_CHECK( L)
1900 1918
1901 // Check 'require' is there; if not, do nothing 1919 // Check 'require' is there; if not, do nothing
1902 // 1920 //
1903 lua_getglobal( L, "require" ); 1921 lua_getglobal( L, "require");
1904 if (lua_isfunction( L, -1 )) 1922 if( lua_isfunction( L, -1))
1905 { 1923 {
1906 // [-1]: original 'require' function 1924 // [-1]: original 'require' function
1907 1925 lua_pushcclosure( L, new_require, 1 /*upvalues*/);
1908 lua_pushcclosure( L, new_require, 1 /*upvalues*/ ); 1926 lua_setglobal( L, "require");
1909 lua_setglobal( L, "require" );
1910
1911 } 1927 }
1912 else 1928 else
1913 { 1929 {
1914 // [-1]: nil 1930 // [-1]: nil
1915 lua_pop(L,1); 1931 lua_pop( L, 1);
1916 } 1932 }
1917 1933
1918 STACK_END(L,0) 1934 STACK_END( L, 0)
1919} 1935}