aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-12-28 15:55:15 +0800
committerLi Jin <dragon-fly@qq.com>2022-12-28 15:55:15 +0800
commitdba662758192b41648e6c1201083d83926f07783 (patch)
tree4eca06097fce6ac52bbf5276a6ac2da4affb90d0
parent5e453de810f8a5e54351609857d742481f057498 (diff)
downloadyuescript-dba662758192b41648e6c1201083d83926f07783.tar.gz
yuescript-dba662758192b41648e6c1201083d83926f07783.tar.bz2
yuescript-dba662758192b41648e6c1201083d83926f07783.zip
add metamethods checking.
-rw-r--r--spec/inputs/import.yue7
-rw-r--r--spec/outputs/destructure.lua72
-rw-r--r--spec/outputs/import.lua16
-rw-r--r--spec/outputs/metatable.lua29
-rw-r--r--src/yuescript/yue_compiler.cpp112
5 files changed, 169 insertions, 67 deletions
diff --git a/spec/inputs/import.yue b/spec/inputs/import.yue
index af5545d..fe5caf5 100644
--- a/spec/inputs/import.yue
+++ b/spec/inputs/import.yue
@@ -64,8 +64,9 @@ do
64 import "org.package.module" as function:func, if:ifVar 64 import "org.package.module" as function:func, if:ifVar
65 65
66do 66do
67 import "m" as {<a>: b} 67 import "m" as {<gc>: b}
68 import "m" as {e: f, <a>: c} 68 import "m" as {:<index>}
69 import "m" as {e: f, <pairs>: c}
69 import "m" as {c: d} 70 import "m" as {c: d}
70 import "m" as {g, {<h>: i}} 71 import "m" as {g, {<close>: i}}
71 72
diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua
index 8953a2a..cb0eb3f 100644
--- a/spec/outputs/destructure.lua
+++ b/spec/outputs/destructure.lua
@@ -288,28 +288,31 @@ do
288 end) 288 end)
289 end 289 end
290 end 290 end
291 local _obj_0 = tb 291 local mtx, y, zItem, index
292 local mtx, y, zItem = getmetatable(_obj_0.x), _obj_0.y, _obj_0.z 292 do
293 if mtx == nil then 293 local _obj_0 = tb
294 mtx = { } 294 mtx, y, zItem = getmetatable(_obj_0.x), _obj_0.y, _obj_0.z
295 end 295 if mtx == nil then
296 local index = getmetatable(_obj_0).__index 296 mtx = { }
297 if index == nil then 297 end
298 index = function() 298 index = getmetatable(_obj_0).__index
299 return nil 299 if index == nil then
300 index = function()
301 return nil
302 end
300 end 303 end
301 end 304 end
302 do 305 do
303 local _tmp_0 306 local _tmp_0
304 do 307 do
305 local _obj_1 = getmetatable(tb) 308 local _obj_0 = getmetatable(tb)
306 _tmp_0 = _obj_1.func 309 _tmp_0 = _obj_0.func
307 end 310 end
308 if _tmp_0 == nil then 311 if _tmp_0 == nil then
309 do 312 do
310 local _obj_1 = item 313 local _obj_0 = item
311 if _obj_1 ~= nil then 314 if _obj_0 ~= nil then
312 _tmp_0 = _obj_1.defVal 315 _tmp_0 = _obj_0.defVal
313 end 316 end
314 end 317 end
315 end 318 end
@@ -455,9 +458,12 @@ do
455 end 458 end
456end 459end
457do 460do
458 local _obj_0 = tb 461 local value, value_meta
459 local value = _obj_0[name] 462 do
460 local value_meta = getmetatable(_obj_0)[name] 463 local _obj_0 = tb
464 value = _obj_0[name]
465 value_meta = getmetatable(_obj_0)[name]
466 end
461end 467end
462do 468do
463 local tostring, add 469 local tostring, add
@@ -492,16 +498,15 @@ do
492end 498end
493do 499do
494 local tb = { } 500 local tb = { }
495 local _obj_0 = tb
496 do 501 do
497 local _tmp_0 = c() 502 local _tmp_0 = c()
498 local v2 = _obj_0[_tmp_0] 503 local v2 = tb[_tmp_0]
499 end 504 end
500 local v1 505 local v1
501 do 506 do
502 local _obj_1 = getmetatable(_obj_0) 507 local _obj_0 = getmetatable(tb)
503 local _tmp_1 = a + b 508 local _tmp_1 = a + b
504 v1 = _obj_1[_tmp_1] 509 v1 = _obj_0[_tmp_1]
505 end 510 end
506end 511end
507do 512do
@@ -575,16 +580,15 @@ do
575 local _tab_0 = type(_exp_0) 580 local _tab_0 = type(_exp_0)
576 _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 581 _tab_0 = "table" == _tab_0 or "userdata" == _tab_0
577 if _tab_0 then 582 if _tab_0 then
578 local _obj_0 = _exp_0
579 do 583 do
580 local _obj_1 = _obj_0.c 584 local _obj_0 = _exp_0.c
581 local _type_0 = type(_obj_1) 585 local _type_0 = type(_obj_0)
582 if "table" == _type_0 or "userdata" == _type_0 then 586 if "table" == _type_0 or "userdata" == _type_0 then
583 do 587 do
584 local _obj_2 = getmetatable(_obj_1) 588 local _obj_1 = getmetatable(_obj_0)
585 local _type_1 = type(_obj_2) 589 local _type_1 = type(_obj_1)
586 if "table" == _type_1 or "userdata" == _type_1 then 590 if "table" == _type_1 or "userdata" == _type_1 then
587 meta_field = _obj_2["abc"] 591 meta_field = _obj_1["abc"]
588 end 592 end
589 end 593 end
590 end 594 end
@@ -593,19 +597,19 @@ do
593 meta_field = "def" 597 meta_field = "def"
594 end 598 end
595 do 599 do
596 local _obj_1 = getmetatable(_obj_0) 600 local _obj_0 = getmetatable(_exp_0)
597 do 601 do
598 local _obj_2 = _obj_1[ [[any string]]] 602 local _obj_1 = _obj_0[ [[any string]]]
599 local _type_0 = type(_obj_2) 603 local _type_0 = type(_obj_1)
600 if "table" == _type_0 or "userdata" == _type_0 then 604 if "table" == _type_0 or "userdata" == _type_0 then
601 abc = _obj_2.d 605 abc = _obj_1.d
602 end 606 end
603 end 607 end
604 do 608 do
605 local _obj_2 = _obj_1['str'] 609 local _obj_1 = _obj_0['str']
606 local _type_0 = type(_obj_2) 610 local _type_0 = type(_obj_1)
607 if "table" == _type_0 or "userdata" == _type_0 then 611 if "table" == _type_0 or "userdata" == _type_0 then
608 def = _obj_2.e 612 def = _obj_1.e
609 end 613 end
610 end 614 end
611 if abc == nil then 615 if abc == nil then
diff --git a/spec/outputs/import.lua b/spec/outputs/import.lua
index edb7c44..f8d6ef0 100644
--- a/spec/outputs/import.lua
+++ b/spec/outputs/import.lua
@@ -89,14 +89,18 @@ do
89 end 89 end
90end 90end
91do 91do
92 local b = getmetatable(require("m")).__a 92 local b = getmetatable(require("m")).__gc
93 local _obj_0 = require("m") 93 local index = getmetatable(require("m")).__index
94 local f = _obj_0.e 94 local f, c
95 local c = getmetatable(_obj_0).__a 95 do
96 local _obj_0 = require("m")
97 f = _obj_0.e
98 c = getmetatable(_obj_0).__pairs
99 end
96 local d = require("m").c 100 local d = require("m").c
97 local g, i 101 local g, i
98 do 102 do
99 local _obj_1 = require("m") 103 local _obj_0 = require("m")
100 g, i = _obj_1[1], getmetatable(_obj_1[2]).__h 104 g, i = _obj_0[1], getmetatable(_obj_0[2]).__close
101 end 105 end
102end 106end
diff --git a/spec/outputs/metatable.lua b/spec/outputs/metatable.lua
index 937136f..907a584 100644
--- a/spec/outputs/metatable.lua
+++ b/spec/outputs/metatable.lua
@@ -38,28 +38,29 @@ getmetatable(a).__add = function(x, y)
38 return x + y 38 return x + y
39end 39end
40do 40do
41 local _obj_0 = a 41 local new = a.new
42 local new = _obj_0.new
43 local close, closeA 42 local close, closeA
44 do 43 do
45 local _obj_1 = getmetatable(_obj_0) 44 local _obj_0 = getmetatable(a)
46 close, closeA = _obj_1.__close, _obj_1.__close 45 close, closeA = _obj_0.__close, _obj_0.__close
47 end 46 end
48 print(new, close, closeA) 47 print(new, close, closeA)
49end 48end
50do 49do
51 local x, new, var, close, closeA, num, add, sub 50 local x, new, var, close, closeA, num, add, sub
52 local _obj_0, _obj_1
53 x, _obj_0, _obj_1 = 123, a.b.c, func()
54 new, var = _obj_0.new, _obj_0.var
55 do
56 local _obj_2 = getmetatable(_obj_0)
57 close, closeA = _obj_2.__close, _obj_2.__close
58 end
59 num = _obj_1.num
60 do 51 do
61 local _obj_2 = getmetatable(_obj_1) 52 local _obj_0, _obj_1
62 add, sub = _obj_2.__add, _obj_2.__sub 53 x, _obj_0, _obj_1 = 123, a.b.c, func()
54 new, var = _obj_0.new, _obj_0.var
55 do
56 local _obj_2 = getmetatable(_obj_0)
57 close, closeA = _obj_2.__close, _obj_2.__close
58 end
59 num = _obj_1.num
60 do
61 local _obj_2 = getmetatable(_obj_1)
62 add, sub = _obj_2.__add, _obj_2.__sub
63 end
63 end 64 end
64end 65end
65setmetatable(a.b, { }) 66setmetatable(a.b, { })
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 0d674f8..42310b2 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -60,7 +60,18 @@ namespace yue {
60 60
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.15.18"sv; 63static std::unordered_set<std::string> Metamethods = {
64 "add"s, "sub"s, "mul"s, "div"s, "mod"s,
65 "pow"s, "unm"s, "concat"s, "len"s, "eq"s,
66 "lt"s, "le"s, "index"s, "newindex"s, "call"s,
67 "gc"s, "mode"s, "tostring"s, "metatable"s, // Lua 5.1
68 "pairs"s, "ipairs"s, // Lua 5.2
69 "name"s, "idiv"s, "band"s, "bor"s, "bxor"s,
70 "bnot"s, "shl"s, "shr"s, // Lua 5.3 ipairs deprecated
71 "close"s // Lua 5.4
72};
73
74const std::string_view version = "0.15.19"sv;
64const std::string_view extension = "yue"sv; 75const std::string_view extension = "yue"sv;
65 76
66class YueCompilerImpl { 77class YueCompilerImpl {
@@ -1089,6 +1100,46 @@ private:
1089 return str; 1100 return str;
1090 } 1101 }
1091 1102
1103 void checkMetamethod(const std::string& name, ast_node* x) {
1104 if (Metamethods.find(name) == Metamethods.end()) {
1105 throw std::logic_error(_info.errorMessage("invalid metamethod name"sv, x));
1106 }
1107 int target = getLuaTarget(x);
1108 switch (target) {
1109 case 501: goto metamethod51;
1110 case 502: goto metamethod52;
1111 case 503: {
1112 if (name == "ipairs"sv) {
1113 throw std::logic_error(_info.errorMessage("metamethod is deprecated since Lua 5.3"sv, x));
1114 }
1115 goto metamethod53;
1116 }
1117 case 504: {
1118 if (name == "ipairs"sv) {
1119 throw std::logic_error(_info.errorMessage("metamethod is not supported since Lua 5.4"sv, x));
1120 }
1121 goto metamethod54;
1122 }
1123 }
1124 metamethod51:
1125 if (name == "pairs"sv || name == "ipairs"sv) {
1126 throw std::logic_error(_info.errorMessage("metamethod is not supported until Lua 5.2"sv, x));
1127 }
1128 metamethod52:
1129 if (name == "name"sv || name == "idiv"sv ||
1130 name == "band"sv || name == "bor"sv ||
1131 name == "bxor"sv || name == "bnot"sv ||
1132 name == "shl"sv || name == "shr"sv) {
1133 throw std::logic_error(_info.errorMessage("metamethod is not supported until Lua 5.3"sv, x));
1134 }
1135 metamethod53:
1136 if (name == "close"sv) {
1137 throw std::logic_error(_info.errorMessage("metamethod is not supported until Lua 5.4"sv, x));
1138 }
1139 metamethod54:
1140 return;
1141 }
1142
1092 void transformStatement(Statement_t* statement, str_list& out) { 1143 void transformStatement(Statement_t* statement, str_list& out) {
1093 auto x = statement; 1144 auto x = statement;
1094 if (statement->appendix) { 1145 if (statement->appendix) {
@@ -1825,11 +1876,32 @@ private:
1825 if (info.destructures.empty()) { 1876 if (info.destructures.empty()) {
1826 transformAssignmentCommon(assignment, out); 1877 transformAssignmentCommon(assignment, out);
1827 } else { 1878 } else {
1879 auto x = assignment;
1828 str_list temp; 1880 str_list temp;
1881 if (info.extraScope) {
1882 str_list defs;
1883 for (auto& destruct : info.destructures) {
1884 for (auto& item : destruct.items) {
1885 if (!item.targetVar.empty()) {
1886 if (!isDefined(item.targetVar)) {
1887 defs.push_back(item.targetVar);
1888 }
1889 }
1890 }
1891 }
1892 if (!defs.empty()) {
1893 for (const auto& def : defs) {
1894 checkConst(def, x);
1895 addToScope(def);
1896 }
1897 temp.push_back(indent() + "local "s + join(defs, ", "sv) + nll(x));
1898 }
1899 temp.push_back(indent() + "do"s + nll(x));
1900 pushScope();
1901 }
1829 if (info.assignment) { 1902 if (info.assignment) {
1830 transformAssignmentCommon(info.assignment, temp); 1903 transformAssignmentCommon(info.assignment, temp);
1831 } 1904 }
1832 auto x = assignment;
1833 for (auto& destruct : info.destructures) { 1905 for (auto& destruct : info.destructures) {
1834 std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; 1906 std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs;
1835 bool extraScope = false; 1907 bool extraScope = false;
@@ -1861,7 +1933,7 @@ private:
1861 } 1933 }
1862 } 1934 }
1863 if (!isNil) { 1935 if (!isNil) {
1864 auto stmt = toAst<Statement_t>(pair.targetVar + "=nil if "s + pair.targetVar + "==nil", pair.defVal); 1936 auto stmt = toAst<Statement_t>(pair.targetVar + "=nil if "s + pair.targetVar + "==nil"s, pair.defVal);
1865 auto defAssign = stmt->content.as<ExpListAssign_t>(); 1937 auto defAssign = stmt->content.as<ExpListAssign_t>();
1866 auto assign = defAssign->action.as<Assign_t>(); 1938 auto assign = defAssign->action.as<Assign_t>();
1867 assign->values.clear(); 1939 assign->values.clear();
@@ -2035,6 +2107,10 @@ private:
2035 temp.push_back(clearBuf()); 2107 temp.push_back(clearBuf());
2036 } 2108 }
2037 } 2109 }
2110 if (info.extraScope) {
2111 popScope();
2112 temp.push_back(indent() + "end"s + nlr(x));
2113 }
2038 out.push_back(join(temp)); 2114 out.push_back(join(temp));
2039 } 2115 }
2040 } 2116 }
@@ -2247,6 +2323,7 @@ private:
2247 } 2323 }
2248 auto mp = static_cast<meta_variable_pair_t*>(pair); 2324 auto mp = static_cast<meta_variable_pair_t*>(pair);
2249 auto name = _parser.toString(mp->name); 2325 auto name = _parser.toString(mp->name);
2326 checkMetamethod(name, mp->name);
2250 _buf << "__"sv << name << ':' << name; 2327 _buf << "__"sv << name << ':' << name;
2251 auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), pair); 2328 auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), pair);
2252 newPairDef->defVal.set(defVal); 2329 newPairDef->defVal.set(defVal);
@@ -2266,6 +2343,7 @@ private:
2266 switch (mp->key->getId()) { 2343 switch (mp->key->getId()) {
2267 case id<Name_t>(): { 2344 case id<Name_t>(): {
2268 auto key = _parser.toString(mp->key); 2345 auto key = _parser.toString(mp->key);
2346 checkMetamethod(key, mp->key);
2269 _buf << "__"sv << key; 2347 _buf << "__"sv << key;
2270 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); 2348 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key);
2271 newPair->key.set(newKey); 2349 newPair->key.set(newKey);
@@ -2309,10 +2387,12 @@ private:
2309 struct DestructureInfo { 2387 struct DestructureInfo {
2310 std::list<Destructure> destructures; 2388 std::list<Destructure> destructures;
2311 ast_ptr<false, ExpListAssign_t> assignment; 2389 ast_ptr<false, ExpListAssign_t> assignment;
2390 bool extraScope = false;
2312 }; 2391 };
2313 2392
2314 DestructureInfo extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) { 2393 DestructureInfo extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) {
2315 auto x = assignment; 2394 auto x = assignment;
2395 bool extraScope = false;
2316 std::list<Destructure> destructs; 2396 std::list<Destructure> destructs;
2317 if (!assignment->action.is<Assign_t>()) return {destructs, nullptr}; 2397 if (!assignment->action.is<Assign_t>()) return {destructs, nullptr};
2318 auto exprs = assignment->expList->exprs.objects(); 2398 auto exprs = assignment->expList->exprs.objects();
@@ -2367,6 +2447,7 @@ private:
2367 auto mvp = static_cast<meta_variable_pair_def_t*>(item); 2447 auto mvp = static_cast<meta_variable_pair_def_t*>(item);
2368 auto mp = mvp->pair.get(); 2448 auto mp = mvp->pair.get();
2369 auto name = _parser.toString(mp->name); 2449 auto name = _parser.toString(mp->name);
2450 checkMetamethod(name, mp->name);
2370 _buf << "__"sv << name << ':' << name; 2451 _buf << "__"sv << name << ':' << name;
2371 auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), item); 2452 auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), item);
2372 newPairDef->defVal.set(mvp->defVal); 2453 newPairDef->defVal.set(mvp->defVal);
@@ -2381,6 +2462,7 @@ private:
2381 switch (mp->key->getId()) { 2462 switch (mp->key->getId()) {
2382 case id<Name_t>(): { 2463 case id<Name_t>(): {
2383 auto key = _parser.toString(mp->key); 2464 auto key = _parser.toString(mp->key);
2465 checkMetamethod(key, mp->key);
2384 _buf << "__"sv << key; 2466 _buf << "__"sv << key;
2385 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); 2467 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key);
2386 newPair->key.set(newKey); 2468 newPair->key.set(newKey);
@@ -2406,6 +2488,7 @@ private:
2406 case id<meta_variable_pair_t>(): { 2488 case id<meta_variable_pair_t>(): {
2407 auto mp = static_cast<meta_variable_pair_t*>(item); 2489 auto mp = static_cast<meta_variable_pair_t*>(item);
2408 auto name = _parser.toString(mp->name); 2490 auto name = _parser.toString(mp->name);
2491 checkMetamethod(name, mp->name);
2409 _buf << "__"sv << name << ':' << name; 2492 _buf << "__"sv << name << ':' << name;
2410 auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), item); 2493 auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), item);
2411 subMetaDestruct->values.push_back(newPairDef); 2494 subMetaDestruct->values.push_back(newPairDef);
@@ -2418,6 +2501,7 @@ private:
2418 switch (mp->key->getId()) { 2501 switch (mp->key->getId()) {
2419 case id<Name_t>(): { 2502 case id<Name_t>(): {
2420 auto key = _parser.toString(mp->key); 2503 auto key = _parser.toString(mp->key);
2504 checkMetamethod(key, mp->key);
2421 _buf << "__"sv << key; 2505 _buf << "__"sv << key;
2422 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); 2506 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key);
2423 newPair->key.set(newKey); 2507 newPair->key.set(newKey);
@@ -2462,12 +2546,16 @@ private:
2462 } 2546 }
2463 valueItems.push_back(*j); 2547 valueItems.push_back(*j);
2464 if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) { 2548 if (!varDefOnly && !subDestruct->values.empty() && !subMetaDestruct->values.empty()) {
2465 auto objVar = getUnusedName("_obj_"sv); 2549 auto var = singleVariableFrom(*j, false);
2466 addToScope(objVar); 2550 if (var.empty() || !isLocal(var)) {
2467 valueItems.pop_back(); 2551 auto objVar = getUnusedName("_obj_"sv);
2468 valueItems.push_back(toAst<Exp_t>(objVar, *j)); 2552 addToScope(objVar);
2469 exprs.push_back(valueItems.back()); 2553 valueItems.pop_back();
2470 values.push_back(*j); 2554 valueItems.push_back(toAst<Exp_t>(objVar, *j));
2555 exprs.push_back(valueItems.back());
2556 values.push_back(*j);
2557 extraScope = true;
2558 }
2471 } 2559 }
2472 TableLit_t* tabs[] = {subDestruct.get(), subMetaDestruct.get()}; 2560 TableLit_t* tabs[] = {subDestruct.get(), subMetaDestruct.get()};
2473 for (auto tab : tabs) { 2561 for (auto tab : tabs) {
@@ -2573,7 +2661,7 @@ private:
2573 } 2661 }
2574 } 2662 }
2575 popScope(); 2663 popScope();
2576 return {std::move(destructs), newAssignment}; 2664 return {std::move(destructs), newAssignment, extraScope};
2577 } 2665 }
2578 2666
2579 void transformAssignmentCommon(ExpListAssign_t* assignment, str_list& out) { 2667 void transformAssignmentCommon(ExpListAssign_t* assignment, str_list& out) {
@@ -5513,6 +5601,7 @@ private:
5513 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->name)); 5601 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->name));
5514 } 5602 }
5515 auto name = _parser.toString(mp->name); 5603 auto name = _parser.toString(mp->name);
5604 checkMetamethod(name, mp->name);
5516 _buf << "__"sv << name << ':' << name; 5605 _buf << "__"sv << name << ':' << name;
5517 auto newPair = toAst<normal_pair_t>(clearBuf(), item); 5606 auto newPair = toAst<normal_pair_t>(clearBuf(), item);
5518 metatable->pairs.push_back(newPair); 5607 metatable->pairs.push_back(newPair);
@@ -5529,6 +5618,7 @@ private:
5529 switch (mp->key->getId()) { 5618 switch (mp->key->getId()) {
5530 case id<Name_t>(): { 5619 case id<Name_t>(): {
5531 auto key = _parser.toString(mp->key); 5620 auto key = _parser.toString(mp->key);
5621 checkMetamethod(key, mp->key);
5532 _buf << "__"sv << key; 5622 _buf << "__"sv << key;
5533 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); 5623 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key);
5534 newPair->key.set(newKey); 5624 newPair->key.set(newKey);
@@ -6739,6 +6829,7 @@ private:
6739 case id<meta_variable_pair_t>(): { 6829 case id<meta_variable_pair_t>(): {
6740 auto mtPair = static_cast<meta_variable_pair_t*>(keyValue); 6830 auto mtPair = static_cast<meta_variable_pair_t*>(keyValue);
6741 auto nameStr = _parser.toString(mtPair->name); 6831 auto nameStr = _parser.toString(mtPair->name);
6832 checkMetamethod(nameStr, mtPair->name);
6742 ref.set(toAst<normal_pair_t>("__"s + nameStr + ':' + nameStr, keyValue)); 6833 ref.set(toAst<normal_pair_t>("__"s + nameStr + ':' + nameStr, keyValue));
6743 keyValue = ref.get(); 6834 keyValue = ref.get();
6744 break; 6835 break;
@@ -6748,6 +6839,7 @@ private:
6748 auto normal_pair = keyValue->new_ptr<normal_pair_t>(); 6839 auto normal_pair = keyValue->new_ptr<normal_pair_t>();
6749 if (auto name = mtPair->key.as<Name_t>()) { 6840 if (auto name = mtPair->key.as<Name_t>()) {
6750 auto nameStr = _parser.toString(name); 6841 auto nameStr = _parser.toString(name);
6842 checkMetamethod(nameStr, name);
6751 normal_pair->key.set(toAst<KeyName_t>("__"s + nameStr, keyValue)); 6843 normal_pair->key.set(toAst<KeyName_t>("__"s + nameStr, keyValue));
6752 } else if (auto str = mtPair->key.as<String_t>()) { 6844 } else if (auto str = mtPair->key.as<String_t>()) {
6753 normal_pair->key.set(newExp(str, str)); 6845 normal_pair->key.set(newExp(str, str));