aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-09 14:00:05 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-09 14:00:05 -0300
commit4e47f81188d37e29027158b76271d02a781242e2 (patch)
treec360912d1901acf8371390cc1f716278e5d91bb4 /testes
parentc63e5d212bc5dec1b1c749e3f07b42cd83081826 (diff)
downloadlua-4e47f81188d37e29027158b76271d02a781242e2.tar.gz
lua-4e47f81188d37e29027158b76271d02a781242e2.tar.bz2
lua-4e47f81188d37e29027158b76271d02a781242e2.zip
New implementation for to-be-closed variables
To-be-closed variables are linked in their own list, embedded into the stack elements. (Due to alignment, this information does not change the size of the stack elements in most architectures.) This new list does not produce garbage and avoids memory errors when creating tbc variables.
Diffstat (limited to 'testes')
-rw-r--r--testes/locals.lua49
1 files changed, 41 insertions, 8 deletions
diff --git a/testes/locals.lua b/testes/locals.lua
index a25b2b9f..446ec13a 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -529,6 +529,40 @@ local function checktable (t1, t2)
529end 529end
530 530
531 531
532do -- test for tbc variable high in the stack
533
534 -- function to force a stack overflow
535 local function overflow (n)
536 overflow(n + 1)
537 end
538
539 -- error handler will create tbc variable handling a stack overflow,
540 -- high in the stack
541 local function errorh (m)
542 assert(string.find(m, "stack overflow"))
543 local x <close> = func2close(function (o) o[1] = 10 end)
544 return x
545 end
546
547 local flag
548 local st, obj
549 -- run test in a coroutine so as not to swell the main stack
550 local co = coroutine.wrap(function ()
551 -- tbc variable down the stack
552 local y <close> = func2close(function (obj, msg)
553 assert(msg == nil)
554 obj[1] = 100
555 flag = obj
556 end)
557 collectgarbage("stop")
558 st, obj = xpcall(overflow, errorh, 0)
559 collectgarbage("restart")
560 end)
561 co()
562 assert(not st and obj[1] == 10 and flag[1] == 100)
563end
564
565
532if rawget(_G, "T") then 566if rawget(_G, "T") then
533 567
534 -- memory error inside closing function 568 -- memory error inside closing function
@@ -563,13 +597,13 @@ if rawget(_G, "T") then
563 597
564 local function test () 598 local function test ()
565 local x <close> = enter(0) -- set a memory limit 599 local x <close> = enter(0) -- set a memory limit
566 -- creation of previous upvalue will raise a memory error 600 local y = {} -- raise a memory error
567 assert(false) -- should not run
568 end 601 end
569 602
570 local _, msg = pcall(test) 603 local _, msg = pcall(test)
571 assert(msg == "not enough memory" and closemsg == "not enough memory") 604 assert(msg == "not enough memory" and closemsg == "not enough memory")
572 605
606
573 -- repeat test with extra closing upvalues 607 -- repeat test with extra closing upvalues
574 local function test () 608 local function test ()
575 local xxx <close> = func2close(function (self, msg) 609 local xxx <close> = func2close(function (self, msg)
@@ -580,8 +614,7 @@ if rawget(_G, "T") then
580 assert(msg == "not enough memory"); 614 assert(msg == "not enough memory");
581 end) 615 end)
582 local x <close> = enter(0) -- set a memory limit 616 local x <close> = enter(0) -- set a memory limit
583 -- creation of previous upvalue will raise a memory error 617 local y = {} -- raise a memory error
584 os.exit(false) -- should not run
585 end 618 end
586 619
587 local _, msg = pcall(test) 620 local _, msg = pcall(test)
@@ -607,7 +640,7 @@ if rawget(_G, "T") then
607 -- concat this table needs two buffer resizes (one for each 's') 640 -- concat this table needs two buffer resizes (one for each 's')
608 local a = {s, s} 641 local a = {s, s}
609 642
610 collectgarbage() 643 collectgarbage(); collectgarbage()
611 644
612 m = T.totalmem() 645 m = T.totalmem()
613 collectgarbage("stop") 646 collectgarbage("stop")
@@ -630,7 +663,7 @@ if rawget(_G, "T") then
630 -- second buffer was released by 'toclose' 663 -- second buffer was released by 'toclose'
631 assert(T.totalmem() - m <= extra) 664 assert(T.totalmem() - m <= extra)
632 665
633 -- userdata, upvalue, buffer, buffer, final string 666 -- userdata, buffer, buffer, final string
634 T.totalmem(m + 4*lim + extra) 667 T.totalmem(m + 4*lim + extra)
635 assert(#table.concat(a) == 2*lim) 668 assert(#table.concat(a) == 2*lim)
636 669
@@ -753,8 +786,8 @@ do
753 checktable({co()}, {true, 10, 20, 30}) 786 checktable({co()}, {true, 10, 20, 30})
754 checktable(trace, {"nowX", "z1", "z2", "nowY", "y1", "y2", "x1", "x2"}) 787 checktable(trace, {"nowX", "z1", "z2", "nowY", "y1", "y2", "x1", "x2"})
755 788
756end 789end
757 790
758 791
759do 792do
760 -- yielding inside closing metamethods after an error 793 -- yielding inside closing metamethods after an error