aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2021-07-08 14:55:04 +0200
committerBenoit Germain <bnt.germain@gmail.com>2021-07-08 14:55:04 +0200
commit663a44a7fea7602b894160ec0608bca378c97d10 (patch)
tree0b1ea725bcaf2ca788608e5db6931bb1c8ce1f9c /src
parent19c4381fd37be09fe6ce3b81d8d7bd12668fc7b8 (diff)
downloadlanes-663a44a7fea7602b894160ec0608bca378c97d10.tar.gz
lanes-663a44a7fea7602b894160ec0608bca378c97d10.tar.bz2
lanes-663a44a7fea7602b894160ec0608bca378c97d10.zip
fix function transfer with lua_dump for Lua 5.4 failing for functions big enough to necessitate a buffer reallocation
Diffstat (limited to 'src')
-rw-r--r--src/lanes.h2
-rw-r--r--src/tools.c40
2 files changed, 27 insertions, 15 deletions
diff --git a/src/lanes.h b/src/lanes.h
index 1a38ba5..41a6b73 100644
--- a/src/lanes.h
+++ b/src/lanes.h
@@ -12,7 +12,7 @@
12 12
13#define LANES_VERSION_MAJOR 3 13#define LANES_VERSION_MAJOR 3
14#define LANES_VERSION_MINOR 15 14#define LANES_VERSION_MINOR 15
15#define LANES_VERSION_PATCH 0 15#define LANES_VERSION_PATCH 1
16 16
17#define LANES_MIN_VERSION_REQUIRED(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR>MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR>MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH>=PATCH)))) 17#define LANES_MIN_VERSION_REQUIRED(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR>MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR>MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH>=PATCH))))
18#define LANES_VERSION_LESS_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR<MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR<MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH<PATCH)))) 18#define LANES_VERSION_LESS_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR<MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR<MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH<PATCH))))
diff --git a/src/tools.c b/src/tools.c
index 18015c1..1436e8d 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -297,7 +297,8 @@ static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length)
297 int i = 1; 297 int i = 1;
298 luaL_Buffer b; 298 luaL_Buffer b;
299 STACK_CHECK( L, 0); 299 STACK_CHECK( L, 0);
300 luaL_buffinit( L, &b); 300 // Lua 5.4 pushes &b as light userdata on the stack. be aware of it...
301 luaL_buffinit( L, &b); // ... {} ... &b?
301 for( ; i < last; ++ i) 302 for( ; i < last; ++ i)
302 { 303 {
303 lua_rawgeti( L, t, i); 304 lua_rawgeti( L, t, i);
@@ -309,7 +310,8 @@ static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length)
309 lua_rawgeti( L, t, i); 310 lua_rawgeti( L, t, i);
310 luaL_addvalue( &b); 311 luaL_addvalue( &b);
311 } 312 }
312 luaL_pushresult( &b); 313 // &b is popped at that point (-> replaced by the result)
314 luaL_pushresult( &b); // ... {} ... "<result>"
313 STACK_END( L, 1); 315 STACK_END( L, 1);
314 return lua_tolstring( L, -1, length); 316 return lua_tolstring( L, -1, length);
315} 317}
@@ -631,14 +633,6 @@ static lua_Integer get_mt_id( Universe* U, lua_State* L, int i)
631 return id; 633 return id;
632} 634}
633 635
634
635static int buf_writer( lua_State *L, const void* b, size_t n, void* B ) {
636 (void)L;
637 luaL_addlstring((luaL_Buffer*) B, (const char *)b, n);
638 return 0;
639}
640
641
642// function sentinel used to transfer native functions from/to keeper states 636// function sentinel used to transfer native functions from/to keeper states
643static int func_lookup_sentinel( lua_State* L) 637static int func_lookup_sentinel( lua_State* L)
644{ 638{
@@ -1138,14 +1132,32 @@ static char const* vt_names[] =
1138}; 1132};
1139#endif // USE_DEBUG_SPEW 1133#endif // USE_DEBUG_SPEW
1140 1134
1135// Lua 5.4.3 style of dumping (see lstrlib.c)
1136// we have to do it that way because we can't unbalance the stack between buffer operations
1137// namely, this means we can't push a function on top of the stack *after* we initialize the buffer!
1138// luckily, this also works with earlier Lua versions
1139static int buf_writer( lua_State* L, void const* b, size_t size, void* ud)
1140{
1141 luaL_Buffer* B = (luaL_Buffer*) ud;
1142 if( !B->L)
1143 {
1144 luaL_buffinit( L, B);
1145 }
1146 luaL_addlstring( B, (char const*) b, size);
1147 return 0;
1148}
1149
1141static void copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, LookupMode mode_, char const* upName_) 1150static void copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, LookupMode mode_, char const* upName_)
1142{ 1151{
1143 int n, needToPush; 1152 int n, needToPush;
1144 luaL_Buffer b; 1153 luaL_Buffer B;
1154 B.L = NULL;
1155
1145 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p 1156 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p
1146 STACK_GROW( L, 2); 1157 STACK_GROW( L, 2);
1147 STACK_CHECK( L, 0); 1158 STACK_CHECK( L, 0);
1148 1159
1160
1149 // 'lua_dump()' needs the function at top of stack 1161 // 'lua_dump()' needs the function at top of stack
1150 // if already on top of the stack, no need to push again 1162 // if already on top of the stack, no need to push again
1151 needToPush = (i != (uint_t)lua_gettop( L)); 1163 needToPush = (i != (uint_t)lua_gettop( L));
@@ -1154,18 +1166,18 @@ static void copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State*
1154 lua_pushvalue( L, i); // ... f 1166 lua_pushvalue( L, i); // ... f
1155 } 1167 }
1156 1168
1157 luaL_buffinit( L, &b);
1158 // 1169 //
1159 // "value returned is the error code returned by the last call 1170 // "value returned is the error code returned by the last call
1160 // to the writer" (and we only return 0) 1171 // to the writer" (and we only return 0)
1161 // not sure this could ever fail but for memory shortage reasons 1172 // not sure this could ever fail but for memory shortage reasons
1162 if( lua504_dump( L, buf_writer, &b, 0) != 0) 1173 // last parameter is Lua 5.4-specific (no stripping)
1174 if( lua504_dump( L, buf_writer, &B, 0) != 0)
1163 { 1175 {
1164 luaL_error( L, "internal error: function dump failed."); 1176 luaL_error( L, "internal error: function dump failed.");
1165 } 1177 }
1166 1178
1167 // pushes dumped string on 'L' 1179 // pushes dumped string on 'L'
1168 luaL_pushresult( &b); // ... f b 1180 luaL_pushresult( &B); // ... f b
1169 1181
1170 // if not pushed, no need to pop 1182 // if not pushed, no need to pop
1171 if( needToPush) 1183 if( needToPush)