diff options
-rw-r--r-- | lapi.c | 1 | ||||
-rw-r--r-- | lundump.c | 9 | ||||
-rw-r--r-- | testes/calls.lua | 21 |
3 files changed, 24 insertions, 7 deletions
@@ -563,6 +563,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
563 | while (n--) { | 563 | while (n--) { |
564 | setobj2n(L, &cl->upvalue[n], s2v(L->top + n)); | 564 | setobj2n(L, &cl->upvalue[n], s2v(L->top + n)); |
565 | /* does not need barrier because closure is white */ | 565 | /* does not need barrier because closure is white */ |
566 | lua_assert(iswhite(cl)); | ||
566 | } | 567 | } |
567 | setclCvalue(L, s2v(L->top), cl); | 568 | setclCvalue(L, s2v(L->top), cl); |
568 | api_incr_top(L); | 569 | api_incr_top(L); |
@@ -200,13 +200,20 @@ static void loadProtos (LoadState *S, Proto *f) { | |||
200 | } | 200 | } |
201 | 201 | ||
202 | 202 | ||
203 | /* | ||
204 | ** Load the upvalues for a function. The names must be filled first, | ||
205 | ** because the filling of the other fields can raise read errors and | ||
206 | ** the creation of the error message can call an emergency collection; | ||
207 | ** in that case all prototypes must be consistent for the GC. | ||
208 | */ | ||
203 | static void loadUpvalues (LoadState *S, Proto *f) { | 209 | static void loadUpvalues (LoadState *S, Proto *f) { |
204 | int i, n; | 210 | int i, n; |
205 | n = loadInt(S); | 211 | n = loadInt(S); |
206 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); | 212 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); |
207 | f->sizeupvalues = n; | 213 | f->sizeupvalues = n; |
208 | for (i = 0; i < n; i++) { | 214 | for (i = 0; i < n; i++) /* make array valid for GC */ |
209 | f->upvalues[i].name = NULL; | 215 | f->upvalues[i].name = NULL; |
216 | for (i = 0; i < n; i++) { /* following calls can raise errors */ | ||
210 | f->upvalues[i].instack = loadByte(S); | 217 | f->upvalues[i].instack = loadByte(S); |
211 | f->upvalues[i].idx = loadByte(S); | 218 | f->upvalues[i].idx = loadByte(S); |
212 | f->upvalues[i].kind = loadByte(S); | 219 | f->upvalues[i].kind = loadByte(S); |
diff --git a/testes/calls.lua b/testes/calls.lua index 1701f155..decf4176 100644 --- a/testes/calls.lua +++ b/testes/calls.lua | |||
@@ -422,20 +422,30 @@ assert((function (a) return a end)() == nil) | |||
422 | 422 | ||
423 | print("testing binary chunks") | 423 | print("testing binary chunks") |
424 | do | 424 | do |
425 | local header = string.pack("c4BBc6BBBj", | 425 | local header = string.pack("c4BBc6BBB", |
426 | "\27Lua", -- signature | 426 | "\27Lua", -- signature |
427 | 0x54, -- version 5.4 (0x54) | 427 | 0x54, -- version 5.4 (0x54) |
428 | 0, -- format | 428 | 0, -- format |
429 | "\x19\x93\r\n\x1a\n", -- data | 429 | "\x19\x93\r\n\x1a\n", -- data |
430 | 4, -- size of instruction | 430 | 4, -- size of instruction |
431 | string.packsize("j"), -- sizeof(lua integer) | 431 | string.packsize("j"), -- sizeof(lua integer) |
432 | string.packsize("n"), -- sizeof(lua number) | 432 | string.packsize("n") -- sizeof(lua number) |
433 | 0x5678 -- LUAC_INT | ||
434 | -- LUAC_NUM may not have a unique binary representation (padding...) | ||
435 | ) | 433 | ) |
436 | local c = string.dump(function () local a = 1; local b = 3; return a+b*3 end) | 434 | local c = string.dump(function () |
435 | local a = 1; local b = 3; | ||
436 | local f = function () return a + b + _ENV.c; end -- upvalues | ||
437 | local s1 = "a constant" | ||
438 | local s2 = "another constant" | ||
439 | return a + b * 3 | ||
440 | end) | ||
437 | 441 | ||
442 | assert(assert(load(c))() == 10) | ||
443 | |||
444 | -- check header | ||
438 | assert(string.sub(c, 1, #header) == header) | 445 | assert(string.sub(c, 1, #header) == header) |
446 | -- check LUAC_INT and LUAC_NUM | ||
447 | local ci, cn = string.unpack("jn", c, #header + 1) | ||
448 | assert(ci == 0x5678 and cn == 370.5) | ||
439 | 449 | ||
440 | -- corrupted header | 450 | -- corrupted header |
441 | for i = 1, #header do | 451 | for i = 1, #header do |
@@ -451,7 +461,6 @@ do | |||
451 | local st, msg = load(string.sub(c, 1, i)) | 461 | local st, msg = load(string.sub(c, 1, i)) |
452 | assert(not st and string.find(msg, "truncated")) | 462 | assert(not st and string.find(msg, "truncated")) |
453 | end | 463 | end |
454 | assert(assert(load(c))() == 10) | ||
455 | end | 464 | end |
456 | 465 | ||
457 | print('OK') | 466 | print('OK') |