diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2021-07-08 14:55:04 +0200 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2021-07-08 14:55:04 +0200 |
commit | 663a44a7fea7602b894160ec0608bca378c97d10 (patch) | |
tree | 0b1ea725bcaf2ca788608e5db6931bb1c8ce1f9c /src | |
parent | 19c4381fd37be09fe6ce3b81d8d7bd12668fc7b8 (diff) | |
download | lanes-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.h | 2 | ||||
-rw-r--r-- | src/tools.c | 40 |
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 | |||
635 | static 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 |
643 | static int func_lookup_sentinel( lua_State* L) | 637 | static 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 | ||
1139 | static 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 | |||
1141 | static void copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, LookupMode mode_, char const* upName_) | 1150 | static 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) |