aboutsummaryrefslogtreecommitdiff
path: root/compat53.lua
diff options
context:
space:
mode:
Diffstat (limited to 'compat53.lua')
-rw-r--r--compat53.lua318
1 files changed, 162 insertions, 156 deletions
diff --git a/compat53.lua b/compat53.lua
index 5f88e8b..67a8c8f 100644
--- a/compat53.lua
+++ b/compat53.lua
@@ -336,12 +336,12 @@ if lua_version < "5.3" then
336 function debug.setuservalue(obj, value) 336 function debug.setuservalue(obj, value)
337 if type(obj) ~= "userdata" then 337 if type(obj) ~= "userdata" then
338 error("bad argument #1 to 'setuservalue' (userdata expected, got ".. 338 error("bad argument #1 to 'setuservalue' (userdata expected, got "..
339 type(obj)..")", 0) 339 type(obj)..")", 2)
340 end 340 end
341 if value == nil then value = _G end 341 if value == nil then value = _G end
342 if type(value) ~= "table" then 342 if type(value) ~= "table" then
343 error("bad argument #2 to 'setuservalue' (table expected, got ".. 343 error("bad argument #2 to 'setuservalue' (table expected, got "..
344 type(value)..")", 0) 344 type(value)..")", 2)
345 end 345 end
346 return debug_setfenv(obj, value) 346 return debug_setfenv(obj, value)
347 end 347 end
@@ -366,96 +366,98 @@ if lua_version < "5.3" then
366 end 366 end
367 end -- not luajit with compat52 enabled 367 end -- not luajit with compat52 enabled
368 368
369 local debug_getinfo = debug.getinfo 369 if not is_luajit then
370 local function calculate_trace_level(co, level) 370 local debug_getinfo = debug.getinfo
371 if level ~= nil then 371 local function calculate_trace_level(co, level)
372 for out = 1, 1/0 do 372 if level ~= nil then
373 local info = (co==nil) and debug_getinfo(out, "") or debug_getinfo(co, out, "") 373 for out = 1, 1/0 do
374 if info == nil then 374 local info = (co==nil) and debug_getinfo(out, "") or debug_getinfo(co, out, "")
375 local max = out-1 375 if info == nil then
376 if level <= max then 376 local max = out-1
377 return level 377 if level <= max then
378 return level
379 end
380 return nil, level-max
378 end 381 end
379 return nil, level-max
380 end 382 end
381 end 383 end
384 return 1
382 end 385 end
383 return 1
384 end
385 386
386 local stack_pattern = "\nstack traceback:" 387 local stack_pattern = "\nstack traceback:"
387 local stack_replace = "" 388 local stack_replace = ""
388 local debug_traceback = debug.traceback 389 local debug_traceback = debug.traceback
389 function debug.traceback(co, msg, level) 390 function debug.traceback(co, msg, level)
390 local lvl 391 local lvl
391 local nilmsg 392 local nilmsg
392 if type(co) ~= "thread" then 393 if type(co) ~= "thread" then
393 co, msg, level = coroutine_running(), co, msg 394 co, msg, level = coroutine_running(), co, msg
394 end 395 end
395 if msg == nil then 396 if msg == nil then
396 msg = "" 397 msg = ""
397 nilmsg = true 398 nilmsg = true
398 elseif type(msg) ~= "string" then 399 elseif type(msg) ~= "string" then
399 return msg 400 return msg
400 end 401 end
401 if co == nil then 402 if co == nil then
402 msg = debug_traceback(msg, level or 1) 403 msg = debug_traceback(msg, level or 1)
403 else
404 local xpco = xpcall_running[co]
405 if xpco ~= nil then
406 lvl, level = calculate_trace_level(xpco, level)
407 if lvl then
408 msg = debug_traceback(xpco, msg, lvl)
409 else
410 msg = msg..stack_pattern
411 end
412 lvl, level = calculate_trace_level(co, level)
413 if lvl then
414 local trace = debug_traceback(co, "", lvl)
415 msg = msg..trace:gsub(stack_pattern, stack_replace)
416 end
417 else 404 else
418 co = pcall_callOf[co] or co 405 local xpco = xpcall_running[co]
419 lvl, level = calculate_trace_level(co, level) 406 if xpco ~= nil then
420 if lvl then 407 lvl, level = calculate_trace_level(xpco, level)
421 msg = debug_traceback(co, msg, lvl) 408 if lvl then
409 msg = debug_traceback(xpco, msg, lvl)
410 else
411 msg = msg..stack_pattern
412 end
413 lvl, level = calculate_trace_level(co, level)
414 if lvl then
415 local trace = debug_traceback(co, "", lvl)
416 msg = msg..trace:gsub(stack_pattern, stack_replace)
417 end
422 else 418 else
423 msg = msg..stack_pattern 419 co = pcall_callOf[co] or co
424 end 420 lvl, level = calculate_trace_level(co, level)
425 end 421 if lvl then
426 co = pcall_previous[co] 422 msg = debug_traceback(co, msg, lvl)
427 while co ~= nil do 423 else
428 lvl, level = calculate_trace_level(co, level) 424 msg = msg..stack_pattern
429 if lvl then 425 end
430 local trace = debug_traceback(co, "", lvl)
431 msg = msg..trace:gsub(stack_pattern, stack_replace)
432 end 426 end
433 co = pcall_previous[co] 427 co = pcall_previous[co]
428 while co ~= nil do
429 lvl, level = calculate_trace_level(co, level)
430 if lvl then
431 local trace = debug_traceback(co, "", lvl)
432 msg = msg..trace:gsub(stack_pattern, stack_replace)
433 end
434 co = pcall_previous[co]
435 end
436 end
437 if nilmsg then
438 msg = msg:gsub("^\n", "")
434 end 439 end
440 msg = msg:gsub("\n\t%(tail call%): %?", "\000")
441 msg = msg:gsub("\n\t%.%.%.\n", "\001\n")
442 msg = msg:gsub("\n\t%.%.%.$", "\001")
443 msg = msg:gsub("(%z+)\001(%z+)", function(some, other)
444 return "\n\t(..."..#some+#other.."+ tail call(s)...)"
445 end)
446 msg = msg:gsub("\001(%z+)", function(zeros)
447 return "\n\t(..."..#zeros.."+ tail call(s)...)"
448 end)
449 msg = msg:gsub("(%z+)\001", function(zeros)
450 return "\n\t(..."..#zeros.."+ tail call(s)...)"
451 end)
452 msg = msg:gsub("%z+", function(zeros)
453 return "\n\t(..."..#zeros.." tail call(s)...)"
454 end)
455 msg = msg:gsub("\001", function(zeros)
456 return "\n\t..."
457 end)
458 return msg
435 end 459 end
436 if nilmsg then 460 end -- is not luajit
437 msg = msg:gsub("^\n", "")
438 end
439 msg = msg:gsub("\n\t%(tail call%): %?", "\000")
440 msg = msg:gsub("\n\t%.%.%.\n", "\001\n")
441 msg = msg:gsub("\n\t%.%.%.$", "\001")
442 msg = msg:gsub("(%z+)\001(%z+)", function(some, other)
443 return "\n\t(..."..#some+#other.."+ tail call(s)...)"
444 end)
445 msg = msg:gsub("\001(%z+)", function(zeros)
446 return "\n\t(..."..#zeros.."+ tail call(s)...)"
447 end)
448 msg = msg:gsub("(%z+)\001", function(zeros)
449 return "\n\t(..."..#zeros.."+ tail call(s)...)"
450 end)
451 msg = msg:gsub("%z+", function(zeros)
452 return "\n\t(..."..#zeros.." tail call(s)...)"
453 end)
454 msg = msg:gsub("\001", function(zeros)
455 return "\n\t..."
456 end)
457 return msg
458 end
459 end -- debug table available 461 end -- debug table available
460 462
461 463
@@ -501,7 +503,7 @@ if lua_version < "5.3" then
501 local ld_type = type(ld) 503 local ld_type = type(ld)
502 if ld_type ~= "function" then 504 if ld_type ~= "function" then
503 error("bad argument #1 to 'load' (function expected, got ".. 505 error("bad argument #1 to 'load' (function expected, got "..
504 ld_type..")", 0) 506 ld_type..")", 2)
505 end 507 end
506 if mode ~= "bt" then 508 if mode ~= "bt" then
507 local checked, merr = false, nil 509 local checked, merr = false, nil
@@ -564,7 +566,7 @@ if lua_version < "5.3" then
564 function rawlen(v) 566 function rawlen(v)
565 local t = type(v) 567 local t = type(v)
566 if t ~= "string" and t ~= "table" then 568 if t ~= "string" and t ~= "table" then
567 error("bad argument #1 to 'rawlen' (table or string expected)", 0) 569 error("bad argument #1 to 'rawlen' (table or string expected)", 2)
568 end 570 end
569 return #v 571 return #v
570 end 572 end
@@ -622,92 +624,94 @@ if lua_version < "5.3" then
622 624
623 local coroutine_yield = coroutine.yield 625 local coroutine_yield = coroutine.yield
624 function coroutine.yield(...) 626 function coroutine.yield(...)
625 local co = coroutine_running() 627 local co, flag = coroutine_running()
626 if co then 628 if co and not flag then
627 return coroutine_yield(...) 629 return coroutine_yield(...)
628 else 630 else
629 error("attempt to yield from outside a coroutine", 0) 631 error("attempt to yield from outside a coroutine", 0)
630 end 632 end
631 end 633 end
632 634
633 local coroutine_resume = coroutine.resume 635 if not is_luajit then
634 function coroutine.resume(co, ...) 636 local coroutine_resume = coroutine.resume
635 if co == main_coroutine then 637 function coroutine.resume(co, ...)
636 return false, "cannot resume non-suspended coroutine" 638 if co == main_coroutine then
637 else 639 return false, "cannot resume non-suspended coroutine"
638 return coroutine_resume(co, ...) 640 else
641 return coroutine_resume(co, ...)
642 end
639 end 643 end
640 end
641 644
642 local coroutine_status = coroutine.status 645 local coroutine_status = coroutine.status
643 function coroutine.status(co) 646 function coroutine.status(co)
644 local notmain = coroutine_running() 647 local notmain = coroutine_running()
645 if co == main_coroutine then 648 if co == main_coroutine then
646 return notmain and "normal" or "running" 649 return notmain and "normal" or "running"
647 else 650 else
648 return coroutine_status(co) 651 return coroutine_status(co)
652 end
649 end 653 end
650 end
651 654
652 local function pcall_results(current, call, success, ...) 655 local function pcall_results(current, call, success, ...)
653 if coroutine_status(call) == "suspended" then 656 if coroutine_status(call) == "suspended" then
654 return pcall_results(current, call, coroutine_resume(call, coroutine_yield(...))) 657 return pcall_results(current, call, coroutine_resume(call, coroutine_yield(...)))
658 end
659 if pcall_previous then
660 pcall_previous[call] = nil
661 local main = pcall_mainOf[call]
662 if main == current then current = nil end
663 pcall_callOf[main] = current
664 end
665 pcall_mainOf[call] = nil
666 return success, ...
655 end 667 end
656 if pcall_previous then 668 local function pcall_exec(current, call, ...)
657 pcall_previous[call] = nil 669 local main = pcall_mainOf[current] or current
658 local main = pcall_mainOf[call] 670 pcall_mainOf[call] = main
659 if main == current then current = nil end 671 if pcall_previous then
660 pcall_callOf[main] = current 672 pcall_previous[call] = current
673 pcall_callOf[main] = call
674 end
675 return pcall_results(current, call, coroutine_resume(call, ...))
661 end 676 end
662 pcall_mainOf[call] = nil 677 local coroutine_create52 = coroutine.create
663 return success, ... 678 local function pcall_coroutine(func)
664 end 679 if type(func) ~= "function" then
665 local function pcall_exec(current, call, ...) 680 local callable = func
666 local main = pcall_mainOf[current] or current 681 func = function (...) return callable(...) end
667 pcall_mainOf[call] = main 682 end
668 if pcall_previous then 683 return coroutine_create52(func)
669 pcall_previous[call] = current
670 pcall_callOf[main] = call
671 end 684 end
672 return pcall_results(current, call, coroutine_resume(call, ...)) 685 function pcall(func, ...)
673 end 686 local current = coroutine_running()
674 local coroutine_create52 = coroutine.create 687 if not current then return _pcall(func, ...) end
675 local function pcall_coroutine(func) 688 return pcall_exec(current, pcall_coroutine(func), ...)
676 if type(func) ~= "function" then
677 local callable = func
678 func = function (...) return callable(...) end
679 end 689 end
680 return coroutine_create52(func)
681 end
682 function pcall(func, ...)
683 local current = coroutine_running()
684 if not current then return _pcall(func, ...) end
685 return pcall_exec(current, pcall_coroutine(func), ...)
686 end
687 690
688 local function xpcall_catch(current, call, msgh, success, ...) 691 local function xpcall_catch(current, call, msgh, success, ...)
689 if not success then 692 if not success then
690 xpcall_running[current] = call 693 xpcall_running[current] = call
691 local ok, result = _pcall(msgh, ...) 694 local ok, result = _pcall(msgh, ...)
692 xpcall_running[current] = nil 695 xpcall_running[current] = nil
693 if not ok then 696 if not ok then
694 return false, "error in error handling ("..tostring(result)..")" 697 return false, "error in error handling ("..tostring(result)..")"
698 end
699 return false, result
695 end 700 end
696 return false, result 701 return true, ...
697 end 702 end
698 return true, ... 703 local _xpcall = xpcall
699 end 704 local _unpack = unpack
700 local _xpcall = xpcall 705 function xpcall(f, msgh, ...)
701 local _unpack = unpack 706 local current = coroutine_running()
702 function xpcall(f, msgh, ...) 707 if not current then
703 local current = coroutine_running() 708 local args, n = { ... }, select('#', ...)
704 if not current then 709 return _xpcall(function() return f(_unpack(args, 1, n)) end, msgh)
705 local args, n = { ... }, select('#', ...) 710 end
706 return _xpcall(function() return f(_unpack(args, 1, n)) end, msgh) 711 local call = pcall_coroutine(f)
712 return xpcall_catch(current, call, msgh, pcall_exec(current, call, ...))
707 end 713 end
708 local call = pcall_coroutine(f) 714 end -- not luajit
709 return xpcall_catch(current, call, msgh, pcall_exec(current, call, ...))
710 end
711 715
712 716
713 if not is_luajit then 717 if not is_luajit then
@@ -806,6 +810,7 @@ if lua_version < "5.3" then
806 return addqt[c] or string_format("\\%03d", c:byte()) 810 return addqt[c] or string_format("\\%03d", c:byte())
807 end 811 end
808 812
813 local _unpack = unpack
809 function string.format(fmt, ...) 814 function string.format(fmt, ...)
810 local args, n = { ... }, select('#', ...) 815 local args, n = { ... }, select('#', ...)
811 local i = 0 816 local i = 0
@@ -846,12 +851,13 @@ if lua_version < "5.3" then
846 if var_1 == nil then 851 if var_1 == nil then
847 if st.doclose then st.f:close() end 852 if st.doclose then st.f:close() end
848 if (...) ~= nil then 853 if (...) ~= nil then
849 error((...), 0) 854 error((...), 2)
850 end 855 end
851 end 856 end
852 return var_1, ... 857 return var_1, ...
853 end 858 end
854 859
860 local _unpack = unpack
855 function lines_iterator(st) 861 function lines_iterator(st)
856 return helper(st, st.f:read(_unpack(st, 1, st.n))) 862 return helper(st, st.f:read(_unpack(st, 1, st.n)))
857 end 863 end
@@ -864,14 +870,14 @@ if lua_version < "5.3" then
864 local doclose, file, msg 870 local doclose, file, msg
865 if fname ~= nil then 871 if fname ~= nil then
866 doclose, file, msg = true, io_open(fname, "r") 872 doclose, file, msg = true, io_open(fname, "r")
867 if not file then error(msg, 0) end 873 if not file then error(msg, 2) end
868 else 874 else
869 doclose, file = false, io_input() 875 doclose, file = false, io_input()
870 end 876 end
871 local st = { f=file, doclose=doclose, n=select('#', ...), ... } 877 local st = { f=file, doclose=doclose, n=select('#', ...), ... }
872 for i = 1, st.n do 878 for i = 1, st.n do
873 if type(st[i]) ~= "number" and not valid_format[st[i]] then 879 if type(st[i]) ~= "number" and not valid_format[st[i]] then
874 error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 0) 880 error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2)
875 end 881 end
876 end 882 end
877 return lines_iterator, st 883 return lines_iterator, st
@@ -894,12 +900,12 @@ if lua_version < "5.3" then
894 900
895 file_meta.__index.lines = function(self, ...) 901 file_meta.__index.lines = function(self, ...)
896 if io_type(self) == "closed file" then 902 if io_type(self) == "closed file" then
897 error("attempt to use a closed file", 0) 903 error("attempt to use a closed file", 2)
898 end 904 end
899 local st = { f=self, doclose=false, n=select('#', ...), ... } 905 local st = { f=self, doclose=false, n=select('#', ...), ... }
900 for i = 1, st.n do 906 for i = 1, st.n do
901 if type(st[i]) ~= "number" and not valid_format[st[i]] then 907 if type(st[i]) ~= "number" and not valid_format[st[i]] then
902 error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 0) 908 error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2)
903 end 909 end
904 end 910 end
905 return lines_iterator, st 911 return lines_iterator, st