diff options
Diffstat (limited to '')
-rw-r--r-- | testes/api.lua | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/testes/api.lua b/testes/api.lua index dece98f5..181c1d53 100644 --- a/testes/api.lua +++ b/testes/api.lua | |||
@@ -407,7 +407,7 @@ do | |||
407 | concat 3]]) == "hi alo mundo") | 407 | concat 3]]) == "hi alo mundo") |
408 | 408 | ||
409 | -- "argerror" without frames | 409 | -- "argerror" without frames |
410 | assert(T.checkpanic("loadstring 4") == | 410 | assert(T.checkpanic("loadstring 4 name bt") == |
411 | "bad argument #4 (string expected, got no value)") | 411 | "bad argument #4 (string expected, got no value)") |
412 | 412 | ||
413 | 413 | ||
@@ -420,7 +420,7 @@ do | |||
420 | if not _soft then | 420 | if not _soft then |
421 | local msg = T.checkpanic[[ | 421 | local msg = T.checkpanic[[ |
422 | pushstring "function f() f() end" | 422 | pushstring "function f() f() end" |
423 | loadstring -1; call 0 0 | 423 | loadstring -1 name t; call 0 0 |
424 | getglobal f; call 0 0 | 424 | getglobal f; call 0 0 |
425 | ]] | 425 | ]] |
426 | assert(string.find(msg, "stack overflow")) | 426 | assert(string.find(msg, "stack overflow")) |
@@ -430,7 +430,7 @@ do | |||
430 | assert(T.checkpanic([[ | 430 | assert(T.checkpanic([[ |
431 | pushstring "return {__close = function () Y = 'ho'; end}" | 431 | pushstring "return {__close = function () Y = 'ho'; end}" |
432 | newtable | 432 | newtable |
433 | loadstring -2 | 433 | loadstring -2 name t |
434 | call 0 1 | 434 | call 0 1 |
435 | setmetatable -2 | 435 | setmetatable -2 |
436 | toclose -1 | 436 | toclose -1 |
@@ -458,6 +458,8 @@ if not _soft then | |||
458 | print'+' | 458 | print'+' |
459 | end | 459 | end |
460 | 460 | ||
461 | |||
462 | |||
461 | local lim = _soft and 500 or 12000 | 463 | local lim = _soft and 500 or 12000 |
462 | local prog = {"checkstack " .. (lim * 2 + 100) .. "msg", "newtable"} | 464 | local prog = {"checkstack " .. (lim * 2 + 100) .. "msg", "newtable"} |
463 | for i = 1,lim do | 465 | for i = 1,lim do |
@@ -481,10 +483,20 @@ for i = 1,lim do assert(t[i] == i*10); t[i] = undef end | |||
481 | assert(next(t) == nil) | 483 | assert(next(t) == nil) |
482 | prog, g, t = nil | 484 | prog, g, t = nil |
483 | 485 | ||
486 | do -- shrink stack | ||
487 | local m1, m2 = 0, collectgarbage"count" * 1024 | ||
488 | while m1 ~= m2 do -- repeat until stable | ||
489 | collectgarbage() | ||
490 | m1 = m2 | ||
491 | m2 = collectgarbage"count" * 1024 | ||
492 | end | ||
493 | end | ||
494 | |||
495 | |||
484 | -- testing errors | 496 | -- testing errors |
485 | 497 | ||
486 | a = T.testC([[ | 498 | a = T.testC([[ |
487 | loadstring 2; pcall 0 1 0; | 499 | loadstring 2 name t; pcall 0 1 0; |
488 | pushvalue 3; insert -2; pcall 1 1 0; | 500 | pushvalue 3; insert -2; pcall 1 1 0; |
489 | pcall 0 0 0; | 501 | pcall 0 0 0; |
490 | return 1 | 502 | return 1 |
@@ -498,7 +510,7 @@ local function check3(p, ...) | |||
498 | assert(#arg == 3) | 510 | assert(#arg == 3) |
499 | assert(string.find(arg[3], p)) | 511 | assert(string.find(arg[3], p)) |
500 | end | 512 | end |
501 | check3(":1:", T.testC("loadstring 2; return *", "x=")) | 513 | check3(":1:", T.testC("loadstring 2 name t; return *", "x=")) |
502 | check3("%.", T.testC("loadfile 2; return *", ".")) | 514 | check3("%.", T.testC("loadfile 2; return *", ".")) |
503 | check3("xxxx", T.testC("loadfile 2; return *", "xxxx")) | 515 | check3("xxxx", T.testC("loadfile 2; return *", "xxxx")) |
504 | 516 | ||
@@ -509,6 +521,35 @@ local function checkerrnopro (code, msg) | |||
509 | assert(not stt and string.find(err, msg)) | 521 | assert(not stt and string.find(err, msg)) |
510 | end | 522 | end |
511 | 523 | ||
524 | |||
525 | do | ||
526 | print("testing load of binaries in fixed buffers") | ||
527 | local source = {} | ||
528 | local N = 1000 | ||
529 | -- create a somewhat "large" source | ||
530 | for i = 1, N do source[i] = "X = X + 1; " end | ||
531 | source = table.concat(source) | ||
532 | -- give chunk an explicit name to avoid using source as name | ||
533 | source = load(source, "name1") | ||
534 | -- dump without debug information | ||
535 | source = string.dump(source, true) | ||
536 | -- each "X=X+1" generates 4 opcodes with 4 bytes each | ||
537 | assert(#source > N * 4 * 4) | ||
538 | collectgarbage(); collectgarbage() | ||
539 | local m1 = collectgarbage"count" * 1024 | ||
540 | -- load dump using fixed buffer | ||
541 | local code = T.testC([[ | ||
542 | loadstring 2 name B; | ||
543 | return 1 | ||
544 | ]], source) | ||
545 | collectgarbage() | ||
546 | local m2 = collectgarbage"count" * 1024 | ||
547 | -- load used fewer than 300 bytes | ||
548 | assert(m2 > m1 and m2 - m1 < 300) | ||
549 | X = 0; code(); assert(X == N); X = nil | ||
550 | end | ||
551 | |||
552 | |||
512 | if not _soft then | 553 | if not _soft then |
513 | collectgarbage("stop") -- avoid __gc with full stack | 554 | collectgarbage("stop") -- avoid __gc with full stack |
514 | checkerrnopro("pushnum 3; call 0 0", "attempt to call") | 555 | checkerrnopro("pushnum 3; call 0 0", "attempt to call") |