aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-07-28 11:53:04 +0800
committerLi Jin <dragon-fly@qq.com>2023-07-28 11:53:04 +0800
commit5497775534d20ba06ab9c13bc4db1c5bee877513 (patch)
treebe68d03cf0928efca4a579125e4ba15ef3ab9325 /src
parentf415df9617d251abd802257d9750618ccc71ca93 (diff)
downloadyuescript-5497775534d20ba06ab9c13bc4db1c5bee877513.tar.gz
yuescript-5497775534d20ba06ab9c13bc4db1c5bee877513.tar.bz2
yuescript-5497775534d20ba06ab9c13bc4db1c5bee877513.zip
fix xpcall usages in different Lua version.
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_compiler.cpp59
-rw-r--r--src/yuescript/yuescript.h17
2 files changed, 50 insertions, 26 deletions
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<std::string> Metamethods = {
72 "close"s // Lua 5.4 72 "close"s // Lua 5.4
73}; 73};
74 74
75const std::string_view version = "0.17.11"sv; 75const std::string_view version = "0.17.12"sv;
76const std::string_view extension = "yue"sv; 76const std::string_view extension = "yue"sv;
77 77
78class CompileError : public std::logic_error { 78class CompileError : public std::logic_error {
@@ -7978,31 +7978,50 @@ private:
7978 auto chainValue = value->item.as<ChainValue_t>(); 7978 auto chainValue = value->item.as<ChainValue_t>();
7979 BREAK_IF(!chainValue); 7979 BREAK_IF(!chainValue);
7980 BREAK_IF(!isChainValueCall(chainValue)); 7980 BREAK_IF(!isChainValueCall(chainValue));
7981 ast_ptr<true, ast_node> last = chainValue->items.back(); 7981 if (errHandler && getLuaTarget(x) < 502) {
7982 chainValue->items.pop_back(); 7982 auto tryExp = toAst<Exp_t>("->"sv, x);
7983 _ast_list* args = nullptr; 7983 auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>();
7984 if (auto invoke = ast_cast<InvokeArgs_t>(last)) { 7984 auto expList = x->new_ptr<ExpList_t>();
7985 args = &invoke->args; 7985 expList->exprs.push_back(tryNode->func);
7986 } else { 7986 auto expListAssign = x->new_ptr<ExpListAssign_t>();
7987 args = &(ast_to<Invoke_t>(last)->args); 7987 expListAssign->expList.set(expList);
7988 } 7988 auto stmt = x->new_ptr<Statement_t>();
7989 if (errHandler) { 7989 stmt->content.set(expListAssign);
7990 auto body = x->new_ptr<Body_t>();
7991 body->content.set(stmt);
7992 funLit->body.set(body);
7990 auto xpcall = toAst<ChainValue_t>("xpcall()", x); 7993 auto xpcall = toAst<ChainValue_t>("xpcall()", x);
7991 auto invoke = ast_to<Invoke_t>(xpcall->items.back()); 7994 auto invoke = ast_to<Invoke_t>(xpcall->items.back());
7992 invoke->args.push_back(tryNode->func); 7995 invoke->args.push_back(tryExp);
7993 invoke->args.push_back(errHandler); 7996 invoke->args.push_back(errHandler);
7994 for (auto arg : args->objects()) {
7995 invoke->args.push_back(arg);
7996 }
7997 transformChainValue(xpcall, out, ExpUsage::Closure); 7997 transformChainValue(xpcall, out, ExpUsage::Closure);
7998 } else { 7998 } else {
7999 auto pcall = toAst<ChainValue_t>("pcall()", x); 7999 ast_ptr<true, ast_node> last = chainValue->items.back();
8000 auto invoke = ast_to<Invoke_t>(pcall->items.back()); 8000 chainValue->items.pop_back();
8001 invoke->args.push_back(tryNode->func); 8001 _ast_list* args = nullptr;
8002 for (auto arg : args->objects()) { 8002 if (auto invoke = ast_cast<InvokeArgs_t>(last)) {
8003 invoke->args.push_back(arg); 8003 args = &invoke->args;
8004 } else {
8005 args = &(ast_to<Invoke_t>(last)->args);
8006 }
8007 if (errHandler) {
8008 auto xpcall = toAst<ChainValue_t>("xpcall()", x);
8009 auto invoke = ast_to<Invoke_t>(xpcall->items.back());
8010 invoke->args.push_back(tryNode->func);
8011 invoke->args.push_back(errHandler);
8012 for (auto arg : args->objects()) {
8013 invoke->args.push_back(arg);
8014 }
8015 transformChainValue(xpcall, out, ExpUsage::Closure);
8016 } else {
8017 auto pcall = toAst<ChainValue_t>("pcall()", x);
8018 auto invoke = ast_to<Invoke_t>(pcall->items.back());
8019 invoke->args.push_back(tryNode->func);
8020 for (auto arg : args->objects()) {
8021 invoke->args.push_back(arg);
8022 }
8023 transformChainValue(pcall, out, ExpUsage::Closure);
8004 } 8024 }
8005 transformChainValue(pcall, out, ExpUsage::Closure);
8006 } 8025 }
8007 if (usage == ExpUsage::Common) { 8026 if (usage == ExpUsage::Common) {
8008 out.back().append(nlr(x)); 8027 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)
106 return concat(tried, "\n\t") 106 return concat(tried, "\n\t")
107end 107end
108local function yue_call(f, ...) 108local function yue_call(f, ...)
109 return xpcall(f, function(err) 109 local args = {...}
110 return yue.traceback(err, 1) 110 return xpcall(function()
111 end, ...) 111 return f(unpack(args))
112 end, function(err)
113 return yue.traceback(err, 2)
114 end)
112end 115end
113yue_loadstring = function(...) 116yue_loadstring = function(...)
114 local options, str, chunk_name, mode, env = get_options(...) 117 local options, str, chunk_name, mode, env = get_options(...)
@@ -166,9 +169,11 @@ local function yue_traceback(err, level)
166end 169end
167local function yue_require(name) 170local function yue_require(name)
168 insert_loader() 171 insert_loader()
169 local success, res = xpcall(require, function(err) 172 local success, res = xpcall(function()
170 return yue_traceback(err, 2) 173 return require(name)
171 end, name) 174 end, function(err)
175 return yue_traceback(err, 3)
176 end)
172 if success then 177 if success then
173 return res 178 return res
174 else 179 else