summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/keeper.c57
-rw-r--r--src/keeper.h2
-rw-r--r--src/lanes.c371
-rw-r--r--src/lanes.lua18
-rw-r--r--src/tools.c249
-rw-r--r--src/tools.h20
6 files changed, 428 insertions, 289 deletions
diff --git a/src/keeper.c b/src/keeper.c
index 0be4fd3..a7c8647 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -557,7 +557,7 @@ void close_keepers( void)
557* unclosed, because it does not really matter. In production code, this 557* unclosed, because it does not really matter. In production code, this
558* function never fails. 558* function never fails.
559*/ 559*/
560char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create) 560char const* init_keepers( lua_State* L, int const _nbKeepers, lua_CFunction _on_state_create)
561{ 561{
562 int i; 562 int i;
563 assert( _nbKeepers >= 1); 563 assert( _nbKeepers >= 1);
@@ -565,15 +565,16 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
565 GKeepers = malloc( _nbKeepers * sizeof( struct s_Keeper)); 565 GKeepers = malloc( _nbKeepers * sizeof( struct s_Keeper));
566 for( i = 0; i < _nbKeepers; ++ i) 566 for( i = 0; i < _nbKeepers; ++ i)
567 { 567 {
568
569 // We need to load all base libraries in the keeper states so that the transfer databases are populated properly 568 // We need to load all base libraries in the keeper states so that the transfer databases are populated properly
570 // 569 //
571 // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs 570 // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs
572 // the others because they export functions that we may store in a keeper for transfer between lanes 571 // the others because they export functions that we may store in a keeper for transfer between lanes
573 lua_State* K = luaG_newstate( "*", _on_state_create); 572 lua_State* K = luaG_newstate( "*", _on_state_create);
574 if (!K) 573 if( !K)
575 return "out of memory"; 574 return "out of memory";
576 575
576 DEBUGSPEW_CODE( fprintf( stderr, "init_keepers %d\n", i));
577
577 STACK_CHECK( K) 578 STACK_CHECK( K)
578 // to see VM name in Decoda debugger 579 // to see VM name in Decoda debugger
579 lua_pushliteral( K, "Keeper #"); 580 lua_pushliteral( K, "Keeper #");
@@ -581,6 +582,11 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
581 lua_concat( K, 2); 582 lua_concat( K, 2);
582 lua_setglobal( K, "decoda_name"); 583 lua_setglobal( K, "decoda_name");
583 584
585 // replace default 'package' contents with stuff gotten from the master state
586 lua_getglobal( L, "package");
587 luaG_inter_copy_package( L, K, -1);
588 lua_pop( L, 1);
589
584#if KEEPER_MODEL == KEEPER_MODEL_C 590#if KEEPER_MODEL == KEEPER_MODEL_C
585 // create the fifos table in the keeper state 591 // create the fifos table in the keeper state
586 lua_pushlightuserdata( K, fifos_key); 592 lua_pushlightuserdata( K, fifos_key);
@@ -589,7 +595,7 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
589#endif // KEEPER_MODEL == KEEPER_MODEL_C 595#endif // KEEPER_MODEL == KEEPER_MODEL_C
590 596
591#if KEEPER_MODEL == KEEPER_MODEL_LUA 597#if KEEPER_MODEL == KEEPER_MODEL_LUA
592 // use package.loaders[2] to find keeper microcode 598 // use package.loaders[2] to find keeper microcode (NOTE: this works only if nobody tampered with the loaders table...)
593 lua_getglobal( K, "package"); // package 599 lua_getglobal( K, "package"); // package
594 lua_getfield( K, -1, "loaders"); // package package.loaders 600 lua_getfield( K, -1, "loaders"); // package package.loaders
595 lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] 601 lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2]
@@ -619,55 +625,38 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
619} 625}
620 626
621// cause each keeper state to populate its database of transferable functions with those from the specified module 627// cause each keeper state to populate its database of transferable functions with those from the specified module
622void populate_keepers( lua_State *L) 628// do do this we simply require the module inside the keeper state, then populate the lookup database
629void populate_keepers( lua_State* L)
623{ 630{
624 size_t name_len; 631 size_t name_len;
625 char const *name = luaL_checklstring( L, -1, &name_len); 632 char const* name = luaL_checklstring( L, -1, &name_len);
626 size_t package_path_len;
627 char const *package_path;
628 size_t package_cpath_len;
629 char const *package_cpath;
630 int i; 633 int i;
631 634
632 // we need to make sure that package.path & package.cpath are the same in the keepers 635 STACK_CHECK( L)
633// than what is currently in use when the module is required in the caller's Lua state
634 STACK_CHECK(L)
635 STACK_GROW( L, 3); 636 STACK_GROW( L, 3);
636 lua_getglobal( L, "package");
637 lua_getfield( L, -1, "path");
638 package_path = luaL_checklstring( L, -1, &package_path_len);
639 lua_getfield( L, -2, "cpath");
640 package_cpath = luaL_checklstring( L, -1, &package_cpath_len);
641 637
642 for( i = 0; i < GNbKeepers; ++ i) 638 for( i = 0; i < GNbKeepers; ++ i)
643 { 639 {
644 lua_State *K = GKeepers[i].L; 640 lua_State* K = GKeepers[i].L;
645 int res; 641 int res;
646 MUTEX_LOCK( &GKeepers[i].lock_); 642 MUTEX_LOCK( &GKeepers[i].lock_);
647 STACK_CHECK(K) 643 STACK_CHECK( K)
648 STACK_GROW( K, 2); 644 STACK_GROW( K, 2);
649 lua_getglobal( K, "package");
650 lua_pushlstring( K, package_path, package_path_len);
651 lua_setfield( K, -2, "path");
652 lua_pushlstring( K, package_cpath, package_cpath_len);
653 lua_setfield( K, -2, "cpath");
654 lua_pop( K, 1);
655 lua_getglobal( K, "require"); 645 lua_getglobal( K, "require");
656 lua_pushlstring( K, name, name_len); 646 lua_pushlstring( K, name, name_len);
657 res = lua_pcall( K, 1, 0, 0); 647 res = lua_pcall( K, 1, 0, 0);
658 if( res != 0) 648 if( res != 0)
659 { 649 {
660 char const *err = luaL_checkstring( K, -1); 650 char const* err = luaL_checkstring( K, -1);
661 luaL_error( L, "error requiring '%s' in keeper state: %s", name, err); 651 luaL_error( L, "error requiring '%s' in keeper state: %s", name, err);
662 } 652 }
663 STACK_END(K, 0) 653 STACK_END( K, 0)
664 MUTEX_UNLOCK( &GKeepers[i].lock_); 654 MUTEX_UNLOCK( &GKeepers[i].lock_);
665 } 655 }
666 lua_pop( L, 3); 656 STACK_END( L, 0)
667 STACK_END(L, 0)
668} 657}
669 658
670struct s_Keeper *keeper_acquire( const void *ptr) 659struct s_Keeper* keeper_acquire( void const* ptr)
671{ 660{
672 // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers) 661 // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers)
673 if( GNbKeepers == 0) 662 if( GNbKeepers == 0)
@@ -691,19 +680,19 @@ struct s_Keeper *keeper_acquire( const void *ptr)
691 } 680 }
692} 681}
693 682
694void keeper_release( struct s_Keeper *K) 683void keeper_release( struct s_Keeper* K)
695{ 684{
696 //-- K->count; 685 //-- K->count;
697 if( K) MUTEX_UNLOCK( &K->lock_); 686 if( K) MUTEX_UNLOCK( &K->lock_);
698} 687}
699 688
700void keeper_toggle_nil_sentinels( lua_State *L, int _val_i, int _nil_to_sentinel) 689void keeper_toggle_nil_sentinels( lua_State* L, int _val_i, int _nil_to_sentinel)
701{ 690{
702 int i, n = lua_gettop( L); 691 int i, n = lua_gettop( L);
703 /* We could use an empty table in 'keeper.lua' as the sentinel, but maybe 692 /* We could use an empty table in 'keeper.lua' as the sentinel, but maybe
704 * checking for a lightuserdata is faster. (any unique value will do -> take the address of some global of ours) 693 * checking for a lightuserdata is faster. (any unique value will do -> take the address of some global of ours)
705 */ 694 */
706 void *nil_sentinel = &GNbKeepers; 695 void* nil_sentinel = &GNbKeepers;
707 for( i = _val_i; i <= n; ++ i) 696 for( i = _val_i; i <= n; ++ i)
708 { 697 {
709 if( _nil_to_sentinel) 698 if( _nil_to_sentinel)
diff --git a/src/keeper.h b/src/keeper.h
index decae4a..15a5a41 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -13,7 +13,7 @@ struct s_Keeper
13// problem: maybe on some platforms (linux) atexit() is called after DLL/so are unloaded... 13// problem: maybe on some platforms (linux) atexit() is called after DLL/so are unloaded...
14#define HAVE_KEEPER_ATEXIT_DESINIT 0 14#define HAVE_KEEPER_ATEXIT_DESINIT 0
15 15
16char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create); 16char const* init_keepers( lua_State* L, int const _nbKeepers, lua_CFunction _on_state_create);
17#if !HAVE_KEEPER_ATEXIT_DESINIT 17#if !HAVE_KEEPER_ATEXIT_DESINIT
18void close_keepers( void); 18void close_keepers( void);
19#endif // HAVE_KEEPER_ATEXIT_DESINIT 19#endif // HAVE_KEEPER_ATEXIT_DESINIT
diff --git a/src/lanes.c b/src/lanes.c
index 8a67621..6fec951 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -52,13 +52,13 @@
52 * ... 52 * ...
53 */ 53 */
54 54
55char const* VERSION = "3.4.2"; 55char const* VERSION = "3.4.3";
56 56
57/* 57/*
58=============================================================================== 58===============================================================================
59 59
60Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> 60Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com>
61 2011-12 Benoit Germain <bnt.germain@gmail.com> 61 2011-13 Benoit Germain <bnt.germain@gmail.com>
62 62
63Permission is hereby granted, free of charge, to any person obtaining a copy 63Permission is hereby granted, free of charge, to any person obtaining a copy
64of this software and associated documentation files (the "Software"), to deal 64of this software and associated documentation files (the "Software"), to deal
@@ -1114,7 +1114,8 @@ static int run_finalizers( lua_State*L, int lua_rc )
1114 // 1114 //
1115 // LUA_ERRRUN / LUA_ERRMEM 1115 // LUA_ERRRUN / LUA_ERRMEM
1116 1116
1117 if (rc!=0) { 1117 if( rc != LUA_OK)
1118 {
1118 // [-1]: error message 1119 // [-1]: error message
1119 // 1120 //
1120 // If one finalizer fails, don't run the others. Return this 1121 // If one finalizer fails, don't run the others. Return this
@@ -1269,7 +1270,7 @@ static bool_t selfdestruct_remove( struct s_lane *s )
1269// Initialized by 'init_once_LOCKED()': the deep userdata Linda object 1270// Initialized by 'init_once_LOCKED()': the deep userdata Linda object
1270// used for timers (each lane will get a proxy to this) 1271// used for timers (each lane will get a proxy to this)
1271// 1272//
1272volatile DEEP_PRELUDE *timer_deep; // = NULL 1273volatile DEEP_PRELUDE* timer_deep; // = NULL
1273 1274
1274/* 1275/*
1275* Process end; cancel any still free-running threads 1276* Process end; cancel any still free-running threads
@@ -1349,7 +1350,7 @@ static int selfdestruct_gc( lua_State*L)
1349 t_now = now_secs(); 1350 t_now = now_secs();
1350 if( n == 0 || ( t_now >= t_until)) 1351 if( n == 0 || ( t_now >= t_until))
1351 { 1352 {
1352 DEBUGEXEC(fprintf( stderr, "%d uncancelled lane(s) remain after waiting %fs at process end.\n", n, shutdown_timeout - (t_until - t_now))); 1353 DEBUGSPEW_CODE( fprintf( stderr, "%d uncancelled lane(s) remain after waiting %fs at process end.\n", n, shutdown_timeout - (t_until - t_now)));
1353 break; 1354 break;
1354 } 1355 }
1355 } 1356 }
@@ -1379,7 +1380,7 @@ static int selfdestruct_gc( lua_State*L)
1379//we want to free memory and such when we exit. 1380//we want to free memory and such when we exit.
1380 // 2.0.2: at least timer lane is still here 1381 // 2.0.2: at least timer lane is still here
1381 // 1382 //
1382 DEBUGEXEC(fprintf( stderr, "Left %d lane(s) with cancel request at process end.\n", n )); 1383 DEBUGSPEW_CODE( fprintf( stderr, "Left %d lane(s) with cancel request at process end.\n", n ));
1383 n=0; 1384 n=0;
1384#else 1385#else
1385 // first thing we did was to raise the linda signals the threads were waiting on (if any) 1386 // first thing we did was to raise the linda signals the threads were waiting on (if any)
@@ -1409,7 +1410,7 @@ static int selfdestruct_gc( lua_State*L)
1409 } 1410 }
1410 MUTEX_UNLOCK( &selfdestruct_cs ); 1411 MUTEX_UNLOCK( &selfdestruct_cs );
1411 1412
1412 DEBUGEXEC(fprintf( stderr, "Killed %d lane(s) at process end.\n", n )); 1413 DEBUGSPEW_CODE( fprintf( stderr, "Killed %d lane(s) at process end.\n", n));
1413#endif 1414#endif
1414 } 1415 }
1415#if !HAVE_KEEPER_ATEXIT_DESINIT 1416#if !HAVE_KEEPER_ATEXIT_DESINIT
@@ -1654,6 +1655,39 @@ LUAG_FUNC( set_debug_threadname)
1654 return 0; 1655 return 0;
1655} 1656}
1656 1657
1658#if USE_DEBUG_SPEW
1659// can't use direct LUA_x errcode indexing because the sequence is not the same between Lua 5.1 and 5.2 :-(
1660// LUA_ERRERR doesn't have the same value
1661struct errcode_name
1662{
1663 int code;
1664 char const* name;
1665};
1666
1667static struct errcode_name s_errcodes[] =
1668{
1669 { LUA_OK, "LUA_OK"},
1670 { LUA_YIELD, "LUA_YIELD"},
1671 { LUA_ERRRUN, "LUA_ERRRUN"},
1672 { LUA_ERRSYNTAX, "LUA_ERRSYNTAX"},
1673 { LUA_ERRMEM, "LUA_ERRMEM"},
1674 { LUA_ERRGCMM, "LUA_ERRGCMM"},
1675 { LUA_ERRERR, "LUA_ERRERR"},
1676};
1677static char const* get_errcode_name( int _code)
1678{
1679 int i;
1680 for( i = 0; i < 7; ++ i)
1681 {
1682 if( s_errcodes[i].code == _code)
1683 {
1684 return s_errcodes[i].name;
1685 }
1686 }
1687 return "<NULL>";
1688}
1689#endif // USE_DEBUG_SPEW
1690
1657//--- 1691//---
1658static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs) 1692static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs)
1659{ 1693{
@@ -1713,7 +1747,8 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs)
1713 // Lua 5.1 error handler is limited to one return value; taking stack trace 1747 // Lua 5.1 error handler is limited to one return value; taking stack trace
1714 // via registry 1748 // via registry
1715 // 1749 //
1716 if (rc!=0) { 1750 if( rc != 0)
1751 {
1717 STACK_GROW(L,1); 1752 STACK_GROW(L,1);
1718 lua_pushlightuserdata( L, STACK_TRACE_KEY ); 1753 lua_pushlightuserdata( L, STACK_TRACE_KEY );
1719 lua_gettable(L, LUA_REGISTRYINDEX); 1754 lua_gettable(L, LUA_REGISTRYINDEX);
@@ -1733,16 +1768,19 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs)
1733 // [2..top]: parameters 1768 // [2..top]: parameters
1734 // 1769 //
1735 rc= lua_pcall( L, lua_gettop(L)-1, LUA_MULTRET, 0 /*no error handler*/ ); 1770 rc= lua_pcall( L, lua_gettop(L)-1, LUA_MULTRET, 0 /*no error handler*/ );
1736 // 0: no error 1771 // LUA_OK(0): no error
1737 // LUA_ERRRUN: a runtime error (error pushed on stack) 1772 // LUA_ERRRUN(2): a runtime error (error pushed on stack)
1738 // LUA_ERRMEM: memory allocation error 1773 // LUA_ERRMEM(4): memory allocation error
1739#endif 1774#endif
1740 1775
1741//STACK_DUMP(L); 1776 DEBUGSPEW_CODE( fprintf( stderr, "Lane %p body: %s\n", L, get_errcode_name( rc)));
1777 //STACK_DUMP(L);
1742 // Call finalizers, if the script has set them up. 1778 // Call finalizers, if the script has set them up.
1743 // 1779 //
1744 rc2= run_finalizers(L,rc); 1780 rc2 = run_finalizers( L, rc);
1745 if (rc2!=0) { 1781 DEBUGSPEW_CODE( fprintf( stderr, "Lane %p finalizer: %s\n", L, get_errcode_name( rc2)));
1782 if( rc2 != LUA_OK)
1783 {
1746 // Error within a finalizer! 1784 // Error within a finalizer!
1747 // 1785 //
1748 // [-1]: error message 1786 // [-1]: error message
@@ -1766,7 +1804,6 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs)
1766 s->L = L = 0; 1804 s->L = L = 0;
1767 1805
1768 lane_cleanup( s); 1806 lane_cleanup( s);
1769
1770 } 1807 }
1771 else 1808 else
1772 { 1809 {
@@ -1809,10 +1846,10 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs)
1809 1846
1810// helper function to require a module in the keeper states and in the target state 1847// helper function to require a module in the keeper states and in the target state
1811// source state contains module name at the top of the stack 1848// source state contains module name at the top of the stack
1812static void require_one_module( lua_State*L, lua_State*L2, bool_t _fatal) 1849static void require_one_module( lua_State* L, lua_State* L2, bool_t _fatal)
1813{ 1850{
1814 size_t len; 1851 size_t len;
1815 char const *name = lua_tolstring( L, -1, &len); 1852 char const* name = lua_tolstring( L, -1, &len);
1816 // require the module in the target lane 1853 // require the module in the target lane
1817 STACK_GROW( L2, 2); 1854 STACK_GROW( L2, 2);
1818 lua_getglobal( L2, "require"); 1855 lua_getglobal( L2, "require");
@@ -1872,39 +1909,11 @@ LUAG_FUNC( thread_new )
1872 1909
1873 ASSERT_L( lua_gettop(L2) == 0); 1910 ASSERT_L( lua_gettop(L2) == 0);
1874 1911
1875 // package.path 1912 // package
1876 STACK_CHECK(L)
1877 STACK_CHECK(L2)
1878 if( package) 1913 if( package)
1879 { 1914 {
1880 if( lua_type( L, package) != LUA_TTABLE) 1915 luaG_inter_copy_package( L, L2, package);
1881 {
1882 return luaL_error( L, "expected package as table, got %s", luaL_typename( L, package));
1883 }
1884 lua_getglobal( L2, "package");
1885 if( !lua_isnil( L2, -1)) // package library not loaded: do nothing
1886 {
1887 int i;
1888 // package.loaders is renamed package.searchers in Lua 5.2
1889 char const* entries[] = { "path", "cpath", "preload", (LUA_VERSION_NUM == 501) ? "loaders" : "searchers", NULL};
1890 for( i = 0; entries[i]; ++ i)
1891 {
1892 lua_getfield( L, package, entries[i]);
1893 if( lua_isnil( L, -1))
1894 {
1895 lua_pop( L, 1);
1896 }
1897 else
1898 {
1899 luaG_inter_move( L, L2, 1); // moves the entry to L2
1900 lua_setfield( L2, -2, entries[i]); // set package[entries[i]]
1901 }
1902 }
1903 }
1904 lua_pop( L2, 1);
1905 } 1916 }
1906 STACK_END(L2,0)
1907 STACK_END(L,0)
1908 1917
1909 // modules to require in the target lane *before* the function is transfered! 1918 // modules to require in the target lane *before* the function is transfered!
1910 1919
@@ -1924,14 +1933,14 @@ LUAG_FUNC( thread_new )
1924 { 1933 {
1925 int nbRequired = 1; 1934 int nbRequired = 1;
1926 // should not happen, was checked in lanes.lua before calling thread_new() 1935 // should not happen, was checked in lanes.lua before calling thread_new()
1927 if (lua_type(L, required) != LUA_TTABLE) 1936 if( lua_type( L, required) != LUA_TTABLE)
1928 { 1937 {
1929 return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required)); 1938 return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required));
1930 } 1939 }
1931 lua_pushnil( L); 1940 lua_pushnil( L);
1932 while( lua_next( L, required) != 0) 1941 while( lua_next( L, required) != 0)
1933 { 1942 {
1934 if (lua_type(L,-1) != LUA_TSTRING || lua_type(L,-2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired) 1943 if( lua_type( L, -1) != LUA_TSTRING || lua_type( L, -2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired)
1935 { 1944 {
1936 return luaL_error( L, "required module list should be a list of strings"); 1945 return luaL_error( L, "required module list should be a list of strings");
1937 } 1946 }
@@ -1949,13 +1958,13 @@ LUAG_FUNC( thread_new )
1949 // Appending the specified globals to the global environment 1958 // Appending the specified globals to the global environment
1950 // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed... 1959 // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed...
1951 // 1960 //
1952 if (glob!=0) 1961 if( glob != 0)
1953 { 1962 {
1954 STACK_CHECK(L) 1963 STACK_CHECK(L)
1955 STACK_CHECK(L2) 1964 STACK_CHECK(L2)
1956 if( !lua_istable( L, glob)) 1965 if( !lua_istable( L, glob))
1957 { 1966 {
1958 return luaL_error( L, "Expected table, got %s", luaL_typename(L,glob)); 1967 return luaL_error( L, "Expected table, got %s", luaL_typename( L, glob));
1959 } 1968 }
1960 1969
1961 lua_pushnil( L); 1970 lua_pushnil( L);
@@ -1987,7 +1996,7 @@ LUAG_FUNC( thread_new )
1987 } 1996 }
1988 STACK_MID(L,0) 1997 STACK_MID(L,0)
1989 } 1998 }
1990 else if( lua_type(L, 1) == LUA_TSTRING) 1999 else if( lua_type( L, 1) == LUA_TSTRING)
1991 { 2000 {
1992 // compile the string 2001 // compile the string
1993 if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) 2002 if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0)
@@ -2089,7 +2098,7 @@ LUAG_FUNC( thread_gc)
2089 // Make sure a kill has proceeded, before cleaning up the data structure. 2098 // Make sure a kill has proceeded, before cleaning up the data structure.
2090 // 2099 //
2091 // NO lua_close() in this case because we don't know where execution of the state was interrupted 2100 // NO lua_close() in this case because we don't know where execution of the state was interrupted
2092 DEBUGEXEC(fprintf( stderr, "** Joining with a killed thread (needs testing) **" )); 2101 DEBUGSPEW_CODE( fprintf( stderr, "** Joining with a killed thread (needs testing) **"));
2093 // make sure the thread is no longer running, just like thread_join() 2102 // make sure the thread is no longer running, just like thread_join()
2094 if(! THREAD_ISNULL( s->thread)) 2103 if(! THREAD_ISNULL( s->thread))
2095 THREAD_WAIT( &s->thread, -1, &s->done_signal, &s->done_lock, &s->status); 2104 THREAD_WAIT( &s->thread, -1, &s->done_signal, &s->done_lock, &s->status);
@@ -2100,7 +2109,7 @@ LUAG_FUNC( thread_gc)
2100 lua_close( s->L); 2109 lua_close( s->L);
2101 s->L = 0; 2110 s->L = 0;
2102 } 2111 }
2103 DEBUGEXEC(fprintf( stderr, "** Joined ok **" )); 2112 DEBUGSPEW_CODE( fprintf( stderr, "** Joined ok **"));
2104 } 2113 }
2105 else if( s->status < DONE) 2114 else if( s->status < DONE)
2106 { 2115 {
@@ -2265,7 +2274,7 @@ LUAG_FUNC( thread_join)
2265 break; 2274 break;
2266 2275
2267 default: 2276 default:
2268 DEBUGEXEC(fprintf( stderr, "Status: %d\n", s->status)); 2277 DEBUGSPEW_CODE( fprintf( stderr, "Status: %d\n", s->status));
2269 ASSERT_L( FALSE ); ret= 0; 2278 ASSERT_L( FALSE ); ret= 0;
2270 } 2279 }
2271 lua_close( L2); 2280 lua_close( L2);
@@ -2547,9 +2556,9 @@ static const struct luaL_Reg lanes_functions [] = {
2547/* 2556/*
2548* One-time initializations 2557* One-time initializations
2549*/ 2558*/
2550static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_ref, int const nbKeepers, lua_CFunction _on_state_create, lua_Number _shutdown_timeout, bool_t _track_lanes) 2559static void init_once_LOCKED( lua_State* L, int const nbKeepers, lua_CFunction _on_state_create, lua_Number _shutdown_timeout, bool_t _track_lanes)
2551{ 2560{
2552 const char *err; 2561 char const* err;
2553 2562
2554#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) 2563#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
2555 now_secs(); // initialize 'now_secs()' internal offset 2564 now_secs(); // initialize 'now_secs()' internal offset
@@ -2604,7 +2613,7 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r
2604 } 2613 }
2605 #endif 2614 #endif
2606#endif 2615#endif
2607 err = init_keepers( nbKeepers, _on_state_create); 2616 err = init_keepers( L, nbKeepers, _on_state_create);
2608 if (err) 2617 if (err)
2609 { 2618 {
2610 (void) luaL_error( L, "Unable to initialize: %s", err ); 2619 (void) luaL_error( L, "Unable to initialize: %s", err );
@@ -2612,7 +2621,7 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r
2612 2621
2613 // Initialize 'timer_deep'; a common Linda object shared by all states 2622 // Initialize 'timer_deep'; a common Linda object shared by all states
2614 // 2623 //
2615 ASSERT_L( timer_deep_ref && (!(*timer_deep_ref)) ); 2624 ASSERT_L( timer_deep == NULL);
2616 2625
2617 STACK_CHECK(L) 2626 STACK_CHECK(L)
2618 { 2627 {
@@ -2627,8 +2636,8 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r
2627 2636
2628 // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer 2637 // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer
2629 // 2638 //
2630 *timer_deep_ref= * (DEEP_PRELUDE**) lua_touserdata( L, -1 ); 2639 timer_deep = * (DEEP_PRELUDE**) lua_touserdata( L, -1);
2631 ASSERT_L( (*timer_deep_ref) && (*timer_deep_ref)->refcount==1 && (*timer_deep_ref)->deep ); 2640 ASSERT_L( timer_deep && (timer_deep->refcount == 1) && timer_deep->deep);
2632 2641
2633 // The host Lua state must always have a reference to this Linda object in order for our 'timer_deep_ref' to be valid. 2642 // The host Lua state must always have a reference to this Linda object in order for our 'timer_deep_ref' to be valid.
2634 // So store a reference that we will never actually use. 2643 // So store a reference that we will never actually use.
@@ -2644,8 +2653,8 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r
2644 lua_setfield( L, -2, "__metatable"); 2653 lua_setfield( L, -2, "__metatable");
2645 lua_setmetatable( L, -2); 2654 lua_setmetatable( L, -2);
2646 } 2655 }
2647 lua_insert(L, -2); // Swap key with the Linda object 2656 lua_insert( L, -2); // Swap key with the Linda object
2648 lua_rawset(L, LUA_REGISTRYINDEX); 2657 lua_rawset( L, LUA_REGISTRYINDEX);
2649 2658
2650 } 2659 }
2651 STACK_END(L,0) 2660 STACK_END(L,0)
@@ -2653,107 +2662,147 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r
2653 2662
2654static volatile long s_initCount = 0; 2663static volatile long s_initCount = 0;
2655 2664
2656LUAG_FUNC( configure ) 2665// upvalue 1: module name
2666// upvalue 2: module table
2667LUAG_FUNC( configure)
2657{ 2668{
2658 char const* name = luaL_checkstring( L, lua_upvalueindex( 1)); 2669 char const* name = luaL_checkstring( L, lua_upvalueindex( 1));
2659 // all parameter checks are done lua-side 2670 // all parameter checks are done lua-side
2660 int const nbKeepers = (int)lua_tointeger( L, 1); 2671 int const nbKeepers = (int)lua_tointeger( L, 1);
2661 lua_CFunction on_state_create = lua_iscfunction( L, 2) ? lua_tocfunction( L, 2) : NULL; 2672 lua_CFunction on_state_create = lua_iscfunction( L, 2) ? lua_tocfunction( L, 2) : NULL;
2662 lua_Number shutdown_timeout = lua_tonumber( L, 3); 2673 lua_Number shutdown_timeout = lua_tonumber( L, 3);
2663 bool_t track_lanes = lua_toboolean( L, 4); 2674 bool_t track_lanes = lua_toboolean( L, 4);
2664 /* 2675
2665 * Making one-time initializations. 2676 STACK_CHECK( L)
2666 * 2677 // Create main module interface table
2667 * When the host application is single-threaded (and all threading happens via Lanes) 2678 lua_pushvalue( L, lua_upvalueindex( 2)); // ... M
2668 * there is no problem. But if the host is multithreaded, we need to lock around the 2679 // remove configure() (this function) from the module interface
2669 * initializations. 2680 lua_pushnil( L); // ... M nil
2670 */ 2681 lua_setfield( L, -2, "configure"); // ... M
2682 // add functions to the module's table
2683 luaG_registerlibfuncs( L, lanes_functions);
2684 STACK_MID( L, 1)
2685
2686 // metatable for threads
2687 // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join }
2688 //
2689 lua_newtable( L); // ... M mt
2690 lua_pushcfunction( L, LG_thread_gc); // ... M mt LG_thread_gc
2691 lua_setfield( L, -2, "__gc"); // ... M mt
2692 lua_pushcfunction( L, LG_thread_index); // ... M mt LG_thread_index
2693 lua_setfield( L, -2, "__index"); // ... M mt
2694 lua_getglobal( L, "error"); // ... M mt error
2695 ASSERT_L( lua_isfunction( L, -1));
2696 lua_setfield( L, -2, "cached_error"); // ... M mt
2697 lua_getglobal( L, "tostring"); // ... M mt tostring
2698 ASSERT_L( lua_isfunction( L, -1));
2699 lua_setfield( L, -2, "cached_tostring"); // ... M mt
2700 lua_pushcfunction( L, LG_thread_join); // ... M mt LG_thread_join
2701 lua_setfield( L, -2, "join"); // ... M mt
2702 lua_pushcfunction( L, LG_thread_cancel); // ... M mt LG_thread_cancel
2703 lua_setfield( L, -2, "cancel"); // ... M mt
2704 lua_pushliteral( L, "Lane"); // ... M mt "Lane"
2705 lua_setfield( L, -2, "__metatable"); // ... M mt
2706
2707 lua_pushcclosure( L, LG_thread_new, 1); // ... M LG_thread_new
2708 lua_setfield(L, -2, "thread_new"); // ... M
2709
2710 lua_pushstring(L, VERSION); // ... M VERSION
2711 lua_setfield(L, -2, "version"); // ... M
2712
2713 lua_pushinteger(L, THREAD_PRIO_MAX); // ... M THREAD_PRIO_MAX
2714 lua_setfield(L, -2, "max_prio"); // ... M
2715
2716 lua_pushlightuserdata( L, CANCEL_ERROR); // ... M CANCEL_ERROR
2717 lua_setfield(L, -2, "cancel_error"); // ... M
2718
2719 // register all native functions found in that module in the transferable functions database
2720 // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names)
2721 // for example in package.loaded.lanes.core.*
2722 populate_func_lookup_table( L, -1, name);
2723
2724 // record all existing C/JIT-fast functions
2725 // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack
2726 lua_pushglobaltable( L); // ... M _G
2727 populate_func_lookup_table( L, -1, NULL);
2728 lua_pop( L, 1); // ... M
2729
2730 STACK_MID( L, 1)
2731 /*
2732 * Making one-time initializations.
2733 *
2734 * When the host application is single-threaded (and all threading happens via Lanes)
2735 * there is no problem. But if the host is multithreaded, we need to lock around the
2736 * initializations.
2737 *
2738 * we must do this after the populate_func_lookup_table is called, else populating the keepers will fail
2739 * because this makes a copy of packages.loaders, which requires the lookup tables to exist!
2740 */
2671#if THREADAPI == THREADAPI_WINDOWS 2741#if THREADAPI == THREADAPI_WINDOWS
2672 { 2742 {
2673 static volatile int /*bool*/ go_ahead; // = 0 2743 static volatile int /*bool*/ go_ahead; // = 0
2674 if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0) 2744 if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0)
2675 { 2745 {
2676 init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create, shutdown_timeout, track_lanes); 2746 init_once_LOCKED( L, nbKeepers, on_state_create, shutdown_timeout, track_lanes);
2677 go_ahead= 1; // let others pass 2747 go_ahead = 1; // let others pass
2678 } 2748 }
2679 else 2749 else
2680 { 2750 {
2681 while( !go_ahead ) { Sleep(1); } // changes threads 2751 while( !go_ahead ) { Sleep(1); } // changes threads
2682 } 2752 }
2683 } 2753 }
2684#else // THREADAPI == THREADAPI_PTHREAD 2754#else // THREADAPI == THREADAPI_PTHREAD
2685 if( s_initCount == 0) 2755 if( s_initCount == 0)
2686 { 2756 {
2687 static pthread_mutex_t my_lock= PTHREAD_MUTEX_INITIALIZER; 2757 static pthread_mutex_t my_lock = PTHREAD_MUTEX_INITIALIZER;
2688 pthread_mutex_lock( &my_lock); 2758 pthread_mutex_lock( &my_lock);
2689 { 2759 {
2690 // Recheck now that we're within the lock 2760 // Recheck now that we're within the lock
2691 // 2761 //
2692 if( s_initCount == 0) 2762 if( s_initCount == 0)
2693 { 2763 {
2694 init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create, shutdown_timeout, track_lanes); 2764 init_once_LOCKED( L, nbKeepers, on_state_create, shutdown_timeout, track_lanes);
2695 s_initCount = 1; 2765 s_initCount = 1;
2696 } 2766 }
2697 } 2767 }
2698 pthread_mutex_unlock(&my_lock); 2768 pthread_mutex_unlock( &my_lock);
2699 } 2769 }
2700#endif // THREADAPI == THREADAPI_PTHREAD 2770#endif // THREADAPI == THREADAPI_PTHREAD
2701 assert( timer_deep != 0 ); 2771 assert( timer_deep != NULL);
2702 2772 STACK_MID( L, 1)
2703 // Create main module interface table 2773
2704 lua_pushvalue( L, lua_upvalueindex( 2)); 2774 // init_once_LOCKED initializes timer_deep, so we must do this after, of course
2705 // remove configure() (this function) from the module interface 2775 luaG_push_proxy( L, linda_id, (DEEP_PRELUDE*) timer_deep); // ... M timer_deep
2706 lua_pushnil( L); 2776 lua_setfield( L, -2, "timer_gateway"); // ... M
2707 lua_setfield( L, -2, "configure"); 2777
2708 // add functions to the module's table 2778 lua_pop( L, 1); // ...
2709 luaG_registerlibfuncs(L, lanes_functions); 2779 STACK_END( L, 0)
2710 2780 // Return nothing
2711 // metatable for threads 2781 return 0;
2712 // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join } 2782}
2713 // 2783
2714 lua_newtable( L); 2784// helper to have correct callstacks when crashing a Win32 running on 64 bits Windows
2715 lua_pushcfunction( L, LG_thread_gc); 2785// don't forget to toggle Debug/Exceptions/Win32 in visual Studio too!
2716 lua_setfield( L, -2, "__gc"); 2786void EnableCrashingOnCrashes()
2717 lua_pushcfunction( L, LG_thread_index); 2787{
2718 lua_setfield( L, -2, "__index"); 2788#if 0 && defined PLATFORM_WIN32
2719 lua_getglobal( L, "error"); 2789 typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
2720 ASSERT_L( lua_isfunction( L, -1)); 2790 typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
2721 lua_setfield( L, -2, "cached_error"); 2791 const DWORD EXCEPTION_SWALLOWING = 0x1;
2722 lua_getglobal( L, "tostring"); 2792
2723 ASSERT_L( lua_isfunction( L, -1)); 2793 HMODULE kernel32 = LoadLibraryA("kernel32.dll");
2724 lua_setfield( L, -2, "cached_tostring"); 2794 tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy");
2725 lua_pushcfunction( L, LG_thread_join); 2795 tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy");
2726 lua_setfield( L, -2, "join"); 2796 if (pGetPolicy && pSetPolicy)
2727 lua_pushcfunction( L, LG_thread_cancel); 2797 {
2728 lua_setfield( L, -2, "cancel"); 2798 DWORD dwFlags;
2729 lua_pushliteral( L, "Lane"); 2799 if (pGetPolicy(&dwFlags))
2730 lua_setfield( L, -2, "__metatable"); 2800 {
2731 2801 // Turn off the filter
2732 lua_pushcclosure( L, LG_thread_new, 1 ); // metatable as closure param 2802 pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
2733 lua_setfield(L, -2, "thread_new"); 2803 }
2734 2804 }
2735 luaG_push_proxy( L, linda_id, (DEEP_PRELUDE *) timer_deep ); 2805#endif // PLATFORM_WIN32
2736 lua_setfield(L, -2, "timer_gateway");
2737
2738 lua_pushstring(L, VERSION);
2739 lua_setfield(L, -2, "version");
2740
2741 lua_pushinteger(L, THREAD_PRIO_MAX);
2742 lua_setfield(L, -2, "max_prio");
2743
2744 lua_pushlightuserdata( L, CANCEL_ERROR );
2745 lua_setfield(L, -2, "cancel_error");
2746
2747 // register all native functions found in that module in the transferable functions database
2748 // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names)
2749 populate_func_lookup_table( L, -1, name);
2750 lua_pop( L, 1);
2751 // record all existing C/JIT-fast functions
2752 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack
2753 populate_func_lookup_table( L, -1, NULL);
2754 lua_pop( L, 1); // done with globals table, pop it
2755 // Return nothing
2756 return 0;
2757} 2806}
2758 2807
2759int 2808int
@@ -2762,6 +2811,8 @@ __declspec(dllexport)
2762#endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) 2811#endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
2763luaopen_lanes_core( lua_State* L) 2812luaopen_lanes_core( lua_State* L)
2764{ 2813{
2814 EnableCrashingOnCrashes();
2815
2765 STACK_GROW( L, 3); 2816 STACK_GROW( L, 3);
2766 STACK_CHECK( L) 2817 STACK_CHECK( L)
2767 2818
diff --git a/src/lanes.lua b/src/lanes.lua
index 8c135c2..6bd9e44 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -210,10 +210,10 @@ local valid_libs= {
210 ["string"]= true, 210 ["string"]= true,
211 ["math"]= true, 211 ["math"]= true,
212 ["debug"]= true, 212 ["debug"]= true,
213 ["bit32"]= true, -- Lua 5.2 only, ignored silently under 5.1
213 -- 214 --
214 ["base"]= true, 215 ["base"]= true,
215 ["coroutine"]= true, 216 ["coroutine"]= true
216 ["*"]= true
217} 217}
218 218
219-- PUBLIC LANES API 219-- PUBLIC LANES API
@@ -251,11 +251,19 @@ local function gen( ... )
251 251
252 -- Check 'libs' already here, so the error goes in the right place 252 -- Check 'libs' already here, so the error goes in the right place
253 -- (otherwise will be noticed only once the generator is called) 253 -- (otherwise will be noticed only once the generator is called)
254 -- "*" is a special case that doesn't require individual checking
254 -- 255 --
255 if libs then 256 if libs and libs ~= "*" then
256 for s in string_gmatch(libs, "[%a*]+") do 257 local found = {}
258 -- check that the caller only provides reserved library names
259 for s in string_gmatch(libs, "[%a%d]+") do
257 if not valid_libs[s] then 260 if not valid_libs[s] then
258 error( "Bad library name: "..s ) 261 error( "Bad library name: " .. s)
262 else
263 found[s] = (found[s] or 0) + 1
264 if found[s] > 1 then
265 error( "libs specification contains '" .. s .. "' more than once")
266 end
259 end 267 end
260 end 268 end
261 end 269 end
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
45DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+");
46
45MUTEX_T deep_lock; 47MUTEX_T deep_lock;
46MUTEX_T mtid_lock; 48MUTEX_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
97static const luaL_Reg libs[] = { 99static 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
111static bool_t openlib( lua_State *L, const char *name, size_t len ) { 117static 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
138static int dummy_writer(lua_State *L, const void* p, size_t sz, void* ud) 147static 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 */
375void populate_func_lookup_table( lua_State *L, int _i, char const *_name) 385void 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
424lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) 434lua_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 */
1129static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ); 1149static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i);
1130 1150
1131static void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) 1151static 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
1337LOG_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
1758int luaG_inter_move( lua_State* L, lua_State *L2, uint_t n ) 1805int 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
1812void 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
diff --git a/src/tools.h b/src/tools.h
index 4a77a6a..d0169cf 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -25,6 +25,8 @@
25#define lua_getuservalue lua_getfenv 25#define lua_getuservalue lua_getfenv
26#define lua_rawlen lua_objlen 26#define lua_rawlen lua_objlen
27#define luaG_registerlibfuncs( L, _funcs) luaL_register( L, NULL, _funcs) 27#define luaG_registerlibfuncs( L, _funcs) luaL_register( L, NULL, _funcs)
28#define LUA_OK 0
29#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value
28#endif // LUA_VERSION_NUM == 501 30#endif // LUA_VERSION_NUM == 501
29 31
30// wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way 32// wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way
@@ -33,14 +35,21 @@
33#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0) 35#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0)
34#endif // LUA_VERSION_NUM == 502 36#endif // LUA_VERSION_NUM == 502
35 37
38#define USE_DEBUG_SPEW 0
39#if USE_DEBUG_SPEW
40extern char const* debugspew_indent;
41#define DEBUGSPEW_CODE(_code) _code
42#else // USE_DEBUG_SPEW
43#define DEBUGSPEW_CODE(_code)
44#endif // USE_DEBUG_SPEW
45
46
36#ifdef NDEBUG 47#ifdef NDEBUG
37 #define _ASSERT_L(lua,c) /*nothing*/ 48 #define _ASSERT_L(lua,c) /*nothing*/
38 #define STACK_CHECK(L) /*nothing*/ 49 #define STACK_CHECK(L) /*nothing*/
39 #define STACK_MID(L,c) /*nothing*/ 50 #define STACK_MID(L,c) /*nothing*/
40 #define STACK_END(L,c) /*nothing*/ 51 #define STACK_END(L,c) /*nothing*/
41 #define STACK_DUMP(L) /*nothing*/ 52 #define STACK_DUMP(L) /*nothing*/
42 #define DEBUG() /*nothing*/
43 #define DEBUGEXEC(_code) {} /*nothing*/
44#else 53#else
45 #define _ASSERT_L(lua,c) do { if (!(c)) luaL_error( lua, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #c ); } while( 0) 54 #define _ASSERT_L(lua,c) do { if (!(c)) luaL_error( lua, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #c ); } while( 0)
46 // 55 //
@@ -50,8 +59,6 @@
50 #define STACK_END(L,change) STACK_MID(L,change) } 59 #define STACK_END(L,change) STACK_MID(L,change) }
51 60
52 #define STACK_DUMP(L) luaG_dump(L); 61 #define STACK_DUMP(L) luaG_dump(L);
53 #define DEBUG() fprintf( stderr, "<<%s %d>>\n", __FILE__, __LINE__ );
54 #define DEBUGEXEC(_code) {_code;} /*nothing*/
55#endif 62#endif
56#define ASSERT_L(c) _ASSERT_L(L,c) 63#define ASSERT_L(c) _ASSERT_L(L,c)
57 64
@@ -73,7 +80,8 @@ typedef struct {
73 void *deep; 80 void *deep;
74} DEEP_PRELUDE; 81} DEEP_PRELUDE;
75 82
76void luaG_push_proxy( lua_State *L, luaG_IdFunction idfunc, DEEP_PRELUDE *deep_userdata ); 83void luaG_push_proxy( lua_State *L, luaG_IdFunction idfunc, DEEP_PRELUDE *deep_userdata);
84void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx);
77 85
78int luaG_inter_copy( lua_State *L, lua_State *L2, uint_t n); 86int luaG_inter_copy( lua_State *L, lua_State *L2, uint_t n);
79int luaG_inter_move( lua_State *L, lua_State *L2, uint_t n); 87int luaG_inter_move( lua_State *L, lua_State *L2, uint_t n);
@@ -85,7 +93,7 @@ int luaG_nameof( lua_State* L);
85extern MUTEX_T deep_lock; 93extern MUTEX_T deep_lock;
86extern MUTEX_T mtid_lock; 94extern MUTEX_T mtid_lock;
87 95
88void populate_func_lookup_table( lua_State *L, int _i, char const *_name); 96void populate_func_lookup_table( lua_State* L, int _i, char const* _name);
89void serialize_require( lua_State *L); 97void serialize_require( lua_State *L);
90extern MUTEX_T require_cs; 98extern MUTEX_T require_cs;
91 99