From 5497775534d20ba06ab9c13bc4db1c5bee877513 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 28 Jul 2023 11:53:04 +0800 Subject: fix xpcall usages in different Lua version. --- src/yuescript/yue_compiler.cpp | 59 ++++++++++++++++++++++++++++-------------- src/yuescript/yuescript.h | 17 +++++++----- 2 files changed, 50 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 1378436..4d8ed86 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -72,7 +72,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.17.11"sv; +const std::string_view version = "0.17.12"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -7978,31 +7978,50 @@ private: auto chainValue = value->item.as(); BREAK_IF(!chainValue); BREAK_IF(!isChainValueCall(chainValue)); - ast_ptr last = chainValue->items.back(); - chainValue->items.pop_back(); - _ast_list* args = nullptr; - if (auto invoke = ast_cast(last)) { - args = &invoke->args; - } else { - args = &(ast_to(last)->args); - } - if (errHandler) { + if (errHandler && getLuaTarget(x) < 502) { + auto tryExp = toAst("->"sv, x); + auto funLit = simpleSingleValueFrom(tryExp)->value.to(); + auto expList = x->new_ptr(); + expList->exprs.push_back(tryNode->func); + auto expListAssign = x->new_ptr(); + expListAssign->expList.set(expList); + auto stmt = x->new_ptr(); + stmt->content.set(expListAssign); + auto body = x->new_ptr(); + body->content.set(stmt); + funLit->body.set(body); auto xpcall = toAst("xpcall()", x); auto invoke = ast_to(xpcall->items.back()); - invoke->args.push_back(tryNode->func); + invoke->args.push_back(tryExp); invoke->args.push_back(errHandler); - for (auto arg : args->objects()) { - invoke->args.push_back(arg); - } transformChainValue(xpcall, out, ExpUsage::Closure); } else { - auto pcall = toAst("pcall()", x); - auto invoke = ast_to(pcall->items.back()); - invoke->args.push_back(tryNode->func); - for (auto arg : args->objects()) { - invoke->args.push_back(arg); + ast_ptr last = chainValue->items.back(); + chainValue->items.pop_back(); + _ast_list* args = nullptr; + if (auto invoke = ast_cast(last)) { + args = &invoke->args; + } else { + args = &(ast_to(last)->args); + } + if (errHandler) { + auto xpcall = toAst("xpcall()", x); + auto invoke = ast_to(xpcall->items.back()); + invoke->args.push_back(tryNode->func); + invoke->args.push_back(errHandler); + for (auto arg : args->objects()) { + invoke->args.push_back(arg); + } + transformChainValue(xpcall, out, ExpUsage::Closure); + } else { + auto pcall = toAst("pcall()", x); + auto invoke = ast_to(pcall->items.back()); + invoke->args.push_back(tryNode->func); + for (auto arg : args->objects()) { + invoke->args.push_back(arg); + } + transformChainValue(pcall, out, ExpUsage::Closure); } - transformChainValue(pcall, out, ExpUsage::Closure); } if (usage == ExpUsage::Common) { out.back().append(nlr(x)); diff --git a/src/yuescript/yuescript.h b/src/yuescript/yuescript.h index 3d8d65c..a160f55 100644 --- a/src/yuescript/yuescript.h +++ b/src/yuescript/yuescript.h @@ -106,9 +106,12 @@ local function yue_loader(name) return concat(tried, "\n\t") end local function yue_call(f, ...) - return xpcall(f, function(err) - return yue.traceback(err, 1) - end, ...) + local args = {...} + return xpcall(function() + return f(unpack(args)) + end, function(err) + return yue.traceback(err, 2) + end) end yue_loadstring = function(...) local options, str, chunk_name, mode, env = get_options(...) @@ -166,9 +169,11 @@ local function yue_traceback(err, level) end local function yue_require(name) insert_loader() - local success, res = xpcall(require, function(err) - return yue_traceback(err, 2) - end, name) + local success, res = xpcall(function() + return require(name) + end, function(err) + return yue_traceback(err, 3) + end) if success then return res else -- cgit v1.2.3-55-g6feb