aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c1
-rw-r--r--lundump.c9
-rw-r--r--testes/calls.lua21
3 files changed, 24 insertions, 7 deletions
diff --git a/lapi.c b/lapi.c
index 3e24781e..184b8dd7 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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);
diff --git a/lundump.c b/lundump.c
index 4243678a..cb124d6f 100644
--- a/lundump.c
+++ b/lundump.c
@@ -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*/
203static void loadUpvalues (LoadState *S, Proto *f) { 209static 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
423print("testing binary chunks") 423print("testing binary chunks")
424do 424do
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)
455end 464end
456 465
457print('OK') 466print('OK')