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') |
