aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
authorBenoit Germain <bnt period germain arrobase gmail period com>2014-01-06 10:40:14 +0100
committerBenoit Germain <bnt period germain arrobase gmail period com>2014-01-06 10:40:14 +0100
commitb335cbcc9f07dc71999b885ffa2962c0ec00f5eb (patch)
treead6398a6f7e5ef155631b984bd41d07d535ea1f9 /src/tools.c
parent132e85cb40f3a88efdb66a6344061bade628fcda (diff)
downloadlanes-b335cbcc9f07dc71999b885ffa2962c0ec00f5eb.tar.gz
lanes-b335cbcc9f07dc71999b885ffa2962c0ec00f5eb.tar.bz2
lanes-b335cbcc9f07dc71999b885ffa2962c0ec00f5eb.zip
fix on_state_create circular logic issue
* if config.on_state_create() is a C function, call it by direct C closure reconstruction in newly created states * bumped version to 3.7.6
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/src/tools.c b/src/tools.c
index 60f9012..9f36858 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -8,7 +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 2011-14 benoit Germain <bnt.germain@gmail.com>
12 12
13Permission 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
14of this software and associated documentation files (the "Software"), to deal 14of this software and associated documentation files (the "Software"), to deal
@@ -161,6 +161,39 @@ void luaG_dump( lua_State* L ) {
161 fprintf( stderr, "\n" ); 161 fprintf( stderr, "\n" );
162} 162}
163 163
164static lua_CFunction s_on_state_create_func = NULL;
165int initialize_on_state_create( lua_State* L)
166{
167 STACK_CHECK( L);
168 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil
169 if( !lua_isnil( L, -1))
170 {
171 // store C function pointer in an internal variable
172 s_on_state_create_func = lua_tocfunction( L, -1); // settings on_state_create
173 if( s_on_state_create_func != NULL)
174 {
175 // make sure the function doesn't have upvalues
176 char const* upname = lua_getupvalue( L, -1, 1); // settings on_state_create upval?
177 if( upname != NULL) // should be "" for C functions with upvalues if any
178 {
179 luaL_error( L, "on_state_create shouldn't have upvalues");
180 }
181 // remove this C function from the config table so that it doesn't cause problems
182 // when we transfer the config table in newly created Lua states
183 lua_pushnil( L); // settings on_state_create nil
184 lua_setfield( L, -3, "on_state_create"); // settings on_state_create
185 }
186 else
187 {
188 // optim: store marker saying we have such a function in the config table
189 s_on_state_create_func = initialize_on_state_create;
190 }
191 }
192 lua_pop( L, 1); // settings
193 STACK_END( L, 0);
194 return 0;
195}
196
164// just like lua_xmove, args are (from, to) 197// just like lua_xmove, args are (from, to)
165void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_) 198void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_)
166{ 199{
@@ -569,7 +602,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
569* Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. 602* Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL.
570* 603*
571*/ 604*/
572lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char const* libs) 605lua_State* luaG_newstate( lua_State* _from, char const* libs)
573{ 606{
574 // reuse alloc function from the originating state 607 // reuse alloc function from the originating state
575#if PROPAGATE_ALLOCF 608#if PROPAGATE_ALLOCF
@@ -587,7 +620,7 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
587 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); 620 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY);
588 621
589 // neither libs (not even 'base') nor special init func: we are done 622 // neither libs (not even 'base') nor special init func: we are done
590 if( libs == NULL && _on_state_create <= 0) 623 if( libs == NULL && s_on_state_create_func == NULL)
591 { 624 {
592 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END)); 625 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END));
593 return L; 626 return L;
@@ -655,22 +688,19 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
655 688
656 STACK_CHECK( L); 689 STACK_CHECK( L);
657 // call this after the base libraries are loaded and GC is restarted 690 // call this after the base libraries are loaded and GC is restarted
658 if( _on_state_create > 0) 691 if( s_on_state_create_func != NULL)
659 { 692 {
660 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); 693 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END));
661 if( lua_iscfunction( _from, _on_state_create)) 694 if( s_on_state_create_func != initialize_on_state_create)
662 { 695 {
663 // C function: recreate a closure in the new state, bypassing the lookup scheme 696 // C function: recreate a closure in the new state, bypassing the lookup scheme
664 lua_CFunction osc = lua_tocfunction( _from, _on_state_create); 697 lua_pushcfunction( L, s_on_state_create_func);
665 lua_pushcfunction( L, osc);
666 } 698 }
667 else 699 else // Lua function located in the config table
668 { 700 {
669 STACK_CHECK( _from); 701 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY);
670 // Lua function: transfer as usual (should work as long as it only uses base libraries) 702 lua_getfield( L, -1, "on_state_create");
671 lua_pushvalue( _from, _on_state_create); 703 lua_remove( L, -2);
672 luaG_inter_move( _from, L, 1, eLM_LaneBody);
673 STACK_END( _from, 0);
674 } 704 }
675 // capture error and forward it to main state 705 // capture error and forward it to main state
676 if( lua_pcall( L, 0, 0, 0) != LUA_OK) 706 if( lua_pcall( L, 0, 0, 0) != LUA_OK)