diff options
author | Li Jin <dragon-fly@qq.com> | 2020-06-22 16:50:40 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2020-06-22 16:50:40 +0800 |
commit | cd2b60b101a398cb9356d746364e70eaed1860f1 (patch) | |
tree | a1fe71b76faabc4883f16905a94164ce5c23e692 /src | |
parent | 88c1052e700f38cf3d8ad82d469da4c487760b7e (diff) | |
download | yuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.tar.gz yuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.tar.bz2 yuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.zip |
add support for local variable declared with attribute 'close' and 'const' for Lua 5.4.
Diffstat (limited to 'src')
-rw-r--r-- | src/LuaMinify.h | 33 | ||||
-rw-r--r-- | src/MoonP/moon_ast.h | 11 | ||||
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 59 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 11 | ||||
-rw-r--r-- | src/MoonP/moon_parser.h | 1 | ||||
-rw-r--r-- | src/MoonP/stacktraceplus.h | 4 | ||||
-rw-r--r-- | src/lua-5.3/lapi.h | 24 | ||||
-rw-r--r-- | src/lua-5.3/lbitlib.c | 233 | ||||
-rw-r--r-- | src/lua-5.3/lcode.c | 1203 | ||||
-rw-r--r-- | src/lua-5.3/ldump.c | 215 | ||||
-rw-r--r-- | src/lua-5.3/lfunc.c | 151 | ||||
-rw-r--r-- | src/lua-5.3/lfunc.h | 61 | ||||
-rw-r--r-- | src/lua-5.3/lgc.c | 1179 | ||||
-rw-r--r-- | src/lua-5.3/license.txt | 6 | ||||
-rw-r--r-- | src/lua-5.3/lmathlib.c | 410 | ||||
-rw-r--r-- | src/lua-5.3/lmem.c | 100 | ||||
-rw-r--r-- | src/lua-5.3/lmem.h | 69 | ||||
-rw-r--r-- | src/lua-5.3/lobject.h | 549 | ||||
-rw-r--r-- | src/lua-5.3/lopcodes.c | 124 | ||||
-rw-r--r-- | src/lua-5.3/lopcodes.h | 297 | ||||
-rw-r--r-- | src/lua-5.3/ltable.c | 688 | ||||
-rw-r--r-- | src/lua-5.3/ltm.c | 165 | ||||
-rw-r--r-- | src/lua-5.3/lundump.c | 279 | ||||
-rw-r--r-- | src/lua-5.3/lvm.c | 1322 | ||||
-rw-r--r-- | src/lua-5.3/lvm.h | 113 | ||||
-rw-r--r-- | src/lua/lapi.c (renamed from src/lua-5.3/lapi.c) | 656 | ||||
-rw-r--r-- | src/lua/lapi.h | 47 | ||||
-rw-r--r-- | src/lua/lauxlib.c (renamed from src/lua-5.3/lauxlib.c) | 352 | ||||
-rw-r--r-- | src/lua/lauxlib.h (renamed from src/lua-5.3/lauxlib.h) | 54 | ||||
-rw-r--r-- | src/lua/lbaselib.c (renamed from src/lua-5.3/lbaselib.c) | 139 | ||||
-rw-r--r-- | src/lua/lcode.c | 1814 | ||||
-rw-r--r-- | src/lua/lcode.h (renamed from src/lua-5.3/lcode.h) | 34 | ||||
-rw-r--r-- | src/lua/lcorolib.c (renamed from src/lua-5.3/lcorolib.c) | 84 | ||||
-rw-r--r-- | src/lua/lctype.c (renamed from src/lua-5.3/lctype.c) | 43 | ||||
-rw-r--r-- | src/lua/lctype.h (renamed from src/lua-5.3/lctype.h) | 4 | ||||
-rw-r--r-- | src/lua/ldblib.c (renamed from src/lua-5.3/ldblib.c) | 73 | ||||
-rw-r--r-- | src/lua/ldebug.c (renamed from src/lua-5.3/ldebug.c) | 428 | ||||
-rw-r--r-- | src/lua/ldebug.h (renamed from src/lua-5.3/ldebug.h) | 18 | ||||
-rw-r--r-- | src/lua/ldo.c (renamed from src/lua-5.3/ldo.c) | 506 | ||||
-rw-r--r-- | src/lua/ldo.h (renamed from src/lua-5.3/ldo.h) | 35 | ||||
-rw-r--r-- | src/lua/ldump.c | 226 | ||||
-rw-r--r-- | src/lua/lfunc.c | 299 | ||||
-rw-r--r-- | src/lua/lfunc.h | 69 | ||||
-rw-r--r-- | src/lua/lgc.c | 1616 | ||||
-rw-r--r-- | src/lua/lgc.h (renamed from src/lua-5.3/lgc.h) | 103 | ||||
-rw-r--r-- | src/lua/linit.c (renamed from src/lua-5.3/linit.c) | 7 | ||||
-rw-r--r-- | src/lua/liolib.c (renamed from src/lua-5.3/liolib.c) | 112 | ||||
-rw-r--r-- | src/lua/ljumptab.h | 112 | ||||
-rw-r--r-- | src/lua/llex.c (renamed from src/lua-5.3/llex.c) | 48 | ||||
-rw-r--r-- | src/lua/llex.h (renamed from src/lua-5.3/llex.h) | 4 | ||||
-rw-r--r-- | src/lua/llimits.h (renamed from src/lua-5.3/llimits.h) | 108 | ||||
-rw-r--r-- | src/lua/lmathlib.c | 763 | ||||
-rw-r--r-- | src/lua/lmem.c | 202 | ||||
-rw-r--r-- | src/lua/lmem.h | 93 | ||||
-rw-r--r-- | src/lua/loadlib.c (renamed from src/lua-5.3/loadlib.c) | 261 | ||||
-rw-r--r-- | src/lua/lobject.c (renamed from src/lua-5.3/lobject.c) | 309 | ||||
-rw-r--r-- | src/lua/lobject.h | 787 | ||||
-rw-r--r-- | src/lua/lopcodes.c | 104 | ||||
-rw-r--r-- | src/lua/lopcodes.h | 392 | ||||
-rw-r--r-- | src/lua/lopnames.h | 103 | ||||
-rw-r--r-- | src/lua/loslib.c (renamed from src/lua-5.3/loslib.c) | 85 | ||||
-rw-r--r-- | src/lua/lparser.c (renamed from src/lua-5.3/lparser.c) | 1000 | ||||
-rw-r--r-- | src/lua/lparser.h (renamed from src/lua-5.3/lparser.h) | 77 | ||||
-rw-r--r-- | src/lua/lprefix.h (renamed from src/lua-5.3/lprefix.h) | 4 | ||||
-rw-r--r-- | src/lua/lstate.c (renamed from src/lua-5.3/lstate.c) | 242 | ||||
-rw-r--r-- | src/lua/lstate.h (renamed from src/lua-5.3/lstate.h) | 195 | ||||
-rw-r--r-- | src/lua/lstring.c (renamed from src/lua-5.3/lstring.c) | 141 | ||||
-rw-r--r-- | src/lua/lstring.h (renamed from src/lua-5.3/lstring.h) | 25 | ||||
-rw-r--r-- | src/lua/lstrlib.c (renamed from src/lua-5.3/lstrlib.c) | 483 | ||||
-rw-r--r-- | src/lua/ltable.c | 924 | ||||
-rw-r--r-- | src/lua/ltable.h (renamed from src/lua-5.3/ltable.h) | 19 | ||||
-rw-r--r-- | src/lua/ltablib.c (renamed from src/lua-5.3/ltablib.c) | 52 | ||||
-rw-r--r-- | src/lua/ltm.c | 270 | ||||
-rw-r--r-- | src/lua/ltm.h (renamed from src/lua-5.3/ltm.h) | 28 | ||||
-rw-r--r-- | src/lua/lua.h (renamed from src/lua-5.3/lua.h) | 65 | ||||
-rw-r--r-- | src/lua/luaconf.h (renamed from src/lua-5.3/luaconf.h) | 260 | ||||
-rw-r--r-- | src/lua/lualib.h (renamed from src/lua-5.3/lualib.h) | 5 | ||||
-rw-r--r-- | src/lua/lundump.c | 323 | ||||
-rw-r--r-- | src/lua/lundump.h (renamed from src/lua-5.3/lundump.h) | 8 | ||||
-rw-r--r-- | src/lua/lutf8lib.c (renamed from src/lua-5.3/lutf8lib.c) | 117 | ||||
-rw-r--r-- | src/lua/lvm.c | 1812 | ||||
-rw-r--r-- | src/lua/lvm.h | 134 | ||||
-rw-r--r-- | src/lua/lzio.c (renamed from src/lua-5.3/lzio.c) | 2 | ||||
-rw-r--r-- | src/lua/lzio.h (renamed from src/lua-5.3/lzio.h) | 2 | ||||
-rw-r--r-- | src/lua/makefile (renamed from src/lua-5.3/makefile) | 5 |
85 files changed, 14051 insertions, 9539 deletions
diff --git a/src/LuaMinify.h b/src/LuaMinify.h index 4990646..76d7759 100644 --- a/src/LuaMinify.h +++ b/src/LuaMinify.h | |||
@@ -298,8 +298,12 @@ local Scope = { | |||
298 | 298 | ||
299 | ObfuscateLocals = function(self, recommendedMaxLength, validNameChars) | 299 | ObfuscateLocals = function(self, recommendedMaxLength, validNameChars) |
300 | for i, var in pairs(self.Locals) do | 300 | for i, var in pairs(self.Locals) do |
301 | local id = GetUnique(self) | 301 | if var.Name == "_ENV" then |
302 | self:RenameLocal(var.Name, id) | 302 | self:RenameLocal(var.Name, "_ENV") |
303 | else | ||
304 | local id = GetUnique(self) | ||
305 | self:RenameLocal(var.Name, id) | ||
306 | end | ||
303 | end | 307 | end |
304 | end | 308 | end |
305 | } | 309 | } |
@@ -1502,13 +1506,24 @@ R"lua_codes( | |||
1502 | 1506 | ||
1503 | elseif tok:ConsumeKeyword('local', tokenList) then | 1507 | elseif tok:ConsumeKeyword('local', tokenList) then |
1504 | if tok:Is('Ident') then | 1508 | if tok:Is('Ident') then |
1505 | local varList = { tok:Get(tokenList).Data } | 1509 | local varList, attrList = {}, {} |
1506 | while tok:ConsumeSymbol(',', tokenList) do | 1510 | repeat |
1507 | if not tok:Is('Ident') then | 1511 | if not tok:Is('Ident') then |
1508 | return false, GenerateError("local var name expected") | 1512 | return false, GenerateError("local var name expected") |
1509 | end | 1513 | end |
1510 | varList[#varList+1] = tok:Get(tokenList).Data | 1514 | varList[#varList+1] = tok:Get(tokenList).Data |
1511 | end | 1515 | if tok:ConsumeSymbol('<', tokenList) then |
1516 | if not tok:Is('Ident') then | ||
1517 | return false, GenerateError("attrib name expected") | ||
1518 | end | ||
1519 | attrList[#attrList+1] = tok:Get(tokenList).Data | ||
1520 | if not tok:ConsumeSymbol('>', tokenList) then | ||
1521 | return false, GenerateError("missing '>' to close attrib name") | ||
1522 | end | ||
1523 | else | ||
1524 | attrList[#attrList+1] = false | ||
1525 | end | ||
1526 | until not tok:ConsumeSymbol(',', tokenList) | ||
1512 | 1527 | ||
1513 | local initList = {} | 1528 | local initList = {} |
1514 | if tok:ConsumeSymbol('=', tokenList) then | 1529 | if tok:ConsumeSymbol('=', tokenList) then |
@@ -1529,6 +1544,7 @@ R"lua_codes( | |||
1529 | local nodeLocal = {} | 1544 | local nodeLocal = {} |
1530 | nodeLocal.AstType = 'LocalStatement' | 1545 | nodeLocal.AstType = 'LocalStatement' |
1531 | nodeLocal.LocalList = varList | 1546 | nodeLocal.LocalList = varList |
1547 | nodeLocal.AttrList = attrList | ||
1532 | nodeLocal.InitList = initList | 1548 | nodeLocal.InitList = initList |
1533 | nodeLocal.Tokens = tokenList | 1549 | nodeLocal.Tokens = tokenList |
1534 | -- | 1550 | -- |
@@ -1923,8 +1939,11 @@ local function Format_Mini(ast) | |||
1923 | out = out.."local " | 1939 | out = out.."local " |
1924 | for i = 1, #statement.LocalList do | 1940 | for i = 1, #statement.LocalList do |
1925 | out = out..statement.LocalList[i].Name | 1941 | out = out..statement.LocalList[i].Name |
1926 | if i ~= #statement.LocalList then | 1942 | if statement.AttrList[i] then |
1927 | out = out.."," | 1943 | out = out.."<"..statement.AttrList[i]..">" |
1944 | if i == #statement.LocalList then | ||
1945 | out = out.." " | ||
1946 | end | ||
1928 | end | 1947 | end |
1929 | end | 1948 | end |
1930 | if #statement.InitList > 0 then | 1949 | if #statement.InitList > 0 then |
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 42522dd..1491344 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
@@ -113,6 +113,15 @@ AST_NODE(Local) | |||
113 | AST_MEMBER(Local, &item) | 113 | AST_MEMBER(Local, &item) |
114 | AST_END(Local) | 114 | AST_END(Local) |
115 | 115 | ||
116 | class Assign_t; | ||
117 | |||
118 | AST_NODE(LocalAttrib) | ||
119 | ast_ptr<true, Name_t> attrib; | ||
120 | ast_ptr<true, NameList_t> nameList; | ||
121 | ast_ptr<true, Assign_t> assign; | ||
122 | AST_MEMBER(LocalAttrib, &attrib, &nameList, &assign) | ||
123 | AST_END(LocalAttrib) | ||
124 | |||
116 | AST_NODE(colon_import_name) | 125 | AST_NODE(colon_import_name) |
117 | ast_ptr<true, Variable_t> name; | 126 | ast_ptr<true, Variable_t> name; |
118 | AST_MEMBER(colon_import_name, &name) | 127 | AST_MEMBER(colon_import_name, &name) |
@@ -686,7 +695,7 @@ AST_END(statement_sep) | |||
686 | AST_NODE(Statement) | 695 | AST_NODE(Statement) |
687 | ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t, | 696 | ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t, |
688 | Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, | 697 | Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, |
689 | Label_t, Goto_t, Backcall_t, ExpListAssign_t> content; | 698 | Label_t, Goto_t, Backcall_t, LocalAttrib_t, ExpListAssign_t> content; |
690 | ast_ptr<false, statement_appendix_t> appendix; | 699 | ast_ptr<false, statement_appendix_t> appendix; |
691 | ast_ptr<false, statement_sep_t> needSep; | 700 | ast_ptr<false, statement_sep_t> needSep; |
692 | AST_MEMBER(Statement, &content, &appendix, &needSep) | 701 | AST_MEMBER(Statement, &content, &appendix, &needSep) |
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index f7462dc..8dc5c94 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -25,6 +25,12 @@ extern "C" { | |||
25 | 25 | ||
26 | } // extern "C" | 26 | } // extern "C" |
27 | 27 | ||
28 | #if LUA_VERSION_NUM > 501 | ||
29 | #ifndef LUA_COMPAT_5_1 | ||
30 | #define lua_objlen lua_rawlen | ||
31 | #endif // LUA_COMPAT_5_1 | ||
32 | #endif // LUA_VERSION_NUM | ||
33 | |||
28 | namespace MoonP { | 34 | namespace MoonP { |
29 | using namespace std::string_view_literals; | 35 | using namespace std::string_view_literals; |
30 | using namespace parserlib; | 36 | using namespace parserlib; |
@@ -43,7 +49,7 @@ inline std::string s(std::string_view sv) { | |||
43 | } | 49 | } |
44 | 50 | ||
45 | const std::string_view version() { | 51 | const std::string_view version() { |
46 | return "0.4.0"sv; | 52 | return "0.4.1"sv; |
47 | } | 53 | } |
48 | 54 | ||
49 | // name of table stored in lua registry | 55 | // name of table stored in lua registry |
@@ -769,6 +775,7 @@ private: | |||
769 | case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; | 775 | case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; |
770 | case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break; | 776 | case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break; |
771 | case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break; | 777 | case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break; |
778 | case id<LocalAttrib_t>(): transformLocalAttrib(static_cast<LocalAttrib_t*>(content), out); break; | ||
772 | case id<ExpListAssign_t>(): { | 779 | case id<ExpListAssign_t>(): { |
773 | auto expListAssign = static_cast<ExpListAssign_t*>(content); | 780 | auto expListAssign = static_cast<ExpListAssign_t*>(content); |
774 | if (expListAssign->action) { | 781 | if (expListAssign->action) { |
@@ -2071,7 +2078,18 @@ private: | |||
2071 | last->needSep.set(nullptr); | 2078 | last->needSep.set(nullptr); |
2072 | auto bLast = ++nodes.rbegin(); | 2079 | auto bLast = ++nodes.rbegin(); |
2073 | if (bLast != nodes.rend()) { | 2080 | if (bLast != nodes.rend()) { |
2074 | static_cast<Statement_t*>(*bLast)->needSep.set(nullptr); | 2081 | bool isMacro = false; |
2082 | BLOCK_START | ||
2083 | BREAK_IF(expListLow->exprs.size() != 1); | ||
2084 | auto exp = static_cast<Exp_t*>(expListLow->exprs.back()); | ||
2085 | BREAK_IF(!exp->opValues.empty()); | ||
2086 | auto chainValue = exp->getByPath<unary_exp_t, Value_t, ChainValue_t>(); | ||
2087 | BREAK_IF(!chainValue); | ||
2088 | isMacro = isMacroChain(chainValue); | ||
2089 | BLOCK_END | ||
2090 | if (!isMacro) { | ||
2091 | ast_to<Statement_t>(*bLast)->needSep.set(nullptr); | ||
2092 | } | ||
2075 | } | 2093 | } |
2076 | BLOCK_END | 2094 | BLOCK_END |
2077 | break; | 2095 | break; |
@@ -5099,6 +5117,43 @@ private: | |||
5099 | out.push_back(join(temp)); | 5117 | out.push_back(join(temp)); |
5100 | } | 5118 | } |
5101 | 5119 | ||
5120 | void transformLocalAttrib(LocalAttrib_t* localAttrib, str_list& out) { | ||
5121 | auto x = localAttrib; | ||
5122 | auto attrib = _parser.toString(localAttrib->attrib); | ||
5123 | if (attrib != "close"sv && attrib != "const"sv) { | ||
5124 | throw std::logic_error(_info.errorMessage(s("unknown attribute '"sv) + attrib + '\'', localAttrib->attrib)); | ||
5125 | } | ||
5126 | auto expList = x->new_ptr<ExpList_t>(); | ||
5127 | str_list tmpVars; | ||
5128 | str_list vars; | ||
5129 | for (auto name : localAttrib->nameList->names.objects()) { | ||
5130 | auto callable = x->new_ptr<Callable_t>(); | ||
5131 | callable->item.set(name); | ||
5132 | auto chainValue = x->new_ptr<ChainValue_t>(); | ||
5133 | chainValue->items.push_back(callable); | ||
5134 | auto value = x->new_ptr<Value_t>(); | ||
5135 | value->item.set(chainValue); | ||
5136 | auto exp = newExp(value, x); | ||
5137 | expList->exprs.push_back(exp); | ||
5138 | tmpVars.push_back(getUnusedName("_var_"sv)); | ||
5139 | vars.push_back(_parser.toString(name)); | ||
5140 | } | ||
5141 | auto tmpVarStr = join(tmpVars, ","sv); | ||
5142 | auto tmpVarList = toAst<ExpList_t>(tmpVarStr, x); | ||
5143 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
5144 | assignment->expList.set(tmpVarList); | ||
5145 | assignment->action.set(localAttrib->assign); | ||
5146 | str_list temp; | ||
5147 | transformAssignment(assignment, temp); | ||
5148 | attrib = s(" <"sv) + attrib + '>'; | ||
5149 | for (auto& var : vars) { | ||
5150 | forceAddToScope(var); | ||
5151 | var.append(attrib); | ||
5152 | } | ||
5153 | temp.push_back(indent() + s("local "sv) + join(vars) + s(" = "sv) + tmpVarStr + nll(x)); | ||
5154 | out.push_back(join(temp)); | ||
5155 | } | ||
5156 | |||
5102 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { | 5157 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { |
5103 | auto keyword = _parser.toString(breakLoop); | 5158 | auto keyword = _parser.toString(breakLoop); |
5104 | if (keyword == "break"sv) { | 5159 | if (keyword == "break"sv) { |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 25e67b3..4dee5b1 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
@@ -174,6 +174,14 @@ MoonParser::MoonParser() { | |||
174 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); | 174 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); |
175 | Local = key("local") >> (Space >> local_flag | local_values); | 175 | Local = key("local") >> (Space >> local_flag | local_values); |
176 | 176 | ||
177 | LocalAttrib = and_(key(pl::user(Name, [](const item_t& item) { | ||
178 | State* st = reinterpret_cast<State*>(item.user_data); | ||
179 | for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); | ||
180 | auto it = Keywords.find(st->buffer); | ||
181 | st->buffer.clear(); | ||
182 | return it == Keywords.end(); | ||
183 | })) >> NameList >> sym('=') >> not_('=')) >> Space >> Name >> NameList >> Assign; | ||
184 | |||
177 | colon_import_name = sym('\\') >> Space >> Variable; | 185 | colon_import_name = sym('\\') >> Space >> Variable; |
178 | ImportName = colon_import_name | Space >> Variable; | 186 | ImportName = colon_import_name | Space >> Variable; |
179 | ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); | 187 | ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); |
@@ -552,7 +560,8 @@ MoonParser::MoonParser() { | |||
552 | Statement = ( | 560 | Statement = ( |
553 | Import | While | Repeat | For | ForEach | | 561 | Import | While | Repeat | For | ForEach | |
554 | Return | Local | Global | Export | Macro | | 562 | Return | Local | Global | Export | Macro | |
555 | Space >> BreakLoop | Label | Goto | Backcall | ExpListAssign | 563 | Space >> BreakLoop | Label | Goto | Backcall | |
564 | LocalAttrib | ExpListAssign | ||
556 | ) >> Space >> | 565 | ) >> Space >> |
557 | -statement_appendix >> -statement_sep; | 566 | -statement_appendix >> -statement_sep; |
558 | 567 | ||
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index 5787438..c6a03f8 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h | |||
@@ -199,6 +199,7 @@ private: | |||
199 | AST_RULE(local_flag) | 199 | AST_RULE(local_flag) |
200 | AST_RULE(local_values) | 200 | AST_RULE(local_values) |
201 | AST_RULE(Local) | 201 | AST_RULE(Local) |
202 | AST_RULE(LocalAttrib); | ||
202 | AST_RULE(colon_import_name) | 203 | AST_RULE(colon_import_name) |
203 | AST_RULE(import_literal_inner) | 204 | AST_RULE(import_literal_inner) |
204 | AST_RULE(ImportLiteral) | 205 | AST_RULE(ImportLiteral) |
diff --git a/src/MoonP/stacktraceplus.h b/src/MoonP/stacktraceplus.h index 3d32322..d658c5c 100644 --- a/src/MoonP/stacktraceplus.h +++ b/src/MoonP/stacktraceplus.h | |||
@@ -406,8 +406,8 @@ function _M.stacktrace(thread, message, level) | |||
406 | end | 406 | end |
407 | end | 407 | end |
408 | if fname then | 408 | if fname then |
409 | fname = fname:gsub("%[string \"", "") | 409 | local fn = fname:match("%[string \"(.-)\"%]") |
410 | fname = fname:gsub("\"%]", "") | 410 | if fn then fname = fn end |
411 | fname = fname:gsub("^%s*(.-)%s*$", "%1") | 411 | fname = fname:gsub("^%s*(.-)%s*$", "%1") |
412 | fname, line = getMoonLineNumber(fname, line) | 412 | fname, line = getMoonLineNumber(fname, line) |
413 | if _M.simplified then | 413 | if _M.simplified then |
diff --git a/src/lua-5.3/lapi.h b/src/lua-5.3/lapi.h deleted file mode 100644 index 8e16ad5..0000000 --- a/src/lua-5.3/lapi.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Auxiliary functions from Lua API | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lapi_h | ||
8 | #define lapi_h | ||
9 | |||
10 | |||
11 | #include "llimits.h" | ||
12 | #include "lstate.h" | ||
13 | |||
14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ | ||
15 | "stack overflow");} | ||
16 | |||
17 | #define adjustresults(L,nres) \ | ||
18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } | ||
19 | |||
20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ | ||
21 | "not enough elements in the stack") | ||
22 | |||
23 | |||
24 | #endif | ||
diff --git a/src/lua-5.3/lbitlib.c b/src/lua-5.3/lbitlib.c deleted file mode 100644 index 4786c0d..0000000 --- a/src/lua-5.3/lbitlib.c +++ /dev/null | |||
@@ -1,233 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Standard library for bitwise operations | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lbitlib_c | ||
8 | #define LUA_LIB | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "lauxlib.h" | ||
16 | #include "lualib.h" | ||
17 | |||
18 | |||
19 | #if defined(LUA_COMPAT_BITLIB) /* { */ | ||
20 | |||
21 | |||
22 | #define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) | ||
23 | #define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i)) | ||
24 | |||
25 | |||
26 | /* number of bits to consider in a number */ | ||
27 | #if !defined(LUA_NBITS) | ||
28 | #define LUA_NBITS 32 | ||
29 | #endif | ||
30 | |||
31 | |||
32 | /* | ||
33 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must | ||
34 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the | ||
35 | ** number of bits in a lua_Unsigned.) | ||
36 | */ | ||
37 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) | ||
38 | |||
39 | |||
40 | /* macro to trim extra bits */ | ||
41 | #define trim(x) ((x) & ALLONES) | ||
42 | |||
43 | |||
44 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ | ||
45 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) | ||
46 | |||
47 | |||
48 | |||
49 | static lua_Unsigned andaux (lua_State *L) { | ||
50 | int i, n = lua_gettop(L); | ||
51 | lua_Unsigned r = ~(lua_Unsigned)0; | ||
52 | for (i = 1; i <= n; i++) | ||
53 | r &= checkunsigned(L, i); | ||
54 | return trim(r); | ||
55 | } | ||
56 | |||
57 | |||
58 | static int b_and (lua_State *L) { | ||
59 | lua_Unsigned r = andaux(L); | ||
60 | pushunsigned(L, r); | ||
61 | return 1; | ||
62 | } | ||
63 | |||
64 | |||
65 | static int b_test (lua_State *L) { | ||
66 | lua_Unsigned r = andaux(L); | ||
67 | lua_pushboolean(L, r != 0); | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | |||
72 | static int b_or (lua_State *L) { | ||
73 | int i, n = lua_gettop(L); | ||
74 | lua_Unsigned r = 0; | ||
75 | for (i = 1; i <= n; i++) | ||
76 | r |= checkunsigned(L, i); | ||
77 | pushunsigned(L, trim(r)); | ||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | |||
82 | static int b_xor (lua_State *L) { | ||
83 | int i, n = lua_gettop(L); | ||
84 | lua_Unsigned r = 0; | ||
85 | for (i = 1; i <= n; i++) | ||
86 | r ^= checkunsigned(L, i); | ||
87 | pushunsigned(L, trim(r)); | ||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | |||
92 | static int b_not (lua_State *L) { | ||
93 | lua_Unsigned r = ~checkunsigned(L, 1); | ||
94 | pushunsigned(L, trim(r)); | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | |||
99 | static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { | ||
100 | if (i < 0) { /* shift right? */ | ||
101 | i = -i; | ||
102 | r = trim(r); | ||
103 | if (i >= LUA_NBITS) r = 0; | ||
104 | else r >>= i; | ||
105 | } | ||
106 | else { /* shift left */ | ||
107 | if (i >= LUA_NBITS) r = 0; | ||
108 | else r <<= i; | ||
109 | r = trim(r); | ||
110 | } | ||
111 | pushunsigned(L, r); | ||
112 | return 1; | ||
113 | } | ||
114 | |||
115 | |||
116 | static int b_lshift (lua_State *L) { | ||
117 | return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2)); | ||
118 | } | ||
119 | |||
120 | |||
121 | static int b_rshift (lua_State *L) { | ||
122 | return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2)); | ||
123 | } | ||
124 | |||
125 | |||
126 | static int b_arshift (lua_State *L) { | ||
127 | lua_Unsigned r = checkunsigned(L, 1); | ||
128 | lua_Integer i = luaL_checkinteger(L, 2); | ||
129 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) | ||
130 | return b_shift(L, r, -i); | ||
131 | else { /* arithmetic shift for 'negative' number */ | ||
132 | if (i >= LUA_NBITS) r = ALLONES; | ||
133 | else | ||
134 | r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ | ||
135 | pushunsigned(L, r); | ||
136 | return 1; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | |||
141 | static int b_rot (lua_State *L, lua_Integer d) { | ||
142 | lua_Unsigned r = checkunsigned(L, 1); | ||
143 | int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ | ||
144 | r = trim(r); | ||
145 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ | ||
146 | r = (r << i) | (r >> (LUA_NBITS - i)); | ||
147 | pushunsigned(L, trim(r)); | ||
148 | return 1; | ||
149 | } | ||
150 | |||
151 | |||
152 | static int b_lrot (lua_State *L) { | ||
153 | return b_rot(L, luaL_checkinteger(L, 2)); | ||
154 | } | ||
155 | |||
156 | |||
157 | static int b_rrot (lua_State *L) { | ||
158 | return b_rot(L, -luaL_checkinteger(L, 2)); | ||
159 | } | ||
160 | |||
161 | |||
162 | /* | ||
163 | ** get field and width arguments for field-manipulation functions, | ||
164 | ** checking whether they are valid. | ||
165 | ** ('luaL_error' called without 'return' to avoid later warnings about | ||
166 | ** 'width' being used uninitialized.) | ||
167 | */ | ||
168 | static int fieldargs (lua_State *L, int farg, int *width) { | ||
169 | lua_Integer f = luaL_checkinteger(L, farg); | ||
170 | lua_Integer w = luaL_optinteger(L, farg + 1, 1); | ||
171 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); | ||
172 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); | ||
173 | if (f + w > LUA_NBITS) | ||
174 | luaL_error(L, "trying to access non-existent bits"); | ||
175 | *width = (int)w; | ||
176 | return (int)f; | ||
177 | } | ||
178 | |||
179 | |||
180 | static int b_extract (lua_State *L) { | ||
181 | int w; | ||
182 | lua_Unsigned r = trim(checkunsigned(L, 1)); | ||
183 | int f = fieldargs(L, 2, &w); | ||
184 | r = (r >> f) & mask(w); | ||
185 | pushunsigned(L, r); | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | |||
190 | static int b_replace (lua_State *L) { | ||
191 | int w; | ||
192 | lua_Unsigned r = trim(checkunsigned(L, 1)); | ||
193 | lua_Unsigned v = trim(checkunsigned(L, 2)); | ||
194 | int f = fieldargs(L, 3, &w); | ||
195 | lua_Unsigned m = mask(w); | ||
196 | r = (r & ~(m << f)) | ((v & m) << f); | ||
197 | pushunsigned(L, r); | ||
198 | return 1; | ||
199 | } | ||
200 | |||
201 | |||
202 | static const luaL_Reg bitlib[] = { | ||
203 | {"arshift", b_arshift}, | ||
204 | {"band", b_and}, | ||
205 | {"bnot", b_not}, | ||
206 | {"bor", b_or}, | ||
207 | {"bxor", b_xor}, | ||
208 | {"btest", b_test}, | ||
209 | {"extract", b_extract}, | ||
210 | {"lrotate", b_lrot}, | ||
211 | {"lshift", b_lshift}, | ||
212 | {"replace", b_replace}, | ||
213 | {"rrotate", b_rrot}, | ||
214 | {"rshift", b_rshift}, | ||
215 | {NULL, NULL} | ||
216 | }; | ||
217 | |||
218 | |||
219 | |||
220 | LUAMOD_API int luaopen_bit32 (lua_State *L) { | ||
221 | luaL_newlib(L, bitlib); | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | |||
226 | #else /* }{ */ | ||
227 | |||
228 | |||
229 | LUAMOD_API int luaopen_bit32 (lua_State *L) { | ||
230 | return luaL_error(L, "library 'bit32' has been deprecated"); | ||
231 | } | ||
232 | |||
233 | #endif /* } */ | ||
diff --git a/src/lua-5.3/lcode.c b/src/lua-5.3/lcode.c deleted file mode 100644 index dc7271d..0000000 --- a/src/lua-5.3/lcode.c +++ /dev/null | |||
@@ -1,1203 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lcode.c,v 2.112.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Code generator for Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lcode_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <math.h> | ||
14 | #include <stdlib.h> | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "lcode.h" | ||
19 | #include "ldebug.h" | ||
20 | #include "ldo.h" | ||
21 | #include "lgc.h" | ||
22 | #include "llex.h" | ||
23 | #include "lmem.h" | ||
24 | #include "lobject.h" | ||
25 | #include "lopcodes.h" | ||
26 | #include "lparser.h" | ||
27 | #include "lstring.h" | ||
28 | #include "ltable.h" | ||
29 | #include "lvm.h" | ||
30 | |||
31 | |||
32 | /* Maximum number of registers in a Lua function (must fit in 8 bits) */ | ||
33 | #define MAXREGS 255 | ||
34 | |||
35 | |||
36 | #define hasjumps(e) ((e)->t != (e)->f) | ||
37 | |||
38 | |||
39 | /* | ||
40 | ** If expression is a numeric constant, fills 'v' with its value | ||
41 | ** and returns 1. Otherwise, returns 0. | ||
42 | */ | ||
43 | static int tonumeral(const expdesc *e, TValue *v) { | ||
44 | if (hasjumps(e)) | ||
45 | return 0; /* not a numeral */ | ||
46 | switch (e->k) { | ||
47 | case VKINT: | ||
48 | if (v) setivalue(v, e->u.ival); | ||
49 | return 1; | ||
50 | case VKFLT: | ||
51 | if (v) setfltvalue(v, e->u.nval); | ||
52 | return 1; | ||
53 | default: return 0; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | |||
58 | /* | ||
59 | ** Create a OP_LOADNIL instruction, but try to optimize: if the previous | ||
60 | ** instruction is also OP_LOADNIL and ranges are compatible, adjust | ||
61 | ** range of previous instruction instead of emitting a new one. (For | ||
62 | ** instance, 'local a; local b' will generate a single opcode.) | ||
63 | */ | ||
64 | void luaK_nil (FuncState *fs, int from, int n) { | ||
65 | Instruction *previous; | ||
66 | int l = from + n - 1; /* last register to set nil */ | ||
67 | if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ | ||
68 | previous = &fs->f->code[fs->pc-1]; | ||
69 | if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */ | ||
70 | int pfrom = GETARG_A(*previous); /* get previous range */ | ||
71 | int pl = pfrom + GETARG_B(*previous); | ||
72 | if ((pfrom <= from && from <= pl + 1) || | ||
73 | (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ | ||
74 | if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ | ||
75 | if (pl > l) l = pl; /* l = max(l, pl) */ | ||
76 | SETARG_A(*previous, from); | ||
77 | SETARG_B(*previous, l - from); | ||
78 | return; | ||
79 | } | ||
80 | } /* else go through */ | ||
81 | } | ||
82 | luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ | ||
83 | } | ||
84 | |||
85 | |||
86 | /* | ||
87 | ** Gets the destination address of a jump instruction. Used to traverse | ||
88 | ** a list of jumps. | ||
89 | */ | ||
90 | static int getjump (FuncState *fs, int pc) { | ||
91 | int offset = GETARG_sBx(fs->f->code[pc]); | ||
92 | if (offset == NO_JUMP) /* point to itself represents end of list */ | ||
93 | return NO_JUMP; /* end of list */ | ||
94 | else | ||
95 | return (pc+1)+offset; /* turn offset into absolute position */ | ||
96 | } | ||
97 | |||
98 | |||
99 | /* | ||
100 | ** Fix jump instruction at position 'pc' to jump to 'dest'. | ||
101 | ** (Jump addresses are relative in Lua) | ||
102 | */ | ||
103 | static void fixjump (FuncState *fs, int pc, int dest) { | ||
104 | Instruction *jmp = &fs->f->code[pc]; | ||
105 | int offset = dest - (pc + 1); | ||
106 | lua_assert(dest != NO_JUMP); | ||
107 | if (abs(offset) > MAXARG_sBx) | ||
108 | luaX_syntaxerror(fs->ls, "control structure too long"); | ||
109 | SETARG_sBx(*jmp, offset); | ||
110 | } | ||
111 | |||
112 | |||
113 | /* | ||
114 | ** Concatenate jump-list 'l2' into jump-list 'l1' | ||
115 | */ | ||
116 | void luaK_concat (FuncState *fs, int *l1, int l2) { | ||
117 | if (l2 == NO_JUMP) return; /* nothing to concatenate? */ | ||
118 | else if (*l1 == NO_JUMP) /* no original list? */ | ||
119 | *l1 = l2; /* 'l1' points to 'l2' */ | ||
120 | else { | ||
121 | int list = *l1; | ||
122 | int next; | ||
123 | while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ | ||
124 | list = next; | ||
125 | fixjump(fs, list, l2); /* last element links to 'l2' */ | ||
126 | } | ||
127 | } | ||
128 | |||
129 | |||
130 | /* | ||
131 | ** Create a jump instruction and return its position, so its destination | ||
132 | ** can be fixed later (with 'fixjump'). If there are jumps to | ||
133 | ** this position (kept in 'jpc'), link them all together so that | ||
134 | ** 'patchlistaux' will fix all them directly to the final destination. | ||
135 | */ | ||
136 | int luaK_jump (FuncState *fs) { | ||
137 | int jpc = fs->jpc; /* save list of jumps to here */ | ||
138 | int j; | ||
139 | fs->jpc = NO_JUMP; /* no more jumps to here */ | ||
140 | j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); | ||
141 | luaK_concat(fs, &j, jpc); /* keep them on hold */ | ||
142 | return j; | ||
143 | } | ||
144 | |||
145 | |||
146 | /* | ||
147 | ** Code a 'return' instruction | ||
148 | */ | ||
149 | void luaK_ret (FuncState *fs, int first, int nret) { | ||
150 | luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); | ||
151 | } | ||
152 | |||
153 | |||
154 | /* | ||
155 | ** Code a "conditional jump", that is, a test or comparison opcode | ||
156 | ** followed by a jump. Return jump position. | ||
157 | */ | ||
158 | static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { | ||
159 | luaK_codeABC(fs, op, A, B, C); | ||
160 | return luaK_jump(fs); | ||
161 | } | ||
162 | |||
163 | |||
164 | /* | ||
165 | ** returns current 'pc' and marks it as a jump target (to avoid wrong | ||
166 | ** optimizations with consecutive instructions not in the same basic block). | ||
167 | */ | ||
168 | int luaK_getlabel (FuncState *fs) { | ||
169 | fs->lasttarget = fs->pc; | ||
170 | return fs->pc; | ||
171 | } | ||
172 | |||
173 | |||
174 | /* | ||
175 | ** Returns the position of the instruction "controlling" a given | ||
176 | ** jump (that is, its condition), or the jump itself if it is | ||
177 | ** unconditional. | ||
178 | */ | ||
179 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { | ||
180 | Instruction *pi = &fs->f->code[pc]; | ||
181 | if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) | ||
182 | return pi-1; | ||
183 | else | ||
184 | return pi; | ||
185 | } | ||
186 | |||
187 | |||
188 | /* | ||
189 | ** Patch destination register for a TESTSET instruction. | ||
190 | ** If instruction in position 'node' is not a TESTSET, return 0 ("fails"). | ||
191 | ** Otherwise, if 'reg' is not 'NO_REG', set it as the destination | ||
192 | ** register. Otherwise, change instruction to a simple 'TEST' (produces | ||
193 | ** no register value) | ||
194 | */ | ||
195 | static int patchtestreg (FuncState *fs, int node, int reg) { | ||
196 | Instruction *i = getjumpcontrol(fs, node); | ||
197 | if (GET_OPCODE(*i) != OP_TESTSET) | ||
198 | return 0; /* cannot patch other instructions */ | ||
199 | if (reg != NO_REG && reg != GETARG_B(*i)) | ||
200 | SETARG_A(*i, reg); | ||
201 | else { | ||
202 | /* no register to put value or register already has the value; | ||
203 | change instruction to simple test */ | ||
204 | *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); | ||
205 | } | ||
206 | return 1; | ||
207 | } | ||
208 | |||
209 | |||
210 | /* | ||
211 | ** Traverse a list of tests ensuring no one produces a value | ||
212 | */ | ||
213 | static void removevalues (FuncState *fs, int list) { | ||
214 | for (; list != NO_JUMP; list = getjump(fs, list)) | ||
215 | patchtestreg(fs, list, NO_REG); | ||
216 | } | ||
217 | |||
218 | |||
219 | /* | ||
220 | ** Traverse a list of tests, patching their destination address and | ||
221 | ** registers: tests producing values jump to 'vtarget' (and put their | ||
222 | ** values in 'reg'), other tests jump to 'dtarget'. | ||
223 | */ | ||
224 | static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, | ||
225 | int dtarget) { | ||
226 | while (list != NO_JUMP) { | ||
227 | int next = getjump(fs, list); | ||
228 | if (patchtestreg(fs, list, reg)) | ||
229 | fixjump(fs, list, vtarget); | ||
230 | else | ||
231 | fixjump(fs, list, dtarget); /* jump to default target */ | ||
232 | list = next; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | |||
237 | /* | ||
238 | ** Ensure all pending jumps to current position are fixed (jumping | ||
239 | ** to current position with no values) and reset list of pending | ||
240 | ** jumps | ||
241 | */ | ||
242 | static void dischargejpc (FuncState *fs) { | ||
243 | patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); | ||
244 | fs->jpc = NO_JUMP; | ||
245 | } | ||
246 | |||
247 | |||
248 | /* | ||
249 | ** Add elements in 'list' to list of pending jumps to "here" | ||
250 | ** (current position) | ||
251 | */ | ||
252 | void luaK_patchtohere (FuncState *fs, int list) { | ||
253 | luaK_getlabel(fs); /* mark "here" as a jump target */ | ||
254 | luaK_concat(fs, &fs->jpc, list); | ||
255 | } | ||
256 | |||
257 | |||
258 | /* | ||
259 | ** Path all jumps in 'list' to jump to 'target'. | ||
260 | ** (The assert means that we cannot fix a jump to a forward address | ||
261 | ** because we only know addresses once code is generated.) | ||
262 | */ | ||
263 | void luaK_patchlist (FuncState *fs, int list, int target) { | ||
264 | if (target == fs->pc) /* 'target' is current position? */ | ||
265 | luaK_patchtohere(fs, list); /* add list to pending jumps */ | ||
266 | else { | ||
267 | lua_assert(target < fs->pc); | ||
268 | patchlistaux(fs, list, target, NO_REG, target); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | |||
273 | /* | ||
274 | ** Path all jumps in 'list' to close upvalues up to given 'level' | ||
275 | ** (The assertion checks that jumps either were closing nothing | ||
276 | ** or were closing higher levels, from inner blocks.) | ||
277 | */ | ||
278 | void luaK_patchclose (FuncState *fs, int list, int level) { | ||
279 | level++; /* argument is +1 to reserve 0 as non-op */ | ||
280 | for (; list != NO_JUMP; list = getjump(fs, list)) { | ||
281 | lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && | ||
282 | (GETARG_A(fs->f->code[list]) == 0 || | ||
283 | GETARG_A(fs->f->code[list]) >= level)); | ||
284 | SETARG_A(fs->f->code[list], level); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | |||
289 | /* | ||
290 | ** Emit instruction 'i', checking for array sizes and saving also its | ||
291 | ** line information. Return 'i' position. | ||
292 | */ | ||
293 | static int luaK_code (FuncState *fs, Instruction i) { | ||
294 | Proto *f = fs->f; | ||
295 | dischargejpc(fs); /* 'pc' will change */ | ||
296 | /* put new instruction in code array */ | ||
297 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, | ||
298 | MAX_INT, "opcodes"); | ||
299 | f->code[fs->pc] = i; | ||
300 | /* save corresponding line information */ | ||
301 | luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, | ||
302 | MAX_INT, "opcodes"); | ||
303 | f->lineinfo[fs->pc] = fs->ls->lastline; | ||
304 | return fs->pc++; | ||
305 | } | ||
306 | |||
307 | |||
308 | /* | ||
309 | ** Format and emit an 'iABC' instruction. (Assertions check consistency | ||
310 | ** of parameters versus opcode.) | ||
311 | */ | ||
312 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { | ||
313 | lua_assert(getOpMode(o) == iABC); | ||
314 | lua_assert(getBMode(o) != OpArgN || b == 0); | ||
315 | lua_assert(getCMode(o) != OpArgN || c == 0); | ||
316 | lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); | ||
317 | return luaK_code(fs, CREATE_ABC(o, a, b, c)); | ||
318 | } | ||
319 | |||
320 | |||
321 | /* | ||
322 | ** Format and emit an 'iABx' instruction. | ||
323 | */ | ||
324 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | ||
325 | lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); | ||
326 | lua_assert(getCMode(o) == OpArgN); | ||
327 | lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); | ||
328 | return luaK_code(fs, CREATE_ABx(o, a, bc)); | ||
329 | } | ||
330 | |||
331 | |||
332 | /* | ||
333 | ** Emit an "extra argument" instruction (format 'iAx') | ||
334 | */ | ||
335 | static int codeextraarg (FuncState *fs, int a) { | ||
336 | lua_assert(a <= MAXARG_Ax); | ||
337 | return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); | ||
338 | } | ||
339 | |||
340 | |||
341 | /* | ||
342 | ** Emit a "load constant" instruction, using either 'OP_LOADK' | ||
343 | ** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' | ||
344 | ** instruction with "extra argument". | ||
345 | */ | ||
346 | int luaK_codek (FuncState *fs, int reg, int k) { | ||
347 | if (k <= MAXARG_Bx) | ||
348 | return luaK_codeABx(fs, OP_LOADK, reg, k); | ||
349 | else { | ||
350 | int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); | ||
351 | codeextraarg(fs, k); | ||
352 | return p; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | |||
357 | /* | ||
358 | ** Check register-stack level, keeping track of its maximum size | ||
359 | ** in field 'maxstacksize' | ||
360 | */ | ||
361 | void luaK_checkstack (FuncState *fs, int n) { | ||
362 | int newstack = fs->freereg + n; | ||
363 | if (newstack > fs->f->maxstacksize) { | ||
364 | if (newstack >= MAXREGS) | ||
365 | luaX_syntaxerror(fs->ls, | ||
366 | "function or expression needs too many registers"); | ||
367 | fs->f->maxstacksize = cast_byte(newstack); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | |||
372 | /* | ||
373 | ** Reserve 'n' registers in register stack | ||
374 | */ | ||
375 | void luaK_reserveregs (FuncState *fs, int n) { | ||
376 | luaK_checkstack(fs, n); | ||
377 | fs->freereg += n; | ||
378 | } | ||
379 | |||
380 | |||
381 | /* | ||
382 | ** Free register 'reg', if it is neither a constant index nor | ||
383 | ** a local variable. | ||
384 | ) | ||
385 | */ | ||
386 | static void freereg (FuncState *fs, int reg) { | ||
387 | if (!ISK(reg) && reg >= fs->nactvar) { | ||
388 | fs->freereg--; | ||
389 | lua_assert(reg == fs->freereg); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | |||
394 | /* | ||
395 | ** Free register used by expression 'e' (if any) | ||
396 | */ | ||
397 | static void freeexp (FuncState *fs, expdesc *e) { | ||
398 | if (e->k == VNONRELOC) | ||
399 | freereg(fs, e->u.info); | ||
400 | } | ||
401 | |||
402 | |||
403 | /* | ||
404 | ** Free registers used by expressions 'e1' and 'e2' (if any) in proper | ||
405 | ** order. | ||
406 | */ | ||
407 | static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { | ||
408 | int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; | ||
409 | int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; | ||
410 | if (r1 > r2) { | ||
411 | freereg(fs, r1); | ||
412 | freereg(fs, r2); | ||
413 | } | ||
414 | else { | ||
415 | freereg(fs, r2); | ||
416 | freereg(fs, r1); | ||
417 | } | ||
418 | } | ||
419 | |||
420 | |||
421 | /* | ||
422 | ** Add constant 'v' to prototype's list of constants (field 'k'). | ||
423 | ** Use scanner's table to cache position of constants in constant list | ||
424 | ** and try to reuse constants. Because some values should not be used | ||
425 | ** as keys (nil cannot be a key, integer keys can collapse with float | ||
426 | ** keys), the caller must provide a useful 'key' for indexing the cache. | ||
427 | */ | ||
428 | static int addk (FuncState *fs, TValue *key, TValue *v) { | ||
429 | lua_State *L = fs->ls->L; | ||
430 | Proto *f = fs->f; | ||
431 | TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ | ||
432 | int k, oldsize; | ||
433 | if (ttisinteger(idx)) { /* is there an index there? */ | ||
434 | k = cast_int(ivalue(idx)); | ||
435 | /* correct value? (warning: must distinguish floats from integers!) */ | ||
436 | if (k < fs->nk && ttype(&f->k[k]) == ttype(v) && | ||
437 | luaV_rawequalobj(&f->k[k], v)) | ||
438 | return k; /* reuse index */ | ||
439 | } | ||
440 | /* constant not found; create a new entry */ | ||
441 | oldsize = f->sizek; | ||
442 | k = fs->nk; | ||
443 | /* numerical value does not need GC barrier; | ||
444 | table has no metatable, so it does not need to invalidate cache */ | ||
445 | setivalue(idx, k); | ||
446 | luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); | ||
447 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); | ||
448 | setobj(L, &f->k[k], v); | ||
449 | fs->nk++; | ||
450 | luaC_barrier(L, f, v); | ||
451 | return k; | ||
452 | } | ||
453 | |||
454 | |||
455 | /* | ||
456 | ** Add a string to list of constants and return its index. | ||
457 | */ | ||
458 | int luaK_stringK (FuncState *fs, TString *s) { | ||
459 | TValue o; | ||
460 | setsvalue(fs->ls->L, &o, s); | ||
461 | return addk(fs, &o, &o); /* use string itself as key */ | ||
462 | } | ||
463 | |||
464 | |||
465 | /* | ||
466 | ** Add an integer to list of constants and return its index. | ||
467 | ** Integers use userdata as keys to avoid collision with floats with | ||
468 | ** same value; conversion to 'void*' is used only for hashing, so there | ||
469 | ** are no "precision" problems. | ||
470 | */ | ||
471 | int luaK_intK (FuncState *fs, lua_Integer n) { | ||
472 | TValue k, o; | ||
473 | setpvalue(&k, cast(void*, cast(size_t, n))); | ||
474 | setivalue(&o, n); | ||
475 | return addk(fs, &k, &o); | ||
476 | } | ||
477 | |||
478 | /* | ||
479 | ** Add a float to list of constants and return its index. | ||
480 | */ | ||
481 | static int luaK_numberK (FuncState *fs, lua_Number r) { | ||
482 | TValue o; | ||
483 | setfltvalue(&o, r); | ||
484 | return addk(fs, &o, &o); /* use number itself as key */ | ||
485 | } | ||
486 | |||
487 | |||
488 | /* | ||
489 | ** Add a boolean to list of constants and return its index. | ||
490 | */ | ||
491 | static int boolK (FuncState *fs, int b) { | ||
492 | TValue o; | ||
493 | setbvalue(&o, b); | ||
494 | return addk(fs, &o, &o); /* use boolean itself as key */ | ||
495 | } | ||
496 | |||
497 | |||
498 | /* | ||
499 | ** Add nil to list of constants and return its index. | ||
500 | */ | ||
501 | static int nilK (FuncState *fs) { | ||
502 | TValue k, v; | ||
503 | setnilvalue(&v); | ||
504 | /* cannot use nil as key; instead use table itself to represent nil */ | ||
505 | sethvalue(fs->ls->L, &k, fs->ls->h); | ||
506 | return addk(fs, &k, &v); | ||
507 | } | ||
508 | |||
509 | |||
510 | /* | ||
511 | ** Fix an expression to return the number of results 'nresults'. | ||
512 | ** Either 'e' is a multi-ret expression (function call or vararg) | ||
513 | ** or 'nresults' is LUA_MULTRET (as any expression can satisfy that). | ||
514 | */ | ||
515 | void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { | ||
516 | if (e->k == VCALL) { /* expression is an open function call? */ | ||
517 | SETARG_C(getinstruction(fs, e), nresults + 1); | ||
518 | } | ||
519 | else if (e->k == VVARARG) { | ||
520 | Instruction *pc = &getinstruction(fs, e); | ||
521 | SETARG_B(*pc, nresults + 1); | ||
522 | SETARG_A(*pc, fs->freereg); | ||
523 | luaK_reserveregs(fs, 1); | ||
524 | } | ||
525 | else lua_assert(nresults == LUA_MULTRET); | ||
526 | } | ||
527 | |||
528 | |||
529 | /* | ||
530 | ** Fix an expression to return one result. | ||
531 | ** If expression is not a multi-ret expression (function call or | ||
532 | ** vararg), it already returns one result, so nothing needs to be done. | ||
533 | ** Function calls become VNONRELOC expressions (as its result comes | ||
534 | ** fixed in the base register of the call), while vararg expressions | ||
535 | ** become VRELOCABLE (as OP_VARARG puts its results where it wants). | ||
536 | ** (Calls are created returning one result, so that does not need | ||
537 | ** to be fixed.) | ||
538 | */ | ||
539 | void luaK_setoneret (FuncState *fs, expdesc *e) { | ||
540 | if (e->k == VCALL) { /* expression is an open function call? */ | ||
541 | /* already returns 1 value */ | ||
542 | lua_assert(GETARG_C(getinstruction(fs, e)) == 2); | ||
543 | e->k = VNONRELOC; /* result has fixed position */ | ||
544 | e->u.info = GETARG_A(getinstruction(fs, e)); | ||
545 | } | ||
546 | else if (e->k == VVARARG) { | ||
547 | SETARG_B(getinstruction(fs, e), 2); | ||
548 | e->k = VRELOCABLE; /* can relocate its simple result */ | ||
549 | } | ||
550 | } | ||
551 | |||
552 | |||
553 | /* | ||
554 | ** Ensure that expression 'e' is not a variable. | ||
555 | */ | ||
556 | void luaK_dischargevars (FuncState *fs, expdesc *e) { | ||
557 | switch (e->k) { | ||
558 | case VLOCAL: { /* already in a register */ | ||
559 | e->k = VNONRELOC; /* becomes a non-relocatable value */ | ||
560 | break; | ||
561 | } | ||
562 | case VUPVAL: { /* move value to some (pending) register */ | ||
563 | e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); | ||
564 | e->k = VRELOCABLE; | ||
565 | break; | ||
566 | } | ||
567 | case VINDEXED: { | ||
568 | OpCode op; | ||
569 | freereg(fs, e->u.ind.idx); | ||
570 | if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */ | ||
571 | freereg(fs, e->u.ind.t); | ||
572 | op = OP_GETTABLE; | ||
573 | } | ||
574 | else { | ||
575 | lua_assert(e->u.ind.vt == VUPVAL); | ||
576 | op = OP_GETTABUP; /* 't' is in an upvalue */ | ||
577 | } | ||
578 | e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); | ||
579 | e->k = VRELOCABLE; | ||
580 | break; | ||
581 | } | ||
582 | case VVARARG: case VCALL: { | ||
583 | luaK_setoneret(fs, e); | ||
584 | break; | ||
585 | } | ||
586 | default: break; /* there is one value available (somewhere) */ | ||
587 | } | ||
588 | } | ||
589 | |||
590 | |||
591 | /* | ||
592 | ** Ensures expression value is in register 'reg' (and therefore | ||
593 | ** 'e' will become a non-relocatable expression). | ||
594 | */ | ||
595 | static void discharge2reg (FuncState *fs, expdesc *e, int reg) { | ||
596 | luaK_dischargevars(fs, e); | ||
597 | switch (e->k) { | ||
598 | case VNIL: { | ||
599 | luaK_nil(fs, reg, 1); | ||
600 | break; | ||
601 | } | ||
602 | case VFALSE: case VTRUE: { | ||
603 | luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); | ||
604 | break; | ||
605 | } | ||
606 | case VK: { | ||
607 | luaK_codek(fs, reg, e->u.info); | ||
608 | break; | ||
609 | } | ||
610 | case VKFLT: { | ||
611 | luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); | ||
612 | break; | ||
613 | } | ||
614 | case VKINT: { | ||
615 | luaK_codek(fs, reg, luaK_intK(fs, e->u.ival)); | ||
616 | break; | ||
617 | } | ||
618 | case VRELOCABLE: { | ||
619 | Instruction *pc = &getinstruction(fs, e); | ||
620 | SETARG_A(*pc, reg); /* instruction will put result in 'reg' */ | ||
621 | break; | ||
622 | } | ||
623 | case VNONRELOC: { | ||
624 | if (reg != e->u.info) | ||
625 | luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); | ||
626 | break; | ||
627 | } | ||
628 | default: { | ||
629 | lua_assert(e->k == VJMP); | ||
630 | return; /* nothing to do... */ | ||
631 | } | ||
632 | } | ||
633 | e->u.info = reg; | ||
634 | e->k = VNONRELOC; | ||
635 | } | ||
636 | |||
637 | |||
638 | /* | ||
639 | ** Ensures expression value is in any register. | ||
640 | */ | ||
641 | static void discharge2anyreg (FuncState *fs, expdesc *e) { | ||
642 | if (e->k != VNONRELOC) { /* no fixed register yet? */ | ||
643 | luaK_reserveregs(fs, 1); /* get a register */ | ||
644 | discharge2reg(fs, e, fs->freereg-1); /* put value there */ | ||
645 | } | ||
646 | } | ||
647 | |||
648 | |||
649 | static int code_loadbool (FuncState *fs, int A, int b, int jump) { | ||
650 | luaK_getlabel(fs); /* those instructions may be jump targets */ | ||
651 | return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); | ||
652 | } | ||
653 | |||
654 | |||
655 | /* | ||
656 | ** check whether list has any jump that do not produce a value | ||
657 | ** or produce an inverted value | ||
658 | */ | ||
659 | static int need_value (FuncState *fs, int list) { | ||
660 | for (; list != NO_JUMP; list = getjump(fs, list)) { | ||
661 | Instruction i = *getjumpcontrol(fs, list); | ||
662 | if (GET_OPCODE(i) != OP_TESTSET) return 1; | ||
663 | } | ||
664 | return 0; /* not found */ | ||
665 | } | ||
666 | |||
667 | |||
668 | /* | ||
669 | ** Ensures final expression result (including results from its jump | ||
670 | ** lists) is in register 'reg'. | ||
671 | ** If expression has jumps, need to patch these jumps either to | ||
672 | ** its final position or to "load" instructions (for those tests | ||
673 | ** that do not produce values). | ||
674 | */ | ||
675 | static void exp2reg (FuncState *fs, expdesc *e, int reg) { | ||
676 | discharge2reg(fs, e, reg); | ||
677 | if (e->k == VJMP) /* expression itself is a test? */ | ||
678 | luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ | ||
679 | if (hasjumps(e)) { | ||
680 | int final; /* position after whole expression */ | ||
681 | int p_f = NO_JUMP; /* position of an eventual LOAD false */ | ||
682 | int p_t = NO_JUMP; /* position of an eventual LOAD true */ | ||
683 | if (need_value(fs, e->t) || need_value(fs, e->f)) { | ||
684 | int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); | ||
685 | p_f = code_loadbool(fs, reg, 0, 1); | ||
686 | p_t = code_loadbool(fs, reg, 1, 0); | ||
687 | luaK_patchtohere(fs, fj); | ||
688 | } | ||
689 | final = luaK_getlabel(fs); | ||
690 | patchlistaux(fs, e->f, final, reg, p_f); | ||
691 | patchlistaux(fs, e->t, final, reg, p_t); | ||
692 | } | ||
693 | e->f = e->t = NO_JUMP; | ||
694 | e->u.info = reg; | ||
695 | e->k = VNONRELOC; | ||
696 | } | ||
697 | |||
698 | |||
699 | /* | ||
700 | ** Ensures final expression result (including results from its jump | ||
701 | ** lists) is in next available register. | ||
702 | */ | ||
703 | void luaK_exp2nextreg (FuncState *fs, expdesc *e) { | ||
704 | luaK_dischargevars(fs, e); | ||
705 | freeexp(fs, e); | ||
706 | luaK_reserveregs(fs, 1); | ||
707 | exp2reg(fs, e, fs->freereg - 1); | ||
708 | } | ||
709 | |||
710 | |||
711 | /* | ||
712 | ** Ensures final expression result (including results from its jump | ||
713 | ** lists) is in some (any) register and return that register. | ||
714 | */ | ||
715 | int luaK_exp2anyreg (FuncState *fs, expdesc *e) { | ||
716 | luaK_dischargevars(fs, e); | ||
717 | if (e->k == VNONRELOC) { /* expression already has a register? */ | ||
718 | if (!hasjumps(e)) /* no jumps? */ | ||
719 | return e->u.info; /* result is already in a register */ | ||
720 | if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ | ||
721 | exp2reg(fs, e, e->u.info); /* put final result in it */ | ||
722 | return e->u.info; | ||
723 | } | ||
724 | } | ||
725 | luaK_exp2nextreg(fs, e); /* otherwise, use next available register */ | ||
726 | return e->u.info; | ||
727 | } | ||
728 | |||
729 | |||
730 | /* | ||
731 | ** Ensures final expression result is either in a register or in an | ||
732 | ** upvalue. | ||
733 | */ | ||
734 | void luaK_exp2anyregup (FuncState *fs, expdesc *e) { | ||
735 | if (e->k != VUPVAL || hasjumps(e)) | ||
736 | luaK_exp2anyreg(fs, e); | ||
737 | } | ||
738 | |||
739 | |||
740 | /* | ||
741 | ** Ensures final expression result is either in a register or it is | ||
742 | ** a constant. | ||
743 | */ | ||
744 | void luaK_exp2val (FuncState *fs, expdesc *e) { | ||
745 | if (hasjumps(e)) | ||
746 | luaK_exp2anyreg(fs, e); | ||
747 | else | ||
748 | luaK_dischargevars(fs, e); | ||
749 | } | ||
750 | |||
751 | |||
752 | /* | ||
753 | ** Ensures final expression result is in a valid R/K index | ||
754 | ** (that is, it is either in a register or in 'k' with an index | ||
755 | ** in the range of R/K indices). | ||
756 | ** Returns R/K index. | ||
757 | */ | ||
758 | int luaK_exp2RK (FuncState *fs, expdesc *e) { | ||
759 | luaK_exp2val(fs, e); | ||
760 | switch (e->k) { /* move constants to 'k' */ | ||
761 | case VTRUE: e->u.info = boolK(fs, 1); goto vk; | ||
762 | case VFALSE: e->u.info = boolK(fs, 0); goto vk; | ||
763 | case VNIL: e->u.info = nilK(fs); goto vk; | ||
764 | case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk; | ||
765 | case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk; | ||
766 | case VK: | ||
767 | vk: | ||
768 | e->k = VK; | ||
769 | if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ | ||
770 | return RKASK(e->u.info); | ||
771 | else break; | ||
772 | default: break; | ||
773 | } | ||
774 | /* not a constant in the right range: put it in a register */ | ||
775 | return luaK_exp2anyreg(fs, e); | ||
776 | } | ||
777 | |||
778 | |||
779 | /* | ||
780 | ** Generate code to store result of expression 'ex' into variable 'var'. | ||
781 | */ | ||
782 | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { | ||
783 | switch (var->k) { | ||
784 | case VLOCAL: { | ||
785 | freeexp(fs, ex); | ||
786 | exp2reg(fs, ex, var->u.info); /* compute 'ex' into proper place */ | ||
787 | return; | ||
788 | } | ||
789 | case VUPVAL: { | ||
790 | int e = luaK_exp2anyreg(fs, ex); | ||
791 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); | ||
792 | break; | ||
793 | } | ||
794 | case VINDEXED: { | ||
795 | OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; | ||
796 | int e = luaK_exp2RK(fs, ex); | ||
797 | luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); | ||
798 | break; | ||
799 | } | ||
800 | default: lua_assert(0); /* invalid var kind to store */ | ||
801 | } | ||
802 | freeexp(fs, ex); | ||
803 | } | ||
804 | |||
805 | |||
806 | /* | ||
807 | ** Emit SELF instruction (convert expression 'e' into 'e:key(e,'). | ||
808 | */ | ||
809 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | ||
810 | int ereg; | ||
811 | luaK_exp2anyreg(fs, e); | ||
812 | ereg = e->u.info; /* register where 'e' was placed */ | ||
813 | freeexp(fs, e); | ||
814 | e->u.info = fs->freereg; /* base register for op_self */ | ||
815 | e->k = VNONRELOC; /* self expression has a fixed register */ | ||
816 | luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ | ||
817 | luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); | ||
818 | freeexp(fs, key); | ||
819 | } | ||
820 | |||
821 | |||
822 | /* | ||
823 | ** Negate condition 'e' (where 'e' is a comparison). | ||
824 | */ | ||
825 | static void negatecondition (FuncState *fs, expdesc *e) { | ||
826 | Instruction *pc = getjumpcontrol(fs, e->u.info); | ||
827 | lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && | ||
828 | GET_OPCODE(*pc) != OP_TEST); | ||
829 | SETARG_A(*pc, !(GETARG_A(*pc))); | ||
830 | } | ||
831 | |||
832 | |||
833 | /* | ||
834 | ** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond' | ||
835 | ** is true, code will jump if 'e' is true.) Return jump position. | ||
836 | ** Optimize when 'e' is 'not' something, inverting the condition | ||
837 | ** and removing the 'not'. | ||
838 | */ | ||
839 | static int jumponcond (FuncState *fs, expdesc *e, int cond) { | ||
840 | if (e->k == VRELOCABLE) { | ||
841 | Instruction ie = getinstruction(fs, e); | ||
842 | if (GET_OPCODE(ie) == OP_NOT) { | ||
843 | fs->pc--; /* remove previous OP_NOT */ | ||
844 | return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); | ||
845 | } | ||
846 | /* else go through */ | ||
847 | } | ||
848 | discharge2anyreg(fs, e); | ||
849 | freeexp(fs, e); | ||
850 | return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); | ||
851 | } | ||
852 | |||
853 | |||
854 | /* | ||
855 | ** Emit code to go through if 'e' is true, jump otherwise. | ||
856 | */ | ||
857 | void luaK_goiftrue (FuncState *fs, expdesc *e) { | ||
858 | int pc; /* pc of new jump */ | ||
859 | luaK_dischargevars(fs, e); | ||
860 | switch (e->k) { | ||
861 | case VJMP: { /* condition? */ | ||
862 | negatecondition(fs, e); /* jump when it is false */ | ||
863 | pc = e->u.info; /* save jump position */ | ||
864 | break; | ||
865 | } | ||
866 | case VK: case VKFLT: case VKINT: case VTRUE: { | ||
867 | pc = NO_JUMP; /* always true; do nothing */ | ||
868 | break; | ||
869 | } | ||
870 | default: { | ||
871 | pc = jumponcond(fs, e, 0); /* jump when false */ | ||
872 | break; | ||
873 | } | ||
874 | } | ||
875 | luaK_concat(fs, &e->f, pc); /* insert new jump in false list */ | ||
876 | luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */ | ||
877 | e->t = NO_JUMP; | ||
878 | } | ||
879 | |||
880 | |||
881 | /* | ||
882 | ** Emit code to go through if 'e' is false, jump otherwise. | ||
883 | */ | ||
884 | void luaK_goiffalse (FuncState *fs, expdesc *e) { | ||
885 | int pc; /* pc of new jump */ | ||
886 | luaK_dischargevars(fs, e); | ||
887 | switch (e->k) { | ||
888 | case VJMP: { | ||
889 | pc = e->u.info; /* already jump if true */ | ||
890 | break; | ||
891 | } | ||
892 | case VNIL: case VFALSE: { | ||
893 | pc = NO_JUMP; /* always false; do nothing */ | ||
894 | break; | ||
895 | } | ||
896 | default: { | ||
897 | pc = jumponcond(fs, e, 1); /* jump if true */ | ||
898 | break; | ||
899 | } | ||
900 | } | ||
901 | luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */ | ||
902 | luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */ | ||
903 | e->f = NO_JUMP; | ||
904 | } | ||
905 | |||
906 | |||
907 | /* | ||
908 | ** Code 'not e', doing constant folding. | ||
909 | */ | ||
910 | static void codenot (FuncState *fs, expdesc *e) { | ||
911 | luaK_dischargevars(fs, e); | ||
912 | switch (e->k) { | ||
913 | case VNIL: case VFALSE: { | ||
914 | e->k = VTRUE; /* true == not nil == not false */ | ||
915 | break; | ||
916 | } | ||
917 | case VK: case VKFLT: case VKINT: case VTRUE: { | ||
918 | e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ | ||
919 | break; | ||
920 | } | ||
921 | case VJMP: { | ||
922 | negatecondition(fs, e); | ||
923 | break; | ||
924 | } | ||
925 | case VRELOCABLE: | ||
926 | case VNONRELOC: { | ||
927 | discharge2anyreg(fs, e); | ||
928 | freeexp(fs, e); | ||
929 | e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); | ||
930 | e->k = VRELOCABLE; | ||
931 | break; | ||
932 | } | ||
933 | default: lua_assert(0); /* cannot happen */ | ||
934 | } | ||
935 | /* interchange true and false lists */ | ||
936 | { int temp = e->f; e->f = e->t; e->t = temp; } | ||
937 | removevalues(fs, e->f); /* values are useless when negated */ | ||
938 | removevalues(fs, e->t); | ||
939 | } | ||
940 | |||
941 | |||
942 | /* | ||
943 | ** Create expression 't[k]'. 't' must have its final result already in a | ||
944 | ** register or upvalue. | ||
945 | */ | ||
946 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | ||
947 | lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL)); | ||
948 | t->u.ind.t = t->u.info; /* register or upvalue index */ | ||
949 | t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */ | ||
950 | t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL; | ||
951 | t->k = VINDEXED; | ||
952 | } | ||
953 | |||
954 | |||
955 | /* | ||
956 | ** Return false if folding can raise an error. | ||
957 | ** Bitwise operations need operands convertible to integers; division | ||
958 | ** operations cannot have 0 as divisor. | ||
959 | */ | ||
960 | static int validop (int op, TValue *v1, TValue *v2) { | ||
961 | switch (op) { | ||
962 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: | ||
963 | case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ | ||
964 | lua_Integer i; | ||
965 | return (tointeger(v1, &i) && tointeger(v2, &i)); | ||
966 | } | ||
967 | case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ | ||
968 | return (nvalue(v2) != 0); | ||
969 | default: return 1; /* everything else is valid */ | ||
970 | } | ||
971 | } | ||
972 | |||
973 | |||
974 | /* | ||
975 | ** Try to "constant-fold" an operation; return 1 iff successful. | ||
976 | ** (In this case, 'e1' has the final result.) | ||
977 | */ | ||
978 | static int constfolding (FuncState *fs, int op, expdesc *e1, | ||
979 | const expdesc *e2) { | ||
980 | TValue v1, v2, res; | ||
981 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) | ||
982 | return 0; /* non-numeric operands or not safe to fold */ | ||
983 | luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ | ||
984 | if (ttisinteger(&res)) { | ||
985 | e1->k = VKINT; | ||
986 | e1->u.ival = ivalue(&res); | ||
987 | } | ||
988 | else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */ | ||
989 | lua_Number n = fltvalue(&res); | ||
990 | if (luai_numisnan(n) || n == 0) | ||
991 | return 0; | ||
992 | e1->k = VKFLT; | ||
993 | e1->u.nval = n; | ||
994 | } | ||
995 | return 1; | ||
996 | } | ||
997 | |||
998 | |||
999 | /* | ||
1000 | ** Emit code for unary expressions that "produce values" | ||
1001 | ** (everything but 'not'). | ||
1002 | ** Expression to produce final result will be encoded in 'e'. | ||
1003 | */ | ||
1004 | static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { | ||
1005 | int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */ | ||
1006 | freeexp(fs, e); | ||
1007 | e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */ | ||
1008 | e->k = VRELOCABLE; /* all those operations are relocatable */ | ||
1009 | luaK_fixline(fs, line); | ||
1010 | } | ||
1011 | |||
1012 | |||
1013 | /* | ||
1014 | ** Emit code for binary expressions that "produce values" | ||
1015 | ** (everything but logical operators 'and'/'or' and comparison | ||
1016 | ** operators). | ||
1017 | ** Expression to produce final result will be encoded in 'e1'. | ||
1018 | ** Because 'luaK_exp2RK' can free registers, its calls must be | ||
1019 | ** in "stack order" (that is, first on 'e2', which may have more | ||
1020 | ** recent registers to be released). | ||
1021 | */ | ||
1022 | static void codebinexpval (FuncState *fs, OpCode op, | ||
1023 | expdesc *e1, expdesc *e2, int line) { | ||
1024 | int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ | ||
1025 | int rk1 = luaK_exp2RK(fs, e1); | ||
1026 | freeexps(fs, e1, e2); | ||
1027 | e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */ | ||
1028 | e1->k = VRELOCABLE; /* all those operations are relocatable */ | ||
1029 | luaK_fixline(fs, line); | ||
1030 | } | ||
1031 | |||
1032 | |||
1033 | /* | ||
1034 | ** Emit code for comparisons. | ||
1035 | ** 'e1' was already put in R/K form by 'luaK_infix'. | ||
1036 | */ | ||
1037 | static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | ||
1038 | int rk1 = (e1->k == VK) ? RKASK(e1->u.info) | ||
1039 | : check_exp(e1->k == VNONRELOC, e1->u.info); | ||
1040 | int rk2 = luaK_exp2RK(fs, e2); | ||
1041 | freeexps(fs, e1, e2); | ||
1042 | switch (opr) { | ||
1043 | case OPR_NE: { /* '(a ~= b)' ==> 'not (a == b)' */ | ||
1044 | e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2); | ||
1045 | break; | ||
1046 | } | ||
1047 | case OPR_GT: case OPR_GE: { | ||
1048 | /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */ | ||
1049 | OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); | ||
1050 | e1->u.info = condjump(fs, op, 1, rk2, rk1); /* invert operands */ | ||
1051 | break; | ||
1052 | } | ||
1053 | default: { /* '==', '<', '<=' use their own opcodes */ | ||
1054 | OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); | ||
1055 | e1->u.info = condjump(fs, op, 1, rk1, rk2); | ||
1056 | break; | ||
1057 | } | ||
1058 | } | ||
1059 | e1->k = VJMP; | ||
1060 | } | ||
1061 | |||
1062 | |||
1063 | /* | ||
1064 | ** Apply prefix operation 'op' to expression 'e'. | ||
1065 | */ | ||
1066 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | ||
1067 | static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; | ||
1068 | switch (op) { | ||
1069 | case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ | ||
1070 | if (constfolding(fs, op + LUA_OPUNM, e, &ef)) | ||
1071 | break; | ||
1072 | /* FALLTHROUGH */ | ||
1073 | case OPR_LEN: | ||
1074 | codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line); | ||
1075 | break; | ||
1076 | case OPR_NOT: codenot(fs, e); break; | ||
1077 | default: lua_assert(0); | ||
1078 | } | ||
1079 | } | ||
1080 | |||
1081 | |||
1082 | /* | ||
1083 | ** Process 1st operand 'v' of binary operation 'op' before reading | ||
1084 | ** 2nd operand. | ||
1085 | */ | ||
1086 | void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | ||
1087 | switch (op) { | ||
1088 | case OPR_AND: { | ||
1089 | luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */ | ||
1090 | break; | ||
1091 | } | ||
1092 | case OPR_OR: { | ||
1093 | luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */ | ||
1094 | break; | ||
1095 | } | ||
1096 | case OPR_CONCAT: { | ||
1097 | luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */ | ||
1098 | break; | ||
1099 | } | ||
1100 | case OPR_ADD: case OPR_SUB: | ||
1101 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: | ||
1102 | case OPR_MOD: case OPR_POW: | ||
1103 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | ||
1104 | case OPR_SHL: case OPR_SHR: { | ||
1105 | if (!tonumeral(v, NULL)) | ||
1106 | luaK_exp2RK(fs, v); | ||
1107 | /* else keep numeral, which may be folded with 2nd operand */ | ||
1108 | break; | ||
1109 | } | ||
1110 | default: { | ||
1111 | luaK_exp2RK(fs, v); | ||
1112 | break; | ||
1113 | } | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1117 | |||
1118 | /* | ||
1119 | ** Finalize code for binary operation, after reading 2nd operand. | ||
1120 | ** For '(a .. b .. c)' (which is '(a .. (b .. c))', because | ||
1121 | ** concatenation is right associative), merge second CONCAT into first | ||
1122 | ** one. | ||
1123 | */ | ||
1124 | void luaK_posfix (FuncState *fs, BinOpr op, | ||
1125 | expdesc *e1, expdesc *e2, int line) { | ||
1126 | switch (op) { | ||
1127 | case OPR_AND: { | ||
1128 | lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */ | ||
1129 | luaK_dischargevars(fs, e2); | ||
1130 | luaK_concat(fs, &e2->f, e1->f); | ||
1131 | *e1 = *e2; | ||
1132 | break; | ||
1133 | } | ||
1134 | case OPR_OR: { | ||
1135 | lua_assert(e1->f == NO_JUMP); /* list closed by 'luK_infix' */ | ||
1136 | luaK_dischargevars(fs, e2); | ||
1137 | luaK_concat(fs, &e2->t, e1->t); | ||
1138 | *e1 = *e2; | ||
1139 | break; | ||
1140 | } | ||
1141 | case OPR_CONCAT: { | ||
1142 | luaK_exp2val(fs, e2); | ||
1143 | if (e2->k == VRELOCABLE && | ||
1144 | GET_OPCODE(getinstruction(fs, e2)) == OP_CONCAT) { | ||
1145 | lua_assert(e1->u.info == GETARG_B(getinstruction(fs, e2))-1); | ||
1146 | freeexp(fs, e1); | ||
1147 | SETARG_B(getinstruction(fs, e2), e1->u.info); | ||
1148 | e1->k = VRELOCABLE; e1->u.info = e2->u.info; | ||
1149 | } | ||
1150 | else { | ||
1151 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ | ||
1152 | codebinexpval(fs, OP_CONCAT, e1, e2, line); | ||
1153 | } | ||
1154 | break; | ||
1155 | } | ||
1156 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: | ||
1157 | case OPR_IDIV: case OPR_MOD: case OPR_POW: | ||
1158 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | ||
1159 | case OPR_SHL: case OPR_SHR: { | ||
1160 | if (!constfolding(fs, op + LUA_OPADD, e1, e2)) | ||
1161 | codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line); | ||
1162 | break; | ||
1163 | } | ||
1164 | case OPR_EQ: case OPR_LT: case OPR_LE: | ||
1165 | case OPR_NE: case OPR_GT: case OPR_GE: { | ||
1166 | codecomp(fs, op, e1, e2); | ||
1167 | break; | ||
1168 | } | ||
1169 | default: lua_assert(0); | ||
1170 | } | ||
1171 | } | ||
1172 | |||
1173 | |||
1174 | /* | ||
1175 | ** Change line information associated with current position. | ||
1176 | */ | ||
1177 | void luaK_fixline (FuncState *fs, int line) { | ||
1178 | fs->f->lineinfo[fs->pc - 1] = line; | ||
1179 | } | ||
1180 | |||
1181 | |||
1182 | /* | ||
1183 | ** Emit a SETLIST instruction. | ||
1184 | ** 'base' is register that keeps table; | ||
1185 | ** 'nelems' is #table plus those to be stored now; | ||
1186 | ** 'tostore' is number of values (in registers 'base + 1',...) to add to | ||
1187 | ** table (or LUA_MULTRET to add up to stack top). | ||
1188 | */ | ||
1189 | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { | ||
1190 | int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; | ||
1191 | int b = (tostore == LUA_MULTRET) ? 0 : tostore; | ||
1192 | lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); | ||
1193 | if (c <= MAXARG_C) | ||
1194 | luaK_codeABC(fs, OP_SETLIST, base, b, c); | ||
1195 | else if (c <= MAXARG_Ax) { | ||
1196 | luaK_codeABC(fs, OP_SETLIST, base, b, 0); | ||
1197 | codeextraarg(fs, c); | ||
1198 | } | ||
1199 | else | ||
1200 | luaX_syntaxerror(fs->ls, "constructor too long"); | ||
1201 | fs->freereg = base + 1; /* free registers with list values */ | ||
1202 | } | ||
1203 | |||
diff --git a/src/lua-5.3/ldump.c b/src/lua-5.3/ldump.c deleted file mode 100644 index f025aca..0000000 --- a/src/lua-5.3/ldump.c +++ /dev/null | |||
@@ -1,215 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** save precompiled Lua chunks | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define ldump_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stddef.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "lobject.h" | ||
18 | #include "lstate.h" | ||
19 | #include "lundump.h" | ||
20 | |||
21 | |||
22 | typedef struct { | ||
23 | lua_State *L; | ||
24 | lua_Writer writer; | ||
25 | void *data; | ||
26 | int strip; | ||
27 | int status; | ||
28 | } DumpState; | ||
29 | |||
30 | |||
31 | /* | ||
32 | ** All high-level dumps go through DumpVector; you can change it to | ||
33 | ** change the endianness of the result | ||
34 | */ | ||
35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) | ||
36 | |||
37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) | ||
38 | |||
39 | |||
40 | static void DumpBlock (const void *b, size_t size, DumpState *D) { | ||
41 | if (D->status == 0 && size > 0) { | ||
42 | lua_unlock(D->L); | ||
43 | D->status = (*D->writer)(D->L, b, size, D->data); | ||
44 | lua_lock(D->L); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | |||
49 | #define DumpVar(x,D) DumpVector(&x,1,D) | ||
50 | |||
51 | |||
52 | static void DumpByte (int y, DumpState *D) { | ||
53 | lu_byte x = (lu_byte)y; | ||
54 | DumpVar(x, D); | ||
55 | } | ||
56 | |||
57 | |||
58 | static void DumpInt (int x, DumpState *D) { | ||
59 | DumpVar(x, D); | ||
60 | } | ||
61 | |||
62 | |||
63 | static void DumpNumber (lua_Number x, DumpState *D) { | ||
64 | DumpVar(x, D); | ||
65 | } | ||
66 | |||
67 | |||
68 | static void DumpInteger (lua_Integer x, DumpState *D) { | ||
69 | DumpVar(x, D); | ||
70 | } | ||
71 | |||
72 | |||
73 | static void DumpString (const TString *s, DumpState *D) { | ||
74 | if (s == NULL) | ||
75 | DumpByte(0, D); | ||
76 | else { | ||
77 | size_t size = tsslen(s) + 1; /* include trailing '\0' */ | ||
78 | const char *str = getstr(s); | ||
79 | if (size < 0xFF) | ||
80 | DumpByte(cast_int(size), D); | ||
81 | else { | ||
82 | DumpByte(0xFF, D); | ||
83 | DumpVar(size, D); | ||
84 | } | ||
85 | DumpVector(str, size - 1, D); /* no need to save '\0' */ | ||
86 | } | ||
87 | } | ||
88 | |||
89 | |||
90 | static void DumpCode (const Proto *f, DumpState *D) { | ||
91 | DumpInt(f->sizecode, D); | ||
92 | DumpVector(f->code, f->sizecode, D); | ||
93 | } | ||
94 | |||
95 | |||
96 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D); | ||
97 | |||
98 | static void DumpConstants (const Proto *f, DumpState *D) { | ||
99 | int i; | ||
100 | int n = f->sizek; | ||
101 | DumpInt(n, D); | ||
102 | for (i = 0; i < n; i++) { | ||
103 | const TValue *o = &f->k[i]; | ||
104 | DumpByte(ttype(o), D); | ||
105 | switch (ttype(o)) { | ||
106 | case LUA_TNIL: | ||
107 | break; | ||
108 | case LUA_TBOOLEAN: | ||
109 | DumpByte(bvalue(o), D); | ||
110 | break; | ||
111 | case LUA_TNUMFLT: | ||
112 | DumpNumber(fltvalue(o), D); | ||
113 | break; | ||
114 | case LUA_TNUMINT: | ||
115 | DumpInteger(ivalue(o), D); | ||
116 | break; | ||
117 | case LUA_TSHRSTR: | ||
118 | case LUA_TLNGSTR: | ||
119 | DumpString(tsvalue(o), D); | ||
120 | break; | ||
121 | default: | ||
122 | lua_assert(0); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | |||
128 | static void DumpProtos (const Proto *f, DumpState *D) { | ||
129 | int i; | ||
130 | int n = f->sizep; | ||
131 | DumpInt(n, D); | ||
132 | for (i = 0; i < n; i++) | ||
133 | DumpFunction(f->p[i], f->source, D); | ||
134 | } | ||
135 | |||
136 | |||
137 | static void DumpUpvalues (const Proto *f, DumpState *D) { | ||
138 | int i, n = f->sizeupvalues; | ||
139 | DumpInt(n, D); | ||
140 | for (i = 0; i < n; i++) { | ||
141 | DumpByte(f->upvalues[i].instack, D); | ||
142 | DumpByte(f->upvalues[i].idx, D); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | |||
147 | static void DumpDebug (const Proto *f, DumpState *D) { | ||
148 | int i, n; | ||
149 | n = (D->strip) ? 0 : f->sizelineinfo; | ||
150 | DumpInt(n, D); | ||
151 | DumpVector(f->lineinfo, n, D); | ||
152 | n = (D->strip) ? 0 : f->sizelocvars; | ||
153 | DumpInt(n, D); | ||
154 | for (i = 0; i < n; i++) { | ||
155 | DumpString(f->locvars[i].varname, D); | ||
156 | DumpInt(f->locvars[i].startpc, D); | ||
157 | DumpInt(f->locvars[i].endpc, D); | ||
158 | } | ||
159 | n = (D->strip) ? 0 : f->sizeupvalues; | ||
160 | DumpInt(n, D); | ||
161 | for (i = 0; i < n; i++) | ||
162 | DumpString(f->upvalues[i].name, D); | ||
163 | } | ||
164 | |||
165 | |||
166 | static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { | ||
167 | if (D->strip || f->source == psource) | ||
168 | DumpString(NULL, D); /* no debug info or same source as its parent */ | ||
169 | else | ||
170 | DumpString(f->source, D); | ||
171 | DumpInt(f->linedefined, D); | ||
172 | DumpInt(f->lastlinedefined, D); | ||
173 | DumpByte(f->numparams, D); | ||
174 | DumpByte(f->is_vararg, D); | ||
175 | DumpByte(f->maxstacksize, D); | ||
176 | DumpCode(f, D); | ||
177 | DumpConstants(f, D); | ||
178 | DumpUpvalues(f, D); | ||
179 | DumpProtos(f, D); | ||
180 | DumpDebug(f, D); | ||
181 | } | ||
182 | |||
183 | |||
184 | static void DumpHeader (DumpState *D) { | ||
185 | DumpLiteral(LUA_SIGNATURE, D); | ||
186 | DumpByte(LUAC_VERSION, D); | ||
187 | DumpByte(LUAC_FORMAT, D); | ||
188 | DumpLiteral(LUAC_DATA, D); | ||
189 | DumpByte(sizeof(int), D); | ||
190 | DumpByte(sizeof(size_t), D); | ||
191 | DumpByte(sizeof(Instruction), D); | ||
192 | DumpByte(sizeof(lua_Integer), D); | ||
193 | DumpByte(sizeof(lua_Number), D); | ||
194 | DumpInteger(LUAC_INT, D); | ||
195 | DumpNumber(LUAC_NUM, D); | ||
196 | } | ||
197 | |||
198 | |||
199 | /* | ||
200 | ** dump Lua function as precompiled chunk | ||
201 | */ | ||
202 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, | ||
203 | int strip) { | ||
204 | DumpState D; | ||
205 | D.L = L; | ||
206 | D.writer = w; | ||
207 | D.data = data; | ||
208 | D.strip = strip; | ||
209 | D.status = 0; | ||
210 | DumpHeader(&D); | ||
211 | DumpByte(f->sizeupvalues, &D); | ||
212 | DumpFunction(f, NULL, &D); | ||
213 | return D.status; | ||
214 | } | ||
215 | |||
diff --git a/src/lua-5.3/lfunc.c b/src/lua-5.3/lfunc.c deleted file mode 100644 index ccafbb8..0000000 --- a/src/lua-5.3/lfunc.c +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $ | ||
3 | ** Auxiliary functions to manipulate prototypes and closures | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lfunc_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stddef.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "lfunc.h" | ||
18 | #include "lgc.h" | ||
19 | #include "lmem.h" | ||
20 | #include "lobject.h" | ||
21 | #include "lstate.h" | ||
22 | |||
23 | |||
24 | |||
25 | CClosure *luaF_newCclosure (lua_State *L, int n) { | ||
26 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); | ||
27 | CClosure *c = gco2ccl(o); | ||
28 | c->nupvalues = cast_byte(n); | ||
29 | return c; | ||
30 | } | ||
31 | |||
32 | |||
33 | LClosure *luaF_newLclosure (lua_State *L, int n) { | ||
34 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); | ||
35 | LClosure *c = gco2lcl(o); | ||
36 | c->p = NULL; | ||
37 | c->nupvalues = cast_byte(n); | ||
38 | while (n--) c->upvals[n] = NULL; | ||
39 | return c; | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | ** fill a closure with new closed upvalues | ||
44 | */ | ||
45 | void luaF_initupvals (lua_State *L, LClosure *cl) { | ||
46 | int i; | ||
47 | for (i = 0; i < cl->nupvalues; i++) { | ||
48 | UpVal *uv = luaM_new(L, UpVal); | ||
49 | uv->refcount = 1; | ||
50 | uv->v = &uv->u.value; /* make it closed */ | ||
51 | setnilvalue(uv->v); | ||
52 | cl->upvals[i] = uv; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | |||
57 | UpVal *luaF_findupval (lua_State *L, StkId level) { | ||
58 | UpVal **pp = &L->openupval; | ||
59 | UpVal *p; | ||
60 | UpVal *uv; | ||
61 | lua_assert(isintwups(L) || L->openupval == NULL); | ||
62 | while (*pp != NULL && (p = *pp)->v >= level) { | ||
63 | lua_assert(upisopen(p)); | ||
64 | if (p->v == level) /* found a corresponding upvalue? */ | ||
65 | return p; /* return it */ | ||
66 | pp = &p->u.open.next; | ||
67 | } | ||
68 | /* not found: create a new upvalue */ | ||
69 | uv = luaM_new(L, UpVal); | ||
70 | uv->refcount = 0; | ||
71 | uv->u.open.next = *pp; /* link it to list of open upvalues */ | ||
72 | uv->u.open.touched = 1; | ||
73 | *pp = uv; | ||
74 | uv->v = level; /* current value lives in the stack */ | ||
75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ | ||
76 | L->twups = G(L)->twups; /* link it to the list */ | ||
77 | G(L)->twups = L; | ||
78 | } | ||
79 | return uv; | ||
80 | } | ||
81 | |||
82 | |||
83 | void luaF_close (lua_State *L, StkId level) { | ||
84 | UpVal *uv; | ||
85 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) { | ||
86 | lua_assert(upisopen(uv)); | ||
87 | L->openupval = uv->u.open.next; /* remove from 'open' list */ | ||
88 | if (uv->refcount == 0) /* no references? */ | ||
89 | luaM_free(L, uv); /* free upvalue */ | ||
90 | else { | ||
91 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ | ||
92 | uv->v = &uv->u.value; /* now current value lives here */ | ||
93 | luaC_upvalbarrier(L, uv); | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | |||
99 | Proto *luaF_newproto (lua_State *L) { | ||
100 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); | ||
101 | Proto *f = gco2p(o); | ||
102 | f->k = NULL; | ||
103 | f->sizek = 0; | ||
104 | f->p = NULL; | ||
105 | f->sizep = 0; | ||
106 | f->code = NULL; | ||
107 | f->cache = NULL; | ||
108 | f->sizecode = 0; | ||
109 | f->lineinfo = NULL; | ||
110 | f->sizelineinfo = 0; | ||
111 | f->upvalues = NULL; | ||
112 | f->sizeupvalues = 0; | ||
113 | f->numparams = 0; | ||
114 | f->is_vararg = 0; | ||
115 | f->maxstacksize = 0; | ||
116 | f->locvars = NULL; | ||
117 | f->sizelocvars = 0; | ||
118 | f->linedefined = 0; | ||
119 | f->lastlinedefined = 0; | ||
120 | f->source = NULL; | ||
121 | return f; | ||
122 | } | ||
123 | |||
124 | |||
125 | void luaF_freeproto (lua_State *L, Proto *f) { | ||
126 | luaM_freearray(L, f->code, f->sizecode); | ||
127 | luaM_freearray(L, f->p, f->sizep); | ||
128 | luaM_freearray(L, f->k, f->sizek); | ||
129 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); | ||
130 | luaM_freearray(L, f->locvars, f->sizelocvars); | ||
131 | luaM_freearray(L, f->upvalues, f->sizeupvalues); | ||
132 | luaM_free(L, f); | ||
133 | } | ||
134 | |||
135 | |||
136 | /* | ||
137 | ** Look for n-th local variable at line 'line' in function 'func'. | ||
138 | ** Returns NULL if not found. | ||
139 | */ | ||
140 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { | ||
141 | int i; | ||
142 | for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { | ||
143 | if (pc < f->locvars[i].endpc) { /* is variable active? */ | ||
144 | local_number--; | ||
145 | if (local_number == 0) | ||
146 | return getstr(f->locvars[i].varname); | ||
147 | } | ||
148 | } | ||
149 | return NULL; /* not found */ | ||
150 | } | ||
151 | |||
diff --git a/src/lua-5.3/lfunc.h b/src/lua-5.3/lfunc.h deleted file mode 100644 index c916e98..0000000 --- a/src/lua-5.3/lfunc.h +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $ | ||
3 | ** Auxiliary functions to manipulate prototypes and closures | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lfunc_h | ||
8 | #define lfunc_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | |||
13 | |||
14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ | ||
15 | cast(int, sizeof(TValue)*((n)-1))) | ||
16 | |||
17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ | ||
18 | cast(int, sizeof(TValue *)*((n)-1))) | ||
19 | |||
20 | |||
21 | /* test whether thread is in 'twups' list */ | ||
22 | #define isintwups(L) (L->twups != L) | ||
23 | |||
24 | |||
25 | /* | ||
26 | ** maximum number of upvalues in a closure (both C and Lua). (Value | ||
27 | ** must fit in a VM register.) | ||
28 | */ | ||
29 | #define MAXUPVAL 255 | ||
30 | |||
31 | |||
32 | /* | ||
33 | ** Upvalues for Lua closures | ||
34 | */ | ||
35 | struct UpVal { | ||
36 | TValue *v; /* points to stack or to its own value */ | ||
37 | lu_mem refcount; /* reference counter */ | ||
38 | union { | ||
39 | struct { /* (when open) */ | ||
40 | UpVal *next; /* linked list */ | ||
41 | int touched; /* mark to avoid cycles with dead threads */ | ||
42 | } open; | ||
43 | TValue value; /* the value (when closed) */ | ||
44 | } u; | ||
45 | }; | ||
46 | |||
47 | #define upisopen(up) ((up)->v != &(up)->u.value) | ||
48 | |||
49 | |||
50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); | ||
51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); | ||
52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); | ||
53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); | ||
54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); | ||
55 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); | ||
56 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); | ||
57 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, | ||
58 | int pc); | ||
59 | |||
60 | |||
61 | #endif | ||
diff --git a/src/lua-5.3/lgc.c b/src/lua-5.3/lgc.c deleted file mode 100644 index db4df82..0000000 --- a/src/lua-5.3/lgc.c +++ /dev/null | |||
@@ -1,1179 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lgc.c,v 2.215.1.2 2017/08/31 16:15:27 roberto Exp $ | ||
3 | ** Garbage Collector | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lgc_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <string.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lfunc.h" | ||
20 | #include "lgc.h" | ||
21 | #include "lmem.h" | ||
22 | #include "lobject.h" | ||
23 | #include "lstate.h" | ||
24 | #include "lstring.h" | ||
25 | #include "ltable.h" | ||
26 | #include "ltm.h" | ||
27 | |||
28 | |||
29 | /* | ||
30 | ** internal state for collector while inside the atomic phase. The | ||
31 | ** collector should never be in this state while running regular code. | ||
32 | */ | ||
33 | #define GCSinsideatomic (GCSpause + 1) | ||
34 | |||
35 | /* | ||
36 | ** cost of sweeping one element (the size of a small object divided | ||
37 | ** by some adjust for the sweep speed) | ||
38 | */ | ||
39 | #define GCSWEEPCOST ((sizeof(TString) + 4) / 4) | ||
40 | |||
41 | /* maximum number of elements to sweep in each single step */ | ||
42 | #define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) | ||
43 | |||
44 | /* cost of calling one finalizer */ | ||
45 | #define GCFINALIZECOST GCSWEEPCOST | ||
46 | |||
47 | |||
48 | /* | ||
49 | ** macro to adjust 'stepmul': 'stepmul' is actually used like | ||
50 | ** 'stepmul / STEPMULADJ' (value chosen by tests) | ||
51 | */ | ||
52 | #define STEPMULADJ 200 | ||
53 | |||
54 | |||
55 | /* | ||
56 | ** macro to adjust 'pause': 'pause' is actually used like | ||
57 | ** 'pause / PAUSEADJ' (value chosen by tests) | ||
58 | */ | ||
59 | #define PAUSEADJ 100 | ||
60 | |||
61 | |||
62 | /* | ||
63 | ** 'makewhite' erases all color bits then sets only the current white | ||
64 | ** bit | ||
65 | */ | ||
66 | #define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS)) | ||
67 | #define makewhite(g,x) \ | ||
68 | (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) | ||
69 | |||
70 | #define white2gray(x) resetbits(x->marked, WHITEBITS) | ||
71 | #define black2gray(x) resetbit(x->marked, BLACKBIT) | ||
72 | |||
73 | |||
74 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | ||
75 | |||
76 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) | ||
77 | |||
78 | |||
79 | #define checkconsistency(obj) \ | ||
80 | lua_longassert(!iscollectable(obj) || righttt(obj)) | ||
81 | |||
82 | |||
83 | #define markvalue(g,o) { checkconsistency(o); \ | ||
84 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } | ||
85 | |||
86 | #define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } | ||
87 | |||
88 | /* | ||
89 | ** mark an object that can be NULL (either because it is really optional, | ||
90 | ** or it was stripped as debug info, or inside an uncompleted structure) | ||
91 | */ | ||
92 | #define markobjectN(g,t) { if (t) markobject(g,t); } | ||
93 | |||
94 | static void reallymarkobject (global_State *g, GCObject *o); | ||
95 | |||
96 | |||
97 | /* | ||
98 | ** {====================================================== | ||
99 | ** Generic functions | ||
100 | ** ======================================================= | ||
101 | */ | ||
102 | |||
103 | |||
104 | /* | ||
105 | ** one after last element in a hash array | ||
106 | */ | ||
107 | #define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) | ||
108 | |||
109 | |||
110 | /* | ||
111 | ** link collectable object 'o' into list pointed by 'p' | ||
112 | */ | ||
113 | #define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o)) | ||
114 | |||
115 | |||
116 | /* | ||
117 | ** If key is not marked, mark its entry as dead. This allows key to be | ||
118 | ** collected, but keeps its entry in the table. A dead node is needed | ||
119 | ** when Lua looks up for a key (it may be part of a chain) and when | ||
120 | ** traversing a weak table (key might be removed from the table during | ||
121 | ** traversal). Other places never manipulate dead keys, because its | ||
122 | ** associated nil value is enough to signal that the entry is logically | ||
123 | ** empty. | ||
124 | */ | ||
125 | static void removeentry (Node *n) { | ||
126 | lua_assert(ttisnil(gval(n))); | ||
127 | if (valiswhite(gkey(n))) | ||
128 | setdeadvalue(wgkey(n)); /* unused and unmarked key; remove it */ | ||
129 | } | ||
130 | |||
131 | |||
132 | /* | ||
133 | ** tells whether a key or value can be cleared from a weak | ||
134 | ** table. Non-collectable objects are never removed from weak | ||
135 | ** tables. Strings behave as 'values', so are never removed too. for | ||
136 | ** other objects: if really collected, cannot keep them; for objects | ||
137 | ** being finalized, keep them in keys, but not in values | ||
138 | */ | ||
139 | static int iscleared (global_State *g, const TValue *o) { | ||
140 | if (!iscollectable(o)) return 0; | ||
141 | else if (ttisstring(o)) { | ||
142 | markobject(g, tsvalue(o)); /* strings are 'values', so are never weak */ | ||
143 | return 0; | ||
144 | } | ||
145 | else return iswhite(gcvalue(o)); | ||
146 | } | ||
147 | |||
148 | |||
149 | /* | ||
150 | ** barrier that moves collector forward, that is, mark the white object | ||
151 | ** being pointed by a black object. (If in sweep phase, clear the black | ||
152 | ** object to white [sweep it] to avoid other barrier calls for this | ||
153 | ** same object.) | ||
154 | */ | ||
155 | void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { | ||
156 | global_State *g = G(L); | ||
157 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | ||
158 | if (keepinvariant(g)) /* must keep invariant? */ | ||
159 | reallymarkobject(g, v); /* restore invariant */ | ||
160 | else { /* sweep phase */ | ||
161 | lua_assert(issweepphase(g)); | ||
162 | makewhite(g, o); /* mark main obj. as white to avoid other barriers */ | ||
163 | } | ||
164 | } | ||
165 | |||
166 | |||
167 | /* | ||
168 | ** barrier that moves collector backward, that is, mark the black object | ||
169 | ** pointing to a white object as gray again. | ||
170 | */ | ||
171 | void luaC_barrierback_ (lua_State *L, Table *t) { | ||
172 | global_State *g = G(L); | ||
173 | lua_assert(isblack(t) && !isdead(g, t)); | ||
174 | black2gray(t); /* make table gray (again) */ | ||
175 | linkgclist(t, g->grayagain); | ||
176 | } | ||
177 | |||
178 | |||
179 | /* | ||
180 | ** barrier for assignments to closed upvalues. Because upvalues are | ||
181 | ** shared among closures, it is impossible to know the color of all | ||
182 | ** closures pointing to it. So, we assume that the object being assigned | ||
183 | ** must be marked. | ||
184 | */ | ||
185 | void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) { | ||
186 | global_State *g = G(L); | ||
187 | GCObject *o = gcvalue(uv->v); | ||
188 | lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */ | ||
189 | if (keepinvariant(g)) | ||
190 | markobject(g, o); | ||
191 | } | ||
192 | |||
193 | |||
194 | void luaC_fix (lua_State *L, GCObject *o) { | ||
195 | global_State *g = G(L); | ||
196 | lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ | ||
197 | white2gray(o); /* they will be gray forever */ | ||
198 | g->allgc = o->next; /* remove object from 'allgc' list */ | ||
199 | o->next = g->fixedgc; /* link it to 'fixedgc' list */ | ||
200 | g->fixedgc = o; | ||
201 | } | ||
202 | |||
203 | |||
204 | /* | ||
205 | ** create a new collectable object (with given type and size) and link | ||
206 | ** it to 'allgc' list. | ||
207 | */ | ||
208 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { | ||
209 | global_State *g = G(L); | ||
210 | GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); | ||
211 | o->marked = luaC_white(g); | ||
212 | o->tt = tt; | ||
213 | o->next = g->allgc; | ||
214 | g->allgc = o; | ||
215 | return o; | ||
216 | } | ||
217 | |||
218 | /* }====================================================== */ | ||
219 | |||
220 | |||
221 | |||
222 | /* | ||
223 | ** {====================================================== | ||
224 | ** Mark functions | ||
225 | ** ======================================================= | ||
226 | */ | ||
227 | |||
228 | |||
229 | /* | ||
230 | ** mark an object. Userdata, strings, and closed upvalues are visited | ||
231 | ** and turned black here. Other objects are marked gray and added | ||
232 | ** to appropriate list to be visited (and turned black) later. (Open | ||
233 | ** upvalues are already linked in 'headuv' list.) | ||
234 | */ | ||
235 | static void reallymarkobject (global_State *g, GCObject *o) { | ||
236 | reentry: | ||
237 | white2gray(o); | ||
238 | switch (o->tt) { | ||
239 | case LUA_TSHRSTR: { | ||
240 | gray2black(o); | ||
241 | g->GCmemtrav += sizelstring(gco2ts(o)->shrlen); | ||
242 | break; | ||
243 | } | ||
244 | case LUA_TLNGSTR: { | ||
245 | gray2black(o); | ||
246 | g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen); | ||
247 | break; | ||
248 | } | ||
249 | case LUA_TUSERDATA: { | ||
250 | TValue uvalue; | ||
251 | markobjectN(g, gco2u(o)->metatable); /* mark its metatable */ | ||
252 | gray2black(o); | ||
253 | g->GCmemtrav += sizeudata(gco2u(o)); | ||
254 | getuservalue(g->mainthread, gco2u(o), &uvalue); | ||
255 | if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */ | ||
256 | o = gcvalue(&uvalue); | ||
257 | goto reentry; | ||
258 | } | ||
259 | break; | ||
260 | } | ||
261 | case LUA_TLCL: { | ||
262 | linkgclist(gco2lcl(o), g->gray); | ||
263 | break; | ||
264 | } | ||
265 | case LUA_TCCL: { | ||
266 | linkgclist(gco2ccl(o), g->gray); | ||
267 | break; | ||
268 | } | ||
269 | case LUA_TTABLE: { | ||
270 | linkgclist(gco2t(o), g->gray); | ||
271 | break; | ||
272 | } | ||
273 | case LUA_TTHREAD: { | ||
274 | linkgclist(gco2th(o), g->gray); | ||
275 | break; | ||
276 | } | ||
277 | case LUA_TPROTO: { | ||
278 | linkgclist(gco2p(o), g->gray); | ||
279 | break; | ||
280 | } | ||
281 | default: lua_assert(0); break; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | |||
286 | /* | ||
287 | ** mark metamethods for basic types | ||
288 | */ | ||
289 | static void markmt (global_State *g) { | ||
290 | int i; | ||
291 | for (i=0; i < LUA_NUMTAGS; i++) | ||
292 | markobjectN(g, g->mt[i]); | ||
293 | } | ||
294 | |||
295 | |||
296 | /* | ||
297 | ** mark all objects in list of being-finalized | ||
298 | */ | ||
299 | static void markbeingfnz (global_State *g) { | ||
300 | GCObject *o; | ||
301 | for (o = g->tobefnz; o != NULL; o = o->next) | ||
302 | markobject(g, o); | ||
303 | } | ||
304 | |||
305 | |||
306 | /* | ||
307 | ** Mark all values stored in marked open upvalues from non-marked threads. | ||
308 | ** (Values from marked threads were already marked when traversing the | ||
309 | ** thread.) Remove from the list threads that no longer have upvalues and | ||
310 | ** not-marked threads. | ||
311 | */ | ||
312 | static void remarkupvals (global_State *g) { | ||
313 | lua_State *thread; | ||
314 | lua_State **p = &g->twups; | ||
315 | while ((thread = *p) != NULL) { | ||
316 | lua_assert(!isblack(thread)); /* threads are never black */ | ||
317 | if (isgray(thread) && thread->openupval != NULL) | ||
318 | p = &thread->twups; /* keep marked thread with upvalues in the list */ | ||
319 | else { /* thread is not marked or without upvalues */ | ||
320 | UpVal *uv; | ||
321 | *p = thread->twups; /* remove thread from the list */ | ||
322 | thread->twups = thread; /* mark that it is out of list */ | ||
323 | for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { | ||
324 | if (uv->u.open.touched) { | ||
325 | markvalue(g, uv->v); /* remark upvalue's value */ | ||
326 | uv->u.open.touched = 0; | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | |||
333 | |||
334 | /* | ||
335 | ** mark root set and reset all gray lists, to start a new collection | ||
336 | */ | ||
337 | static void restartcollection (global_State *g) { | ||
338 | g->gray = g->grayagain = NULL; | ||
339 | g->weak = g->allweak = g->ephemeron = NULL; | ||
340 | markobject(g, g->mainthread); | ||
341 | markvalue(g, &g->l_registry); | ||
342 | markmt(g); | ||
343 | markbeingfnz(g); /* mark any finalizing object left from previous cycle */ | ||
344 | } | ||
345 | |||
346 | /* }====================================================== */ | ||
347 | |||
348 | |||
349 | /* | ||
350 | ** {====================================================== | ||
351 | ** Traverse functions | ||
352 | ** ======================================================= | ||
353 | */ | ||
354 | |||
355 | /* | ||
356 | ** Traverse a table with weak values and link it to proper list. During | ||
357 | ** propagate phase, keep it in 'grayagain' list, to be revisited in the | ||
358 | ** atomic phase. In the atomic phase, if table has any white value, | ||
359 | ** put it in 'weak' list, to be cleared. | ||
360 | */ | ||
361 | static void traverseweakvalue (global_State *g, Table *h) { | ||
362 | Node *n, *limit = gnodelast(h); | ||
363 | /* if there is array part, assume it may have white values (it is not | ||
364 | worth traversing it now just to check) */ | ||
365 | int hasclears = (h->sizearray > 0); | ||
366 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ | ||
367 | checkdeadkey(n); | ||
368 | if (ttisnil(gval(n))) /* entry is empty? */ | ||
369 | removeentry(n); /* remove it */ | ||
370 | else { | ||
371 | lua_assert(!ttisnil(gkey(n))); | ||
372 | markvalue(g, gkey(n)); /* mark key */ | ||
373 | if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ | ||
374 | hasclears = 1; /* table will have to be cleared */ | ||
375 | } | ||
376 | } | ||
377 | if (g->gcstate == GCSpropagate) | ||
378 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ | ||
379 | else if (hasclears) | ||
380 | linkgclist(h, g->weak); /* has to be cleared later */ | ||
381 | } | ||
382 | |||
383 | |||
384 | /* | ||
385 | ** Traverse an ephemeron table and link it to proper list. Returns true | ||
386 | ** iff any object was marked during this traversal (which implies that | ||
387 | ** convergence has to continue). During propagation phase, keep table | ||
388 | ** in 'grayagain' list, to be visited again in the atomic phase. In | ||
389 | ** the atomic phase, if table has any white->white entry, it has to | ||
390 | ** be revisited during ephemeron convergence (as that key may turn | ||
391 | ** black). Otherwise, if it has any white key, table has to be cleared | ||
392 | ** (in the atomic phase). | ||
393 | */ | ||
394 | static int traverseephemeron (global_State *g, Table *h) { | ||
395 | int marked = 0; /* true if an object is marked in this traversal */ | ||
396 | int hasclears = 0; /* true if table has white keys */ | ||
397 | int hasww = 0; /* true if table has entry "white-key -> white-value" */ | ||
398 | Node *n, *limit = gnodelast(h); | ||
399 | unsigned int i; | ||
400 | /* traverse array part */ | ||
401 | for (i = 0; i < h->sizearray; i++) { | ||
402 | if (valiswhite(&h->array[i])) { | ||
403 | marked = 1; | ||
404 | reallymarkobject(g, gcvalue(&h->array[i])); | ||
405 | } | ||
406 | } | ||
407 | /* traverse hash part */ | ||
408 | for (n = gnode(h, 0); n < limit; n++) { | ||
409 | checkdeadkey(n); | ||
410 | if (ttisnil(gval(n))) /* entry is empty? */ | ||
411 | removeentry(n); /* remove it */ | ||
412 | else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ | ||
413 | hasclears = 1; /* table must be cleared */ | ||
414 | if (valiswhite(gval(n))) /* value not marked yet? */ | ||
415 | hasww = 1; /* white-white entry */ | ||
416 | } | ||
417 | else if (valiswhite(gval(n))) { /* value not marked yet? */ | ||
418 | marked = 1; | ||
419 | reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ | ||
420 | } | ||
421 | } | ||
422 | /* link table into proper list */ | ||
423 | if (g->gcstate == GCSpropagate) | ||
424 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ | ||
425 | else if (hasww) /* table has white->white entries? */ | ||
426 | linkgclist(h, g->ephemeron); /* have to propagate again */ | ||
427 | else if (hasclears) /* table has white keys? */ | ||
428 | linkgclist(h, g->allweak); /* may have to clean white keys */ | ||
429 | return marked; | ||
430 | } | ||
431 | |||
432 | |||
433 | static void traversestrongtable (global_State *g, Table *h) { | ||
434 | Node *n, *limit = gnodelast(h); | ||
435 | unsigned int i; | ||
436 | for (i = 0; i < h->sizearray; i++) /* traverse array part */ | ||
437 | markvalue(g, &h->array[i]); | ||
438 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ | ||
439 | checkdeadkey(n); | ||
440 | if (ttisnil(gval(n))) /* entry is empty? */ | ||
441 | removeentry(n); /* remove it */ | ||
442 | else { | ||
443 | lua_assert(!ttisnil(gkey(n))); | ||
444 | markvalue(g, gkey(n)); /* mark key */ | ||
445 | markvalue(g, gval(n)); /* mark value */ | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | |||
451 | static lu_mem traversetable (global_State *g, Table *h) { | ||
452 | const char *weakkey, *weakvalue; | ||
453 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); | ||
454 | markobjectN(g, h->metatable); | ||
455 | if (mode && ttisstring(mode) && /* is there a weak mode? */ | ||
456 | ((weakkey = strchr(svalue(mode), 'k')), | ||
457 | (weakvalue = strchr(svalue(mode), 'v')), | ||
458 | (weakkey || weakvalue))) { /* is really weak? */ | ||
459 | black2gray(h); /* keep table gray */ | ||
460 | if (!weakkey) /* strong keys? */ | ||
461 | traverseweakvalue(g, h); | ||
462 | else if (!weakvalue) /* strong values? */ | ||
463 | traverseephemeron(g, h); | ||
464 | else /* all weak */ | ||
465 | linkgclist(h, g->allweak); /* nothing to traverse now */ | ||
466 | } | ||
467 | else /* not weak */ | ||
468 | traversestrongtable(g, h); | ||
469 | return sizeof(Table) + sizeof(TValue) * h->sizearray + | ||
470 | sizeof(Node) * cast(size_t, allocsizenode(h)); | ||
471 | } | ||
472 | |||
473 | |||
474 | /* | ||
475 | ** Traverse a prototype. (While a prototype is being build, its | ||
476 | ** arrays can be larger than needed; the extra slots are filled with | ||
477 | ** NULL, so the use of 'markobjectN') | ||
478 | */ | ||
479 | static int traverseproto (global_State *g, Proto *f) { | ||
480 | int i; | ||
481 | if (f->cache && iswhite(f->cache)) | ||
482 | f->cache = NULL; /* allow cache to be collected */ | ||
483 | markobjectN(g, f->source); | ||
484 | for (i = 0; i < f->sizek; i++) /* mark literals */ | ||
485 | markvalue(g, &f->k[i]); | ||
486 | for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ | ||
487 | markobjectN(g, f->upvalues[i].name); | ||
488 | for (i = 0; i < f->sizep; i++) /* mark nested protos */ | ||
489 | markobjectN(g, f->p[i]); | ||
490 | for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ | ||
491 | markobjectN(g, f->locvars[i].varname); | ||
492 | return sizeof(Proto) + sizeof(Instruction) * f->sizecode + | ||
493 | sizeof(Proto *) * f->sizep + | ||
494 | sizeof(TValue) * f->sizek + | ||
495 | sizeof(int) * f->sizelineinfo + | ||
496 | sizeof(LocVar) * f->sizelocvars + | ||
497 | sizeof(Upvaldesc) * f->sizeupvalues; | ||
498 | } | ||
499 | |||
500 | |||
501 | static lu_mem traverseCclosure (global_State *g, CClosure *cl) { | ||
502 | int i; | ||
503 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ | ||
504 | markvalue(g, &cl->upvalue[i]); | ||
505 | return sizeCclosure(cl->nupvalues); | ||
506 | } | ||
507 | |||
508 | /* | ||
509 | ** open upvalues point to values in a thread, so those values should | ||
510 | ** be marked when the thread is traversed except in the atomic phase | ||
511 | ** (because then the value cannot be changed by the thread and the | ||
512 | ** thread may not be traversed again) | ||
513 | */ | ||
514 | static lu_mem traverseLclosure (global_State *g, LClosure *cl) { | ||
515 | int i; | ||
516 | markobjectN(g, cl->p); /* mark its prototype */ | ||
517 | for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */ | ||
518 | UpVal *uv = cl->upvals[i]; | ||
519 | if (uv != NULL) { | ||
520 | if (upisopen(uv) && g->gcstate != GCSinsideatomic) | ||
521 | uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */ | ||
522 | else | ||
523 | markvalue(g, uv->v); | ||
524 | } | ||
525 | } | ||
526 | return sizeLclosure(cl->nupvalues); | ||
527 | } | ||
528 | |||
529 | |||
530 | static lu_mem traversethread (global_State *g, lua_State *th) { | ||
531 | StkId o = th->stack; | ||
532 | if (o == NULL) | ||
533 | return 1; /* stack not completely built yet */ | ||
534 | lua_assert(g->gcstate == GCSinsideatomic || | ||
535 | th->openupval == NULL || isintwups(th)); | ||
536 | for (; o < th->top; o++) /* mark live elements in the stack */ | ||
537 | markvalue(g, o); | ||
538 | if (g->gcstate == GCSinsideatomic) { /* final traversal? */ | ||
539 | StkId lim = th->stack + th->stacksize; /* real end of stack */ | ||
540 | for (; o < lim; o++) /* clear not-marked stack slice */ | ||
541 | setnilvalue(o); | ||
542 | /* 'remarkupvals' may have removed thread from 'twups' list */ | ||
543 | if (!isintwups(th) && th->openupval != NULL) { | ||
544 | th->twups = g->twups; /* link it back to the list */ | ||
545 | g->twups = th; | ||
546 | } | ||
547 | } | ||
548 | else if (g->gckind != KGC_EMERGENCY) | ||
549 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ | ||
550 | return (sizeof(lua_State) + sizeof(TValue) * th->stacksize + | ||
551 | sizeof(CallInfo) * th->nci); | ||
552 | } | ||
553 | |||
554 | |||
555 | /* | ||
556 | ** traverse one gray object, turning it to black (except for threads, | ||
557 | ** which are always gray). | ||
558 | */ | ||
559 | static void propagatemark (global_State *g) { | ||
560 | lu_mem size; | ||
561 | GCObject *o = g->gray; | ||
562 | lua_assert(isgray(o)); | ||
563 | gray2black(o); | ||
564 | switch (o->tt) { | ||
565 | case LUA_TTABLE: { | ||
566 | Table *h = gco2t(o); | ||
567 | g->gray = h->gclist; /* remove from 'gray' list */ | ||
568 | size = traversetable(g, h); | ||
569 | break; | ||
570 | } | ||
571 | case LUA_TLCL: { | ||
572 | LClosure *cl = gco2lcl(o); | ||
573 | g->gray = cl->gclist; /* remove from 'gray' list */ | ||
574 | size = traverseLclosure(g, cl); | ||
575 | break; | ||
576 | } | ||
577 | case LUA_TCCL: { | ||
578 | CClosure *cl = gco2ccl(o); | ||
579 | g->gray = cl->gclist; /* remove from 'gray' list */ | ||
580 | size = traverseCclosure(g, cl); | ||
581 | break; | ||
582 | } | ||
583 | case LUA_TTHREAD: { | ||
584 | lua_State *th = gco2th(o); | ||
585 | g->gray = th->gclist; /* remove from 'gray' list */ | ||
586 | linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ | ||
587 | black2gray(o); | ||
588 | size = traversethread(g, th); | ||
589 | break; | ||
590 | } | ||
591 | case LUA_TPROTO: { | ||
592 | Proto *p = gco2p(o); | ||
593 | g->gray = p->gclist; /* remove from 'gray' list */ | ||
594 | size = traverseproto(g, p); | ||
595 | break; | ||
596 | } | ||
597 | default: lua_assert(0); return; | ||
598 | } | ||
599 | g->GCmemtrav += size; | ||
600 | } | ||
601 | |||
602 | |||
603 | static void propagateall (global_State *g) { | ||
604 | while (g->gray) propagatemark(g); | ||
605 | } | ||
606 | |||
607 | |||
608 | static void convergeephemerons (global_State *g) { | ||
609 | int changed; | ||
610 | do { | ||
611 | GCObject *w; | ||
612 | GCObject *next = g->ephemeron; /* get ephemeron list */ | ||
613 | g->ephemeron = NULL; /* tables may return to this list when traversed */ | ||
614 | changed = 0; | ||
615 | while ((w = next) != NULL) { | ||
616 | next = gco2t(w)->gclist; | ||
617 | if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ | ||
618 | propagateall(g); /* propagate changes */ | ||
619 | changed = 1; /* will have to revisit all ephemeron tables */ | ||
620 | } | ||
621 | } | ||
622 | } while (changed); | ||
623 | } | ||
624 | |||
625 | /* }====================================================== */ | ||
626 | |||
627 | |||
628 | /* | ||
629 | ** {====================================================== | ||
630 | ** Sweep Functions | ||
631 | ** ======================================================= | ||
632 | */ | ||
633 | |||
634 | |||
635 | /* | ||
636 | ** clear entries with unmarked keys from all weaktables in list 'l' up | ||
637 | ** to element 'f' | ||
638 | */ | ||
639 | static void clearkeys (global_State *g, GCObject *l, GCObject *f) { | ||
640 | for (; l != f; l = gco2t(l)->gclist) { | ||
641 | Table *h = gco2t(l); | ||
642 | Node *n, *limit = gnodelast(h); | ||
643 | for (n = gnode(h, 0); n < limit; n++) { | ||
644 | if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { | ||
645 | setnilvalue(gval(n)); /* remove value ... */ | ||
646 | } | ||
647 | if (ttisnil(gval(n))) /* is entry empty? */ | ||
648 | removeentry(n); /* remove entry from table */ | ||
649 | } | ||
650 | } | ||
651 | } | ||
652 | |||
653 | |||
654 | /* | ||
655 | ** clear entries with unmarked values from all weaktables in list 'l' up | ||
656 | ** to element 'f' | ||
657 | */ | ||
658 | static void clearvalues (global_State *g, GCObject *l, GCObject *f) { | ||
659 | for (; l != f; l = gco2t(l)->gclist) { | ||
660 | Table *h = gco2t(l); | ||
661 | Node *n, *limit = gnodelast(h); | ||
662 | unsigned int i; | ||
663 | for (i = 0; i < h->sizearray; i++) { | ||
664 | TValue *o = &h->array[i]; | ||
665 | if (iscleared(g, o)) /* value was collected? */ | ||
666 | setnilvalue(o); /* remove value */ | ||
667 | } | ||
668 | for (n = gnode(h, 0); n < limit; n++) { | ||
669 | if (!ttisnil(gval(n)) && iscleared(g, gval(n))) { | ||
670 | setnilvalue(gval(n)); /* remove value ... */ | ||
671 | removeentry(n); /* and remove entry from table */ | ||
672 | } | ||
673 | } | ||
674 | } | ||
675 | } | ||
676 | |||
677 | |||
678 | void luaC_upvdeccount (lua_State *L, UpVal *uv) { | ||
679 | lua_assert(uv->refcount > 0); | ||
680 | uv->refcount--; | ||
681 | if (uv->refcount == 0 && !upisopen(uv)) | ||
682 | luaM_free(L, uv); | ||
683 | } | ||
684 | |||
685 | |||
686 | static void freeLclosure (lua_State *L, LClosure *cl) { | ||
687 | int i; | ||
688 | for (i = 0; i < cl->nupvalues; i++) { | ||
689 | UpVal *uv = cl->upvals[i]; | ||
690 | if (uv) | ||
691 | luaC_upvdeccount(L, uv); | ||
692 | } | ||
693 | luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); | ||
694 | } | ||
695 | |||
696 | |||
697 | static void freeobj (lua_State *L, GCObject *o) { | ||
698 | switch (o->tt) { | ||
699 | case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; | ||
700 | case LUA_TLCL: { | ||
701 | freeLclosure(L, gco2lcl(o)); | ||
702 | break; | ||
703 | } | ||
704 | case LUA_TCCL: { | ||
705 | luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); | ||
706 | break; | ||
707 | } | ||
708 | case LUA_TTABLE: luaH_free(L, gco2t(o)); break; | ||
709 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; | ||
710 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; | ||
711 | case LUA_TSHRSTR: | ||
712 | luaS_remove(L, gco2ts(o)); /* remove it from hash table */ | ||
713 | luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen)); | ||
714 | break; | ||
715 | case LUA_TLNGSTR: { | ||
716 | luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen)); | ||
717 | break; | ||
718 | } | ||
719 | default: lua_assert(0); | ||
720 | } | ||
721 | } | ||
722 | |||
723 | |||
724 | #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) | ||
725 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); | ||
726 | |||
727 | |||
728 | /* | ||
729 | ** sweep at most 'count' elements from a list of GCObjects erasing dead | ||
730 | ** objects, where a dead object is one marked with the old (non current) | ||
731 | ** white; change all non-dead objects back to white, preparing for next | ||
732 | ** collection cycle. Return where to continue the traversal or NULL if | ||
733 | ** list is finished. | ||
734 | */ | ||
735 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | ||
736 | global_State *g = G(L); | ||
737 | int ow = otherwhite(g); | ||
738 | int white = luaC_white(g); /* current white */ | ||
739 | while (*p != NULL && count-- > 0) { | ||
740 | GCObject *curr = *p; | ||
741 | int marked = curr->marked; | ||
742 | if (isdeadm(ow, marked)) { /* is 'curr' dead? */ | ||
743 | *p = curr->next; /* remove 'curr' from list */ | ||
744 | freeobj(L, curr); /* erase 'curr' */ | ||
745 | } | ||
746 | else { /* change mark to 'white' */ | ||
747 | curr->marked = cast_byte((marked & maskcolors) | white); | ||
748 | p = &curr->next; /* go to next element */ | ||
749 | } | ||
750 | } | ||
751 | return (*p == NULL) ? NULL : p; | ||
752 | } | ||
753 | |||
754 | |||
755 | /* | ||
756 | ** sweep a list until a live object (or end of list) | ||
757 | */ | ||
758 | static GCObject **sweeptolive (lua_State *L, GCObject **p) { | ||
759 | GCObject **old = p; | ||
760 | do { | ||
761 | p = sweeplist(L, p, 1); | ||
762 | } while (p == old); | ||
763 | return p; | ||
764 | } | ||
765 | |||
766 | /* }====================================================== */ | ||
767 | |||
768 | |||
769 | /* | ||
770 | ** {====================================================== | ||
771 | ** Finalization | ||
772 | ** ======================================================= | ||
773 | */ | ||
774 | |||
775 | /* | ||
776 | ** If possible, shrink string table | ||
777 | */ | ||
778 | static void checkSizes (lua_State *L, global_State *g) { | ||
779 | if (g->gckind != KGC_EMERGENCY) { | ||
780 | l_mem olddebt = g->GCdebt; | ||
781 | if (g->strt.nuse < g->strt.size / 4) /* string table too big? */ | ||
782 | luaS_resize(L, g->strt.size / 2); /* shrink it a little */ | ||
783 | g->GCestimate += g->GCdebt - olddebt; /* update estimate */ | ||
784 | } | ||
785 | } | ||
786 | |||
787 | |||
788 | static GCObject *udata2finalize (global_State *g) { | ||
789 | GCObject *o = g->tobefnz; /* get first element */ | ||
790 | lua_assert(tofinalize(o)); | ||
791 | g->tobefnz = o->next; /* remove it from 'tobefnz' list */ | ||
792 | o->next = g->allgc; /* return it to 'allgc' list */ | ||
793 | g->allgc = o; | ||
794 | resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ | ||
795 | if (issweepphase(g)) | ||
796 | makewhite(g, o); /* "sweep" object */ | ||
797 | return o; | ||
798 | } | ||
799 | |||
800 | |||
801 | static void dothecall (lua_State *L, void *ud) { | ||
802 | UNUSED(ud); | ||
803 | luaD_callnoyield(L, L->top - 2, 0); | ||
804 | } | ||
805 | |||
806 | |||
807 | static void GCTM (lua_State *L, int propagateerrors) { | ||
808 | global_State *g = G(L); | ||
809 | const TValue *tm; | ||
810 | TValue v; | ||
811 | setgcovalue(L, &v, udata2finalize(g)); | ||
812 | tm = luaT_gettmbyobj(L, &v, TM_GC); | ||
813 | if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ | ||
814 | int status; | ||
815 | lu_byte oldah = L->allowhook; | ||
816 | int running = g->gcrunning; | ||
817 | L->allowhook = 0; /* stop debug hooks during GC metamethod */ | ||
818 | g->gcrunning = 0; /* avoid GC steps */ | ||
819 | setobj2s(L, L->top, tm); /* push finalizer... */ | ||
820 | setobj2s(L, L->top + 1, &v); /* ... and its argument */ | ||
821 | L->top += 2; /* and (next line) call the finalizer */ | ||
822 | L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ | ||
823 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); | ||
824 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ | ||
825 | L->allowhook = oldah; /* restore hooks */ | ||
826 | g->gcrunning = running; /* restore state */ | ||
827 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ | ||
828 | if (status == LUA_ERRRUN) { /* is there an error object? */ | ||
829 | const char *msg = (ttisstring(L->top - 1)) | ||
830 | ? svalue(L->top - 1) | ||
831 | : "no message"; | ||
832 | luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); | ||
833 | status = LUA_ERRGCMM; /* error in __gc metamethod */ | ||
834 | } | ||
835 | luaD_throw(L, status); /* re-throw error */ | ||
836 | } | ||
837 | } | ||
838 | } | ||
839 | |||
840 | |||
841 | /* | ||
842 | ** call a few (up to 'g->gcfinnum') finalizers | ||
843 | */ | ||
844 | static int runafewfinalizers (lua_State *L) { | ||
845 | global_State *g = G(L); | ||
846 | unsigned int i; | ||
847 | lua_assert(!g->tobefnz || g->gcfinnum > 0); | ||
848 | for (i = 0; g->tobefnz && i < g->gcfinnum; i++) | ||
849 | GCTM(L, 1); /* call one finalizer */ | ||
850 | g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */ | ||
851 | : g->gcfinnum * 2; /* else call a few more next time */ | ||
852 | return i; | ||
853 | } | ||
854 | |||
855 | |||
856 | /* | ||
857 | ** call all pending finalizers | ||
858 | */ | ||
859 | static void callallpendingfinalizers (lua_State *L) { | ||
860 | global_State *g = G(L); | ||
861 | while (g->tobefnz) | ||
862 | GCTM(L, 0); | ||
863 | } | ||
864 | |||
865 | |||
866 | /* | ||
867 | ** find last 'next' field in list 'p' list (to add elements in its end) | ||
868 | */ | ||
869 | static GCObject **findlast (GCObject **p) { | ||
870 | while (*p != NULL) | ||
871 | p = &(*p)->next; | ||
872 | return p; | ||
873 | } | ||
874 | |||
875 | |||
876 | /* | ||
877 | ** move all unreachable objects (or 'all' objects) that need | ||
878 | ** finalization from list 'finobj' to list 'tobefnz' (to be finalized) | ||
879 | */ | ||
880 | static void separatetobefnz (global_State *g, int all) { | ||
881 | GCObject *curr; | ||
882 | GCObject **p = &g->finobj; | ||
883 | GCObject **lastnext = findlast(&g->tobefnz); | ||
884 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ | ||
885 | lua_assert(tofinalize(curr)); | ||
886 | if (!(iswhite(curr) || all)) /* not being collected? */ | ||
887 | p = &curr->next; /* don't bother with it */ | ||
888 | else { | ||
889 | *p = curr->next; /* remove 'curr' from 'finobj' list */ | ||
890 | curr->next = *lastnext; /* link at the end of 'tobefnz' list */ | ||
891 | *lastnext = curr; | ||
892 | lastnext = &curr->next; | ||
893 | } | ||
894 | } | ||
895 | } | ||
896 | |||
897 | |||
898 | /* | ||
899 | ** if object 'o' has a finalizer, remove it from 'allgc' list (must | ||
900 | ** search the list to find it) and link it in 'finobj' list. | ||
901 | */ | ||
902 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | ||
903 | global_State *g = G(L); | ||
904 | if (tofinalize(o) || /* obj. is already marked... */ | ||
905 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ | ||
906 | return; /* nothing to be done */ | ||
907 | else { /* move 'o' to 'finobj' list */ | ||
908 | GCObject **p; | ||
909 | if (issweepphase(g)) { | ||
910 | makewhite(g, o); /* "sweep" object 'o' */ | ||
911 | if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ | ||
912 | g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ | ||
913 | } | ||
914 | /* search for pointer pointing to 'o' */ | ||
915 | for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } | ||
916 | *p = o->next; /* remove 'o' from 'allgc' list */ | ||
917 | o->next = g->finobj; /* link it in 'finobj' list */ | ||
918 | g->finobj = o; | ||
919 | l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ | ||
920 | } | ||
921 | } | ||
922 | |||
923 | /* }====================================================== */ | ||
924 | |||
925 | |||
926 | |||
927 | /* | ||
928 | ** {====================================================== | ||
929 | ** GC control | ||
930 | ** ======================================================= | ||
931 | */ | ||
932 | |||
933 | |||
934 | /* | ||
935 | ** Set a reasonable "time" to wait before starting a new GC cycle; cycle | ||
936 | ** will start when memory use hits threshold. (Division by 'estimate' | ||
937 | ** should be OK: it cannot be zero (because Lua cannot even start with | ||
938 | ** less than PAUSEADJ bytes). | ||
939 | */ | ||
940 | static void setpause (global_State *g) { | ||
941 | l_mem threshold, debt; | ||
942 | l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ | ||
943 | lua_assert(estimate > 0); | ||
944 | threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ | ||
945 | ? estimate * g->gcpause /* no overflow */ | ||
946 | : MAX_LMEM; /* overflow; truncate to maximum */ | ||
947 | debt = gettotalbytes(g) - threshold; | ||
948 | luaE_setdebt(g, debt); | ||
949 | } | ||
950 | |||
951 | |||
952 | /* | ||
953 | ** Enter first sweep phase. | ||
954 | ** The call to 'sweeplist' tries to make pointer point to an object | ||
955 | ** inside the list (instead of to the header), so that the real sweep do | ||
956 | ** not need to skip objects created between "now" and the start of the | ||
957 | ** real sweep. | ||
958 | */ | ||
959 | static void entersweep (lua_State *L) { | ||
960 | global_State *g = G(L); | ||
961 | g->gcstate = GCSswpallgc; | ||
962 | lua_assert(g->sweepgc == NULL); | ||
963 | g->sweepgc = sweeplist(L, &g->allgc, 1); | ||
964 | } | ||
965 | |||
966 | |||
967 | void luaC_freeallobjects (lua_State *L) { | ||
968 | global_State *g = G(L); | ||
969 | separatetobefnz(g, 1); /* separate all objects with finalizers */ | ||
970 | lua_assert(g->finobj == NULL); | ||
971 | callallpendingfinalizers(L); | ||
972 | lua_assert(g->tobefnz == NULL); | ||
973 | g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ | ||
974 | g->gckind = KGC_NORMAL; | ||
975 | sweepwholelist(L, &g->finobj); | ||
976 | sweepwholelist(L, &g->allgc); | ||
977 | sweepwholelist(L, &g->fixedgc); /* collect fixed objects */ | ||
978 | lua_assert(g->strt.nuse == 0); | ||
979 | } | ||
980 | |||
981 | |||
982 | static l_mem atomic (lua_State *L) { | ||
983 | global_State *g = G(L); | ||
984 | l_mem work; | ||
985 | GCObject *origweak, *origall; | ||
986 | GCObject *grayagain = g->grayagain; /* save original list */ | ||
987 | lua_assert(g->ephemeron == NULL && g->weak == NULL); | ||
988 | lua_assert(!iswhite(g->mainthread)); | ||
989 | g->gcstate = GCSinsideatomic; | ||
990 | g->GCmemtrav = 0; /* start counting work */ | ||
991 | markobject(g, L); /* mark running thread */ | ||
992 | /* registry and global metatables may be changed by API */ | ||
993 | markvalue(g, &g->l_registry); | ||
994 | markmt(g); /* mark global metatables */ | ||
995 | /* remark occasional upvalues of (maybe) dead threads */ | ||
996 | remarkupvals(g); | ||
997 | propagateall(g); /* propagate changes */ | ||
998 | work = g->GCmemtrav; /* stop counting (do not recount 'grayagain') */ | ||
999 | g->gray = grayagain; | ||
1000 | propagateall(g); /* traverse 'grayagain' list */ | ||
1001 | g->GCmemtrav = 0; /* restart counting */ | ||
1002 | convergeephemerons(g); | ||
1003 | /* at this point, all strongly accessible objects are marked. */ | ||
1004 | /* Clear values from weak tables, before checking finalizers */ | ||
1005 | clearvalues(g, g->weak, NULL); | ||
1006 | clearvalues(g, g->allweak, NULL); | ||
1007 | origweak = g->weak; origall = g->allweak; | ||
1008 | work += g->GCmemtrav; /* stop counting (objects being finalized) */ | ||
1009 | separatetobefnz(g, 0); /* separate objects to be finalized */ | ||
1010 | g->gcfinnum = 1; /* there may be objects to be finalized */ | ||
1011 | markbeingfnz(g); /* mark objects that will be finalized */ | ||
1012 | propagateall(g); /* remark, to propagate 'resurrection' */ | ||
1013 | g->GCmemtrav = 0; /* restart counting */ | ||
1014 | convergeephemerons(g); | ||
1015 | /* at this point, all resurrected objects are marked. */ | ||
1016 | /* remove dead objects from weak tables */ | ||
1017 | clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ | ||
1018 | clearkeys(g, g->allweak, NULL); /* clear keys from all 'allweak' tables */ | ||
1019 | /* clear values from resurrected weak tables */ | ||
1020 | clearvalues(g, g->weak, origweak); | ||
1021 | clearvalues(g, g->allweak, origall); | ||
1022 | luaS_clearcache(g); | ||
1023 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | ||
1024 | work += g->GCmemtrav; /* complete counting */ | ||
1025 | return work; /* estimate of memory marked by 'atomic' */ | ||
1026 | } | ||
1027 | |||
1028 | |||
1029 | static lu_mem sweepstep (lua_State *L, global_State *g, | ||
1030 | int nextstate, GCObject **nextlist) { | ||
1031 | if (g->sweepgc) { | ||
1032 | l_mem olddebt = g->GCdebt; | ||
1033 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | ||
1034 | g->GCestimate += g->GCdebt - olddebt; /* update estimate */ | ||
1035 | if (g->sweepgc) /* is there still something to sweep? */ | ||
1036 | return (GCSWEEPMAX * GCSWEEPCOST); | ||
1037 | } | ||
1038 | /* else enter next state */ | ||
1039 | g->gcstate = nextstate; | ||
1040 | g->sweepgc = nextlist; | ||
1041 | return 0; | ||
1042 | } | ||
1043 | |||
1044 | |||
1045 | static lu_mem singlestep (lua_State *L) { | ||
1046 | global_State *g = G(L); | ||
1047 | switch (g->gcstate) { | ||
1048 | case GCSpause: { | ||
1049 | g->GCmemtrav = g->strt.size * sizeof(GCObject*); | ||
1050 | restartcollection(g); | ||
1051 | g->gcstate = GCSpropagate; | ||
1052 | return g->GCmemtrav; | ||
1053 | } | ||
1054 | case GCSpropagate: { | ||
1055 | g->GCmemtrav = 0; | ||
1056 | lua_assert(g->gray); | ||
1057 | propagatemark(g); | ||
1058 | if (g->gray == NULL) /* no more gray objects? */ | ||
1059 | g->gcstate = GCSatomic; /* finish propagate phase */ | ||
1060 | return g->GCmemtrav; /* memory traversed in this step */ | ||
1061 | } | ||
1062 | case GCSatomic: { | ||
1063 | lu_mem work; | ||
1064 | propagateall(g); /* make sure gray list is empty */ | ||
1065 | work = atomic(L); /* work is what was traversed by 'atomic' */ | ||
1066 | entersweep(L); | ||
1067 | g->GCestimate = gettotalbytes(g); /* first estimate */; | ||
1068 | return work; | ||
1069 | } | ||
1070 | case GCSswpallgc: { /* sweep "regular" objects */ | ||
1071 | return sweepstep(L, g, GCSswpfinobj, &g->finobj); | ||
1072 | } | ||
1073 | case GCSswpfinobj: { /* sweep objects with finalizers */ | ||
1074 | return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); | ||
1075 | } | ||
1076 | case GCSswptobefnz: { /* sweep objects to be finalized */ | ||
1077 | return sweepstep(L, g, GCSswpend, NULL); | ||
1078 | } | ||
1079 | case GCSswpend: { /* finish sweeps */ | ||
1080 | makewhite(g, g->mainthread); /* sweep main thread */ | ||
1081 | checkSizes(L, g); | ||
1082 | g->gcstate = GCScallfin; | ||
1083 | return 0; | ||
1084 | } | ||
1085 | case GCScallfin: { /* call remaining finalizers */ | ||
1086 | if (g->tobefnz && g->gckind != KGC_EMERGENCY) { | ||
1087 | int n = runafewfinalizers(L); | ||
1088 | return (n * GCFINALIZECOST); | ||
1089 | } | ||
1090 | else { /* emergency mode or no more finalizers */ | ||
1091 | g->gcstate = GCSpause; /* finish collection */ | ||
1092 | return 0; | ||
1093 | } | ||
1094 | } | ||
1095 | default: lua_assert(0); return 0; | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | |||
1100 | /* | ||
1101 | ** advances the garbage collector until it reaches a state allowed | ||
1102 | ** by 'statemask' | ||
1103 | */ | ||
1104 | void luaC_runtilstate (lua_State *L, int statesmask) { | ||
1105 | global_State *g = G(L); | ||
1106 | while (!testbit(statesmask, g->gcstate)) | ||
1107 | singlestep(L); | ||
1108 | } | ||
1109 | |||
1110 | |||
1111 | /* | ||
1112 | ** get GC debt and convert it from Kb to 'work units' (avoid zero debt | ||
1113 | ** and overflows) | ||
1114 | */ | ||
1115 | static l_mem getdebt (global_State *g) { | ||
1116 | l_mem debt = g->GCdebt; | ||
1117 | int stepmul = g->gcstepmul; | ||
1118 | if (debt <= 0) return 0; /* minimal debt */ | ||
1119 | else { | ||
1120 | debt = (debt / STEPMULADJ) + 1; | ||
1121 | debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; | ||
1122 | return debt; | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | /* | ||
1127 | ** performs a basic GC step when collector is running | ||
1128 | */ | ||
1129 | void luaC_step (lua_State *L) { | ||
1130 | global_State *g = G(L); | ||
1131 | l_mem debt = getdebt(g); /* GC deficit (be paid now) */ | ||
1132 | if (!g->gcrunning) { /* not running? */ | ||
1133 | luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */ | ||
1134 | return; | ||
1135 | } | ||
1136 | do { /* repeat until pause or enough "credit" (negative debt) */ | ||
1137 | lu_mem work = singlestep(L); /* perform one single step */ | ||
1138 | debt -= work; | ||
1139 | } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); | ||
1140 | if (g->gcstate == GCSpause) | ||
1141 | setpause(g); /* pause until next cycle */ | ||
1142 | else { | ||
1143 | debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */ | ||
1144 | luaE_setdebt(g, debt); | ||
1145 | runafewfinalizers(L); | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | |||
1150 | /* | ||
1151 | ** Performs a full GC cycle; if 'isemergency', set a flag to avoid | ||
1152 | ** some operations which could change the interpreter state in some | ||
1153 | ** unexpected ways (running finalizers and shrinking some structures). | ||
1154 | ** Before running the collection, check 'keepinvariant'; if it is true, | ||
1155 | ** there may be some objects marked as black, so the collector has | ||
1156 | ** to sweep all objects to turn them back to white (as white has not | ||
1157 | ** changed, nothing will be collected). | ||
1158 | */ | ||
1159 | void luaC_fullgc (lua_State *L, int isemergency) { | ||
1160 | global_State *g = G(L); | ||
1161 | lua_assert(g->gckind == KGC_NORMAL); | ||
1162 | if (isemergency) g->gckind = KGC_EMERGENCY; /* set flag */ | ||
1163 | if (keepinvariant(g)) { /* black objects? */ | ||
1164 | entersweep(L); /* sweep everything to turn them back to white */ | ||
1165 | } | ||
1166 | /* finish any pending sweep phase to start a new cycle */ | ||
1167 | luaC_runtilstate(L, bitmask(GCSpause)); | ||
1168 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ | ||
1169 | luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ | ||
1170 | /* estimate must be correct after a full GC cycle */ | ||
1171 | lua_assert(g->GCestimate == gettotalbytes(g)); | ||
1172 | luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ | ||
1173 | g->gckind = KGC_NORMAL; | ||
1174 | setpause(g); | ||
1175 | } | ||
1176 | |||
1177 | /* }====================================================== */ | ||
1178 | |||
1179 | |||
diff --git a/src/lua-5.3/license.txt b/src/lua-5.3/license.txt deleted file mode 100644 index 5049d14..0000000 --- a/src/lua-5.3/license.txt +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | Copyright © 1994–2019 Lua.org, PUC-Rio. | ||
2 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
3 | |||
4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
5 | |||
6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/src/lua-5.3/lmathlib.c b/src/lua-5.3/lmathlib.c deleted file mode 100644 index 7ef7e59..0000000 --- a/src/lua-5.3/lmathlib.c +++ /dev/null | |||
@@ -1,410 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Standard mathematical library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lmathlib_c | ||
8 | #define LUA_LIB | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stdlib.h> | ||
14 | #include <math.h> | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "lauxlib.h" | ||
19 | #include "lualib.h" | ||
20 | |||
21 | |||
22 | #undef PI | ||
23 | #define PI (l_mathop(3.141592653589793238462643383279502884)) | ||
24 | |||
25 | |||
26 | #if !defined(l_rand) /* { */ | ||
27 | #if defined(LUA_USE_POSIX) | ||
28 | #define l_rand() random() | ||
29 | #define l_srand(x) srandom(x) | ||
30 | #define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */ | ||
31 | #else | ||
32 | #define l_rand() rand() | ||
33 | #define l_srand(x) srand(x) | ||
34 | #define L_RANDMAX RAND_MAX | ||
35 | #endif | ||
36 | #endif /* } */ | ||
37 | |||
38 | |||
39 | static int math_abs (lua_State *L) { | ||
40 | if (lua_isinteger(L, 1)) { | ||
41 | lua_Integer n = lua_tointeger(L, 1); | ||
42 | if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); | ||
43 | lua_pushinteger(L, n); | ||
44 | } | ||
45 | else | ||
46 | lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | static int math_sin (lua_State *L) { | ||
51 | lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); | ||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | static int math_cos (lua_State *L) { | ||
56 | lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); | ||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | static int math_tan (lua_State *L) { | ||
61 | lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); | ||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | static int math_asin (lua_State *L) { | ||
66 | lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); | ||
67 | return 1; | ||
68 | } | ||
69 | |||
70 | static int math_acos (lua_State *L) { | ||
71 | lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); | ||
72 | return 1; | ||
73 | } | ||
74 | |||
75 | static int math_atan (lua_State *L) { | ||
76 | lua_Number y = luaL_checknumber(L, 1); | ||
77 | lua_Number x = luaL_optnumber(L, 2, 1); | ||
78 | lua_pushnumber(L, l_mathop(atan2)(y, x)); | ||
79 | return 1; | ||
80 | } | ||
81 | |||
82 | |||
83 | static int math_toint (lua_State *L) { | ||
84 | int valid; | ||
85 | lua_Integer n = lua_tointegerx(L, 1, &valid); | ||
86 | if (valid) | ||
87 | lua_pushinteger(L, n); | ||
88 | else { | ||
89 | luaL_checkany(L, 1); | ||
90 | lua_pushnil(L); /* value is not convertible to integer */ | ||
91 | } | ||
92 | return 1; | ||
93 | } | ||
94 | |||
95 | |||
96 | static void pushnumint (lua_State *L, lua_Number d) { | ||
97 | lua_Integer n; | ||
98 | if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ | ||
99 | lua_pushinteger(L, n); /* result is integer */ | ||
100 | else | ||
101 | lua_pushnumber(L, d); /* result is float */ | ||
102 | } | ||
103 | |||
104 | |||
105 | static int math_floor (lua_State *L) { | ||
106 | if (lua_isinteger(L, 1)) | ||
107 | lua_settop(L, 1); /* integer is its own floor */ | ||
108 | else { | ||
109 | lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); | ||
110 | pushnumint(L, d); | ||
111 | } | ||
112 | return 1; | ||
113 | } | ||
114 | |||
115 | |||
116 | static int math_ceil (lua_State *L) { | ||
117 | if (lua_isinteger(L, 1)) | ||
118 | lua_settop(L, 1); /* integer is its own ceil */ | ||
119 | else { | ||
120 | lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); | ||
121 | pushnumint(L, d); | ||
122 | } | ||
123 | return 1; | ||
124 | } | ||
125 | |||
126 | |||
127 | static int math_fmod (lua_State *L) { | ||
128 | if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { | ||
129 | lua_Integer d = lua_tointeger(L, 2); | ||
130 | if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ | ||
131 | luaL_argcheck(L, d != 0, 2, "zero"); | ||
132 | lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ | ||
133 | } | ||
134 | else | ||
135 | lua_pushinteger(L, lua_tointeger(L, 1) % d); | ||
136 | } | ||
137 | else | ||
138 | lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), | ||
139 | luaL_checknumber(L, 2))); | ||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | |||
144 | /* | ||
145 | ** next function does not use 'modf', avoiding problems with 'double*' | ||
146 | ** (which is not compatible with 'float*') when lua_Number is not | ||
147 | ** 'double'. | ||
148 | */ | ||
149 | static int math_modf (lua_State *L) { | ||
150 | if (lua_isinteger(L ,1)) { | ||
151 | lua_settop(L, 1); /* number is its own integer part */ | ||
152 | lua_pushnumber(L, 0); /* no fractional part */ | ||
153 | } | ||
154 | else { | ||
155 | lua_Number n = luaL_checknumber(L, 1); | ||
156 | /* integer part (rounds toward zero) */ | ||
157 | lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); | ||
158 | pushnumint(L, ip); | ||
159 | /* fractional part (test needed for inf/-inf) */ | ||
160 | lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); | ||
161 | } | ||
162 | return 2; | ||
163 | } | ||
164 | |||
165 | |||
166 | static int math_sqrt (lua_State *L) { | ||
167 | lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); | ||
168 | return 1; | ||
169 | } | ||
170 | |||
171 | |||
172 | static int math_ult (lua_State *L) { | ||
173 | lua_Integer a = luaL_checkinteger(L, 1); | ||
174 | lua_Integer b = luaL_checkinteger(L, 2); | ||
175 | lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | static int math_log (lua_State *L) { | ||
180 | lua_Number x = luaL_checknumber(L, 1); | ||
181 | lua_Number res; | ||
182 | if (lua_isnoneornil(L, 2)) | ||
183 | res = l_mathop(log)(x); | ||
184 | else { | ||
185 | lua_Number base = luaL_checknumber(L, 2); | ||
186 | #if !defined(LUA_USE_C89) | ||
187 | if (base == l_mathop(2.0)) | ||
188 | res = l_mathop(log2)(x); else | ||
189 | #endif | ||
190 | if (base == l_mathop(10.0)) | ||
191 | res = l_mathop(log10)(x); | ||
192 | else | ||
193 | res = l_mathop(log)(x)/l_mathop(log)(base); | ||
194 | } | ||
195 | lua_pushnumber(L, res); | ||
196 | return 1; | ||
197 | } | ||
198 | |||
199 | static int math_exp (lua_State *L) { | ||
200 | lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); | ||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | static int math_deg (lua_State *L) { | ||
205 | lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); | ||
206 | return 1; | ||
207 | } | ||
208 | |||
209 | static int math_rad (lua_State *L) { | ||
210 | lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); | ||
211 | return 1; | ||
212 | } | ||
213 | |||
214 | |||
215 | static int math_min (lua_State *L) { | ||
216 | int n = lua_gettop(L); /* number of arguments */ | ||
217 | int imin = 1; /* index of current minimum value */ | ||
218 | int i; | ||
219 | luaL_argcheck(L, n >= 1, 1, "value expected"); | ||
220 | for (i = 2; i <= n; i++) { | ||
221 | if (lua_compare(L, i, imin, LUA_OPLT)) | ||
222 | imin = i; | ||
223 | } | ||
224 | lua_pushvalue(L, imin); | ||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | |||
229 | static int math_max (lua_State *L) { | ||
230 | int n = lua_gettop(L); /* number of arguments */ | ||
231 | int imax = 1; /* index of current maximum value */ | ||
232 | int i; | ||
233 | luaL_argcheck(L, n >= 1, 1, "value expected"); | ||
234 | for (i = 2; i <= n; i++) { | ||
235 | if (lua_compare(L, imax, i, LUA_OPLT)) | ||
236 | imax = i; | ||
237 | } | ||
238 | lua_pushvalue(L, imax); | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | ** This function uses 'double' (instead of 'lua_Number') to ensure that | ||
244 | ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0' | ||
245 | ** will keep full precision (ensuring that 'r' is always less than 1.0.) | ||
246 | */ | ||
247 | static int math_random (lua_State *L) { | ||
248 | lua_Integer low, up; | ||
249 | double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0)); | ||
250 | switch (lua_gettop(L)) { /* check number of arguments */ | ||
251 | case 0: { /* no arguments */ | ||
252 | lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */ | ||
253 | return 1; | ||
254 | } | ||
255 | case 1: { /* only upper limit */ | ||
256 | low = 1; | ||
257 | up = luaL_checkinteger(L, 1); | ||
258 | break; | ||
259 | } | ||
260 | case 2: { /* lower and upper limits */ | ||
261 | low = luaL_checkinteger(L, 1); | ||
262 | up = luaL_checkinteger(L, 2); | ||
263 | break; | ||
264 | } | ||
265 | default: return luaL_error(L, "wrong number of arguments"); | ||
266 | } | ||
267 | /* random integer in the interval [low, up] */ | ||
268 | luaL_argcheck(L, low <= up, 1, "interval is empty"); | ||
269 | luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, | ||
270 | "interval too large"); | ||
271 | r *= (double)(up - low) + 1.0; | ||
272 | lua_pushinteger(L, (lua_Integer)r + low); | ||
273 | return 1; | ||
274 | } | ||
275 | |||
276 | |||
277 | static int math_randomseed (lua_State *L) { | ||
278 | l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1)); | ||
279 | (void)l_rand(); /* discard first value to avoid undesirable correlations */ | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | |||
284 | static int math_type (lua_State *L) { | ||
285 | if (lua_type(L, 1) == LUA_TNUMBER) { | ||
286 | if (lua_isinteger(L, 1)) | ||
287 | lua_pushliteral(L, "integer"); | ||
288 | else | ||
289 | lua_pushliteral(L, "float"); | ||
290 | } | ||
291 | else { | ||
292 | luaL_checkany(L, 1); | ||
293 | lua_pushnil(L); | ||
294 | } | ||
295 | return 1; | ||
296 | } | ||
297 | |||
298 | |||
299 | /* | ||
300 | ** {================================================================== | ||
301 | ** Deprecated functions (for compatibility only) | ||
302 | ** =================================================================== | ||
303 | */ | ||
304 | #if defined(LUA_COMPAT_MATHLIB) | ||
305 | |||
306 | static int math_cosh (lua_State *L) { | ||
307 | lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); | ||
308 | return 1; | ||
309 | } | ||
310 | |||
311 | static int math_sinh (lua_State *L) { | ||
312 | lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); | ||
313 | return 1; | ||
314 | } | ||
315 | |||
316 | static int math_tanh (lua_State *L) { | ||
317 | lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); | ||
318 | return 1; | ||
319 | } | ||
320 | |||
321 | static int math_pow (lua_State *L) { | ||
322 | lua_Number x = luaL_checknumber(L, 1); | ||
323 | lua_Number y = luaL_checknumber(L, 2); | ||
324 | lua_pushnumber(L, l_mathop(pow)(x, y)); | ||
325 | return 1; | ||
326 | } | ||
327 | |||
328 | static int math_frexp (lua_State *L) { | ||
329 | int e; | ||
330 | lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); | ||
331 | lua_pushinteger(L, e); | ||
332 | return 2; | ||
333 | } | ||
334 | |||
335 | static int math_ldexp (lua_State *L) { | ||
336 | lua_Number x = luaL_checknumber(L, 1); | ||
337 | int ep = (int)luaL_checkinteger(L, 2); | ||
338 | lua_pushnumber(L, l_mathop(ldexp)(x, ep)); | ||
339 | return 1; | ||
340 | } | ||
341 | |||
342 | static int math_log10 (lua_State *L) { | ||
343 | lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); | ||
344 | return 1; | ||
345 | } | ||
346 | |||
347 | #endif | ||
348 | /* }================================================================== */ | ||
349 | |||
350 | |||
351 | |||
352 | static const luaL_Reg mathlib[] = { | ||
353 | {"abs", math_abs}, | ||
354 | {"acos", math_acos}, | ||
355 | {"asin", math_asin}, | ||
356 | {"atan", math_atan}, | ||
357 | {"ceil", math_ceil}, | ||
358 | {"cos", math_cos}, | ||
359 | {"deg", math_deg}, | ||
360 | {"exp", math_exp}, | ||
361 | {"tointeger", math_toint}, | ||
362 | {"floor", math_floor}, | ||
363 | {"fmod", math_fmod}, | ||
364 | {"ult", math_ult}, | ||
365 | {"log", math_log}, | ||
366 | {"max", math_max}, | ||
367 | {"min", math_min}, | ||
368 | {"modf", math_modf}, | ||
369 | {"rad", math_rad}, | ||
370 | {"random", math_random}, | ||
371 | {"randomseed", math_randomseed}, | ||
372 | {"sin", math_sin}, | ||
373 | {"sqrt", math_sqrt}, | ||
374 | {"tan", math_tan}, | ||
375 | {"type", math_type}, | ||
376 | #if defined(LUA_COMPAT_MATHLIB) | ||
377 | {"atan2", math_atan}, | ||
378 | {"cosh", math_cosh}, | ||
379 | {"sinh", math_sinh}, | ||
380 | {"tanh", math_tanh}, | ||
381 | {"pow", math_pow}, | ||
382 | {"frexp", math_frexp}, | ||
383 | {"ldexp", math_ldexp}, | ||
384 | {"log10", math_log10}, | ||
385 | #endif | ||
386 | /* placeholders */ | ||
387 | {"pi", NULL}, | ||
388 | {"huge", NULL}, | ||
389 | {"maxinteger", NULL}, | ||
390 | {"mininteger", NULL}, | ||
391 | {NULL, NULL} | ||
392 | }; | ||
393 | |||
394 | |||
395 | /* | ||
396 | ** Open math library | ||
397 | */ | ||
398 | LUAMOD_API int luaopen_math (lua_State *L) { | ||
399 | luaL_newlib(L, mathlib); | ||
400 | lua_pushnumber(L, PI); | ||
401 | lua_setfield(L, -2, "pi"); | ||
402 | lua_pushnumber(L, (lua_Number)HUGE_VAL); | ||
403 | lua_setfield(L, -2, "huge"); | ||
404 | lua_pushinteger(L, LUA_MAXINTEGER); | ||
405 | lua_setfield(L, -2, "maxinteger"); | ||
406 | lua_pushinteger(L, LUA_MININTEGER); | ||
407 | lua_setfield(L, -2, "mininteger"); | ||
408 | return 1; | ||
409 | } | ||
410 | |||
diff --git a/src/lua-5.3/lmem.c b/src/lua-5.3/lmem.c deleted file mode 100644 index 0241cc3..0000000 --- a/src/lua-5.3/lmem.c +++ /dev/null | |||
@@ -1,100 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Interface to Memory Manager | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lmem_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stddef.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lgc.h" | ||
20 | #include "lmem.h" | ||
21 | #include "lobject.h" | ||
22 | #include "lstate.h" | ||
23 | |||
24 | |||
25 | |||
26 | /* | ||
27 | ** About the realloc function: | ||
28 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); | ||
29 | ** ('osize' is the old size, 'nsize' is the new size) | ||
30 | ** | ||
31 | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no | ||
32 | ** matter 'x'). | ||
33 | ** | ||
34 | ** * frealloc(ud, p, x, 0) frees the block 'p' | ||
35 | ** (in this specific case, frealloc must return NULL); | ||
36 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing | ||
37 | ** (which is equivalent to free(NULL) in ISO C) | ||
38 | ** | ||
39 | ** frealloc returns NULL if it cannot create or reallocate the area | ||
40 | ** (any reallocation to an equal or smaller size cannot fail!) | ||
41 | */ | ||
42 | |||
43 | |||
44 | |||
45 | #define MINSIZEARRAY 4 | ||
46 | |||
47 | |||
48 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, | ||
49 | int limit, const char *what) { | ||
50 | void *newblock; | ||
51 | int newsize; | ||
52 | if (*size >= limit/2) { /* cannot double it? */ | ||
53 | if (*size >= limit) /* cannot grow even a little? */ | ||
54 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); | ||
55 | newsize = limit; /* still have at least one free place */ | ||
56 | } | ||
57 | else { | ||
58 | newsize = (*size)*2; | ||
59 | if (newsize < MINSIZEARRAY) | ||
60 | newsize = MINSIZEARRAY; /* minimum size */ | ||
61 | } | ||
62 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); | ||
63 | *size = newsize; /* update only when everything else is OK */ | ||
64 | return newblock; | ||
65 | } | ||
66 | |||
67 | |||
68 | l_noret luaM_toobig (lua_State *L) { | ||
69 | luaG_runerror(L, "memory allocation error: block too big"); | ||
70 | } | ||
71 | |||
72 | |||
73 | |||
74 | /* | ||
75 | ** generic allocation routine. | ||
76 | */ | ||
77 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { | ||
78 | void *newblock; | ||
79 | global_State *g = G(L); | ||
80 | size_t realosize = (block) ? osize : 0; | ||
81 | lua_assert((realosize == 0) == (block == NULL)); | ||
82 | #if defined(HARDMEMTESTS) | ||
83 | if (nsize > realosize && g->gcrunning) | ||
84 | luaC_fullgc(L, 1); /* force a GC whenever possible */ | ||
85 | #endif | ||
86 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); | ||
87 | if (newblock == NULL && nsize > 0) { | ||
88 | lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ | ||
89 | if (g->version) { /* is state fully built? */ | ||
90 | luaC_fullgc(L, 1); /* try to free some memory... */ | ||
91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ | ||
92 | } | ||
93 | if (newblock == NULL) | ||
94 | luaD_throw(L, LUA_ERRMEM); | ||
95 | } | ||
96 | lua_assert((nsize == 0) == (newblock == NULL)); | ||
97 | g->GCdebt = (g->GCdebt + nsize) - realosize; | ||
98 | return newblock; | ||
99 | } | ||
100 | |||
diff --git a/src/lua-5.3/lmem.h b/src/lua-5.3/lmem.h deleted file mode 100644 index 357b1e4..0000000 --- a/src/lua-5.3/lmem.h +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Interface to Memory Manager | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lmem_h | ||
8 | #define lmem_h | ||
9 | |||
10 | |||
11 | #include <stddef.h> | ||
12 | |||
13 | #include "llimits.h" | ||
14 | #include "lua.h" | ||
15 | |||
16 | |||
17 | /* | ||
18 | ** This macro reallocs a vector 'b' from 'on' to 'n' elements, where | ||
19 | ** each element has size 'e'. In case of arithmetic overflow of the | ||
20 | ** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because | ||
21 | ** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). | ||
22 | ** | ||
23 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' | ||
24 | ** comparison avoids a runtime comparison when overflow cannot occur. | ||
25 | ** The compiler should be able to optimize the real test by itself, but | ||
26 | ** when it does it, it may give a warning about "comparison is always | ||
27 | ** false due to limited range of data type"; the +1 tricks the compiler, | ||
28 | ** avoiding this warning but also this optimization.) | ||
29 | */ | ||
30 | #define luaM_reallocv(L,b,on,n,e) \ | ||
31 | (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ | ||
32 | ? luaM_toobig(L) : cast_void(0)) , \ | ||
33 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) | ||
34 | |||
35 | /* | ||
36 | ** Arrays of chars do not need any test | ||
37 | */ | ||
38 | #define luaM_reallocvchar(L,b,on,n) \ | ||
39 | cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) | ||
40 | |||
41 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) | ||
42 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) | ||
43 | #define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) | ||
44 | |||
45 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) | ||
46 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) | ||
47 | #define luaM_newvector(L,n,t) \ | ||
48 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) | ||
49 | |||
50 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) | ||
51 | |||
52 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ | ||
53 | if ((nelems)+1 > (size)) \ | ||
54 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) | ||
55 | |||
56 | #define luaM_reallocvector(L, v,oldn,n,t) \ | ||
57 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) | ||
58 | |||
59 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); | ||
60 | |||
61 | /* not to be called directly */ | ||
62 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, | ||
63 | size_t size); | ||
64 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, | ||
65 | size_t size_elem, int limit, | ||
66 | const char *what); | ||
67 | |||
68 | #endif | ||
69 | |||
diff --git a/src/lua-5.3/lobject.h b/src/lua-5.3/lobject.h deleted file mode 100644 index 2408861..0000000 --- a/src/lua-5.3/lobject.h +++ /dev/null | |||
@@ -1,549 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lobject.h,v 2.117.1.1 2017/04/19 17:39:34 roberto Exp $ | ||
3 | ** Type definitions for Lua objects | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #ifndef lobject_h | ||
9 | #define lobject_h | ||
10 | |||
11 | |||
12 | #include <stdarg.h> | ||
13 | |||
14 | |||
15 | #include "llimits.h" | ||
16 | #include "lua.h" | ||
17 | |||
18 | |||
19 | /* | ||
20 | ** Extra tags for non-values | ||
21 | */ | ||
22 | #define LUA_TPROTO LUA_NUMTAGS /* function prototypes */ | ||
23 | #define LUA_TDEADKEY (LUA_NUMTAGS+1) /* removed keys in tables */ | ||
24 | |||
25 | /* | ||
26 | ** number of all possible tags (including LUA_TNONE but excluding DEADKEY) | ||
27 | */ | ||
28 | #define LUA_TOTALTAGS (LUA_TPROTO + 2) | ||
29 | |||
30 | |||
31 | /* | ||
32 | ** tags for Tagged Values have the following use of bits: | ||
33 | ** bits 0-3: actual tag (a LUA_T* value) | ||
34 | ** bits 4-5: variant bits | ||
35 | ** bit 6: whether value is collectable | ||
36 | */ | ||
37 | |||
38 | |||
39 | /* | ||
40 | ** LUA_TFUNCTION variants: | ||
41 | ** 0 - Lua function | ||
42 | ** 1 - light C function | ||
43 | ** 2 - regular C function (closure) | ||
44 | */ | ||
45 | |||
46 | /* Variant tags for functions */ | ||
47 | #define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ | ||
48 | #define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ | ||
49 | #define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ | ||
50 | |||
51 | |||
52 | /* Variant tags for strings */ | ||
53 | #define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ | ||
54 | #define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ | ||
55 | |||
56 | |||
57 | /* Variant tags for numbers */ | ||
58 | #define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */ | ||
59 | #define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */ | ||
60 | |||
61 | |||
62 | /* Bit mark for collectable types */ | ||
63 | #define BIT_ISCOLLECTABLE (1 << 6) | ||
64 | |||
65 | /* mark a tag as collectable */ | ||
66 | #define ctb(t) ((t) | BIT_ISCOLLECTABLE) | ||
67 | |||
68 | |||
69 | /* | ||
70 | ** Common type for all collectable objects | ||
71 | */ | ||
72 | typedef struct GCObject GCObject; | ||
73 | |||
74 | |||
75 | /* | ||
76 | ** Common Header for all collectable objects (in macro form, to be | ||
77 | ** included in other objects) | ||
78 | */ | ||
79 | #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked | ||
80 | |||
81 | |||
82 | /* | ||
83 | ** Common type has only the common header | ||
84 | */ | ||
85 | struct GCObject { | ||
86 | CommonHeader; | ||
87 | }; | ||
88 | |||
89 | |||
90 | |||
91 | |||
92 | /* | ||
93 | ** Tagged Values. This is the basic representation of values in Lua, | ||
94 | ** an actual value plus a tag with its type. | ||
95 | */ | ||
96 | |||
97 | /* | ||
98 | ** Union of all Lua values | ||
99 | */ | ||
100 | typedef union Value { | ||
101 | GCObject *gc; /* collectable objects */ | ||
102 | void *p; /* light userdata */ | ||
103 | int b; /* booleans */ | ||
104 | lua_CFunction f; /* light C functions */ | ||
105 | lua_Integer i; /* integer numbers */ | ||
106 | lua_Number n; /* float numbers */ | ||
107 | } Value; | ||
108 | |||
109 | |||
110 | #define TValuefields Value value_; int tt_ | ||
111 | |||
112 | |||
113 | typedef struct lua_TValue { | ||
114 | TValuefields; | ||
115 | } TValue; | ||
116 | |||
117 | |||
118 | |||
119 | /* macro defining a nil value */ | ||
120 | #define NILCONSTANT {NULL}, LUA_TNIL | ||
121 | |||
122 | |||
123 | #define val_(o) ((o)->value_) | ||
124 | |||
125 | |||
126 | /* raw type tag of a TValue */ | ||
127 | #define rttype(o) ((o)->tt_) | ||
128 | |||
129 | /* tag with no variants (bits 0-3) */ | ||
130 | #define novariant(x) ((x) & 0x0F) | ||
131 | |||
132 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ | ||
133 | #define ttype(o) (rttype(o) & 0x3F) | ||
134 | |||
135 | /* type tag of a TValue with no variants (bits 0-3) */ | ||
136 | #define ttnov(o) (novariant(rttype(o))) | ||
137 | |||
138 | |||
139 | /* Macros to test type */ | ||
140 | #define checktag(o,t) (rttype(o) == (t)) | ||
141 | #define checktype(o,t) (ttnov(o) == (t)) | ||
142 | #define ttisnumber(o) checktype((o), LUA_TNUMBER) | ||
143 | #define ttisfloat(o) checktag((o), LUA_TNUMFLT) | ||
144 | #define ttisinteger(o) checktag((o), LUA_TNUMINT) | ||
145 | #define ttisnil(o) checktag((o), LUA_TNIL) | ||
146 | #define ttisboolean(o) checktag((o), LUA_TBOOLEAN) | ||
147 | #define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) | ||
148 | #define ttisstring(o) checktype((o), LUA_TSTRING) | ||
149 | #define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) | ||
150 | #define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) | ||
151 | #define ttistable(o) checktag((o), ctb(LUA_TTABLE)) | ||
152 | #define ttisfunction(o) checktype(o, LUA_TFUNCTION) | ||
153 | #define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) | ||
154 | #define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) | ||
155 | #define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) | ||
156 | #define ttislcf(o) checktag((o), LUA_TLCF) | ||
157 | #define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) | ||
158 | #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) | ||
159 | #define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) | ||
160 | |||
161 | |||
162 | /* Macros to access values */ | ||
163 | #define ivalue(o) check_exp(ttisinteger(o), val_(o).i) | ||
164 | #define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) | ||
165 | #define nvalue(o) check_exp(ttisnumber(o), \ | ||
166 | (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) | ||
167 | #define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) | ||
168 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) | ||
169 | #define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) | ||
170 | #define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) | ||
171 | #define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) | ||
172 | #define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) | ||
173 | #define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) | ||
174 | #define fvalue(o) check_exp(ttislcf(o), val_(o).f) | ||
175 | #define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) | ||
176 | #define bvalue(o) check_exp(ttisboolean(o), val_(o).b) | ||
177 | #define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) | ||
178 | /* a dead value may get the 'gc' field, but cannot access its contents */ | ||
179 | #define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) | ||
180 | |||
181 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) | ||
182 | |||
183 | |||
184 | #define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) | ||
185 | |||
186 | |||
187 | /* Macros for internal tests */ | ||
188 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->tt) | ||
189 | |||
190 | #define checkliveness(L,obj) \ | ||
191 | lua_longassert(!iscollectable(obj) || \ | ||
192 | (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj))))) | ||
193 | |||
194 | |||
195 | /* Macros to set values */ | ||
196 | #define settt_(o,t) ((o)->tt_=(t)) | ||
197 | |||
198 | #define setfltvalue(obj,x) \ | ||
199 | { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); } | ||
200 | |||
201 | #define chgfltvalue(obj,x) \ | ||
202 | { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); } | ||
203 | |||
204 | #define setivalue(obj,x) \ | ||
205 | { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); } | ||
206 | |||
207 | #define chgivalue(obj,x) \ | ||
208 | { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); } | ||
209 | |||
210 | #define setnilvalue(obj) settt_(obj, LUA_TNIL) | ||
211 | |||
212 | #define setfvalue(obj,x) \ | ||
213 | { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } | ||
214 | |||
215 | #define setpvalue(obj,x) \ | ||
216 | { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } | ||
217 | |||
218 | #define setbvalue(obj,x) \ | ||
219 | { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } | ||
220 | |||
221 | #define setgcovalue(L,obj,x) \ | ||
222 | { TValue *io = (obj); GCObject *i_g=(x); \ | ||
223 | val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } | ||
224 | |||
225 | #define setsvalue(L,obj,x) \ | ||
226 | { TValue *io = (obj); TString *x_ = (x); \ | ||
227 | val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ | ||
228 | checkliveness(L,io); } | ||
229 | |||
230 | #define setuvalue(L,obj,x) \ | ||
231 | { TValue *io = (obj); Udata *x_ = (x); \ | ||
232 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \ | ||
233 | checkliveness(L,io); } | ||
234 | |||
235 | #define setthvalue(L,obj,x) \ | ||
236 | { TValue *io = (obj); lua_State *x_ = (x); \ | ||
237 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \ | ||
238 | checkliveness(L,io); } | ||
239 | |||
240 | #define setclLvalue(L,obj,x) \ | ||
241 | { TValue *io = (obj); LClosure *x_ = (x); \ | ||
242 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \ | ||
243 | checkliveness(L,io); } | ||
244 | |||
245 | #define setclCvalue(L,obj,x) \ | ||
246 | { TValue *io = (obj); CClosure *x_ = (x); \ | ||
247 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \ | ||
248 | checkliveness(L,io); } | ||
249 | |||
250 | #define sethvalue(L,obj,x) \ | ||
251 | { TValue *io = (obj); Table *x_ = (x); \ | ||
252 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \ | ||
253 | checkliveness(L,io); } | ||
254 | |||
255 | #define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) | ||
256 | |||
257 | |||
258 | |||
259 | #define setobj(L,obj1,obj2) \ | ||
260 | { TValue *io1=(obj1); *io1 = *(obj2); \ | ||
261 | (void)L; checkliveness(L,io1); } | ||
262 | |||
263 | |||
264 | /* | ||
265 | ** different types of assignments, according to destination | ||
266 | */ | ||
267 | |||
268 | /* from stack to (same) stack */ | ||
269 | #define setobjs2s setobj | ||
270 | /* to stack (not from same stack) */ | ||
271 | #define setobj2s setobj | ||
272 | #define setsvalue2s setsvalue | ||
273 | #define sethvalue2s sethvalue | ||
274 | #define setptvalue2s setptvalue | ||
275 | /* from table to same table */ | ||
276 | #define setobjt2t setobj | ||
277 | /* to new object */ | ||
278 | #define setobj2n setobj | ||
279 | #define setsvalue2n setsvalue | ||
280 | |||
281 | /* to table (define it as an expression to be used in macros) */ | ||
282 | #define setobj2t(L,o1,o2) ((void)L, *(o1)=*(o2), checkliveness(L,(o1))) | ||
283 | |||
284 | |||
285 | |||
286 | |||
287 | /* | ||
288 | ** {====================================================== | ||
289 | ** types and prototypes | ||
290 | ** ======================================================= | ||
291 | */ | ||
292 | |||
293 | |||
294 | typedef TValue *StkId; /* index to stack elements */ | ||
295 | |||
296 | |||
297 | |||
298 | |||
299 | /* | ||
300 | ** Header for string value; string bytes follow the end of this structure | ||
301 | ** (aligned according to 'UTString'; see next). | ||
302 | */ | ||
303 | typedef struct TString { | ||
304 | CommonHeader; | ||
305 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ | ||
306 | lu_byte shrlen; /* length for short strings */ | ||
307 | unsigned int hash; | ||
308 | union { | ||
309 | size_t lnglen; /* length for long strings */ | ||
310 | struct TString *hnext; /* linked list for hash table */ | ||
311 | } u; | ||
312 | } TString; | ||
313 | |||
314 | |||
315 | /* | ||
316 | ** Ensures that address after this type is always fully aligned. | ||
317 | */ | ||
318 | typedef union UTString { | ||
319 | L_Umaxalign dummy; /* ensures maximum alignment for strings */ | ||
320 | TString tsv; | ||
321 | } UTString; | ||
322 | |||
323 | |||
324 | /* | ||
325 | ** Get the actual string (array of bytes) from a 'TString'. | ||
326 | ** (Access to 'extra' ensures that value is really a 'TString'.) | ||
327 | */ | ||
328 | #define getstr(ts) \ | ||
329 | check_exp(sizeof((ts)->extra), cast(char *, (ts)) + sizeof(UTString)) | ||
330 | |||
331 | |||
332 | /* get the actual string (array of bytes) from a Lua value */ | ||
333 | #define svalue(o) getstr(tsvalue(o)) | ||
334 | |||
335 | /* get string length from 'TString *s' */ | ||
336 | #define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen) | ||
337 | |||
338 | /* get string length from 'TValue *o' */ | ||
339 | #define vslen(o) tsslen(tsvalue(o)) | ||
340 | |||
341 | |||
342 | /* | ||
343 | ** Header for userdata; memory area follows the end of this structure | ||
344 | ** (aligned according to 'UUdata'; see next). | ||
345 | */ | ||
346 | typedef struct Udata { | ||
347 | CommonHeader; | ||
348 | lu_byte ttuv_; /* user value's tag */ | ||
349 | struct Table *metatable; | ||
350 | size_t len; /* number of bytes */ | ||
351 | union Value user_; /* user value */ | ||
352 | } Udata; | ||
353 | |||
354 | |||
355 | /* | ||
356 | ** Ensures that address after this type is always fully aligned. | ||
357 | */ | ||
358 | typedef union UUdata { | ||
359 | L_Umaxalign dummy; /* ensures maximum alignment for 'local' udata */ | ||
360 | Udata uv; | ||
361 | } UUdata; | ||
362 | |||
363 | |||
364 | /* | ||
365 | ** Get the address of memory block inside 'Udata'. | ||
366 | ** (Access to 'ttuv_' ensures that value is really a 'Udata'.) | ||
367 | */ | ||
368 | #define getudatamem(u) \ | ||
369 | check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata))) | ||
370 | |||
371 | #define setuservalue(L,u,o) \ | ||
372 | { const TValue *io=(o); Udata *iu = (u); \ | ||
373 | iu->user_ = io->value_; iu->ttuv_ = rttype(io); \ | ||
374 | checkliveness(L,io); } | ||
375 | |||
376 | |||
377 | #define getuservalue(L,u,o) \ | ||
378 | { TValue *io=(o); const Udata *iu = (u); \ | ||
379 | io->value_ = iu->user_; settt_(io, iu->ttuv_); \ | ||
380 | checkliveness(L,io); } | ||
381 | |||
382 | |||
383 | /* | ||
384 | ** Description of an upvalue for function prototypes | ||
385 | */ | ||
386 | typedef struct Upvaldesc { | ||
387 | TString *name; /* upvalue name (for debug information) */ | ||
388 | lu_byte instack; /* whether it is in stack (register) */ | ||
389 | lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ | ||
390 | } Upvaldesc; | ||
391 | |||
392 | |||
393 | /* | ||
394 | ** Description of a local variable for function prototypes | ||
395 | ** (used for debug information) | ||
396 | */ | ||
397 | typedef struct LocVar { | ||
398 | TString *varname; | ||
399 | int startpc; /* first point where variable is active */ | ||
400 | int endpc; /* first point where variable is dead */ | ||
401 | } LocVar; | ||
402 | |||
403 | |||
404 | /* | ||
405 | ** Function Prototypes | ||
406 | */ | ||
407 | typedef struct Proto { | ||
408 | CommonHeader; | ||
409 | lu_byte numparams; /* number of fixed parameters */ | ||
410 | lu_byte is_vararg; | ||
411 | lu_byte maxstacksize; /* number of registers needed by this function */ | ||
412 | int sizeupvalues; /* size of 'upvalues' */ | ||
413 | int sizek; /* size of 'k' */ | ||
414 | int sizecode; | ||
415 | int sizelineinfo; | ||
416 | int sizep; /* size of 'p' */ | ||
417 | int sizelocvars; | ||
418 | int linedefined; /* debug information */ | ||
419 | int lastlinedefined; /* debug information */ | ||
420 | TValue *k; /* constants used by the function */ | ||
421 | Instruction *code; /* opcodes */ | ||
422 | struct Proto **p; /* functions defined inside the function */ | ||
423 | int *lineinfo; /* map from opcodes to source lines (debug information) */ | ||
424 | LocVar *locvars; /* information about local variables (debug information) */ | ||
425 | Upvaldesc *upvalues; /* upvalue information */ | ||
426 | struct LClosure *cache; /* last-created closure with this prototype */ | ||
427 | TString *source; /* used for debug information */ | ||
428 | GCObject *gclist; | ||
429 | } Proto; | ||
430 | |||
431 | |||
432 | |||
433 | /* | ||
434 | ** Lua Upvalues | ||
435 | */ | ||
436 | typedef struct UpVal UpVal; | ||
437 | |||
438 | |||
439 | /* | ||
440 | ** Closures | ||
441 | */ | ||
442 | |||
443 | #define ClosureHeader \ | ||
444 | CommonHeader; lu_byte nupvalues; GCObject *gclist | ||
445 | |||
446 | typedef struct CClosure { | ||
447 | ClosureHeader; | ||
448 | lua_CFunction f; | ||
449 | TValue upvalue[1]; /* list of upvalues */ | ||
450 | } CClosure; | ||
451 | |||
452 | |||
453 | typedef struct LClosure { | ||
454 | ClosureHeader; | ||
455 | struct Proto *p; | ||
456 | UpVal *upvals[1]; /* list of upvalues */ | ||
457 | } LClosure; | ||
458 | |||
459 | |||
460 | typedef union Closure { | ||
461 | CClosure c; | ||
462 | LClosure l; | ||
463 | } Closure; | ||
464 | |||
465 | |||
466 | #define isLfunction(o) ttisLclosure(o) | ||
467 | |||
468 | #define getproto(o) (clLvalue(o)->p) | ||
469 | |||
470 | |||
471 | /* | ||
472 | ** Tables | ||
473 | */ | ||
474 | |||
475 | typedef union TKey { | ||
476 | struct { | ||
477 | TValuefields; | ||
478 | int next; /* for chaining (offset for next node) */ | ||
479 | } nk; | ||
480 | TValue tvk; | ||
481 | } TKey; | ||
482 | |||
483 | |||
484 | /* copy a value into a key without messing up field 'next' */ | ||
485 | #define setnodekey(L,key,obj) \ | ||
486 | { TKey *k_=(key); const TValue *io_=(obj); \ | ||
487 | k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \ | ||
488 | (void)L; checkliveness(L,io_); } | ||
489 | |||
490 | |||
491 | typedef struct Node { | ||
492 | TValue i_val; | ||
493 | TKey i_key; | ||
494 | } Node; | ||
495 | |||
496 | |||
497 | typedef struct Table { | ||
498 | CommonHeader; | ||
499 | lu_byte flags; /* 1<<p means tagmethod(p) is not present */ | ||
500 | lu_byte lsizenode; /* log2 of size of 'node' array */ | ||
501 | unsigned int sizearray; /* size of 'array' array */ | ||
502 | TValue *array; /* array part */ | ||
503 | Node *node; | ||
504 | Node *lastfree; /* any free position is before this position */ | ||
505 | struct Table *metatable; | ||
506 | GCObject *gclist; | ||
507 | } Table; | ||
508 | |||
509 | |||
510 | |||
511 | /* | ||
512 | ** 'module' operation for hashing (size is always a power of 2) | ||
513 | */ | ||
514 | #define lmod(s,size) \ | ||
515 | (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))) | ||
516 | |||
517 | |||
518 | #define twoto(x) (1<<(x)) | ||
519 | #define sizenode(t) (twoto((t)->lsizenode)) | ||
520 | |||
521 | |||
522 | /* | ||
523 | ** (address of) a fixed nil value | ||
524 | */ | ||
525 | #define luaO_nilobject (&luaO_nilobject_) | ||
526 | |||
527 | |||
528 | LUAI_DDEC const TValue luaO_nilobject_; | ||
529 | |||
530 | /* size of buffer for 'luaO_utf8esc' function */ | ||
531 | #define UTF8BUFFSZ 8 | ||
532 | |||
533 | LUAI_FUNC int luaO_int2fb (unsigned int x); | ||
534 | LUAI_FUNC int luaO_fb2int (int x); | ||
535 | LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); | ||
536 | LUAI_FUNC int luaO_ceillog2 (unsigned int x); | ||
537 | LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, | ||
538 | const TValue *p2, TValue *res); | ||
539 | LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); | ||
540 | LUAI_FUNC int luaO_hexavalue (int c); | ||
541 | LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj); | ||
542 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, | ||
543 | va_list argp); | ||
544 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); | ||
545 | LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); | ||
546 | |||
547 | |||
548 | #endif | ||
549 | |||
diff --git a/src/lua-5.3/lopcodes.c b/src/lua-5.3/lopcodes.c deleted file mode 100644 index 5ca3eb2..0000000 --- a/src/lua-5.3/lopcodes.c +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Opcodes for Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lopcodes_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stddef.h> | ||
14 | |||
15 | #include "lopcodes.h" | ||
16 | |||
17 | |||
18 | /* ORDER OP */ | ||
19 | |||
20 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { | ||
21 | "MOVE", | ||
22 | "LOADK", | ||
23 | "LOADKX", | ||
24 | "LOADBOOL", | ||
25 | "LOADNIL", | ||
26 | "GETUPVAL", | ||
27 | "GETTABUP", | ||
28 | "GETTABLE", | ||
29 | "SETTABUP", | ||
30 | "SETUPVAL", | ||
31 | "SETTABLE", | ||
32 | "NEWTABLE", | ||
33 | "SELF", | ||
34 | "ADD", | ||
35 | "SUB", | ||
36 | "MUL", | ||
37 | "MOD", | ||
38 | "POW", | ||
39 | "DIV", | ||
40 | "IDIV", | ||
41 | "BAND", | ||
42 | "BOR", | ||
43 | "BXOR", | ||
44 | "SHL", | ||
45 | "SHR", | ||
46 | "UNM", | ||
47 | "BNOT", | ||
48 | "NOT", | ||
49 | "LEN", | ||
50 | "CONCAT", | ||
51 | "JMP", | ||
52 | "EQ", | ||
53 | "LT", | ||
54 | "LE", | ||
55 | "TEST", | ||
56 | "TESTSET", | ||
57 | "CALL", | ||
58 | "TAILCALL", | ||
59 | "RETURN", | ||
60 | "FORLOOP", | ||
61 | "FORPREP", | ||
62 | "TFORCALL", | ||
63 | "TFORLOOP", | ||
64 | "SETLIST", | ||
65 | "CLOSURE", | ||
66 | "VARARG", | ||
67 | "EXTRAARG", | ||
68 | NULL | ||
69 | }; | ||
70 | |||
71 | |||
72 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) | ||
73 | |||
74 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | ||
75 | /* T A B C mode opcode */ | ||
76 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ | ||
77 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ | ||
78 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ | ||
79 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ | ||
80 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ | ||
81 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ | ||
82 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ | ||
83 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ | ||
84 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ | ||
85 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ | ||
86 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ | ||
87 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ | ||
88 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ | ||
89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ | ||
90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ | ||
91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ | ||
92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ | ||
93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ | ||
94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ | ||
95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ | ||
96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ | ||
97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ | ||
98 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ | ||
99 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ | ||
100 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ | ||
101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ | ||
102 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ | ||
103 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ | ||
104 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ | ||
105 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ | ||
106 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ | ||
107 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ | ||
108 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ | ||
109 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ | ||
110 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ | ||
111 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ | ||
112 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ | ||
113 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ | ||
114 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ | ||
115 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ | ||
116 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ | ||
117 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ | ||
118 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ | ||
119 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ | ||
120 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ | ||
121 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ | ||
122 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ | ||
123 | }; | ||
124 | |||
diff --git a/src/lua-5.3/lopcodes.h b/src/lua-5.3/lopcodes.h deleted file mode 100644 index 6feaa1c..0000000 --- a/src/lua-5.3/lopcodes.h +++ /dev/null | |||
@@ -1,297 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lopcodes.h,v 1.149.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Opcodes for Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lopcodes_h | ||
8 | #define lopcodes_h | ||
9 | |||
10 | #include "llimits.h" | ||
11 | |||
12 | |||
13 | /*=========================================================================== | ||
14 | We assume that instructions are unsigned numbers. | ||
15 | All instructions have an opcode in the first 6 bits. | ||
16 | Instructions can have the following fields: | ||
17 | 'A' : 8 bits | ||
18 | 'B' : 9 bits | ||
19 | 'C' : 9 bits | ||
20 | 'Ax' : 26 bits ('A', 'B', and 'C' together) | ||
21 | 'Bx' : 18 bits ('B' and 'C' together) | ||
22 | 'sBx' : signed Bx | ||
23 | |||
24 | A signed argument is represented in excess K; that is, the number | ||
25 | value is the unsigned value minus K. K is exactly the maximum value | ||
26 | for that argument (so that -max is represented by 0, and +max is | ||
27 | represented by 2*max), which is half the maximum for the corresponding | ||
28 | unsigned argument. | ||
29 | ===========================================================================*/ | ||
30 | |||
31 | |||
32 | enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ | ||
33 | |||
34 | |||
35 | /* | ||
36 | ** size and position of opcode arguments. | ||
37 | */ | ||
38 | #define SIZE_C 9 | ||
39 | #define SIZE_B 9 | ||
40 | #define SIZE_Bx (SIZE_C + SIZE_B) | ||
41 | #define SIZE_A 8 | ||
42 | #define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) | ||
43 | |||
44 | #define SIZE_OP 6 | ||
45 | |||
46 | #define POS_OP 0 | ||
47 | #define POS_A (POS_OP + SIZE_OP) | ||
48 | #define POS_C (POS_A + SIZE_A) | ||
49 | #define POS_B (POS_C + SIZE_C) | ||
50 | #define POS_Bx POS_C | ||
51 | #define POS_Ax POS_A | ||
52 | |||
53 | |||
54 | /* | ||
55 | ** limits for opcode arguments. | ||
56 | ** we use (signed) int to manipulate most arguments, | ||
57 | ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) | ||
58 | */ | ||
59 | #if SIZE_Bx < LUAI_BITSINT-1 | ||
60 | #define MAXARG_Bx ((1<<SIZE_Bx)-1) | ||
61 | #define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */ | ||
62 | #else | ||
63 | #define MAXARG_Bx MAX_INT | ||
64 | #define MAXARG_sBx MAX_INT | ||
65 | #endif | ||
66 | |||
67 | #if SIZE_Ax < LUAI_BITSINT-1 | ||
68 | #define MAXARG_Ax ((1<<SIZE_Ax)-1) | ||
69 | #else | ||
70 | #define MAXARG_Ax MAX_INT | ||
71 | #endif | ||
72 | |||
73 | |||
74 | #define MAXARG_A ((1<<SIZE_A)-1) | ||
75 | #define MAXARG_B ((1<<SIZE_B)-1) | ||
76 | #define MAXARG_C ((1<<SIZE_C)-1) | ||
77 | |||
78 | |||
79 | /* creates a mask with 'n' 1 bits at position 'p' */ | ||
80 | #define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p)) | ||
81 | |||
82 | /* creates a mask with 'n' 0 bits at position 'p' */ | ||
83 | #define MASK0(n,p) (~MASK1(n,p)) | ||
84 | |||
85 | /* | ||
86 | ** the following macros help to manipulate instructions | ||
87 | */ | ||
88 | |||
89 | #define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) | ||
90 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ | ||
91 | ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP)))) | ||
92 | |||
93 | #define getarg(i,pos,size) (cast(int, ((i)>>pos) & MASK1(size,0))) | ||
94 | #define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ | ||
95 | ((cast(Instruction, v)<<pos)&MASK1(size,pos)))) | ||
96 | |||
97 | #define GETARG_A(i) getarg(i, POS_A, SIZE_A) | ||
98 | #define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) | ||
99 | |||
100 | #define GETARG_B(i) getarg(i, POS_B, SIZE_B) | ||
101 | #define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) | ||
102 | |||
103 | #define GETARG_C(i) getarg(i, POS_C, SIZE_C) | ||
104 | #define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) | ||
105 | |||
106 | #define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx) | ||
107 | #define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx) | ||
108 | |||
109 | #define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax) | ||
110 | #define SETARG_Ax(i,v) setarg(i, v, POS_Ax, SIZE_Ax) | ||
111 | |||
112 | #define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx) | ||
113 | #define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx)) | ||
114 | |||
115 | |||
116 | #define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \ | ||
117 | | (cast(Instruction, a)<<POS_A) \ | ||
118 | | (cast(Instruction, b)<<POS_B) \ | ||
119 | | (cast(Instruction, c)<<POS_C)) | ||
120 | |||
121 | #define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \ | ||
122 | | (cast(Instruction, a)<<POS_A) \ | ||
123 | | (cast(Instruction, bc)<<POS_Bx)) | ||
124 | |||
125 | #define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \ | ||
126 | | (cast(Instruction, a)<<POS_Ax)) | ||
127 | |||
128 | |||
129 | /* | ||
130 | ** Macros to operate RK indices | ||
131 | */ | ||
132 | |||
133 | /* this bit 1 means constant (0 means register) */ | ||
134 | #define BITRK (1 << (SIZE_B - 1)) | ||
135 | |||
136 | /* test whether value is a constant */ | ||
137 | #define ISK(x) ((x) & BITRK) | ||
138 | |||
139 | /* gets the index of the constant */ | ||
140 | #define INDEXK(r) ((int)(r) & ~BITRK) | ||
141 | |||
142 | #if !defined(MAXINDEXRK) /* (for debugging only) */ | ||
143 | #define MAXINDEXRK (BITRK - 1) | ||
144 | #endif | ||
145 | |||
146 | /* code a constant index as a RK value */ | ||
147 | #define RKASK(x) ((x) | BITRK) | ||
148 | |||
149 | |||
150 | /* | ||
151 | ** invalid register that fits in 8 bits | ||
152 | */ | ||
153 | #define NO_REG MAXARG_A | ||
154 | |||
155 | |||
156 | /* | ||
157 | ** R(x) - register | ||
158 | ** Kst(x) - constant (in constant table) | ||
159 | ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x) | ||
160 | */ | ||
161 | |||
162 | |||
163 | /* | ||
164 | ** grep "ORDER OP" if you change these enums | ||
165 | */ | ||
166 | |||
167 | typedef enum { | ||
168 | /*---------------------------------------------------------------------- | ||
169 | name args description | ||
170 | ------------------------------------------------------------------------*/ | ||
171 | OP_MOVE,/* A B R(A) := R(B) */ | ||
172 | OP_LOADK,/* A Bx R(A) := Kst(Bx) */ | ||
173 | OP_LOADKX,/* A R(A) := Kst(extra arg) */ | ||
174 | OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ | ||
175 | OP_LOADNIL,/* A B R(A), R(A+1), ..., R(A+B) := nil */ | ||
176 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ | ||
177 | |||
178 | OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */ | ||
179 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ | ||
180 | |||
181 | OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */ | ||
182 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ | ||
183 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ | ||
184 | |||
185 | OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */ | ||
186 | |||
187 | OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ | ||
188 | |||
189 | OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ | ||
190 | OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ | ||
191 | OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ | ||
192 | OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ | ||
193 | OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ | ||
194 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ | ||
195 | OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */ | ||
196 | OP_BAND,/* A B C R(A) := RK(B) & RK(C) */ | ||
197 | OP_BOR,/* A B C R(A) := RK(B) | RK(C) */ | ||
198 | OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */ | ||
199 | OP_SHL,/* A B C R(A) := RK(B) << RK(C) */ | ||
200 | OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */ | ||
201 | OP_UNM,/* A B R(A) := -R(B) */ | ||
202 | OP_BNOT,/* A B R(A) := ~R(B) */ | ||
203 | OP_NOT,/* A B R(A) := not R(B) */ | ||
204 | OP_LEN,/* A B R(A) := length of R(B) */ | ||
205 | |||
206 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ | ||
207 | |||
208 | OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */ | ||
209 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ | ||
210 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ | ||
211 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ | ||
212 | |||
213 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ | ||
214 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ | ||
215 | |||
216 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ | ||
217 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ | ||
218 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ | ||
219 | |||
220 | OP_FORLOOP,/* A sBx R(A)+=R(A+2); | ||
221 | if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ | ||
222 | OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ | ||
223 | |||
224 | OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */ | ||
225 | OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ | ||
226 | |||
227 | OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ | ||
228 | |||
229 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ | ||
230 | |||
231 | OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */ | ||
232 | |||
233 | OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ | ||
234 | } OpCode; | ||
235 | |||
236 | |||
237 | #define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1) | ||
238 | |||
239 | |||
240 | |||
241 | /*=========================================================================== | ||
242 | Notes: | ||
243 | (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then 'top' is | ||
244 | set to last_result+1, so next open instruction (OP_CALL, OP_RETURN, | ||
245 | OP_SETLIST) may use 'top'. | ||
246 | |||
247 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and | ||
248 | set top (like in OP_CALL with C == 0). | ||
249 | |||
250 | (*) In OP_RETURN, if (B == 0) then return up to 'top'. | ||
251 | |||
252 | (*) In OP_SETLIST, if (B == 0) then B = 'top'; if (C == 0) then next | ||
253 | 'instruction' is EXTRAARG(real C). | ||
254 | |||
255 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. | ||
256 | |||
257 | (*) For comparisons, A specifies what condition the test should accept | ||
258 | (true or false). | ||
259 | |||
260 | (*) All 'skips' (pc++) assume that next instruction is a jump. | ||
261 | |||
262 | ===========================================================================*/ | ||
263 | |||
264 | |||
265 | /* | ||
266 | ** masks for instruction properties. The format is: | ||
267 | ** bits 0-1: op mode | ||
268 | ** bits 2-3: C arg mode | ||
269 | ** bits 4-5: B arg mode | ||
270 | ** bit 6: instruction set register A | ||
271 | ** bit 7: operator is a test (next instruction must be a jump) | ||
272 | */ | ||
273 | |||
274 | enum OpArgMask { | ||
275 | OpArgN, /* argument is not used */ | ||
276 | OpArgU, /* argument is used */ | ||
277 | OpArgR, /* argument is a register or a jump offset */ | ||
278 | OpArgK /* argument is a constant or register/constant */ | ||
279 | }; | ||
280 | |||
281 | LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES]; | ||
282 | |||
283 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) | ||
284 | #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) | ||
285 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) | ||
286 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) | ||
287 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) | ||
288 | |||
289 | |||
290 | LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ | ||
291 | |||
292 | |||
293 | /* number of list items to accumulate before a SETLIST instruction */ | ||
294 | #define LFIELDS_PER_FLUSH 50 | ||
295 | |||
296 | |||
297 | #endif | ||
diff --git a/src/lua-5.3/ltable.c b/src/lua-5.3/ltable.c deleted file mode 100644 index ea4fe7f..0000000 --- a/src/lua-5.3/ltable.c +++ /dev/null | |||
@@ -1,688 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $ | ||
3 | ** Lua tables (hash) | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define ltable_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | /* | ||
14 | ** Implementation of tables (aka arrays, objects, or hash tables). | ||
15 | ** Tables keep its elements in two parts: an array part and a hash part. | ||
16 | ** Non-negative integer keys are all candidates to be kept in the array | ||
17 | ** part. The actual size of the array is the largest 'n' such that | ||
18 | ** more than half the slots between 1 and n are in use. | ||
19 | ** Hash uses a mix of chained scatter table with Brent's variation. | ||
20 | ** A main invariant of these tables is that, if an element is not | ||
21 | ** in its main position (i.e. the 'original' position that its hash gives | ||
22 | ** to it), then the colliding element is in its own main position. | ||
23 | ** Hence even when the load factor reaches 100%, performance remains good. | ||
24 | */ | ||
25 | |||
26 | #include <math.h> | ||
27 | #include <limits.h> | ||
28 | |||
29 | #include "lua.h" | ||
30 | |||
31 | #include "ldebug.h" | ||
32 | #include "ldo.h" | ||
33 | #include "lgc.h" | ||
34 | #include "lmem.h" | ||
35 | #include "lobject.h" | ||
36 | #include "lstate.h" | ||
37 | #include "lstring.h" | ||
38 | #include "ltable.h" | ||
39 | #include "lvm.h" | ||
40 | |||
41 | |||
42 | /* | ||
43 | ** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is | ||
44 | ** the largest integer such that MAXASIZE fits in an unsigned int. | ||
45 | */ | ||
46 | #define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) | ||
47 | #define MAXASIZE (1u << MAXABITS) | ||
48 | |||
49 | /* | ||
50 | ** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest | ||
51 | ** integer such that 2^MAXHBITS fits in a signed int. (Note that the | ||
52 | ** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still | ||
53 | ** fits comfortably in an unsigned int.) | ||
54 | */ | ||
55 | #define MAXHBITS (MAXABITS - 1) | ||
56 | |||
57 | |||
58 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) | ||
59 | |||
60 | #define hashstr(t,str) hashpow2(t, (str)->hash) | ||
61 | #define hashboolean(t,p) hashpow2(t, p) | ||
62 | #define hashint(t,i) hashpow2(t, i) | ||
63 | |||
64 | |||
65 | /* | ||
66 | ** for some types, it is better to avoid modulus by power of 2, as | ||
67 | ** they tend to have many 2 factors. | ||
68 | */ | ||
69 | #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) | ||
70 | |||
71 | |||
72 | #define hashpointer(t,p) hashmod(t, point2uint(p)) | ||
73 | |||
74 | |||
75 | #define dummynode (&dummynode_) | ||
76 | |||
77 | static const Node dummynode_ = { | ||
78 | {NILCONSTANT}, /* value */ | ||
79 | {{NILCONSTANT, 0}} /* key */ | ||
80 | }; | ||
81 | |||
82 | |||
83 | /* | ||
84 | ** Hash for floating-point numbers. | ||
85 | ** The main computation should be just | ||
86 | ** n = frexp(n, &i); return (n * INT_MAX) + i | ||
87 | ** but there are some numerical subtleties. | ||
88 | ** In a two-complement representation, INT_MAX does not has an exact | ||
89 | ** representation as a float, but INT_MIN does; because the absolute | ||
90 | ** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the | ||
91 | ** absolute value of the product 'frexp * -INT_MIN' is smaller or equal | ||
92 | ** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when | ||
93 | ** adding 'i'; the use of '~u' (instead of '-u') avoids problems with | ||
94 | ** INT_MIN. | ||
95 | */ | ||
96 | #if !defined(l_hashfloat) | ||
97 | static int l_hashfloat (lua_Number n) { | ||
98 | int i; | ||
99 | lua_Integer ni; | ||
100 | n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN); | ||
101 | if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */ | ||
102 | lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL)); | ||
103 | return 0; | ||
104 | } | ||
105 | else { /* normal case */ | ||
106 | unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni); | ||
107 | return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u); | ||
108 | } | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | |||
113 | /* | ||
114 | ** returns the 'main' position of an element in a table (that is, the index | ||
115 | ** of its hash value) | ||
116 | */ | ||
117 | static Node *mainposition (const Table *t, const TValue *key) { | ||
118 | switch (ttype(key)) { | ||
119 | case LUA_TNUMINT: | ||
120 | return hashint(t, ivalue(key)); | ||
121 | case LUA_TNUMFLT: | ||
122 | return hashmod(t, l_hashfloat(fltvalue(key))); | ||
123 | case LUA_TSHRSTR: | ||
124 | return hashstr(t, tsvalue(key)); | ||
125 | case LUA_TLNGSTR: | ||
126 | return hashpow2(t, luaS_hashlongstr(tsvalue(key))); | ||
127 | case LUA_TBOOLEAN: | ||
128 | return hashboolean(t, bvalue(key)); | ||
129 | case LUA_TLIGHTUSERDATA: | ||
130 | return hashpointer(t, pvalue(key)); | ||
131 | case LUA_TLCF: | ||
132 | return hashpointer(t, fvalue(key)); | ||
133 | default: | ||
134 | lua_assert(!ttisdeadkey(key)); | ||
135 | return hashpointer(t, gcvalue(key)); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | |||
140 | /* | ||
141 | ** returns the index for 'key' if 'key' is an appropriate key to live in | ||
142 | ** the array part of the table, 0 otherwise. | ||
143 | */ | ||
144 | static unsigned int arrayindex (const TValue *key) { | ||
145 | if (ttisinteger(key)) { | ||
146 | lua_Integer k = ivalue(key); | ||
147 | if (0 < k && (lua_Unsigned)k <= MAXASIZE) | ||
148 | return cast(unsigned int, k); /* 'key' is an appropriate array index */ | ||
149 | } | ||
150 | return 0; /* 'key' did not match some condition */ | ||
151 | } | ||
152 | |||
153 | |||
154 | /* | ||
155 | ** returns the index of a 'key' for table traversals. First goes all | ||
156 | ** elements in the array part, then elements in the hash part. The | ||
157 | ** beginning of a traversal is signaled by 0. | ||
158 | */ | ||
159 | static unsigned int findindex (lua_State *L, Table *t, StkId key) { | ||
160 | unsigned int i; | ||
161 | if (ttisnil(key)) return 0; /* first iteration */ | ||
162 | i = arrayindex(key); | ||
163 | if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */ | ||
164 | return i; /* yes; that's the index */ | ||
165 | else { | ||
166 | int nx; | ||
167 | Node *n = mainposition(t, key); | ||
168 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
169 | /* key may be dead already, but it is ok to use it in 'next' */ | ||
170 | if (luaV_rawequalobj(gkey(n), key) || | ||
171 | (ttisdeadkey(gkey(n)) && iscollectable(key) && | ||
172 | deadvalue(gkey(n)) == gcvalue(key))) { | ||
173 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ | ||
174 | /* hash elements are numbered after array ones */ | ||
175 | return (i + 1) + t->sizearray; | ||
176 | } | ||
177 | nx = gnext(n); | ||
178 | if (nx == 0) | ||
179 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ | ||
180 | else n += nx; | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | |||
186 | int luaH_next (lua_State *L, Table *t, StkId key) { | ||
187 | unsigned int i = findindex(L, t, key); /* find original element */ | ||
188 | for (; i < t->sizearray; i++) { /* try first array part */ | ||
189 | if (!ttisnil(&t->array[i])) { /* a non-nil value? */ | ||
190 | setivalue(key, i + 1); | ||
191 | setobj2s(L, key+1, &t->array[i]); | ||
192 | return 1; | ||
193 | } | ||
194 | } | ||
195 | for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ | ||
196 | if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ | ||
197 | setobj2s(L, key, gkey(gnode(t, i))); | ||
198 | setobj2s(L, key+1, gval(gnode(t, i))); | ||
199 | return 1; | ||
200 | } | ||
201 | } | ||
202 | return 0; /* no more elements */ | ||
203 | } | ||
204 | |||
205 | |||
206 | /* | ||
207 | ** {============================================================= | ||
208 | ** Rehash | ||
209 | ** ============================================================== | ||
210 | */ | ||
211 | |||
212 | /* | ||
213 | ** Compute the optimal size for the array part of table 't'. 'nums' is a | ||
214 | ** "count array" where 'nums[i]' is the number of integers in the table | ||
215 | ** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of | ||
216 | ** integer keys in the table and leaves with the number of keys that | ||
217 | ** will go to the array part; return the optimal size. | ||
218 | */ | ||
219 | static unsigned int computesizes (unsigned int nums[], unsigned int *pna) { | ||
220 | int i; | ||
221 | unsigned int twotoi; /* 2^i (candidate for optimal size) */ | ||
222 | unsigned int a = 0; /* number of elements smaller than 2^i */ | ||
223 | unsigned int na = 0; /* number of elements to go to array part */ | ||
224 | unsigned int optimal = 0; /* optimal size for array part */ | ||
225 | /* loop while keys can fill more than half of total size */ | ||
226 | for (i = 0, twotoi = 1; | ||
227 | twotoi > 0 && *pna > twotoi / 2; | ||
228 | i++, twotoi *= 2) { | ||
229 | if (nums[i] > 0) { | ||
230 | a += nums[i]; | ||
231 | if (a > twotoi/2) { /* more than half elements present? */ | ||
232 | optimal = twotoi; /* optimal size (till now) */ | ||
233 | na = a; /* all elements up to 'optimal' will go to array part */ | ||
234 | } | ||
235 | } | ||
236 | } | ||
237 | lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal); | ||
238 | *pna = na; | ||
239 | return optimal; | ||
240 | } | ||
241 | |||
242 | |||
243 | static int countint (const TValue *key, unsigned int *nums) { | ||
244 | unsigned int k = arrayindex(key); | ||
245 | if (k != 0) { /* is 'key' an appropriate array index? */ | ||
246 | nums[luaO_ceillog2(k)]++; /* count as such */ | ||
247 | return 1; | ||
248 | } | ||
249 | else | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | |||
254 | /* | ||
255 | ** Count keys in array part of table 't': Fill 'nums[i]' with | ||
256 | ** number of keys that will go into corresponding slice and return | ||
257 | ** total number of non-nil keys. | ||
258 | */ | ||
259 | static unsigned int numusearray (const Table *t, unsigned int *nums) { | ||
260 | int lg; | ||
261 | unsigned int ttlg; /* 2^lg */ | ||
262 | unsigned int ause = 0; /* summation of 'nums' */ | ||
263 | unsigned int i = 1; /* count to traverse all array keys */ | ||
264 | /* traverse each slice */ | ||
265 | for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { | ||
266 | unsigned int lc = 0; /* counter */ | ||
267 | unsigned int lim = ttlg; | ||
268 | if (lim > t->sizearray) { | ||
269 | lim = t->sizearray; /* adjust upper limit */ | ||
270 | if (i > lim) | ||
271 | break; /* no more elements to count */ | ||
272 | } | ||
273 | /* count elements in range (2^(lg - 1), 2^lg] */ | ||
274 | for (; i <= lim; i++) { | ||
275 | if (!ttisnil(&t->array[i-1])) | ||
276 | lc++; | ||
277 | } | ||
278 | nums[lg] += lc; | ||
279 | ause += lc; | ||
280 | } | ||
281 | return ause; | ||
282 | } | ||
283 | |||
284 | |||
285 | static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) { | ||
286 | int totaluse = 0; /* total number of elements */ | ||
287 | int ause = 0; /* elements added to 'nums' (can go to array part) */ | ||
288 | int i = sizenode(t); | ||
289 | while (i--) { | ||
290 | Node *n = &t->node[i]; | ||
291 | if (!ttisnil(gval(n))) { | ||
292 | ause += countint(gkey(n), nums); | ||
293 | totaluse++; | ||
294 | } | ||
295 | } | ||
296 | *pna += ause; | ||
297 | return totaluse; | ||
298 | } | ||
299 | |||
300 | |||
301 | static void setarrayvector (lua_State *L, Table *t, unsigned int size) { | ||
302 | unsigned int i; | ||
303 | luaM_reallocvector(L, t->array, t->sizearray, size, TValue); | ||
304 | for (i=t->sizearray; i<size; i++) | ||
305 | setnilvalue(&t->array[i]); | ||
306 | t->sizearray = size; | ||
307 | } | ||
308 | |||
309 | |||
310 | static void setnodevector (lua_State *L, Table *t, unsigned int size) { | ||
311 | if (size == 0) { /* no elements to hash part? */ | ||
312 | t->node = cast(Node *, dummynode); /* use common 'dummynode' */ | ||
313 | t->lsizenode = 0; | ||
314 | t->lastfree = NULL; /* signal that it is using dummy node */ | ||
315 | } | ||
316 | else { | ||
317 | int i; | ||
318 | int lsize = luaO_ceillog2(size); | ||
319 | if (lsize > MAXHBITS) | ||
320 | luaG_runerror(L, "table overflow"); | ||
321 | size = twoto(lsize); | ||
322 | t->node = luaM_newvector(L, size, Node); | ||
323 | for (i = 0; i < (int)size; i++) { | ||
324 | Node *n = gnode(t, i); | ||
325 | gnext(n) = 0; | ||
326 | setnilvalue(wgkey(n)); | ||
327 | setnilvalue(gval(n)); | ||
328 | } | ||
329 | t->lsizenode = cast_byte(lsize); | ||
330 | t->lastfree = gnode(t, size); /* all positions are free */ | ||
331 | } | ||
332 | } | ||
333 | |||
334 | |||
335 | typedef struct { | ||
336 | Table *t; | ||
337 | unsigned int nhsize; | ||
338 | } AuxsetnodeT; | ||
339 | |||
340 | |||
341 | static void auxsetnode (lua_State *L, void *ud) { | ||
342 | AuxsetnodeT *asn = cast(AuxsetnodeT *, ud); | ||
343 | setnodevector(L, asn->t, asn->nhsize); | ||
344 | } | ||
345 | |||
346 | |||
347 | void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | ||
348 | unsigned int nhsize) { | ||
349 | unsigned int i; | ||
350 | int j; | ||
351 | AuxsetnodeT asn; | ||
352 | unsigned int oldasize = t->sizearray; | ||
353 | int oldhsize = allocsizenode(t); | ||
354 | Node *nold = t->node; /* save old hash ... */ | ||
355 | if (nasize > oldasize) /* array part must grow? */ | ||
356 | setarrayvector(L, t, nasize); | ||
357 | /* create new hash part with appropriate size */ | ||
358 | asn.t = t; asn.nhsize = nhsize; | ||
359 | if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK) { /* mem. error? */ | ||
360 | setarrayvector(L, t, oldasize); /* array back to its original size */ | ||
361 | luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */ | ||
362 | } | ||
363 | if (nasize < oldasize) { /* array part must shrink? */ | ||
364 | t->sizearray = nasize; | ||
365 | /* re-insert elements from vanishing slice */ | ||
366 | for (i=nasize; i<oldasize; i++) { | ||
367 | if (!ttisnil(&t->array[i])) | ||
368 | luaH_setint(L, t, i + 1, &t->array[i]); | ||
369 | } | ||
370 | /* shrink array */ | ||
371 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); | ||
372 | } | ||
373 | /* re-insert elements from hash part */ | ||
374 | for (j = oldhsize - 1; j >= 0; j--) { | ||
375 | Node *old = nold + j; | ||
376 | if (!ttisnil(gval(old))) { | ||
377 | /* doesn't need barrier/invalidate cache, as entry was | ||
378 | already present in the table */ | ||
379 | setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); | ||
380 | } | ||
381 | } | ||
382 | if (oldhsize > 0) /* not the dummy node? */ | ||
383 | luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */ | ||
384 | } | ||
385 | |||
386 | |||
387 | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { | ||
388 | int nsize = allocsizenode(t); | ||
389 | luaH_resize(L, t, nasize, nsize); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | ** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i | ||
394 | */ | ||
395 | static void rehash (lua_State *L, Table *t, const TValue *ek) { | ||
396 | unsigned int asize; /* optimal size for array part */ | ||
397 | unsigned int na; /* number of keys in the array part */ | ||
398 | unsigned int nums[MAXABITS + 1]; | ||
399 | int i; | ||
400 | int totaluse; | ||
401 | for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */ | ||
402 | na = numusearray(t, nums); /* count keys in array part */ | ||
403 | totaluse = na; /* all those keys are integer keys */ | ||
404 | totaluse += numusehash(t, nums, &na); /* count keys in hash part */ | ||
405 | /* count extra key */ | ||
406 | na += countint(ek, nums); | ||
407 | totaluse++; | ||
408 | /* compute new size for array part */ | ||
409 | asize = computesizes(nums, &na); | ||
410 | /* resize the table to new computed sizes */ | ||
411 | luaH_resize(L, t, asize, totaluse - na); | ||
412 | } | ||
413 | |||
414 | |||
415 | |||
416 | /* | ||
417 | ** }============================================================= | ||
418 | */ | ||
419 | |||
420 | |||
421 | Table *luaH_new (lua_State *L) { | ||
422 | GCObject *o = luaC_newobj(L, LUA_TTABLE, sizeof(Table)); | ||
423 | Table *t = gco2t(o); | ||
424 | t->metatable = NULL; | ||
425 | t->flags = cast_byte(~0); | ||
426 | t->array = NULL; | ||
427 | t->sizearray = 0; | ||
428 | setnodevector(L, t, 0); | ||
429 | return t; | ||
430 | } | ||
431 | |||
432 | |||
433 | void luaH_free (lua_State *L, Table *t) { | ||
434 | if (!isdummy(t)) | ||
435 | luaM_freearray(L, t->node, cast(size_t, sizenode(t))); | ||
436 | luaM_freearray(L, t->array, t->sizearray); | ||
437 | luaM_free(L, t); | ||
438 | } | ||
439 | |||
440 | |||
441 | static Node *getfreepos (Table *t) { | ||
442 | if (!isdummy(t)) { | ||
443 | while (t->lastfree > t->node) { | ||
444 | t->lastfree--; | ||
445 | if (ttisnil(gkey(t->lastfree))) | ||
446 | return t->lastfree; | ||
447 | } | ||
448 | } | ||
449 | return NULL; /* could not find a free place */ | ||
450 | } | ||
451 | |||
452 | |||
453 | |||
454 | /* | ||
455 | ** inserts a new key into a hash table; first, check whether key's main | ||
456 | ** position is free. If not, check whether colliding node is in its main | ||
457 | ** position or not: if it is not, move colliding node to an empty place and | ||
458 | ** put new key in its main position; otherwise (colliding node is in its main | ||
459 | ** position), new key goes to an empty position. | ||
460 | */ | ||
461 | TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | ||
462 | Node *mp; | ||
463 | TValue aux; | ||
464 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); | ||
465 | else if (ttisfloat(key)) { | ||
466 | lua_Integer k; | ||
467 | if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */ | ||
468 | setivalue(&aux, k); | ||
469 | key = &aux; /* insert it as an integer */ | ||
470 | } | ||
471 | else if (luai_numisnan(fltvalue(key))) | ||
472 | luaG_runerror(L, "table index is NaN"); | ||
473 | } | ||
474 | mp = mainposition(t, key); | ||
475 | if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */ | ||
476 | Node *othern; | ||
477 | Node *f = getfreepos(t); /* get a free place */ | ||
478 | if (f == NULL) { /* cannot find a free place? */ | ||
479 | rehash(L, t, key); /* grow table */ | ||
480 | /* whatever called 'newkey' takes care of TM cache */ | ||
481 | return luaH_set(L, t, key); /* insert key into grown table */ | ||
482 | } | ||
483 | lua_assert(!isdummy(t)); | ||
484 | othern = mainposition(t, gkey(mp)); | ||
485 | if (othern != mp) { /* is colliding node out of its main position? */ | ||
486 | /* yes; move colliding node into free position */ | ||
487 | while (othern + gnext(othern) != mp) /* find previous */ | ||
488 | othern += gnext(othern); | ||
489 | gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */ | ||
490 | *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | ||
491 | if (gnext(mp) != 0) { | ||
492 | gnext(f) += cast_int(mp - f); /* correct 'next' */ | ||
493 | gnext(mp) = 0; /* now 'mp' is free */ | ||
494 | } | ||
495 | setnilvalue(gval(mp)); | ||
496 | } | ||
497 | else { /* colliding node is in its own main position */ | ||
498 | /* new node will go into free position */ | ||
499 | if (gnext(mp) != 0) | ||
500 | gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */ | ||
501 | else lua_assert(gnext(f) == 0); | ||
502 | gnext(mp) = cast_int(f - mp); | ||
503 | mp = f; | ||
504 | } | ||
505 | } | ||
506 | setnodekey(L, &mp->i_key, key); | ||
507 | luaC_barrierback(L, t, key); | ||
508 | lua_assert(ttisnil(gval(mp))); | ||
509 | return gval(mp); | ||
510 | } | ||
511 | |||
512 | |||
513 | /* | ||
514 | ** search function for integers | ||
515 | */ | ||
516 | const TValue *luaH_getint (Table *t, lua_Integer key) { | ||
517 | /* (1 <= key && key <= t->sizearray) */ | ||
518 | if (l_castS2U(key) - 1 < t->sizearray) | ||
519 | return &t->array[key - 1]; | ||
520 | else { | ||
521 | Node *n = hashint(t, key); | ||
522 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
523 | if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) | ||
524 | return gval(n); /* that's it */ | ||
525 | else { | ||
526 | int nx = gnext(n); | ||
527 | if (nx == 0) break; | ||
528 | n += nx; | ||
529 | } | ||
530 | } | ||
531 | return luaO_nilobject; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | |||
536 | /* | ||
537 | ** search function for short strings | ||
538 | */ | ||
539 | const TValue *luaH_getshortstr (Table *t, TString *key) { | ||
540 | Node *n = hashstr(t, key); | ||
541 | lua_assert(key->tt == LUA_TSHRSTR); | ||
542 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
543 | const TValue *k = gkey(n); | ||
544 | if (ttisshrstring(k) && eqshrstr(tsvalue(k), key)) | ||
545 | return gval(n); /* that's it */ | ||
546 | else { | ||
547 | int nx = gnext(n); | ||
548 | if (nx == 0) | ||
549 | return luaO_nilobject; /* not found */ | ||
550 | n += nx; | ||
551 | } | ||
552 | } | ||
553 | } | ||
554 | |||
555 | |||
556 | /* | ||
557 | ** "Generic" get version. (Not that generic: not valid for integers, | ||
558 | ** which may be in array part, nor for floats with integral values.) | ||
559 | */ | ||
560 | static const TValue *getgeneric (Table *t, const TValue *key) { | ||
561 | Node *n = mainposition(t, key); | ||
562 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
563 | if (luaV_rawequalobj(gkey(n), key)) | ||
564 | return gval(n); /* that's it */ | ||
565 | else { | ||
566 | int nx = gnext(n); | ||
567 | if (nx == 0) | ||
568 | return luaO_nilobject; /* not found */ | ||
569 | n += nx; | ||
570 | } | ||
571 | } | ||
572 | } | ||
573 | |||
574 | |||
575 | const TValue *luaH_getstr (Table *t, TString *key) { | ||
576 | if (key->tt == LUA_TSHRSTR) | ||
577 | return luaH_getshortstr(t, key); | ||
578 | else { /* for long strings, use generic case */ | ||
579 | TValue ko; | ||
580 | setsvalue(cast(lua_State *, NULL), &ko, key); | ||
581 | return getgeneric(t, &ko); | ||
582 | } | ||
583 | } | ||
584 | |||
585 | |||
586 | /* | ||
587 | ** main search function | ||
588 | */ | ||
589 | const TValue *luaH_get (Table *t, const TValue *key) { | ||
590 | switch (ttype(key)) { | ||
591 | case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key)); | ||
592 | case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); | ||
593 | case LUA_TNIL: return luaO_nilobject; | ||
594 | case LUA_TNUMFLT: { | ||
595 | lua_Integer k; | ||
596 | if (luaV_tointeger(key, &k, 0)) /* index is int? */ | ||
597 | return luaH_getint(t, k); /* use specialized version */ | ||
598 | /* else... */ | ||
599 | } /* FALLTHROUGH */ | ||
600 | default: | ||
601 | return getgeneric(t, key); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | |||
606 | /* | ||
607 | ** beware: when using this function you probably need to check a GC | ||
608 | ** barrier and invalidate the TM cache. | ||
609 | */ | ||
610 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { | ||
611 | const TValue *p = luaH_get(t, key); | ||
612 | if (p != luaO_nilobject) | ||
613 | return cast(TValue *, p); | ||
614 | else return luaH_newkey(L, t, key); | ||
615 | } | ||
616 | |||
617 | |||
618 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | ||
619 | const TValue *p = luaH_getint(t, key); | ||
620 | TValue *cell; | ||
621 | if (p != luaO_nilobject) | ||
622 | cell = cast(TValue *, p); | ||
623 | else { | ||
624 | TValue k; | ||
625 | setivalue(&k, key); | ||
626 | cell = luaH_newkey(L, t, &k); | ||
627 | } | ||
628 | setobj2t(L, cell, value); | ||
629 | } | ||
630 | |||
631 | |||
632 | static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) { | ||
633 | lua_Unsigned i = j; /* i is zero or a present index */ | ||
634 | j++; | ||
635 | /* find 'i' and 'j' such that i is present and j is not */ | ||
636 | while (!ttisnil(luaH_getint(t, j))) { | ||
637 | i = j; | ||
638 | if (j > l_castS2U(LUA_MAXINTEGER) / 2) { /* overflow? */ | ||
639 | /* table was built with bad purposes: resort to linear search */ | ||
640 | i = 1; | ||
641 | while (!ttisnil(luaH_getint(t, i))) i++; | ||
642 | return i - 1; | ||
643 | } | ||
644 | j *= 2; | ||
645 | } | ||
646 | /* now do a binary search between them */ | ||
647 | while (j - i > 1) { | ||
648 | lua_Unsigned m = (i+j)/2; | ||
649 | if (ttisnil(luaH_getint(t, m))) j = m; | ||
650 | else i = m; | ||
651 | } | ||
652 | return i; | ||
653 | } | ||
654 | |||
655 | |||
656 | /* | ||
657 | ** Try to find a boundary in table 't'. A 'boundary' is an integer index | ||
658 | ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). | ||
659 | */ | ||
660 | lua_Unsigned luaH_getn (Table *t) { | ||
661 | unsigned int j = t->sizearray; | ||
662 | if (j > 0 && ttisnil(&t->array[j - 1])) { | ||
663 | /* there is a boundary in the array part: (binary) search for it */ | ||
664 | unsigned int i = 0; | ||
665 | while (j - i > 1) { | ||
666 | unsigned int m = (i+j)/2; | ||
667 | if (ttisnil(&t->array[m - 1])) j = m; | ||
668 | else i = m; | ||
669 | } | ||
670 | return i; | ||
671 | } | ||
672 | /* else must find a boundary in hash part */ | ||
673 | else if (isdummy(t)) /* hash part is empty? */ | ||
674 | return j; /* that is easy... */ | ||
675 | else return unbound_search(t, j); | ||
676 | } | ||
677 | |||
678 | |||
679 | |||
680 | #if defined(LUA_DEBUG) | ||
681 | |||
682 | Node *luaH_mainposition (const Table *t, const TValue *key) { | ||
683 | return mainposition(t, key); | ||
684 | } | ||
685 | |||
686 | int luaH_isdummy (const Table *t) { return isdummy(t); } | ||
687 | |||
688 | #endif | ||
diff --git a/src/lua-5.3/ltm.c b/src/lua-5.3/ltm.c deleted file mode 100644 index 0e7c713..0000000 --- a/src/lua-5.3/ltm.c +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $ | ||
3 | ** Tag methods | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define ltm_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <string.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lobject.h" | ||
20 | #include "lstate.h" | ||
21 | #include "lstring.h" | ||
22 | #include "ltable.h" | ||
23 | #include "ltm.h" | ||
24 | #include "lvm.h" | ||
25 | |||
26 | |||
27 | static const char udatatypename[] = "userdata"; | ||
28 | |||
29 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { | ||
30 | "no value", | ||
31 | "nil", "boolean", udatatypename, "number", | ||
32 | "string", "table", "function", udatatypename, "thread", | ||
33 | "proto" /* this last case is used for tests only */ | ||
34 | }; | ||
35 | |||
36 | |||
37 | void luaT_init (lua_State *L) { | ||
38 | static const char *const luaT_eventname[] = { /* ORDER TM */ | ||
39 | "__index", "__newindex", | ||
40 | "__gc", "__mode", "__len", "__eq", | ||
41 | "__add", "__sub", "__mul", "__mod", "__pow", | ||
42 | "__div", "__idiv", | ||
43 | "__band", "__bor", "__bxor", "__shl", "__shr", | ||
44 | "__unm", "__bnot", "__lt", "__le", | ||
45 | "__concat", "__call" | ||
46 | }; | ||
47 | int i; | ||
48 | for (i=0; i<TM_N; i++) { | ||
49 | G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); | ||
50 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ | ||
51 | } | ||
52 | } | ||
53 | |||
54 | |||
55 | /* | ||
56 | ** function to be used with macro "fasttm": optimized for absence of | ||
57 | ** tag methods | ||
58 | */ | ||
59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { | ||
60 | const TValue *tm = luaH_getshortstr(events, ename); | ||
61 | lua_assert(event <= TM_EQ); | ||
62 | if (ttisnil(tm)) { /* no tag method? */ | ||
63 | events->flags |= cast_byte(1u<<event); /* cache this fact */ | ||
64 | return NULL; | ||
65 | } | ||
66 | else return tm; | ||
67 | } | ||
68 | |||
69 | |||
70 | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { | ||
71 | Table *mt; | ||
72 | switch (ttnov(o)) { | ||
73 | case LUA_TTABLE: | ||
74 | mt = hvalue(o)->metatable; | ||
75 | break; | ||
76 | case LUA_TUSERDATA: | ||
77 | mt = uvalue(o)->metatable; | ||
78 | break; | ||
79 | default: | ||
80 | mt = G(L)->mt[ttnov(o)]; | ||
81 | } | ||
82 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject); | ||
83 | } | ||
84 | |||
85 | |||
86 | /* | ||
87 | ** Return the name of the type of an object. For tables and userdata | ||
88 | ** with metatable, use their '__name' metafield, if present. | ||
89 | */ | ||
90 | const char *luaT_objtypename (lua_State *L, const TValue *o) { | ||
91 | Table *mt; | ||
92 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || | ||
93 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { | ||
94 | const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); | ||
95 | if (ttisstring(name)) /* is '__name' a string? */ | ||
96 | return getstr(tsvalue(name)); /* use it as type name */ | ||
97 | } | ||
98 | return ttypename(ttnov(o)); /* else use standard type name */ | ||
99 | } | ||
100 | |||
101 | |||
102 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, | ||
103 | const TValue *p2, TValue *p3, int hasres) { | ||
104 | ptrdiff_t result = savestack(L, p3); | ||
105 | StkId func = L->top; | ||
106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ | ||
107 | setobj2s(L, func + 1, p1); /* 1st argument */ | ||
108 | setobj2s(L, func + 2, p2); /* 2nd argument */ | ||
109 | L->top += 3; | ||
110 | if (!hasres) /* no result? 'p3' is third argument */ | ||
111 | setobj2s(L, L->top++, p3); /* 3rd argument */ | ||
112 | /* metamethod may yield only when called from Lua code */ | ||
113 | if (isLua(L->ci)) | ||
114 | luaD_call(L, func, hasres); | ||
115 | else | ||
116 | luaD_callnoyield(L, func, hasres); | ||
117 | if (hasres) { /* if has result, move it to its place */ | ||
118 | p3 = restorestack(L, result); | ||
119 | setobjs2s(L, p3, --L->top); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | |||
124 | int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
125 | StkId res, TMS event) { | ||
126 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | ||
127 | if (ttisnil(tm)) | ||
128 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | ||
129 | if (ttisnil(tm)) return 0; | ||
130 | luaT_callTM(L, tm, p1, p2, res, 1); | ||
131 | return 1; | ||
132 | } | ||
133 | |||
134 | |||
135 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
136 | StkId res, TMS event) { | ||
137 | if (!luaT_callbinTM(L, p1, p2, res, event)) { | ||
138 | switch (event) { | ||
139 | case TM_CONCAT: | ||
140 | luaG_concaterror(L, p1, p2); | ||
141 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ | ||
142 | case TM_BAND: case TM_BOR: case TM_BXOR: | ||
143 | case TM_SHL: case TM_SHR: case TM_BNOT: { | ||
144 | lua_Number dummy; | ||
145 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) | ||
146 | luaG_tointerror(L, p1, p2); | ||
147 | else | ||
148 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); | ||
149 | } | ||
150 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ | ||
151 | default: | ||
152 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
159 | TMS event) { | ||
160 | if (!luaT_callbinTM(L, p1, p2, L->top, event)) | ||
161 | return -1; /* no metamethod */ | ||
162 | else | ||
163 | return !l_isfalse(L->top); | ||
164 | } | ||
165 | |||
diff --git a/src/lua-5.3/lundump.c b/src/lua-5.3/lundump.c deleted file mode 100644 index 7a67d75..0000000 --- a/src/lua-5.3/lundump.c +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** load precompiled Lua chunks | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lundump_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <string.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lfunc.h" | ||
20 | #include "lmem.h" | ||
21 | #include "lobject.h" | ||
22 | #include "lstring.h" | ||
23 | #include "lundump.h" | ||
24 | #include "lzio.h" | ||
25 | |||
26 | |||
27 | #if !defined(luai_verifycode) | ||
28 | #define luai_verifycode(L,b,f) /* empty */ | ||
29 | #endif | ||
30 | |||
31 | |||
32 | typedef struct { | ||
33 | lua_State *L; | ||
34 | ZIO *Z; | ||
35 | const char *name; | ||
36 | } LoadState; | ||
37 | |||
38 | |||
39 | static l_noret error(LoadState *S, const char *why) { | ||
40 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); | ||
41 | luaD_throw(S->L, LUA_ERRSYNTAX); | ||
42 | } | ||
43 | |||
44 | |||
45 | /* | ||
46 | ** All high-level loads go through LoadVector; you can change it to | ||
47 | ** adapt to the endianness of the input | ||
48 | */ | ||
49 | #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0])) | ||
50 | |||
51 | static void LoadBlock (LoadState *S, void *b, size_t size) { | ||
52 | if (luaZ_read(S->Z, b, size) != 0) | ||
53 | error(S, "truncated"); | ||
54 | } | ||
55 | |||
56 | |||
57 | #define LoadVar(S,x) LoadVector(S,&x,1) | ||
58 | |||
59 | |||
60 | static lu_byte LoadByte (LoadState *S) { | ||
61 | lu_byte x; | ||
62 | LoadVar(S, x); | ||
63 | return x; | ||
64 | } | ||
65 | |||
66 | |||
67 | static int LoadInt (LoadState *S) { | ||
68 | int x; | ||
69 | LoadVar(S, x); | ||
70 | return x; | ||
71 | } | ||
72 | |||
73 | |||
74 | static lua_Number LoadNumber (LoadState *S) { | ||
75 | lua_Number x; | ||
76 | LoadVar(S, x); | ||
77 | return x; | ||
78 | } | ||
79 | |||
80 | |||
81 | static lua_Integer LoadInteger (LoadState *S) { | ||
82 | lua_Integer x; | ||
83 | LoadVar(S, x); | ||
84 | return x; | ||
85 | } | ||
86 | |||
87 | |||
88 | static TString *LoadString (LoadState *S) { | ||
89 | size_t size = LoadByte(S); | ||
90 | if (size == 0xFF) | ||
91 | LoadVar(S, size); | ||
92 | if (size == 0) | ||
93 | return NULL; | ||
94 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ | ||
95 | char buff[LUAI_MAXSHORTLEN]; | ||
96 | LoadVector(S, buff, size); | ||
97 | return luaS_newlstr(S->L, buff, size); | ||
98 | } | ||
99 | else { /* long string */ | ||
100 | TString *ts = luaS_createlngstrobj(S->L, size); | ||
101 | LoadVector(S, getstr(ts), size); /* load directly in final place */ | ||
102 | return ts; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | |||
107 | static void LoadCode (LoadState *S, Proto *f) { | ||
108 | int n = LoadInt(S); | ||
109 | f->code = luaM_newvector(S->L, n, Instruction); | ||
110 | f->sizecode = n; | ||
111 | LoadVector(S, f->code, n); | ||
112 | } | ||
113 | |||
114 | |||
115 | static void LoadFunction(LoadState *S, Proto *f, TString *psource); | ||
116 | |||
117 | |||
118 | static void LoadConstants (LoadState *S, Proto *f) { | ||
119 | int i; | ||
120 | int n = LoadInt(S); | ||
121 | f->k = luaM_newvector(S->L, n, TValue); | ||
122 | f->sizek = n; | ||
123 | for (i = 0; i < n; i++) | ||
124 | setnilvalue(&f->k[i]); | ||
125 | for (i = 0; i < n; i++) { | ||
126 | TValue *o = &f->k[i]; | ||
127 | int t = LoadByte(S); | ||
128 | switch (t) { | ||
129 | case LUA_TNIL: | ||
130 | setnilvalue(o); | ||
131 | break; | ||
132 | case LUA_TBOOLEAN: | ||
133 | setbvalue(o, LoadByte(S)); | ||
134 | break; | ||
135 | case LUA_TNUMFLT: | ||
136 | setfltvalue(o, LoadNumber(S)); | ||
137 | break; | ||
138 | case LUA_TNUMINT: | ||
139 | setivalue(o, LoadInteger(S)); | ||
140 | break; | ||
141 | case LUA_TSHRSTR: | ||
142 | case LUA_TLNGSTR: | ||
143 | setsvalue2n(S->L, o, LoadString(S)); | ||
144 | break; | ||
145 | default: | ||
146 | lua_assert(0); | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | |||
152 | static void LoadProtos (LoadState *S, Proto *f) { | ||
153 | int i; | ||
154 | int n = LoadInt(S); | ||
155 | f->p = luaM_newvector(S->L, n, Proto *); | ||
156 | f->sizep = n; | ||
157 | for (i = 0; i < n; i++) | ||
158 | f->p[i] = NULL; | ||
159 | for (i = 0; i < n; i++) { | ||
160 | f->p[i] = luaF_newproto(S->L); | ||
161 | LoadFunction(S, f->p[i], f->source); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | |||
166 | static void LoadUpvalues (LoadState *S, Proto *f) { | ||
167 | int i, n; | ||
168 | n = LoadInt(S); | ||
169 | f->upvalues = luaM_newvector(S->L, n, Upvaldesc); | ||
170 | f->sizeupvalues = n; | ||
171 | for (i = 0; i < n; i++) | ||
172 | f->upvalues[i].name = NULL; | ||
173 | for (i = 0; i < n; i++) { | ||
174 | f->upvalues[i].instack = LoadByte(S); | ||
175 | f->upvalues[i].idx = LoadByte(S); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | |||
180 | static void LoadDebug (LoadState *S, Proto *f) { | ||
181 | int i, n; | ||
182 | n = LoadInt(S); | ||
183 | f->lineinfo = luaM_newvector(S->L, n, int); | ||
184 | f->sizelineinfo = n; | ||
185 | LoadVector(S, f->lineinfo, n); | ||
186 | n = LoadInt(S); | ||
187 | f->locvars = luaM_newvector(S->L, n, LocVar); | ||
188 | f->sizelocvars = n; | ||
189 | for (i = 0; i < n; i++) | ||
190 | f->locvars[i].varname = NULL; | ||
191 | for (i = 0; i < n; i++) { | ||
192 | f->locvars[i].varname = LoadString(S); | ||
193 | f->locvars[i].startpc = LoadInt(S); | ||
194 | f->locvars[i].endpc = LoadInt(S); | ||
195 | } | ||
196 | n = LoadInt(S); | ||
197 | for (i = 0; i < n; i++) | ||
198 | f->upvalues[i].name = LoadString(S); | ||
199 | } | ||
200 | |||
201 | |||
202 | static void LoadFunction (LoadState *S, Proto *f, TString *psource) { | ||
203 | f->source = LoadString(S); | ||
204 | if (f->source == NULL) /* no source in dump? */ | ||
205 | f->source = psource; /* reuse parent's source */ | ||
206 | f->linedefined = LoadInt(S); | ||
207 | f->lastlinedefined = LoadInt(S); | ||
208 | f->numparams = LoadByte(S); | ||
209 | f->is_vararg = LoadByte(S); | ||
210 | f->maxstacksize = LoadByte(S); | ||
211 | LoadCode(S, f); | ||
212 | LoadConstants(S, f); | ||
213 | LoadUpvalues(S, f); | ||
214 | LoadProtos(S, f); | ||
215 | LoadDebug(S, f); | ||
216 | } | ||
217 | |||
218 | |||
219 | static void checkliteral (LoadState *S, const char *s, const char *msg) { | ||
220 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ | ||
221 | size_t len = strlen(s); | ||
222 | LoadVector(S, buff, len); | ||
223 | if (memcmp(s, buff, len) != 0) | ||
224 | error(S, msg); | ||
225 | } | ||
226 | |||
227 | |||
228 | static void fchecksize (LoadState *S, size_t size, const char *tname) { | ||
229 | if (LoadByte(S) != size) | ||
230 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); | ||
231 | } | ||
232 | |||
233 | |||
234 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) | ||
235 | |||
236 | static void checkHeader (LoadState *S) { | ||
237 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ | ||
238 | if (LoadByte(S) != LUAC_VERSION) | ||
239 | error(S, "version mismatch in"); | ||
240 | if (LoadByte(S) != LUAC_FORMAT) | ||
241 | error(S, "format mismatch in"); | ||
242 | checkliteral(S, LUAC_DATA, "corrupted"); | ||
243 | checksize(S, int); | ||
244 | checksize(S, size_t); | ||
245 | checksize(S, Instruction); | ||
246 | checksize(S, lua_Integer); | ||
247 | checksize(S, lua_Number); | ||
248 | if (LoadInteger(S) != LUAC_INT) | ||
249 | error(S, "endianness mismatch in"); | ||
250 | if (LoadNumber(S) != LUAC_NUM) | ||
251 | error(S, "float format mismatch in"); | ||
252 | } | ||
253 | |||
254 | |||
255 | /* | ||
256 | ** load precompiled chunk | ||
257 | */ | ||
258 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { | ||
259 | LoadState S; | ||
260 | LClosure *cl; | ||
261 | if (*name == '@' || *name == '=') | ||
262 | S.name = name + 1; | ||
263 | else if (*name == LUA_SIGNATURE[0]) | ||
264 | S.name = "binary string"; | ||
265 | else | ||
266 | S.name = name; | ||
267 | S.L = L; | ||
268 | S.Z = Z; | ||
269 | checkHeader(&S); | ||
270 | cl = luaF_newLclosure(L, LoadByte(&S)); | ||
271 | setclLvalue(L, L->top, cl); | ||
272 | luaD_inctop(L); | ||
273 | cl->p = luaF_newproto(L); | ||
274 | LoadFunction(&S, cl->p, NULL); | ||
275 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); | ||
276 | luai_verifycode(L, buff, cl->p); | ||
277 | return cl; | ||
278 | } | ||
279 | |||
diff --git a/src/lua-5.3/lvm.c b/src/lua-5.3/lvm.c deleted file mode 100644 index cc43d87..0000000 --- a/src/lua-5.3/lvm.c +++ /dev/null | |||
@@ -1,1322 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lvm.c,v 2.268.1.1 2017/04/19 17:39:34 roberto Exp $ | ||
3 | ** Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lvm_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | #include <float.h> | ||
13 | #include <limits.h> | ||
14 | #include <math.h> | ||
15 | #include <stdio.h> | ||
16 | #include <stdlib.h> | ||
17 | #include <string.h> | ||
18 | |||
19 | #include "lua.h" | ||
20 | |||
21 | #include "ldebug.h" | ||
22 | #include "ldo.h" | ||
23 | #include "lfunc.h" | ||
24 | #include "lgc.h" | ||
25 | #include "lobject.h" | ||
26 | #include "lopcodes.h" | ||
27 | #include "lstate.h" | ||
28 | #include "lstring.h" | ||
29 | #include "ltable.h" | ||
30 | #include "ltm.h" | ||
31 | #include "lvm.h" | ||
32 | |||
33 | |||
34 | /* limit for table tag-method chains (to avoid loops) */ | ||
35 | #define MAXTAGLOOP 2000 | ||
36 | |||
37 | |||
38 | |||
39 | /* | ||
40 | ** 'l_intfitsf' checks whether a given integer can be converted to a | ||
41 | ** float without rounding. Used in comparisons. Left undefined if | ||
42 | ** all integers fit in a float precisely. | ||
43 | */ | ||
44 | #if !defined(l_intfitsf) | ||
45 | |||
46 | /* number of bits in the mantissa of a float */ | ||
47 | #define NBM (l_mathlim(MANT_DIG)) | ||
48 | |||
49 | /* | ||
50 | ** Check whether some integers may not fit in a float, that is, whether | ||
51 | ** (maxinteger >> NBM) > 0 (that implies (1 << NBM) <= maxinteger). | ||
52 | ** (The shifts are done in parts to avoid shifting by more than the size | ||
53 | ** of an integer. In a worst case, NBM == 113 for long double and | ||
54 | ** sizeof(integer) == 32.) | ||
55 | */ | ||
56 | #if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \ | ||
57 | >> (NBM - (3 * (NBM / 4)))) > 0 | ||
58 | |||
59 | #define l_intfitsf(i) \ | ||
60 | (-((lua_Integer)1 << NBM) <= (i) && (i) <= ((lua_Integer)1 << NBM)) | ||
61 | |||
62 | #endif | ||
63 | |||
64 | #endif | ||
65 | |||
66 | |||
67 | |||
68 | /* | ||
69 | ** Try to convert a value to a float. The float case is already handled | ||
70 | ** by the macro 'tonumber'. | ||
71 | */ | ||
72 | int luaV_tonumber_ (const TValue *obj, lua_Number *n) { | ||
73 | TValue v; | ||
74 | if (ttisinteger(obj)) { | ||
75 | *n = cast_num(ivalue(obj)); | ||
76 | return 1; | ||
77 | } | ||
78 | else if (cvt2num(obj) && /* string convertible to number? */ | ||
79 | luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { | ||
80 | *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ | ||
81 | return 1; | ||
82 | } | ||
83 | else | ||
84 | return 0; /* conversion failed */ | ||
85 | } | ||
86 | |||
87 | |||
88 | /* | ||
89 | ** try to convert a value to an integer, rounding according to 'mode': | ||
90 | ** mode == 0: accepts only integral values | ||
91 | ** mode == 1: takes the floor of the number | ||
92 | ** mode == 2: takes the ceil of the number | ||
93 | */ | ||
94 | int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | ||
95 | TValue v; | ||
96 | again: | ||
97 | if (ttisfloat(obj)) { | ||
98 | lua_Number n = fltvalue(obj); | ||
99 | lua_Number f = l_floor(n); | ||
100 | if (n != f) { /* not an integral value? */ | ||
101 | if (mode == 0) return 0; /* fails if mode demands integral value */ | ||
102 | else if (mode > 1) /* needs ceil? */ | ||
103 | f += 1; /* convert floor to ceil (remember: n != f) */ | ||
104 | } | ||
105 | return lua_numbertointeger(f, p); | ||
106 | } | ||
107 | else if (ttisinteger(obj)) { | ||
108 | *p = ivalue(obj); | ||
109 | return 1; | ||
110 | } | ||
111 | else if (cvt2num(obj) && | ||
112 | luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { | ||
113 | obj = &v; | ||
114 | goto again; /* convert result from 'luaO_str2num' to an integer */ | ||
115 | } | ||
116 | return 0; /* conversion failed */ | ||
117 | } | ||
118 | |||
119 | |||
120 | /* | ||
121 | ** Try to convert a 'for' limit to an integer, preserving the | ||
122 | ** semantics of the loop. | ||
123 | ** (The following explanation assumes a non-negative step; it is valid | ||
124 | ** for negative steps mutatis mutandis.) | ||
125 | ** If the limit can be converted to an integer, rounding down, that is | ||
126 | ** it. | ||
127 | ** Otherwise, check whether the limit can be converted to a number. If | ||
128 | ** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, | ||
129 | ** which means no limit. If the number is too negative, the loop | ||
130 | ** should not run, because any initial integer value is larger than the | ||
131 | ** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects | ||
132 | ** the extreme case when the initial value is LUA_MININTEGER, in which | ||
133 | ** case the LUA_MININTEGER limit would still run the loop once. | ||
134 | */ | ||
135 | static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, | ||
136 | int *stopnow) { | ||
137 | *stopnow = 0; /* usually, let loops run */ | ||
138 | if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */ | ||
139 | lua_Number n; /* try to convert to float */ | ||
140 | if (!tonumber(obj, &n)) /* cannot convert to float? */ | ||
141 | return 0; /* not a number */ | ||
142 | if (luai_numlt(0, n)) { /* if true, float is larger than max integer */ | ||
143 | *p = LUA_MAXINTEGER; | ||
144 | if (step < 0) *stopnow = 1; | ||
145 | } | ||
146 | else { /* float is smaller than min integer */ | ||
147 | *p = LUA_MININTEGER; | ||
148 | if (step >= 0) *stopnow = 1; | ||
149 | } | ||
150 | } | ||
151 | return 1; | ||
152 | } | ||
153 | |||
154 | |||
155 | /* | ||
156 | ** Finish the table access 'val = t[key]'. | ||
157 | ** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to | ||
158 | ** t[k] entry (which must be nil). | ||
159 | */ | ||
160 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | ||
161 | const TValue *slot) { | ||
162 | int loop; /* counter to avoid infinite loops */ | ||
163 | const TValue *tm; /* metamethod */ | ||
164 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | ||
165 | if (slot == NULL) { /* 't' is not a table? */ | ||
166 | lua_assert(!ttistable(t)); | ||
167 | tm = luaT_gettmbyobj(L, t, TM_INDEX); | ||
168 | if (ttisnil(tm)) | ||
169 | luaG_typeerror(L, t, "index"); /* no metamethod */ | ||
170 | /* else will try the metamethod */ | ||
171 | } | ||
172 | else { /* 't' is a table */ | ||
173 | lua_assert(ttisnil(slot)); | ||
174 | tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ | ||
175 | if (tm == NULL) { /* no metamethod? */ | ||
176 | setnilvalue(val); /* result is nil */ | ||
177 | return; | ||
178 | } | ||
179 | /* else will try the metamethod */ | ||
180 | } | ||
181 | if (ttisfunction(tm)) { /* is metamethod a function? */ | ||
182 | luaT_callTM(L, tm, t, key, val, 1); /* call it */ | ||
183 | return; | ||
184 | } | ||
185 | t = tm; /* else try to access 'tm[key]' */ | ||
186 | if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */ | ||
187 | setobj2s(L, val, slot); /* done */ | ||
188 | return; | ||
189 | } | ||
190 | /* else repeat (tail call 'luaV_finishget') */ | ||
191 | } | ||
192 | luaG_runerror(L, "'__index' chain too long; possible loop"); | ||
193 | } | ||
194 | |||
195 | |||
196 | /* | ||
197 | ** Finish a table assignment 't[key] = val'. | ||
198 | ** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points | ||
199 | ** to the entry 't[key]', or to 'luaO_nilobject' if there is no such | ||
200 | ** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset' | ||
201 | ** would have done the job.) | ||
202 | */ | ||
203 | void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | ||
204 | StkId val, const TValue *slot) { | ||
205 | int loop; /* counter to avoid infinite loops */ | ||
206 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | ||
207 | const TValue *tm; /* '__newindex' metamethod */ | ||
208 | if (slot != NULL) { /* is 't' a table? */ | ||
209 | Table *h = hvalue(t); /* save 't' table */ | ||
210 | lua_assert(ttisnil(slot)); /* old value must be nil */ | ||
211 | tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ | ||
212 | if (tm == NULL) { /* no metamethod? */ | ||
213 | if (slot == luaO_nilobject) /* no previous entry? */ | ||
214 | slot = luaH_newkey(L, h, key); /* create one */ | ||
215 | /* no metamethod and (now) there is an entry with given key */ | ||
216 | setobj2t(L, cast(TValue *, slot), val); /* set its new value */ | ||
217 | invalidateTMcache(h); | ||
218 | luaC_barrierback(L, h, val); | ||
219 | return; | ||
220 | } | ||
221 | /* else will try the metamethod */ | ||
222 | } | ||
223 | else { /* not a table; check metamethod */ | ||
224 | if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) | ||
225 | luaG_typeerror(L, t, "index"); | ||
226 | } | ||
227 | /* try the metamethod */ | ||
228 | if (ttisfunction(tm)) { | ||
229 | luaT_callTM(L, tm, t, key, val, 0); | ||
230 | return; | ||
231 | } | ||
232 | t = tm; /* else repeat assignment over 'tm' */ | ||
233 | if (luaV_fastset(L, t, key, slot, luaH_get, val)) | ||
234 | return; /* done */ | ||
235 | /* else loop */ | ||
236 | } | ||
237 | luaG_runerror(L, "'__newindex' chain too long; possible loop"); | ||
238 | } | ||
239 | |||
240 | |||
241 | /* | ||
242 | ** Compare two strings 'ls' x 'rs', returning an integer smaller-equal- | ||
243 | ** -larger than zero if 'ls' is smaller-equal-larger than 'rs'. | ||
244 | ** The code is a little tricky because it allows '\0' in the strings | ||
245 | ** and it uses 'strcoll' (to respect locales) for each segments | ||
246 | ** of the strings. | ||
247 | */ | ||
248 | static int l_strcmp (const TString *ls, const TString *rs) { | ||
249 | const char *l = getstr(ls); | ||
250 | size_t ll = tsslen(ls); | ||
251 | const char *r = getstr(rs); | ||
252 | size_t lr = tsslen(rs); | ||
253 | for (;;) { /* for each segment */ | ||
254 | int temp = strcoll(l, r); | ||
255 | if (temp != 0) /* not equal? */ | ||
256 | return temp; /* done */ | ||
257 | else { /* strings are equal up to a '\0' */ | ||
258 | size_t len = strlen(l); /* index of first '\0' in both strings */ | ||
259 | if (len == lr) /* 'rs' is finished? */ | ||
260 | return (len == ll) ? 0 : 1; /* check 'ls' */ | ||
261 | else if (len == ll) /* 'ls' is finished? */ | ||
262 | return -1; /* 'ls' is smaller than 'rs' ('rs' is not finished) */ | ||
263 | /* both strings longer than 'len'; go on comparing after the '\0' */ | ||
264 | len++; | ||
265 | l += len; ll -= len; r += len; lr -= len; | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | |||
270 | |||
271 | /* | ||
272 | ** Check whether integer 'i' is less than float 'f'. If 'i' has an | ||
273 | ** exact representation as a float ('l_intfitsf'), compare numbers as | ||
274 | ** floats. Otherwise, if 'f' is outside the range for integers, result | ||
275 | ** is trivial. Otherwise, compare them as integers. (When 'i' has no | ||
276 | ** float representation, either 'f' is "far away" from 'i' or 'f' has | ||
277 | ** no precision left for a fractional part; either way, how 'f' is | ||
278 | ** truncated is irrelevant.) When 'f' is NaN, comparisons must result | ||
279 | ** in false. | ||
280 | */ | ||
281 | static int LTintfloat (lua_Integer i, lua_Number f) { | ||
282 | #if defined(l_intfitsf) | ||
283 | if (!l_intfitsf(i)) { | ||
284 | if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */ | ||
285 | return 1; /* f >= maxint + 1 > i */ | ||
286 | else if (f > cast_num(LUA_MININTEGER)) /* minint < f <= maxint ? */ | ||
287 | return (i < cast(lua_Integer, f)); /* compare them as integers */ | ||
288 | else /* f <= minint <= i (or 'f' is NaN) --> not(i < f) */ | ||
289 | return 0; | ||
290 | } | ||
291 | #endif | ||
292 | return luai_numlt(cast_num(i), f); /* compare them as floats */ | ||
293 | } | ||
294 | |||
295 | |||
296 | /* | ||
297 | ** Check whether integer 'i' is less than or equal to float 'f'. | ||
298 | ** See comments on previous function. | ||
299 | */ | ||
300 | static int LEintfloat (lua_Integer i, lua_Number f) { | ||
301 | #if defined(l_intfitsf) | ||
302 | if (!l_intfitsf(i)) { | ||
303 | if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */ | ||
304 | return 1; /* f >= maxint + 1 > i */ | ||
305 | else if (f >= cast_num(LUA_MININTEGER)) /* minint <= f <= maxint ? */ | ||
306 | return (i <= cast(lua_Integer, f)); /* compare them as integers */ | ||
307 | else /* f < minint <= i (or 'f' is NaN) --> not(i <= f) */ | ||
308 | return 0; | ||
309 | } | ||
310 | #endif | ||
311 | return luai_numle(cast_num(i), f); /* compare them as floats */ | ||
312 | } | ||
313 | |||
314 | |||
315 | /* | ||
316 | ** Return 'l < r', for numbers. | ||
317 | */ | ||
318 | static int LTnum (const TValue *l, const TValue *r) { | ||
319 | if (ttisinteger(l)) { | ||
320 | lua_Integer li = ivalue(l); | ||
321 | if (ttisinteger(r)) | ||
322 | return li < ivalue(r); /* both are integers */ | ||
323 | else /* 'l' is int and 'r' is float */ | ||
324 | return LTintfloat(li, fltvalue(r)); /* l < r ? */ | ||
325 | } | ||
326 | else { | ||
327 | lua_Number lf = fltvalue(l); /* 'l' must be float */ | ||
328 | if (ttisfloat(r)) | ||
329 | return luai_numlt(lf, fltvalue(r)); /* both are float */ | ||
330 | else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */ | ||
331 | return 0; /* NaN < i is always false */ | ||
332 | else /* without NaN, (l < r) <--> not(r <= l) */ | ||
333 | return !LEintfloat(ivalue(r), lf); /* not (r <= l) ? */ | ||
334 | } | ||
335 | } | ||
336 | |||
337 | |||
338 | /* | ||
339 | ** Return 'l <= r', for numbers. | ||
340 | */ | ||
341 | static int LEnum (const TValue *l, const TValue *r) { | ||
342 | if (ttisinteger(l)) { | ||
343 | lua_Integer li = ivalue(l); | ||
344 | if (ttisinteger(r)) | ||
345 | return li <= ivalue(r); /* both are integers */ | ||
346 | else /* 'l' is int and 'r' is float */ | ||
347 | return LEintfloat(li, fltvalue(r)); /* l <= r ? */ | ||
348 | } | ||
349 | else { | ||
350 | lua_Number lf = fltvalue(l); /* 'l' must be float */ | ||
351 | if (ttisfloat(r)) | ||
352 | return luai_numle(lf, fltvalue(r)); /* both are float */ | ||
353 | else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */ | ||
354 | return 0; /* NaN <= i is always false */ | ||
355 | else /* without NaN, (l <= r) <--> not(r < l) */ | ||
356 | return !LTintfloat(ivalue(r), lf); /* not (r < l) ? */ | ||
357 | } | ||
358 | } | ||
359 | |||
360 | |||
361 | /* | ||
362 | ** Main operation less than; return 'l < r'. | ||
363 | */ | ||
364 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | ||
365 | int res; | ||
366 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ | ||
367 | return LTnum(l, r); | ||
368 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | ||
369 | return l_strcmp(tsvalue(l), tsvalue(r)) < 0; | ||
370 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */ | ||
371 | luaG_ordererror(L, l, r); /* error */ | ||
372 | return res; | ||
373 | } | ||
374 | |||
375 | |||
376 | /* | ||
377 | ** Main operation less than or equal to; return 'l <= r'. If it needs | ||
378 | ** a metamethod and there is no '__le', try '__lt', based on | ||
379 | ** l <= r iff !(r < l) (assuming a total order). If the metamethod | ||
380 | ** yields during this substitution, the continuation has to know | ||
381 | ** about it (to negate the result of r<l); bit CIST_LEQ in the call | ||
382 | ** status keeps that information. | ||
383 | */ | ||
384 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | ||
385 | int res; | ||
386 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ | ||
387 | return LEnum(l, r); | ||
388 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | ||
389 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; | ||
390 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ | ||
391 | return res; | ||
392 | else { /* try 'lt': */ | ||
393 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ | ||
394 | res = luaT_callorderTM(L, r, l, TM_LT); | ||
395 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ | ||
396 | if (res < 0) | ||
397 | luaG_ordererror(L, l, r); | ||
398 | return !res; /* result is negated */ | ||
399 | } | ||
400 | } | ||
401 | |||
402 | |||
403 | /* | ||
404 | ** Main operation for equality of Lua values; return 't1 == t2'. | ||
405 | ** L == NULL means raw equality (no metamethods) | ||
406 | */ | ||
407 | int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | ||
408 | const TValue *tm; | ||
409 | if (ttype(t1) != ttype(t2)) { /* not the same variant? */ | ||
410 | if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER) | ||
411 | return 0; /* only numbers can be equal with different variants */ | ||
412 | else { /* two numbers with different variants */ | ||
413 | lua_Integer i1, i2; /* compare them as integers */ | ||
414 | return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2); | ||
415 | } | ||
416 | } | ||
417 | /* values have same type and same variant */ | ||
418 | switch (ttype(t1)) { | ||
419 | case LUA_TNIL: return 1; | ||
420 | case LUA_TNUMINT: return (ivalue(t1) == ivalue(t2)); | ||
421 | case LUA_TNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); | ||
422 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ | ||
423 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | ||
424 | case LUA_TLCF: return fvalue(t1) == fvalue(t2); | ||
425 | case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); | ||
426 | case LUA_TLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2)); | ||
427 | case LUA_TUSERDATA: { | ||
428 | if (uvalue(t1) == uvalue(t2)) return 1; | ||
429 | else if (L == NULL) return 0; | ||
430 | tm = fasttm(L, uvalue(t1)->metatable, TM_EQ); | ||
431 | if (tm == NULL) | ||
432 | tm = fasttm(L, uvalue(t2)->metatable, TM_EQ); | ||
433 | break; /* will try TM */ | ||
434 | } | ||
435 | case LUA_TTABLE: { | ||
436 | if (hvalue(t1) == hvalue(t2)) return 1; | ||
437 | else if (L == NULL) return 0; | ||
438 | tm = fasttm(L, hvalue(t1)->metatable, TM_EQ); | ||
439 | if (tm == NULL) | ||
440 | tm = fasttm(L, hvalue(t2)->metatable, TM_EQ); | ||
441 | break; /* will try TM */ | ||
442 | } | ||
443 | default: | ||
444 | return gcvalue(t1) == gcvalue(t2); | ||
445 | } | ||
446 | if (tm == NULL) /* no TM? */ | ||
447 | return 0; /* objects are different */ | ||
448 | luaT_callTM(L, tm, t1, t2, L->top, 1); /* call TM */ | ||
449 | return !l_isfalse(L->top); | ||
450 | } | ||
451 | |||
452 | |||
453 | /* macro used by 'luaV_concat' to ensure that element at 'o' is a string */ | ||
454 | #define tostring(L,o) \ | ||
455 | (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) | ||
456 | |||
457 | #define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) | ||
458 | |||
459 | /* copy strings in stack from top - n up to top - 1 to buffer */ | ||
460 | static void copy2buff (StkId top, int n, char *buff) { | ||
461 | size_t tl = 0; /* size already copied */ | ||
462 | do { | ||
463 | size_t l = vslen(top - n); /* length of string being copied */ | ||
464 | memcpy(buff + tl, svalue(top - n), l * sizeof(char)); | ||
465 | tl += l; | ||
466 | } while (--n > 0); | ||
467 | } | ||
468 | |||
469 | |||
470 | /* | ||
471 | ** Main operation for concatenation: concat 'total' values in the stack, | ||
472 | ** from 'L->top - total' up to 'L->top - 1'. | ||
473 | */ | ||
474 | void luaV_concat (lua_State *L, int total) { | ||
475 | lua_assert(total >= 2); | ||
476 | do { | ||
477 | StkId top = L->top; | ||
478 | int n = 2; /* number of elements handled in this pass (at least 2) */ | ||
479 | if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1)) | ||
480 | luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT); | ||
481 | else if (isemptystr(top - 1)) /* second operand is empty? */ | ||
482 | cast_void(tostring(L, top - 2)); /* result is first operand */ | ||
483 | else if (isemptystr(top - 2)) { /* first operand is an empty string? */ | ||
484 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ | ||
485 | } | ||
486 | else { | ||
487 | /* at least two non-empty string values; get as many as possible */ | ||
488 | size_t tl = vslen(top - 1); | ||
489 | TString *ts; | ||
490 | /* collect total length and number of strings */ | ||
491 | for (n = 1; n < total && tostring(L, top - n - 1); n++) { | ||
492 | size_t l = vslen(top - n - 1); | ||
493 | if (l >= (MAX_SIZE/sizeof(char)) - tl) | ||
494 | luaG_runerror(L, "string length overflow"); | ||
495 | tl += l; | ||
496 | } | ||
497 | if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ | ||
498 | char buff[LUAI_MAXSHORTLEN]; | ||
499 | copy2buff(top, n, buff); /* copy strings to buffer */ | ||
500 | ts = luaS_newlstr(L, buff, tl); | ||
501 | } | ||
502 | else { /* long string; copy strings directly to final result */ | ||
503 | ts = luaS_createlngstrobj(L, tl); | ||
504 | copy2buff(top, n, getstr(ts)); | ||
505 | } | ||
506 | setsvalue2s(L, top - n, ts); /* create result */ | ||
507 | } | ||
508 | total -= n-1; /* got 'n' strings to create 1 new */ | ||
509 | L->top -= n-1; /* popped 'n' strings and pushed one */ | ||
510 | } while (total > 1); /* repeat until only 1 result left */ | ||
511 | } | ||
512 | |||
513 | |||
514 | /* | ||
515 | ** Main operation 'ra' = #rb'. | ||
516 | */ | ||
517 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { | ||
518 | const TValue *tm; | ||
519 | switch (ttype(rb)) { | ||
520 | case LUA_TTABLE: { | ||
521 | Table *h = hvalue(rb); | ||
522 | tm = fasttm(L, h->metatable, TM_LEN); | ||
523 | if (tm) break; /* metamethod? break switch to call it */ | ||
524 | setivalue(ra, luaH_getn(h)); /* else primitive len */ | ||
525 | return; | ||
526 | } | ||
527 | case LUA_TSHRSTR: { | ||
528 | setivalue(ra, tsvalue(rb)->shrlen); | ||
529 | return; | ||
530 | } | ||
531 | case LUA_TLNGSTR: { | ||
532 | setivalue(ra, tsvalue(rb)->u.lnglen); | ||
533 | return; | ||
534 | } | ||
535 | default: { /* try metamethod */ | ||
536 | tm = luaT_gettmbyobj(L, rb, TM_LEN); | ||
537 | if (ttisnil(tm)) /* no metamethod? */ | ||
538 | luaG_typeerror(L, rb, "get length of"); | ||
539 | break; | ||
540 | } | ||
541 | } | ||
542 | luaT_callTM(L, tm, rb, rb, ra, 1); | ||
543 | } | ||
544 | |||
545 | |||
546 | /* | ||
547 | ** Integer division; return 'm // n', that is, floor(m/n). | ||
548 | ** C division truncates its result (rounds towards zero). | ||
549 | ** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer, | ||
550 | ** otherwise 'floor(q) == trunc(q) - 1'. | ||
551 | */ | ||
552 | lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) { | ||
553 | if (l_castS2U(n) + 1u <= 1u) { /* special cases: -1 or 0 */ | ||
554 | if (n == 0) | ||
555 | luaG_runerror(L, "attempt to divide by zero"); | ||
556 | return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ | ||
557 | } | ||
558 | else { | ||
559 | lua_Integer q = m / n; /* perform C division */ | ||
560 | if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */ | ||
561 | q -= 1; /* correct result for different rounding */ | ||
562 | return q; | ||
563 | } | ||
564 | } | ||
565 | |||
566 | |||
567 | /* | ||
568 | ** Integer modulus; return 'm % n'. (Assume that C '%' with | ||
569 | ** negative operands follows C99 behavior. See previous comment | ||
570 | ** about luaV_div.) | ||
571 | */ | ||
572 | lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { | ||
573 | if (l_castS2U(n) + 1u <= 1u) { /* special cases: -1 or 0 */ | ||
574 | if (n == 0) | ||
575 | luaG_runerror(L, "attempt to perform 'n%%0'"); | ||
576 | return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ | ||
577 | } | ||
578 | else { | ||
579 | lua_Integer r = m % n; | ||
580 | if (r != 0 && (m ^ n) < 0) /* 'm/n' would be non-integer negative? */ | ||
581 | r += n; /* correct result for different rounding */ | ||
582 | return r; | ||
583 | } | ||
584 | } | ||
585 | |||
586 | |||
587 | /* number of bits in an integer */ | ||
588 | #define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) | ||
589 | |||
590 | /* | ||
591 | ** Shift left operation. (Shift right just negates 'y'.) | ||
592 | */ | ||
593 | lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { | ||
594 | if (y < 0) { /* shift right? */ | ||
595 | if (y <= -NBITS) return 0; | ||
596 | else return intop(>>, x, -y); | ||
597 | } | ||
598 | else { /* shift left */ | ||
599 | if (y >= NBITS) return 0; | ||
600 | else return intop(<<, x, y); | ||
601 | } | ||
602 | } | ||
603 | |||
604 | |||
605 | /* | ||
606 | ** check whether cached closure in prototype 'p' may be reused, that is, | ||
607 | ** whether there is a cached closure with the same upvalues needed by | ||
608 | ** new closure to be created. | ||
609 | */ | ||
610 | static LClosure *getcached (Proto *p, UpVal **encup, StkId base) { | ||
611 | LClosure *c = p->cache; | ||
612 | if (c != NULL) { /* is there a cached closure? */ | ||
613 | int nup = p->sizeupvalues; | ||
614 | Upvaldesc *uv = p->upvalues; | ||
615 | int i; | ||
616 | for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ | ||
617 | TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; | ||
618 | if (c->upvals[i]->v != v) | ||
619 | return NULL; /* wrong upvalue; cannot reuse closure */ | ||
620 | } | ||
621 | } | ||
622 | return c; /* return cached closure (or NULL if no cached closure) */ | ||
623 | } | ||
624 | |||
625 | |||
626 | /* | ||
627 | ** create a new Lua closure, push it in the stack, and initialize | ||
628 | ** its upvalues. Note that the closure is not cached if prototype is | ||
629 | ** already black (which means that 'cache' was already cleared by the | ||
630 | ** GC). | ||
631 | */ | ||
632 | static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | ||
633 | StkId ra) { | ||
634 | int nup = p->sizeupvalues; | ||
635 | Upvaldesc *uv = p->upvalues; | ||
636 | int i; | ||
637 | LClosure *ncl = luaF_newLclosure(L, nup); | ||
638 | ncl->p = p; | ||
639 | setclLvalue(L, ra, ncl); /* anchor new closure in stack */ | ||
640 | for (i = 0; i < nup; i++) { /* fill in its upvalues */ | ||
641 | if (uv[i].instack) /* upvalue refers to local variable? */ | ||
642 | ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx); | ||
643 | else /* get upvalue from enclosing function */ | ||
644 | ncl->upvals[i] = encup[uv[i].idx]; | ||
645 | ncl->upvals[i]->refcount++; | ||
646 | /* new closure is white, so we do not need a barrier here */ | ||
647 | } | ||
648 | if (!isblack(p)) /* cache will not break GC invariant? */ | ||
649 | p->cache = ncl; /* save it on cache for reuse */ | ||
650 | } | ||
651 | |||
652 | |||
653 | /* | ||
654 | ** finish execution of an opcode interrupted by an yield | ||
655 | */ | ||
656 | void luaV_finishOp (lua_State *L) { | ||
657 | CallInfo *ci = L->ci; | ||
658 | StkId base = ci->u.l.base; | ||
659 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | ||
660 | OpCode op = GET_OPCODE(inst); | ||
661 | switch (op) { /* finish its execution */ | ||
662 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: | ||
663 | case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: | ||
664 | case OP_MOD: case OP_POW: | ||
665 | case OP_UNM: case OP_BNOT: case OP_LEN: | ||
666 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { | ||
667 | setobjs2s(L, base + GETARG_A(inst), --L->top); | ||
668 | break; | ||
669 | } | ||
670 | case OP_LE: case OP_LT: case OP_EQ: { | ||
671 | int res = !l_isfalse(L->top - 1); | ||
672 | L->top--; | ||
673 | if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ | ||
674 | lua_assert(op == OP_LE); | ||
675 | ci->callstatus ^= CIST_LEQ; /* clear mark */ | ||
676 | res = !res; /* negate result */ | ||
677 | } | ||
678 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); | ||
679 | if (res != GETARG_A(inst)) /* condition failed? */ | ||
680 | ci->u.l.savedpc++; /* skip jump instruction */ | ||
681 | break; | ||
682 | } | ||
683 | case OP_CONCAT: { | ||
684 | StkId top = L->top - 1; /* top when 'luaT_trybinTM' was called */ | ||
685 | int b = GETARG_B(inst); /* first element to concatenate */ | ||
686 | int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ | ||
687 | setobj2s(L, top - 2, top); /* put TM result in proper position */ | ||
688 | if (total > 1) { /* are there elements to concat? */ | ||
689 | L->top = top - 1; /* top is one after last element (at top-2) */ | ||
690 | luaV_concat(L, total); /* concat them (may yield again) */ | ||
691 | } | ||
692 | /* move final result to final position */ | ||
693 | setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); | ||
694 | L->top = ci->top; /* restore top */ | ||
695 | break; | ||
696 | } | ||
697 | case OP_TFORCALL: { | ||
698 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); | ||
699 | L->top = ci->top; /* correct top */ | ||
700 | break; | ||
701 | } | ||
702 | case OP_CALL: { | ||
703 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ | ||
704 | L->top = ci->top; /* adjust results */ | ||
705 | break; | ||
706 | } | ||
707 | case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: | ||
708 | break; | ||
709 | default: lua_assert(0); | ||
710 | } | ||
711 | } | ||
712 | |||
713 | |||
714 | |||
715 | |||
716 | /* | ||
717 | ** {================================================================== | ||
718 | ** Function 'luaV_execute': main interpreter loop | ||
719 | ** =================================================================== | ||
720 | */ | ||
721 | |||
722 | |||
723 | /* | ||
724 | ** some macros for common tasks in 'luaV_execute' | ||
725 | */ | ||
726 | |||
727 | |||
728 | #define RA(i) (base+GETARG_A(i)) | ||
729 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) | ||
730 | #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) | ||
731 | #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ | ||
732 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) | ||
733 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ | ||
734 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) | ||
735 | |||
736 | |||
737 | /* execute a jump instruction */ | ||
738 | #define dojump(ci,i,e) \ | ||
739 | { int a = GETARG_A(i); \ | ||
740 | if (a != 0) luaF_close(L, ci->u.l.base + a - 1); \ | ||
741 | ci->u.l.savedpc += GETARG_sBx(i) + e; } | ||
742 | |||
743 | /* for test instructions, execute the jump instruction that follows it */ | ||
744 | #define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } | ||
745 | |||
746 | |||
747 | #define Protect(x) { {x;}; base = ci->u.l.base; } | ||
748 | |||
749 | #define checkGC(L,c) \ | ||
750 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ | ||
751 | Protect(L->top = ci->top)); /* restore top */ \ | ||
752 | luai_threadyield(L); } | ||
753 | |||
754 | |||
755 | /* fetch an instruction and prepare its execution */ | ||
756 | #define vmfetch() { \ | ||
757 | i = *(ci->u.l.savedpc++); \ | ||
758 | if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \ | ||
759 | Protect(luaG_traceexec(L)); \ | ||
760 | ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \ | ||
761 | lua_assert(base == ci->u.l.base); \ | ||
762 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \ | ||
763 | } | ||
764 | |||
765 | #define vmdispatch(o) switch(o) | ||
766 | #define vmcase(l) case l: | ||
767 | #define vmbreak break | ||
768 | |||
769 | |||
770 | /* | ||
771 | ** copy of 'luaV_gettable', but protecting the call to potential | ||
772 | ** metamethod (which can reallocate the stack) | ||
773 | */ | ||
774 | #define gettableProtected(L,t,k,v) { const TValue *slot; \ | ||
775 | if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \ | ||
776 | else Protect(luaV_finishget(L,t,k,v,slot)); } | ||
777 | |||
778 | |||
779 | /* same for 'luaV_settable' */ | ||
780 | #define settableProtected(L,t,k,v) { const TValue *slot; \ | ||
781 | if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ | ||
782 | Protect(luaV_finishset(L,t,k,v,slot)); } | ||
783 | |||
784 | |||
785 | |||
786 | void luaV_execute (lua_State *L) { | ||
787 | CallInfo *ci = L->ci; | ||
788 | LClosure *cl; | ||
789 | TValue *k; | ||
790 | StkId base; | ||
791 | ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ | ||
792 | newframe: /* reentry point when frame changes (call/return) */ | ||
793 | lua_assert(ci == L->ci); | ||
794 | cl = clLvalue(ci->func); /* local reference to function's closure */ | ||
795 | k = cl->p->k; /* local reference to function's constant table */ | ||
796 | base = ci->u.l.base; /* local copy of function's base */ | ||
797 | /* main loop of interpreter */ | ||
798 | for (;;) { | ||
799 | Instruction i; | ||
800 | StkId ra; | ||
801 | vmfetch(); | ||
802 | vmdispatch (GET_OPCODE(i)) { | ||
803 | vmcase(OP_MOVE) { | ||
804 | setobjs2s(L, ra, RB(i)); | ||
805 | vmbreak; | ||
806 | } | ||
807 | vmcase(OP_LOADK) { | ||
808 | TValue *rb = k + GETARG_Bx(i); | ||
809 | setobj2s(L, ra, rb); | ||
810 | vmbreak; | ||
811 | } | ||
812 | vmcase(OP_LOADKX) { | ||
813 | TValue *rb; | ||
814 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); | ||
815 | rb = k + GETARG_Ax(*ci->u.l.savedpc++); | ||
816 | setobj2s(L, ra, rb); | ||
817 | vmbreak; | ||
818 | } | ||
819 | vmcase(OP_LOADBOOL) { | ||
820 | setbvalue(ra, GETARG_B(i)); | ||
821 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ | ||
822 | vmbreak; | ||
823 | } | ||
824 | vmcase(OP_LOADNIL) { | ||
825 | int b = GETARG_B(i); | ||
826 | do { | ||
827 | setnilvalue(ra++); | ||
828 | } while (b--); | ||
829 | vmbreak; | ||
830 | } | ||
831 | vmcase(OP_GETUPVAL) { | ||
832 | int b = GETARG_B(i); | ||
833 | setobj2s(L, ra, cl->upvals[b]->v); | ||
834 | vmbreak; | ||
835 | } | ||
836 | vmcase(OP_GETTABUP) { | ||
837 | TValue *upval = cl->upvals[GETARG_B(i)]->v; | ||
838 | TValue *rc = RKC(i); | ||
839 | gettableProtected(L, upval, rc, ra); | ||
840 | vmbreak; | ||
841 | } | ||
842 | vmcase(OP_GETTABLE) { | ||
843 | StkId rb = RB(i); | ||
844 | TValue *rc = RKC(i); | ||
845 | gettableProtected(L, rb, rc, ra); | ||
846 | vmbreak; | ||
847 | } | ||
848 | vmcase(OP_SETTABUP) { | ||
849 | TValue *upval = cl->upvals[GETARG_A(i)]->v; | ||
850 | TValue *rb = RKB(i); | ||
851 | TValue *rc = RKC(i); | ||
852 | settableProtected(L, upval, rb, rc); | ||
853 | vmbreak; | ||
854 | } | ||
855 | vmcase(OP_SETUPVAL) { | ||
856 | UpVal *uv = cl->upvals[GETARG_B(i)]; | ||
857 | setobj(L, uv->v, ra); | ||
858 | luaC_upvalbarrier(L, uv); | ||
859 | vmbreak; | ||
860 | } | ||
861 | vmcase(OP_SETTABLE) { | ||
862 | TValue *rb = RKB(i); | ||
863 | TValue *rc = RKC(i); | ||
864 | settableProtected(L, ra, rb, rc); | ||
865 | vmbreak; | ||
866 | } | ||
867 | vmcase(OP_NEWTABLE) { | ||
868 | int b = GETARG_B(i); | ||
869 | int c = GETARG_C(i); | ||
870 | Table *t = luaH_new(L); | ||
871 | sethvalue(L, ra, t); | ||
872 | if (b != 0 || c != 0) | ||
873 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); | ||
874 | checkGC(L, ra + 1); | ||
875 | vmbreak; | ||
876 | } | ||
877 | vmcase(OP_SELF) { | ||
878 | const TValue *aux; | ||
879 | StkId rb = RB(i); | ||
880 | TValue *rc = RKC(i); | ||
881 | TString *key = tsvalue(rc); /* key must be a string */ | ||
882 | setobjs2s(L, ra + 1, rb); | ||
883 | if (luaV_fastget(L, rb, key, aux, luaH_getstr)) { | ||
884 | setobj2s(L, ra, aux); | ||
885 | } | ||
886 | else Protect(luaV_finishget(L, rb, rc, ra, aux)); | ||
887 | vmbreak; | ||
888 | } | ||
889 | vmcase(OP_ADD) { | ||
890 | TValue *rb = RKB(i); | ||
891 | TValue *rc = RKC(i); | ||
892 | lua_Number nb; lua_Number nc; | ||
893 | if (ttisinteger(rb) && ttisinteger(rc)) { | ||
894 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | ||
895 | setivalue(ra, intop(+, ib, ic)); | ||
896 | } | ||
897 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | ||
898 | setfltvalue(ra, luai_numadd(L, nb, nc)); | ||
899 | } | ||
900 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } | ||
901 | vmbreak; | ||
902 | } | ||
903 | vmcase(OP_SUB) { | ||
904 | TValue *rb = RKB(i); | ||
905 | TValue *rc = RKC(i); | ||
906 | lua_Number nb; lua_Number nc; | ||
907 | if (ttisinteger(rb) && ttisinteger(rc)) { | ||
908 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | ||
909 | setivalue(ra, intop(-, ib, ic)); | ||
910 | } | ||
911 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | ||
912 | setfltvalue(ra, luai_numsub(L, nb, nc)); | ||
913 | } | ||
914 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); } | ||
915 | vmbreak; | ||
916 | } | ||
917 | vmcase(OP_MUL) { | ||
918 | TValue *rb = RKB(i); | ||
919 | TValue *rc = RKC(i); | ||
920 | lua_Number nb; lua_Number nc; | ||
921 | if (ttisinteger(rb) && ttisinteger(rc)) { | ||
922 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | ||
923 | setivalue(ra, intop(*, ib, ic)); | ||
924 | } | ||
925 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | ||
926 | setfltvalue(ra, luai_nummul(L, nb, nc)); | ||
927 | } | ||
928 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); } | ||
929 | vmbreak; | ||
930 | } | ||
931 | vmcase(OP_DIV) { /* float division (always with floats) */ | ||
932 | TValue *rb = RKB(i); | ||
933 | TValue *rc = RKC(i); | ||
934 | lua_Number nb; lua_Number nc; | ||
935 | if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | ||
936 | setfltvalue(ra, luai_numdiv(L, nb, nc)); | ||
937 | } | ||
938 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); } | ||
939 | vmbreak; | ||
940 | } | ||
941 | vmcase(OP_BAND) { | ||
942 | TValue *rb = RKB(i); | ||
943 | TValue *rc = RKC(i); | ||
944 | lua_Integer ib; lua_Integer ic; | ||
945 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
946 | setivalue(ra, intop(&, ib, ic)); | ||
947 | } | ||
948 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } | ||
949 | vmbreak; | ||
950 | } | ||
951 | vmcase(OP_BOR) { | ||
952 | TValue *rb = RKB(i); | ||
953 | TValue *rc = RKC(i); | ||
954 | lua_Integer ib; lua_Integer ic; | ||
955 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
956 | setivalue(ra, intop(|, ib, ic)); | ||
957 | } | ||
958 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } | ||
959 | vmbreak; | ||
960 | } | ||
961 | vmcase(OP_BXOR) { | ||
962 | TValue *rb = RKB(i); | ||
963 | TValue *rc = RKC(i); | ||
964 | lua_Integer ib; lua_Integer ic; | ||
965 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
966 | setivalue(ra, intop(^, ib, ic)); | ||
967 | } | ||
968 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | ||
969 | vmbreak; | ||
970 | } | ||
971 | vmcase(OP_SHL) { | ||
972 | TValue *rb = RKB(i); | ||
973 | TValue *rc = RKC(i); | ||
974 | lua_Integer ib; lua_Integer ic; | ||
975 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
976 | setivalue(ra, luaV_shiftl(ib, ic)); | ||
977 | } | ||
978 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } | ||
979 | vmbreak; | ||
980 | } | ||
981 | vmcase(OP_SHR) { | ||
982 | TValue *rb = RKB(i); | ||
983 | TValue *rc = RKC(i); | ||
984 | lua_Integer ib; lua_Integer ic; | ||
985 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
986 | setivalue(ra, luaV_shiftl(ib, -ic)); | ||
987 | } | ||
988 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } | ||
989 | vmbreak; | ||
990 | } | ||
991 | vmcase(OP_MOD) { | ||
992 | TValue *rb = RKB(i); | ||
993 | TValue *rc = RKC(i); | ||
994 | lua_Number nb; lua_Number nc; | ||
995 | if (ttisinteger(rb) && ttisinteger(rc)) { | ||
996 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | ||
997 | setivalue(ra, luaV_mod(L, ib, ic)); | ||
998 | } | ||
999 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | ||
1000 | lua_Number m; | ||
1001 | luai_nummod(L, nb, nc, m); | ||
1002 | setfltvalue(ra, m); | ||
1003 | } | ||
1004 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); } | ||
1005 | vmbreak; | ||
1006 | } | ||
1007 | vmcase(OP_IDIV) { /* floor division */ | ||
1008 | TValue *rb = RKB(i); | ||
1009 | TValue *rc = RKC(i); | ||
1010 | lua_Number nb; lua_Number nc; | ||
1011 | if (ttisinteger(rb) && ttisinteger(rc)) { | ||
1012 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | ||
1013 | setivalue(ra, luaV_div(L, ib, ic)); | ||
1014 | } | ||
1015 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | ||
1016 | setfltvalue(ra, luai_numidiv(L, nb, nc)); | ||
1017 | } | ||
1018 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } | ||
1019 | vmbreak; | ||
1020 | } | ||
1021 | vmcase(OP_POW) { | ||
1022 | TValue *rb = RKB(i); | ||
1023 | TValue *rc = RKC(i); | ||
1024 | lua_Number nb; lua_Number nc; | ||
1025 | if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | ||
1026 | setfltvalue(ra, luai_numpow(L, nb, nc)); | ||
1027 | } | ||
1028 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); } | ||
1029 | vmbreak; | ||
1030 | } | ||
1031 | vmcase(OP_UNM) { | ||
1032 | TValue *rb = RB(i); | ||
1033 | lua_Number nb; | ||
1034 | if (ttisinteger(rb)) { | ||
1035 | lua_Integer ib = ivalue(rb); | ||
1036 | setivalue(ra, intop(-, 0, ib)); | ||
1037 | } | ||
1038 | else if (tonumber(rb, &nb)) { | ||
1039 | setfltvalue(ra, luai_numunm(L, nb)); | ||
1040 | } | ||
1041 | else { | ||
1042 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); | ||
1043 | } | ||
1044 | vmbreak; | ||
1045 | } | ||
1046 | vmcase(OP_BNOT) { | ||
1047 | TValue *rb = RB(i); | ||
1048 | lua_Integer ib; | ||
1049 | if (tointeger(rb, &ib)) { | ||
1050 | setivalue(ra, intop(^, ~l_castS2U(0), ib)); | ||
1051 | } | ||
1052 | else { | ||
1053 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); | ||
1054 | } | ||
1055 | vmbreak; | ||
1056 | } | ||
1057 | vmcase(OP_NOT) { | ||
1058 | TValue *rb = RB(i); | ||
1059 | int res = l_isfalse(rb); /* next assignment may change this value */ | ||
1060 | setbvalue(ra, res); | ||
1061 | vmbreak; | ||
1062 | } | ||
1063 | vmcase(OP_LEN) { | ||
1064 | Protect(luaV_objlen(L, ra, RB(i))); | ||
1065 | vmbreak; | ||
1066 | } | ||
1067 | vmcase(OP_CONCAT) { | ||
1068 | int b = GETARG_B(i); | ||
1069 | int c = GETARG_C(i); | ||
1070 | StkId rb; | ||
1071 | L->top = base + c + 1; /* mark the end of concat operands */ | ||
1072 | Protect(luaV_concat(L, c - b + 1)); | ||
1073 | ra = RA(i); /* 'luaV_concat' may invoke TMs and move the stack */ | ||
1074 | rb = base + b; | ||
1075 | setobjs2s(L, ra, rb); | ||
1076 | checkGC(L, (ra >= rb ? ra + 1 : rb)); | ||
1077 | L->top = ci->top; /* restore top */ | ||
1078 | vmbreak; | ||
1079 | } | ||
1080 | vmcase(OP_JMP) { | ||
1081 | dojump(ci, i, 0); | ||
1082 | vmbreak; | ||
1083 | } | ||
1084 | vmcase(OP_EQ) { | ||
1085 | TValue *rb = RKB(i); | ||
1086 | TValue *rc = RKC(i); | ||
1087 | Protect( | ||
1088 | if (luaV_equalobj(L, rb, rc) != GETARG_A(i)) | ||
1089 | ci->u.l.savedpc++; | ||
1090 | else | ||
1091 | donextjump(ci); | ||
1092 | ) | ||
1093 | vmbreak; | ||
1094 | } | ||
1095 | vmcase(OP_LT) { | ||
1096 | Protect( | ||
1097 | if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) | ||
1098 | ci->u.l.savedpc++; | ||
1099 | else | ||
1100 | donextjump(ci); | ||
1101 | ) | ||
1102 | vmbreak; | ||
1103 | } | ||
1104 | vmcase(OP_LE) { | ||
1105 | Protect( | ||
1106 | if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) | ||
1107 | ci->u.l.savedpc++; | ||
1108 | else | ||
1109 | donextjump(ci); | ||
1110 | ) | ||
1111 | vmbreak; | ||
1112 | } | ||
1113 | vmcase(OP_TEST) { | ||
1114 | if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) | ||
1115 | ci->u.l.savedpc++; | ||
1116 | else | ||
1117 | donextjump(ci); | ||
1118 | vmbreak; | ||
1119 | } | ||
1120 | vmcase(OP_TESTSET) { | ||
1121 | TValue *rb = RB(i); | ||
1122 | if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) | ||
1123 | ci->u.l.savedpc++; | ||
1124 | else { | ||
1125 | setobjs2s(L, ra, rb); | ||
1126 | donextjump(ci); | ||
1127 | } | ||
1128 | vmbreak; | ||
1129 | } | ||
1130 | vmcase(OP_CALL) { | ||
1131 | int b = GETARG_B(i); | ||
1132 | int nresults = GETARG_C(i) - 1; | ||
1133 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | ||
1134 | if (luaD_precall(L, ra, nresults)) { /* C function? */ | ||
1135 | if (nresults >= 0) | ||
1136 | L->top = ci->top; /* adjust results */ | ||
1137 | Protect((void)0); /* update 'base' */ | ||
1138 | } | ||
1139 | else { /* Lua function */ | ||
1140 | ci = L->ci; | ||
1141 | goto newframe; /* restart luaV_execute over new Lua function */ | ||
1142 | } | ||
1143 | vmbreak; | ||
1144 | } | ||
1145 | vmcase(OP_TAILCALL) { | ||
1146 | int b = GETARG_B(i); | ||
1147 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | ||
1148 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | ||
1149 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ | ||
1150 | Protect((void)0); /* update 'base' */ | ||
1151 | } | ||
1152 | else { | ||
1153 | /* tail call: put called frame (n) in place of caller one (o) */ | ||
1154 | CallInfo *nci = L->ci; /* called frame */ | ||
1155 | CallInfo *oci = nci->previous; /* caller frame */ | ||
1156 | StkId nfunc = nci->func; /* called function */ | ||
1157 | StkId ofunc = oci->func; /* caller function */ | ||
1158 | /* last stack slot filled by 'precall' */ | ||
1159 | StkId lim = nci->u.l.base + getproto(nfunc)->numparams; | ||
1160 | int aux; | ||
1161 | /* close all upvalues from previous call */ | ||
1162 | if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); | ||
1163 | /* move new frame into old one */ | ||
1164 | for (aux = 0; nfunc + aux < lim; aux++) | ||
1165 | setobjs2s(L, ofunc + aux, nfunc + aux); | ||
1166 | oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ | ||
1167 | oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ | ||
1168 | oci->u.l.savedpc = nci->u.l.savedpc; | ||
1169 | oci->callstatus |= CIST_TAIL; /* function was tail called */ | ||
1170 | ci = L->ci = oci; /* remove new frame */ | ||
1171 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); | ||
1172 | goto newframe; /* restart luaV_execute over new Lua function */ | ||
1173 | } | ||
1174 | vmbreak; | ||
1175 | } | ||
1176 | vmcase(OP_RETURN) { | ||
1177 | int b = GETARG_B(i); | ||
1178 | if (cl->p->sizep > 0) luaF_close(L, base); | ||
1179 | b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); | ||
1180 | if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */ | ||
1181 | return; /* external invocation: return */ | ||
1182 | else { /* invocation via reentry: continue execution */ | ||
1183 | ci = L->ci; | ||
1184 | if (b) L->top = ci->top; | ||
1185 | lua_assert(isLua(ci)); | ||
1186 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); | ||
1187 | goto newframe; /* restart luaV_execute over new Lua function */ | ||
1188 | } | ||
1189 | } | ||
1190 | vmcase(OP_FORLOOP) { | ||
1191 | if (ttisinteger(ra)) { /* integer loop? */ | ||
1192 | lua_Integer step = ivalue(ra + 2); | ||
1193 | lua_Integer idx = intop(+, ivalue(ra), step); /* increment index */ | ||
1194 | lua_Integer limit = ivalue(ra + 1); | ||
1195 | if ((0 < step) ? (idx <= limit) : (limit <= idx)) { | ||
1196 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | ||
1197 | chgivalue(ra, idx); /* update internal index... */ | ||
1198 | setivalue(ra + 3, idx); /* ...and external index */ | ||
1199 | } | ||
1200 | } | ||
1201 | else { /* floating loop */ | ||
1202 | lua_Number step = fltvalue(ra + 2); | ||
1203 | lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */ | ||
1204 | lua_Number limit = fltvalue(ra + 1); | ||
1205 | if (luai_numlt(0, step) ? luai_numle(idx, limit) | ||
1206 | : luai_numle(limit, idx)) { | ||
1207 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | ||
1208 | chgfltvalue(ra, idx); /* update internal index... */ | ||
1209 | setfltvalue(ra + 3, idx); /* ...and external index */ | ||
1210 | } | ||
1211 | } | ||
1212 | vmbreak; | ||
1213 | } | ||
1214 | vmcase(OP_FORPREP) { | ||
1215 | TValue *init = ra; | ||
1216 | TValue *plimit = ra + 1; | ||
1217 | TValue *pstep = ra + 2; | ||
1218 | lua_Integer ilimit; | ||
1219 | int stopnow; | ||
1220 | if (ttisinteger(init) && ttisinteger(pstep) && | ||
1221 | forlimit(plimit, &ilimit, ivalue(pstep), &stopnow)) { | ||
1222 | /* all values are integer */ | ||
1223 | lua_Integer initv = (stopnow ? 0 : ivalue(init)); | ||
1224 | setivalue(plimit, ilimit); | ||
1225 | setivalue(init, intop(-, initv, ivalue(pstep))); | ||
1226 | } | ||
1227 | else { /* try making all values floats */ | ||
1228 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; | ||
1229 | if (!tonumber(plimit, &nlimit)) | ||
1230 | luaG_runerror(L, "'for' limit must be a number"); | ||
1231 | setfltvalue(plimit, nlimit); | ||
1232 | if (!tonumber(pstep, &nstep)) | ||
1233 | luaG_runerror(L, "'for' step must be a number"); | ||
1234 | setfltvalue(pstep, nstep); | ||
1235 | if (!tonumber(init, &ninit)) | ||
1236 | luaG_runerror(L, "'for' initial value must be a number"); | ||
1237 | setfltvalue(init, luai_numsub(L, ninit, nstep)); | ||
1238 | } | ||
1239 | ci->u.l.savedpc += GETARG_sBx(i); | ||
1240 | vmbreak; | ||
1241 | } | ||
1242 | vmcase(OP_TFORCALL) { | ||
1243 | StkId cb = ra + 3; /* call base */ | ||
1244 | setobjs2s(L, cb+2, ra+2); | ||
1245 | setobjs2s(L, cb+1, ra+1); | ||
1246 | setobjs2s(L, cb, ra); | ||
1247 | L->top = cb + 3; /* func. + 2 args (state and index) */ | ||
1248 | Protect(luaD_call(L, cb, GETARG_C(i))); | ||
1249 | L->top = ci->top; | ||
1250 | i = *(ci->u.l.savedpc++); /* go to next instruction */ | ||
1251 | ra = RA(i); | ||
1252 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); | ||
1253 | goto l_tforloop; | ||
1254 | } | ||
1255 | vmcase(OP_TFORLOOP) { | ||
1256 | l_tforloop: | ||
1257 | if (!ttisnil(ra + 1)) { /* continue loop? */ | ||
1258 | setobjs2s(L, ra, ra + 1); /* save control variable */ | ||
1259 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | ||
1260 | } | ||
1261 | vmbreak; | ||
1262 | } | ||
1263 | vmcase(OP_SETLIST) { | ||
1264 | int n = GETARG_B(i); | ||
1265 | int c = GETARG_C(i); | ||
1266 | unsigned int last; | ||
1267 | Table *h; | ||
1268 | if (n == 0) n = cast_int(L->top - ra) - 1; | ||
1269 | if (c == 0) { | ||
1270 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); | ||
1271 | c = GETARG_Ax(*ci->u.l.savedpc++); | ||
1272 | } | ||
1273 | h = hvalue(ra); | ||
1274 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | ||
1275 | if (last > h->sizearray) /* needs more space? */ | ||
1276 | luaH_resizearray(L, h, last); /* preallocate it at once */ | ||
1277 | for (; n > 0; n--) { | ||
1278 | TValue *val = ra+n; | ||
1279 | luaH_setint(L, h, last--, val); | ||
1280 | luaC_barrierback(L, h, val); | ||
1281 | } | ||
1282 | L->top = ci->top; /* correct top (in case of previous open call) */ | ||
1283 | vmbreak; | ||
1284 | } | ||
1285 | vmcase(OP_CLOSURE) { | ||
1286 | Proto *p = cl->p->p[GETARG_Bx(i)]; | ||
1287 | LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ | ||
1288 | if (ncl == NULL) /* no match? */ | ||
1289 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ | ||
1290 | else | ||
1291 | setclLvalue(L, ra, ncl); /* push cashed closure */ | ||
1292 | checkGC(L, ra + 1); | ||
1293 | vmbreak; | ||
1294 | } | ||
1295 | vmcase(OP_VARARG) { | ||
1296 | int b = GETARG_B(i) - 1; /* required results */ | ||
1297 | int j; | ||
1298 | int n = cast_int(base - ci->func) - cl->p->numparams - 1; | ||
1299 | if (n < 0) /* less arguments than parameters? */ | ||
1300 | n = 0; /* no vararg arguments */ | ||
1301 | if (b < 0) { /* B == 0? */ | ||
1302 | b = n; /* get all var. arguments */ | ||
1303 | Protect(luaD_checkstack(L, n)); | ||
1304 | ra = RA(i); /* previous call may change the stack */ | ||
1305 | L->top = ra + n; | ||
1306 | } | ||
1307 | for (j = 0; j < b && j < n; j++) | ||
1308 | setobjs2s(L, ra + j, base - n + j); | ||
1309 | for (; j < b; j++) /* complete required results with nil */ | ||
1310 | setnilvalue(ra + j); | ||
1311 | vmbreak; | ||
1312 | } | ||
1313 | vmcase(OP_EXTRAARG) { | ||
1314 | lua_assert(0); | ||
1315 | vmbreak; | ||
1316 | } | ||
1317 | } | ||
1318 | } | ||
1319 | } | ||
1320 | |||
1321 | /* }================================================================== */ | ||
1322 | |||
diff --git a/src/lua-5.3/lvm.h b/src/lua-5.3/lvm.h deleted file mode 100644 index a8f954f..0000000 --- a/src/lua-5.3/lvm.h +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $ | ||
3 | ** Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lvm_h | ||
8 | #define lvm_h | ||
9 | |||
10 | |||
11 | #include "ldo.h" | ||
12 | #include "lobject.h" | ||
13 | #include "ltm.h" | ||
14 | |||
15 | |||
16 | #if !defined(LUA_NOCVTN2S) | ||
17 | #define cvt2str(o) ttisnumber(o) | ||
18 | #else | ||
19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ | ||
20 | #endif | ||
21 | |||
22 | |||
23 | #if !defined(LUA_NOCVTS2N) | ||
24 | #define cvt2num(o) ttisstring(o) | ||
25 | #else | ||
26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ | ||
27 | #endif | ||
28 | |||
29 | |||
30 | /* | ||
31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers | ||
32 | ** by flooring them (instead of raising an error if they are not | ||
33 | ** integral values) | ||
34 | */ | ||
35 | #if !defined(LUA_FLOORN2I) | ||
36 | #define LUA_FLOORN2I 0 | ||
37 | #endif | ||
38 | |||
39 | |||
40 | #define tonumber(o,n) \ | ||
41 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) | ||
42 | |||
43 | #define tointeger(o,i) \ | ||
44 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) | ||
45 | |||
46 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) | ||
47 | |||
48 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) | ||
49 | |||
50 | |||
51 | /* | ||
52 | ** fast track for 'gettable': if 't' is a table and 't[k]' is not nil, | ||
53 | ** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise, | ||
54 | ** return 0 (meaning it will have to check metamethod) with 'slot' | ||
55 | ** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise). | ||
56 | ** 'f' is the raw get function to use. | ||
57 | */ | ||
58 | #define luaV_fastget(L,t,k,slot,f) \ | ||
59 | (!ttistable(t) \ | ||
60 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ | ||
61 | : (slot = f(hvalue(t), k), /* else, do raw access */ \ | ||
62 | !ttisnil(slot))) /* result not nil? */ | ||
63 | |||
64 | /* | ||
65 | ** standard implementation for 'gettable' | ||
66 | */ | ||
67 | #define luaV_gettable(L,t,k,v) { const TValue *slot; \ | ||
68 | if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \ | ||
69 | else luaV_finishget(L,t,k,v,slot); } | ||
70 | |||
71 | |||
72 | /* | ||
73 | ** Fast track for set table. If 't' is a table and 't[k]' is not nil, | ||
74 | ** call GC barrier, do a raw 't[k]=v', and return true; otherwise, | ||
75 | ** return false with 'slot' equal to NULL (if 't' is not a table) or | ||
76 | ** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro | ||
77 | ** returns true, there is no need to 'invalidateTMcache', because the | ||
78 | ** call is not creating a new entry. | ||
79 | */ | ||
80 | #define luaV_fastset(L,t,k,slot,f,v) \ | ||
81 | (!ttistable(t) \ | ||
82 | ? (slot = NULL, 0) \ | ||
83 | : (slot = f(hvalue(t), k), \ | ||
84 | ttisnil(slot) ? 0 \ | ||
85 | : (luaC_barrierback(L, hvalue(t), v), \ | ||
86 | setobj2t(L, cast(TValue *,slot), v), \ | ||
87 | 1))) | ||
88 | |||
89 | |||
90 | #define luaV_settable(L,t,k,v) { const TValue *slot; \ | ||
91 | if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ | ||
92 | luaV_finishset(L,t,k,v,slot); } | ||
93 | |||
94 | |||
95 | |||
96 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); | ||
97 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); | ||
98 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); | ||
99 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); | ||
100 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); | ||
101 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, | ||
102 | StkId val, const TValue *slot); | ||
103 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | ||
104 | StkId val, const TValue *slot); | ||
105 | LUAI_FUNC void luaV_finishOp (lua_State *L); | ||
106 | LUAI_FUNC void luaV_execute (lua_State *L); | ||
107 | LUAI_FUNC void luaV_concat (lua_State *L, int total); | ||
108 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); | ||
109 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); | ||
110 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); | ||
111 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); | ||
112 | |||
113 | #endif | ||
diff --git a/src/lua-5.3/lapi.c b/src/lua/lapi.c index 711895b..3e24781 100644 --- a/src/lua-5.3/lapi.c +++ b/src/lua/lapi.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.259.1.2 2017/12/06 18:35:12 roberto Exp $ | 2 | ** $Id: lapi.c $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -10,6 +10,7 @@ | |||
10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
11 | 11 | ||
12 | 12 | ||
13 | #include <limits.h> | ||
13 | #include <stdarg.h> | 14 | #include <stdarg.h> |
14 | #include <string.h> | 15 | #include <string.h> |
15 | 16 | ||
@@ -36,11 +37,14 @@ const char lua_ident[] = | |||
36 | "$LuaAuthors: " LUA_AUTHORS " $"; | 37 | "$LuaAuthors: " LUA_AUTHORS " $"; |
37 | 38 | ||
38 | 39 | ||
39 | /* value at a non-valid index */ | ||
40 | #define NONVALIDVALUE cast(TValue *, luaO_nilobject) | ||
41 | 40 | ||
42 | /* corresponding test */ | 41 | /* |
43 | #define isvalid(o) ((o) != luaO_nilobject) | 42 | ** Test for a valid index. |
43 | ** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed. | ||
44 | ** However, it covers the most common cases in a faster way. | ||
45 | */ | ||
46 | #define isvalid(L, o) (!ttisnil(o) || o != &G(L)->nilvalue) | ||
47 | |||
44 | 48 | ||
45 | /* test for pseudo index */ | 49 | /* test for pseudo index */ |
46 | #define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) | 50 | #define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) |
@@ -48,49 +52,46 @@ const char lua_ident[] = | |||
48 | /* test for upvalue */ | 52 | /* test for upvalue */ |
49 | #define isupvalue(i) ((i) < LUA_REGISTRYINDEX) | 53 | #define isupvalue(i) ((i) < LUA_REGISTRYINDEX) |
50 | 54 | ||
51 | /* test for valid but not pseudo index */ | ||
52 | #define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) | ||
53 | |||
54 | #define api_checkvalidindex(l,o) api_check(l, isvalid(o), "invalid index") | ||
55 | |||
56 | #define api_checkstackindex(l, i, o) \ | ||
57 | api_check(l, isstackindex(i, o), "index not in the stack") | ||
58 | 55 | ||
59 | 56 | static TValue *index2value (lua_State *L, int idx) { | |
60 | static TValue *index2addr (lua_State *L, int idx) { | ||
61 | CallInfo *ci = L->ci; | 57 | CallInfo *ci = L->ci; |
62 | if (idx > 0) { | 58 | if (idx > 0) { |
63 | TValue *o = ci->func + idx; | 59 | StkId o = ci->func + idx; |
64 | api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); | 60 | api_check(L, idx <= L->ci->top - (ci->func + 1), "unacceptable index"); |
65 | if (o >= L->top) return NONVALIDVALUE; | 61 | if (o >= L->top) return &G(L)->nilvalue; |
66 | else return o; | 62 | else return s2v(o); |
67 | } | 63 | } |
68 | else if (!ispseudo(idx)) { /* negative index */ | 64 | else if (!ispseudo(idx)) { /* negative index */ |
69 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); | 65 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
70 | return L->top + idx; | 66 | return s2v(L->top + idx); |
71 | } | 67 | } |
72 | else if (idx == LUA_REGISTRYINDEX) | 68 | else if (idx == LUA_REGISTRYINDEX) |
73 | return &G(L)->l_registry; | 69 | return &G(L)->l_registry; |
74 | else { /* upvalues */ | 70 | else { /* upvalues */ |
75 | idx = LUA_REGISTRYINDEX - idx; | 71 | idx = LUA_REGISTRYINDEX - idx; |
76 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); | 72 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); |
77 | if (ttislcf(ci->func)) /* light C function? */ | 73 | if (ttislcf(s2v(ci->func))) /* light C function? */ |
78 | return NONVALIDVALUE; /* it has no upvalues */ | 74 | return &G(L)->nilvalue; /* it has no upvalues */ |
79 | else { | 75 | else { |
80 | CClosure *func = clCvalue(ci->func); | 76 | CClosure *func = clCvalue(s2v(ci->func)); |
81 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; | 77 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : &G(L)->nilvalue; |
82 | } | 78 | } |
83 | } | 79 | } |
84 | } | 80 | } |
85 | 81 | ||
86 | 82 | ||
87 | /* | 83 | static StkId index2stack (lua_State *L, int idx) { |
88 | ** to be called by 'lua_checkstack' in protected mode, to grow stack | 84 | CallInfo *ci = L->ci; |
89 | ** capturing memory errors | 85 | if (idx > 0) { |
90 | */ | 86 | StkId o = ci->func + idx; |
91 | static void growstack (lua_State *L, void *ud) { | 87 | api_check(L, o < L->top, "unacceptable index"); |
92 | int size = *(int *)ud; | 88 | return o; |
93 | luaD_growstack(L, size); | 89 | } |
90 | else { /* non-positive index */ | ||
91 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); | ||
92 | api_check(L, !ispseudo(idx), "invalid index"); | ||
93 | return L->top + idx; | ||
94 | } | ||
94 | } | 95 | } |
95 | 96 | ||
96 | 97 | ||
@@ -106,7 +107,7 @@ LUA_API int lua_checkstack (lua_State *L, int n) { | |||
106 | if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */ | 107 | if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */ |
107 | res = 0; /* no */ | 108 | res = 0; /* no */ |
108 | else /* try to grow stack */ | 109 | else /* try to grow stack */ |
109 | res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK); | 110 | res = luaD_growstack(L, n, 0); |
110 | } | 111 | } |
111 | if (res && ci->top < L->top + n) | 112 | if (res && ci->top < L->top + n) |
112 | ci->top = L->top + n; /* adjust frame top */ | 113 | ci->top = L->top + n; /* adjust frame top */ |
@@ -124,7 +125,7 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { | |||
124 | api_check(from, to->ci->top - to->top >= n, "stack overflow"); | 125 | api_check(from, to->ci->top - to->top >= n, "stack overflow"); |
125 | from->top -= n; | 126 | from->top -= n; |
126 | for (i = 0; i < n; i++) { | 127 | for (i = 0; i < n; i++) { |
127 | setobj2s(to, to->top, from->top + i); | 128 | setobjs2s(to, to->top, from->top + i); |
128 | to->top++; /* stack already checked by previous 'api_check' */ | 129 | to->top++; /* stack already checked by previous 'api_check' */ |
129 | } | 130 | } |
130 | lua_unlock(to); | 131 | lua_unlock(to); |
@@ -141,10 +142,9 @@ LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { | |||
141 | } | 142 | } |
142 | 143 | ||
143 | 144 | ||
144 | LUA_API const lua_Number *lua_version (lua_State *L) { | 145 | LUA_API lua_Number lua_version (lua_State *L) { |
145 | static const lua_Number version = LUA_VERSION_NUM; | 146 | UNUSED(L); |
146 | if (L == NULL) return &version; | 147 | return LUA_VERSION_NUM; |
147 | else return G(L)->version; | ||
148 | } | 148 | } |
149 | 149 | ||
150 | 150 | ||
@@ -170,18 +170,23 @@ LUA_API int lua_gettop (lua_State *L) { | |||
170 | 170 | ||
171 | 171 | ||
172 | LUA_API void lua_settop (lua_State *L, int idx) { | 172 | LUA_API void lua_settop (lua_State *L, int idx) { |
173 | StkId func = L->ci->func; | 173 | CallInfo *ci = L->ci; |
174 | StkId func = ci->func; | ||
175 | ptrdiff_t diff; /* difference for new top */ | ||
174 | lua_lock(L); | 176 | lua_lock(L); |
175 | if (idx >= 0) { | 177 | if (idx >= 0) { |
176 | api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); | 178 | api_check(L, idx <= ci->top - (func + 1), "new top too large"); |
177 | while (L->top < (func + 1) + idx) | 179 | diff = ((func + 1) + idx) - L->top; |
178 | setnilvalue(L->top++); | 180 | for (; diff > 0; diff--) |
179 | L->top = (func + 1) + idx; | 181 | setnilvalue(s2v(L->top++)); /* clear new slots */ |
180 | } | 182 | } |
181 | else { | 183 | else { |
182 | api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); | 184 | api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); |
183 | L->top += idx+1; /* 'subtract' index (index is negative) */ | 185 | diff = idx + 1; /* will "subtract" index (as it is negative) */ |
184 | } | 186 | } |
187 | if (diff < 0 && hastocloseCfunc(ci->nresults)) | ||
188 | luaF_close(L, L->top + diff, LUA_OK); | ||
189 | L->top += diff; /* correct top only after closing any upvalue */ | ||
185 | lua_unlock(L); | 190 | lua_unlock(L); |
186 | } | 191 | } |
187 | 192 | ||
@@ -189,11 +194,13 @@ LUA_API void lua_settop (lua_State *L, int idx) { | |||
189 | /* | 194 | /* |
190 | ** Reverse the stack segment from 'from' to 'to' | 195 | ** Reverse the stack segment from 'from' to 'to' |
191 | ** (auxiliary to 'lua_rotate') | 196 | ** (auxiliary to 'lua_rotate') |
197 | ** Note that we move(copy) only the value inside the stack. | ||
198 | ** (We do not move additional fields that may exist.) | ||
192 | */ | 199 | */ |
193 | static void reverse (lua_State *L, StkId from, StkId to) { | 200 | static void reverse (lua_State *L, StkId from, StkId to) { |
194 | for (; from < to; from++, to--) { | 201 | for (; from < to; from++, to--) { |
195 | TValue temp; | 202 | TValue temp; |
196 | setobj(L, &temp, from); | 203 | setobj(L, &temp, s2v(from)); |
197 | setobjs2s(L, from, to); | 204 | setobjs2s(L, from, to); |
198 | setobj2s(L, to, &temp); | 205 | setobj2s(L, to, &temp); |
199 | } | 206 | } |
@@ -208,8 +215,7 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) { | |||
208 | StkId p, t, m; | 215 | StkId p, t, m; |
209 | lua_lock(L); | 216 | lua_lock(L); |
210 | t = L->top - 1; /* end of stack segment being rotated */ | 217 | t = L->top - 1; /* end of stack segment being rotated */ |
211 | p = index2addr(L, idx); /* start of segment */ | 218 | p = index2stack(L, idx); /* start of segment */ |
212 | api_checkstackindex(L, idx, p); | ||
213 | api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'"); | 219 | api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'"); |
214 | m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */ | 220 | m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */ |
215 | reverse(L, p, m); /* reverse the prefix with length 'n' */ | 221 | reverse(L, p, m); /* reverse the prefix with length 'n' */ |
@@ -222,12 +228,12 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) { | |||
222 | LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { | 228 | LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { |
223 | TValue *fr, *to; | 229 | TValue *fr, *to; |
224 | lua_lock(L); | 230 | lua_lock(L); |
225 | fr = index2addr(L, fromidx); | 231 | fr = index2value(L, fromidx); |
226 | to = index2addr(L, toidx); | 232 | to = index2value(L, toidx); |
227 | api_checkvalidindex(L, to); | 233 | api_check(L, isvalid(L, to), "invalid index"); |
228 | setobj(L, to, fr); | 234 | setobj(L, to, fr); |
229 | if (isupvalue(toidx)) /* function upvalue? */ | 235 | if (isupvalue(toidx)) /* function upvalue? */ |
230 | luaC_barrier(L, clCvalue(L->ci->func), fr); | 236 | luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr); |
231 | /* LUA_REGISTRYINDEX does not need gc barrier | 237 | /* LUA_REGISTRYINDEX does not need gc barrier |
232 | (collector revisits it before finishing collection) */ | 238 | (collector revisits it before finishing collection) */ |
233 | lua_unlock(L); | 239 | lua_unlock(L); |
@@ -236,7 +242,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { | |||
236 | 242 | ||
237 | LUA_API void lua_pushvalue (lua_State *L, int idx) { | 243 | LUA_API void lua_pushvalue (lua_State *L, int idx) { |
238 | lua_lock(L); | 244 | lua_lock(L); |
239 | setobj2s(L, L->top, index2addr(L, idx)); | 245 | setobj2s(L, L->top, index2value(L, idx)); |
240 | api_incr_top(L); | 246 | api_incr_top(L); |
241 | lua_unlock(L); | 247 | lua_unlock(L); |
242 | } | 248 | } |
@@ -249,53 +255,53 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { | |||
249 | 255 | ||
250 | 256 | ||
251 | LUA_API int lua_type (lua_State *L, int idx) { | 257 | LUA_API int lua_type (lua_State *L, int idx) { |
252 | StkId o = index2addr(L, idx); | 258 | const TValue *o = index2value(L, idx); |
253 | return (isvalid(o) ? ttnov(o) : LUA_TNONE); | 259 | return (isvalid(L, o) ? ttype(o) : LUA_TNONE); |
254 | } | 260 | } |
255 | 261 | ||
256 | 262 | ||
257 | LUA_API const char *lua_typename (lua_State *L, int t) { | 263 | LUA_API const char *lua_typename (lua_State *L, int t) { |
258 | UNUSED(L); | 264 | UNUSED(L); |
259 | api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag"); | 265 | api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type"); |
260 | return ttypename(t); | 266 | return ttypename(t); |
261 | } | 267 | } |
262 | 268 | ||
263 | 269 | ||
264 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | 270 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
265 | StkId o = index2addr(L, idx); | 271 | const TValue *o = index2value(L, idx); |
266 | return (ttislcf(o) || (ttisCclosure(o))); | 272 | return (ttislcf(o) || (ttisCclosure(o))); |
267 | } | 273 | } |
268 | 274 | ||
269 | 275 | ||
270 | LUA_API int lua_isinteger (lua_State *L, int idx) { | 276 | LUA_API int lua_isinteger (lua_State *L, int idx) { |
271 | StkId o = index2addr(L, idx); | 277 | const TValue *o = index2value(L, idx); |
272 | return ttisinteger(o); | 278 | return ttisinteger(o); |
273 | } | 279 | } |
274 | 280 | ||
275 | 281 | ||
276 | LUA_API int lua_isnumber (lua_State *L, int idx) { | 282 | LUA_API int lua_isnumber (lua_State *L, int idx) { |
277 | lua_Number n; | 283 | lua_Number n; |
278 | const TValue *o = index2addr(L, idx); | 284 | const TValue *o = index2value(L, idx); |
279 | return tonumber(o, &n); | 285 | return tonumber(o, &n); |
280 | } | 286 | } |
281 | 287 | ||
282 | 288 | ||
283 | LUA_API int lua_isstring (lua_State *L, int idx) { | 289 | LUA_API int lua_isstring (lua_State *L, int idx) { |
284 | const TValue *o = index2addr(L, idx); | 290 | const TValue *o = index2value(L, idx); |
285 | return (ttisstring(o) || cvt2str(o)); | 291 | return (ttisstring(o) || cvt2str(o)); |
286 | } | 292 | } |
287 | 293 | ||
288 | 294 | ||
289 | LUA_API int lua_isuserdata (lua_State *L, int idx) { | 295 | LUA_API int lua_isuserdata (lua_State *L, int idx) { |
290 | const TValue *o = index2addr(L, idx); | 296 | const TValue *o = index2value(L, idx); |
291 | return (ttisfulluserdata(o) || ttislightuserdata(o)); | 297 | return (ttisfulluserdata(o) || ttislightuserdata(o)); |
292 | } | 298 | } |
293 | 299 | ||
294 | 300 | ||
295 | LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { | 301 | LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { |
296 | StkId o1 = index2addr(L, index1); | 302 | const TValue *o1 = index2value(L, index1); |
297 | StkId o2 = index2addr(L, index2); | 303 | const TValue *o2 = index2value(L, index2); |
298 | return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; | 304 | return (isvalid(L, o1) && isvalid(L, o2)) ? luaV_rawequalobj(o1, o2) : 0; |
299 | } | 305 | } |
300 | 306 | ||
301 | 307 | ||
@@ -309,19 +315,20 @@ LUA_API void lua_arith (lua_State *L, int op) { | |||
309 | api_incr_top(L); | 315 | api_incr_top(L); |
310 | } | 316 | } |
311 | /* first operand at top - 2, second at top - 1; result go to top - 2 */ | 317 | /* first operand at top - 2, second at top - 1; result go to top - 2 */ |
312 | luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2); | 318 | luaO_arith(L, op, s2v(L->top - 2), s2v(L->top - 1), L->top - 2); |
313 | L->top--; /* remove second operand */ | 319 | L->top--; /* remove second operand */ |
314 | lua_unlock(L); | 320 | lua_unlock(L); |
315 | } | 321 | } |
316 | 322 | ||
317 | 323 | ||
318 | LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { | 324 | LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { |
319 | StkId o1, o2; | 325 | const TValue *o1; |
326 | const TValue *o2; | ||
320 | int i = 0; | 327 | int i = 0; |
321 | lua_lock(L); /* may call tag method */ | 328 | lua_lock(L); /* may call tag method */ |
322 | o1 = index2addr(L, index1); | 329 | o1 = index2value(L, index1); |
323 | o2 = index2addr(L, index2); | 330 | o2 = index2value(L, index2); |
324 | if (isvalid(o1) && isvalid(o2)) { | 331 | if (isvalid(L, o1) && isvalid(L, o2)) { |
325 | switch (op) { | 332 | switch (op) { |
326 | case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break; | 333 | case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break; |
327 | case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; | 334 | case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; |
@@ -335,7 +342,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { | |||
335 | 342 | ||
336 | 343 | ||
337 | LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { | 344 | LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { |
338 | size_t sz = luaO_str2num(s, L->top); | 345 | size_t sz = luaO_str2num(s, s2v(L->top)); |
339 | if (sz != 0) | 346 | if (sz != 0) |
340 | api_incr_top(L); | 347 | api_incr_top(L); |
341 | return sz; | 348 | return sz; |
@@ -343,35 +350,33 @@ LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { | |||
343 | 350 | ||
344 | 351 | ||
345 | LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { | 352 | LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { |
346 | lua_Number n; | 353 | lua_Number n = 0; |
347 | const TValue *o = index2addr(L, idx); | 354 | const TValue *o = index2value(L, idx); |
348 | int isnum = tonumber(o, &n); | 355 | int isnum = tonumber(o, &n); |
349 | if (!isnum) | 356 | if (pisnum) |
350 | n = 0; /* call to 'tonumber' may change 'n' even if it fails */ | 357 | *pisnum = isnum; |
351 | if (pisnum) *pisnum = isnum; | ||
352 | return n; | 358 | return n; |
353 | } | 359 | } |
354 | 360 | ||
355 | 361 | ||
356 | LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { | 362 | LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { |
357 | lua_Integer res; | 363 | lua_Integer res = 0; |
358 | const TValue *o = index2addr(L, idx); | 364 | const TValue *o = index2value(L, idx); |
359 | int isnum = tointeger(o, &res); | 365 | int isnum = tointeger(o, &res); |
360 | if (!isnum) | 366 | if (pisnum) |
361 | res = 0; /* call to 'tointeger' may change 'n' even if it fails */ | 367 | *pisnum = isnum; |
362 | if (pisnum) *pisnum = isnum; | ||
363 | return res; | 368 | return res; |
364 | } | 369 | } |
365 | 370 | ||
366 | 371 | ||
367 | LUA_API int lua_toboolean (lua_State *L, int idx) { | 372 | LUA_API int lua_toboolean (lua_State *L, int idx) { |
368 | const TValue *o = index2addr(L, idx); | 373 | const TValue *o = index2value(L, idx); |
369 | return !l_isfalse(o); | 374 | return !l_isfalse(o); |
370 | } | 375 | } |
371 | 376 | ||
372 | 377 | ||
373 | LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { | 378 | LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { |
374 | StkId o = index2addr(L, idx); | 379 | TValue *o = index2value(L, idx); |
375 | if (!ttisstring(o)) { | 380 | if (!ttisstring(o)) { |
376 | if (!cvt2str(o)) { /* not convertible? */ | 381 | if (!cvt2str(o)) { /* not convertible? */ |
377 | if (len != NULL) *len = 0; | 382 | if (len != NULL) *len = 0; |
@@ -380,7 +385,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { | |||
380 | lua_lock(L); /* 'luaO_tostring' may create a new string */ | 385 | lua_lock(L); /* 'luaO_tostring' may create a new string */ |
381 | luaO_tostring(L, o); | 386 | luaO_tostring(L, o); |
382 | luaC_checkGC(L); | 387 | luaC_checkGC(L); |
383 | o = index2addr(L, idx); /* previous call may reallocate the stack */ | 388 | o = index2value(L, idx); /* previous call may reallocate the stack */ |
384 | lua_unlock(L); | 389 | lua_unlock(L); |
385 | } | 390 | } |
386 | if (len != NULL) | 391 | if (len != NULL) |
@@ -389,20 +394,20 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { | |||
389 | } | 394 | } |
390 | 395 | ||
391 | 396 | ||
392 | LUA_API size_t lua_rawlen (lua_State *L, int idx) { | 397 | LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) { |
393 | StkId o = index2addr(L, idx); | 398 | const TValue *o = index2value(L, idx); |
394 | switch (ttype(o)) { | 399 | switch (ttypetag(o)) { |
395 | case LUA_TSHRSTR: return tsvalue(o)->shrlen; | 400 | case LUA_VSHRSTR: return tsvalue(o)->shrlen; |
396 | case LUA_TLNGSTR: return tsvalue(o)->u.lnglen; | 401 | case LUA_VLNGSTR: return tsvalue(o)->u.lnglen; |
397 | case LUA_TUSERDATA: return uvalue(o)->len; | 402 | case LUA_VUSERDATA: return uvalue(o)->len; |
398 | case LUA_TTABLE: return luaH_getn(hvalue(o)); | 403 | case LUA_VTABLE: return luaH_getn(hvalue(o)); |
399 | default: return 0; | 404 | default: return 0; |
400 | } | 405 | } |
401 | } | 406 | } |
402 | 407 | ||
403 | 408 | ||
404 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | 409 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
405 | StkId o = index2addr(L, idx); | 410 | const TValue *o = index2value(L, idx); |
406 | if (ttislcf(o)) return fvalue(o); | 411 | if (ttislcf(o)) return fvalue(o); |
407 | else if (ttisCclosure(o)) | 412 | else if (ttisCclosure(o)) |
408 | return clCvalue(o)->f; | 413 | return clCvalue(o)->f; |
@@ -410,9 +415,8 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | |||
410 | } | 415 | } |
411 | 416 | ||
412 | 417 | ||
413 | LUA_API void *lua_touserdata (lua_State *L, int idx) { | 418 | static void *touserdata (const TValue *o) { |
414 | StkId o = index2addr(L, idx); | 419 | switch (ttype(o)) { |
415 | switch (ttnov(o)) { | ||
416 | case LUA_TUSERDATA: return getudatamem(uvalue(o)); | 420 | case LUA_TUSERDATA: return getudatamem(uvalue(o)); |
417 | case LUA_TLIGHTUSERDATA: return pvalue(o); | 421 | case LUA_TLIGHTUSERDATA: return pvalue(o); |
418 | default: return NULL; | 422 | default: return NULL; |
@@ -420,23 +424,37 @@ LUA_API void *lua_touserdata (lua_State *L, int idx) { | |||
420 | } | 424 | } |
421 | 425 | ||
422 | 426 | ||
427 | LUA_API void *lua_touserdata (lua_State *L, int idx) { | ||
428 | const TValue *o = index2value(L, idx); | ||
429 | return touserdata(o); | ||
430 | } | ||
431 | |||
432 | |||
423 | LUA_API lua_State *lua_tothread (lua_State *L, int idx) { | 433 | LUA_API lua_State *lua_tothread (lua_State *L, int idx) { |
424 | StkId o = index2addr(L, idx); | 434 | const TValue *o = index2value(L, idx); |
425 | return (!ttisthread(o)) ? NULL : thvalue(o); | 435 | return (!ttisthread(o)) ? NULL : thvalue(o); |
426 | } | 436 | } |
427 | 437 | ||
428 | 438 | ||
439 | /* | ||
440 | ** Returns a pointer to the internal representation of an object. | ||
441 | ** Note that ANSI C does not allow the conversion of a pointer to | ||
442 | ** function to a 'void*', so the conversion here goes through | ||
443 | ** a 'size_t'. (As the returned pointer is only informative, this | ||
444 | ** conversion should not be a problem.) | ||
445 | */ | ||
429 | LUA_API const void *lua_topointer (lua_State *L, int idx) { | 446 | LUA_API const void *lua_topointer (lua_State *L, int idx) { |
430 | StkId o = index2addr(L, idx); | 447 | const TValue *o = index2value(L, idx); |
431 | switch (ttype(o)) { | 448 | switch (ttypetag(o)) { |
432 | case LUA_TTABLE: return hvalue(o); | 449 | case LUA_VLCF: return cast_voidp(cast_sizet(fvalue(o))); |
433 | case LUA_TLCL: return clLvalue(o); | 450 | case LUA_VUSERDATA: case LUA_VLIGHTUSERDATA: |
434 | case LUA_TCCL: return clCvalue(o); | 451 | return touserdata(o); |
435 | case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); | 452 | default: { |
436 | case LUA_TTHREAD: return thvalue(o); | 453 | if (iscollectable(o)) |
437 | case LUA_TUSERDATA: return getudatamem(uvalue(o)); | 454 | return gcvalue(o); |
438 | case LUA_TLIGHTUSERDATA: return pvalue(o); | 455 | else |
439 | default: return NULL; | 456 | return NULL; |
457 | } | ||
440 | } | 458 | } |
441 | } | 459 | } |
442 | 460 | ||
@@ -449,7 +467,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { | |||
449 | 467 | ||
450 | LUA_API void lua_pushnil (lua_State *L) { | 468 | LUA_API void lua_pushnil (lua_State *L) { |
451 | lua_lock(L); | 469 | lua_lock(L); |
452 | setnilvalue(L->top); | 470 | setnilvalue(s2v(L->top)); |
453 | api_incr_top(L); | 471 | api_incr_top(L); |
454 | lua_unlock(L); | 472 | lua_unlock(L); |
455 | } | 473 | } |
@@ -457,7 +475,7 @@ LUA_API void lua_pushnil (lua_State *L) { | |||
457 | 475 | ||
458 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { | 476 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { |
459 | lua_lock(L); | 477 | lua_lock(L); |
460 | setfltvalue(L->top, n); | 478 | setfltvalue(s2v(L->top), n); |
461 | api_incr_top(L); | 479 | api_incr_top(L); |
462 | lua_unlock(L); | 480 | lua_unlock(L); |
463 | } | 481 | } |
@@ -465,7 +483,7 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { | |||
465 | 483 | ||
466 | LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { | 484 | LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { |
467 | lua_lock(L); | 485 | lua_lock(L); |
468 | setivalue(L->top, n); | 486 | setivalue(s2v(L->top), n); |
469 | api_incr_top(L); | 487 | api_incr_top(L); |
470 | lua_unlock(L); | 488 | lua_unlock(L); |
471 | } | 489 | } |
@@ -491,7 +509,7 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { | |||
491 | LUA_API const char *lua_pushstring (lua_State *L, const char *s) { | 509 | LUA_API const char *lua_pushstring (lua_State *L, const char *s) { |
492 | lua_lock(L); | 510 | lua_lock(L); |
493 | if (s == NULL) | 511 | if (s == NULL) |
494 | setnilvalue(L->top); | 512 | setnilvalue(s2v(L->top)); |
495 | else { | 513 | else { |
496 | TString *ts; | 514 | TString *ts; |
497 | ts = luaS_new(L, s); | 515 | ts = luaS_new(L, s); |
@@ -532,7 +550,7 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { | |||
532 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | 550 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { |
533 | lua_lock(L); | 551 | lua_lock(L); |
534 | if (n == 0) { | 552 | if (n == 0) { |
535 | setfvalue(L->top, fn); | 553 | setfvalue(s2v(L->top), fn); |
536 | api_incr_top(L); | 554 | api_incr_top(L); |
537 | } | 555 | } |
538 | else { | 556 | else { |
@@ -543,10 +561,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
543 | cl->f = fn; | 561 | cl->f = fn; |
544 | L->top -= n; | 562 | L->top -= n; |
545 | while (n--) { | 563 | while (n--) { |
546 | setobj2n(L, &cl->upvalue[n], L->top + n); | 564 | setobj2n(L, &cl->upvalue[n], s2v(L->top + n)); |
547 | /* does not need barrier because closure is white */ | 565 | /* does not need barrier because closure is white */ |
548 | } | 566 | } |
549 | setclCvalue(L, L->top, cl); | 567 | setclCvalue(L, s2v(L->top), cl); |
550 | api_incr_top(L); | 568 | api_incr_top(L); |
551 | luaC_checkGC(L); | 569 | luaC_checkGC(L); |
552 | } | 570 | } |
@@ -556,7 +574,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
556 | 574 | ||
557 | LUA_API void lua_pushboolean (lua_State *L, int b) { | 575 | LUA_API void lua_pushboolean (lua_State *L, int b) { |
558 | lua_lock(L); | 576 | lua_lock(L); |
559 | setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ | 577 | if (b) |
578 | setbtvalue(s2v(L->top)); | ||
579 | else | ||
580 | setbfvalue(s2v(L->top)); | ||
560 | api_incr_top(L); | 581 | api_incr_top(L); |
561 | lua_unlock(L); | 582 | lua_unlock(L); |
562 | } | 583 | } |
@@ -564,7 +585,7 @@ LUA_API void lua_pushboolean (lua_State *L, int b) { | |||
564 | 585 | ||
565 | LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { | 586 | LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { |
566 | lua_lock(L); | 587 | lua_lock(L); |
567 | setpvalue(L->top, p); | 588 | setpvalue(s2v(L->top), p); |
568 | api_incr_top(L); | 589 | api_incr_top(L); |
569 | lua_unlock(L); | 590 | lua_unlock(L); |
570 | } | 591 | } |
@@ -572,7 +593,7 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { | |||
572 | 593 | ||
573 | LUA_API int lua_pushthread (lua_State *L) { | 594 | LUA_API int lua_pushthread (lua_State *L) { |
574 | lua_lock(L); | 595 | lua_lock(L); |
575 | setthvalue(L, L->top, L); | 596 | setthvalue(L, s2v(L->top), L); |
576 | api_incr_top(L); | 597 | api_incr_top(L); |
577 | lua_unlock(L); | 598 | lua_unlock(L); |
578 | return (G(L)->mainthread == L); | 599 | return (G(L)->mainthread == L); |
@@ -595,10 +616,10 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) { | |||
595 | else { | 616 | else { |
596 | setsvalue2s(L, L->top, str); | 617 | setsvalue2s(L, L->top, str); |
597 | api_incr_top(L); | 618 | api_incr_top(L); |
598 | luaV_finishget(L, t, L->top - 1, L->top - 1, slot); | 619 | luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot); |
599 | } | 620 | } |
600 | lua_unlock(L); | 621 | lua_unlock(L); |
601 | return ttnov(L->top - 1); | 622 | return ttype(s2v(L->top - 1)); |
602 | } | 623 | } |
603 | 624 | ||
604 | 625 | ||
@@ -610,74 +631,90 @@ LUA_API int lua_getglobal (lua_State *L, const char *name) { | |||
610 | 631 | ||
611 | 632 | ||
612 | LUA_API int lua_gettable (lua_State *L, int idx) { | 633 | LUA_API int lua_gettable (lua_State *L, int idx) { |
613 | StkId t; | 634 | const TValue *slot; |
635 | TValue *t; | ||
614 | lua_lock(L); | 636 | lua_lock(L); |
615 | t = index2addr(L, idx); | 637 | t = index2value(L, idx); |
616 | luaV_gettable(L, t, L->top - 1, L->top - 1); | 638 | if (luaV_fastget(L, t, s2v(L->top - 1), slot, luaH_get)) { |
639 | setobj2s(L, L->top - 1, slot); | ||
640 | } | ||
641 | else | ||
642 | luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot); | ||
617 | lua_unlock(L); | 643 | lua_unlock(L); |
618 | return ttnov(L->top - 1); | 644 | return ttype(s2v(L->top - 1)); |
619 | } | 645 | } |
620 | 646 | ||
621 | 647 | ||
622 | LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { | 648 | LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { |
623 | lua_lock(L); | 649 | lua_lock(L); |
624 | return auxgetstr(L, index2addr(L, idx), k); | 650 | return auxgetstr(L, index2value(L, idx), k); |
625 | } | 651 | } |
626 | 652 | ||
627 | 653 | ||
628 | LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { | 654 | LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { |
629 | StkId t; | 655 | TValue *t; |
630 | const TValue *slot; | 656 | const TValue *slot; |
631 | lua_lock(L); | 657 | lua_lock(L); |
632 | t = index2addr(L, idx); | 658 | t = index2value(L, idx); |
633 | if (luaV_fastget(L, t, n, slot, luaH_getint)) { | 659 | if (luaV_fastgeti(L, t, n, slot)) { |
634 | setobj2s(L, L->top, slot); | 660 | setobj2s(L, L->top, slot); |
635 | api_incr_top(L); | ||
636 | } | 661 | } |
637 | else { | 662 | else { |
638 | setivalue(L->top, n); | 663 | TValue aux; |
639 | api_incr_top(L); | 664 | setivalue(&aux, n); |
640 | luaV_finishget(L, t, L->top - 1, L->top - 1, slot); | 665 | luaV_finishget(L, t, &aux, L->top, slot); |
641 | } | 666 | } |
667 | api_incr_top(L); | ||
642 | lua_unlock(L); | 668 | lua_unlock(L); |
643 | return ttnov(L->top - 1); | 669 | return ttype(s2v(L->top - 1)); |
670 | } | ||
671 | |||
672 | |||
673 | static int finishrawget (lua_State *L, const TValue *val) { | ||
674 | if (isempty(val)) /* avoid copying empty items to the stack */ | ||
675 | setnilvalue(s2v(L->top)); | ||
676 | else | ||
677 | setobj2s(L, L->top, val); | ||
678 | api_incr_top(L); | ||
679 | lua_unlock(L); | ||
680 | return ttype(s2v(L->top - 1)); | ||
681 | } | ||
682 | |||
683 | |||
684 | static Table *gettable (lua_State *L, int idx) { | ||
685 | TValue *t = index2value(L, idx); | ||
686 | api_check(L, ttistable(t), "table expected"); | ||
687 | return hvalue(t); | ||
644 | } | 688 | } |
645 | 689 | ||
646 | 690 | ||
647 | LUA_API int lua_rawget (lua_State *L, int idx) { | 691 | LUA_API int lua_rawget (lua_State *L, int idx) { |
648 | StkId t; | 692 | Table *t; |
693 | const TValue *val; | ||
649 | lua_lock(L); | 694 | lua_lock(L); |
650 | t = index2addr(L, idx); | 695 | api_checknelems(L, 1); |
651 | api_check(L, ttistable(t), "table expected"); | 696 | t = gettable(L, idx); |
652 | setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); | 697 | val = luaH_get(t, s2v(L->top - 1)); |
653 | lua_unlock(L); | 698 | L->top--; /* remove key */ |
654 | return ttnov(L->top - 1); | 699 | return finishrawget(L, val); |
655 | } | 700 | } |
656 | 701 | ||
657 | 702 | ||
658 | LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { | 703 | LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { |
659 | StkId t; | 704 | Table *t; |
660 | lua_lock(L); | 705 | lua_lock(L); |
661 | t = index2addr(L, idx); | 706 | t = gettable(L, idx); |
662 | api_check(L, ttistable(t), "table expected"); | 707 | return finishrawget(L, luaH_getint(t, n)); |
663 | setobj2s(L, L->top, luaH_getint(hvalue(t), n)); | ||
664 | api_incr_top(L); | ||
665 | lua_unlock(L); | ||
666 | return ttnov(L->top - 1); | ||
667 | } | 708 | } |
668 | 709 | ||
669 | 710 | ||
670 | LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { | 711 | LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { |
671 | StkId t; | 712 | Table *t; |
672 | TValue k; | 713 | TValue k; |
673 | lua_lock(L); | 714 | lua_lock(L); |
674 | t = index2addr(L, idx); | 715 | t = gettable(L, idx); |
675 | api_check(L, ttistable(t), "table expected"); | 716 | setpvalue(&k, cast_voidp(p)); |
676 | setpvalue(&k, cast(void *, p)); | 717 | return finishrawget(L, luaH_get(t, &k)); |
677 | setobj2s(L, L->top, luaH_get(hvalue(t), &k)); | ||
678 | api_incr_top(L); | ||
679 | lua_unlock(L); | ||
680 | return ttnov(L->top - 1); | ||
681 | } | 718 | } |
682 | 719 | ||
683 | 720 | ||
@@ -685,7 +722,7 @@ LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { | |||
685 | Table *t; | 722 | Table *t; |
686 | lua_lock(L); | 723 | lua_lock(L); |
687 | t = luaH_new(L); | 724 | t = luaH_new(L); |
688 | sethvalue(L, L->top, t); | 725 | sethvalue2s(L, L->top, t); |
689 | api_incr_top(L); | 726 | api_incr_top(L); |
690 | if (narray > 0 || nrec > 0) | 727 | if (narray > 0 || nrec > 0) |
691 | luaH_resize(L, t, narray, nrec); | 728 | luaH_resize(L, t, narray, nrec); |
@@ -699,8 +736,8 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { | |||
699 | Table *mt; | 736 | Table *mt; |
700 | int res = 0; | 737 | int res = 0; |
701 | lua_lock(L); | 738 | lua_lock(L); |
702 | obj = index2addr(L, objindex); | 739 | obj = index2value(L, objindex); |
703 | switch (ttnov(obj)) { | 740 | switch (ttype(obj)) { |
704 | case LUA_TTABLE: | 741 | case LUA_TTABLE: |
705 | mt = hvalue(obj)->metatable; | 742 | mt = hvalue(obj)->metatable; |
706 | break; | 743 | break; |
@@ -708,11 +745,11 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { | |||
708 | mt = uvalue(obj)->metatable; | 745 | mt = uvalue(obj)->metatable; |
709 | break; | 746 | break; |
710 | default: | 747 | default: |
711 | mt = G(L)->mt[ttnov(obj)]; | 748 | mt = G(L)->mt[ttype(obj)]; |
712 | break; | 749 | break; |
713 | } | 750 | } |
714 | if (mt != NULL) { | 751 | if (mt != NULL) { |
715 | sethvalue(L, L->top, mt); | 752 | sethvalue2s(L, L->top, mt); |
716 | api_incr_top(L); | 753 | api_incr_top(L); |
717 | res = 1; | 754 | res = 1; |
718 | } | 755 | } |
@@ -721,15 +758,23 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { | |||
721 | } | 758 | } |
722 | 759 | ||
723 | 760 | ||
724 | LUA_API int lua_getuservalue (lua_State *L, int idx) { | 761 | LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) { |
725 | StkId o; | 762 | TValue *o; |
763 | int t; | ||
726 | lua_lock(L); | 764 | lua_lock(L); |
727 | o = index2addr(L, idx); | 765 | o = index2value(L, idx); |
728 | api_check(L, ttisfulluserdata(o), "full userdata expected"); | 766 | api_check(L, ttisfulluserdata(o), "full userdata expected"); |
729 | getuservalue(L, uvalue(o), L->top); | 767 | if (n <= 0 || n > uvalue(o)->nuvalue) { |
768 | setnilvalue(s2v(L->top)); | ||
769 | t = LUA_TNONE; | ||
770 | } | ||
771 | else { | ||
772 | setobj2s(L, L->top, &uvalue(o)->uv[n - 1].uv); | ||
773 | t = ttype(s2v(L->top)); | ||
774 | } | ||
730 | api_incr_top(L); | 775 | api_incr_top(L); |
731 | lua_unlock(L); | 776 | lua_unlock(L); |
732 | return ttnov(L->top - 1); | 777 | return t; |
733 | } | 778 | } |
734 | 779 | ||
735 | 780 | ||
@@ -744,12 +789,14 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) { | |||
744 | const TValue *slot; | 789 | const TValue *slot; |
745 | TString *str = luaS_new(L, k); | 790 | TString *str = luaS_new(L, k); |
746 | api_checknelems(L, 1); | 791 | api_checknelems(L, 1); |
747 | if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1)) | 792 | if (luaV_fastget(L, t, str, slot, luaH_getstr)) { |
793 | luaV_finishfastset(L, t, slot, s2v(L->top - 1)); | ||
748 | L->top--; /* pop value */ | 794 | L->top--; /* pop value */ |
795 | } | ||
749 | else { | 796 | else { |
750 | setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */ | 797 | setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */ |
751 | api_incr_top(L); | 798 | api_incr_top(L); |
752 | luaV_finishset(L, t, L->top - 1, L->top - 2, slot); | 799 | luaV_finishset(L, t, s2v(L->top - 1), s2v(L->top - 2), slot); |
753 | L->top -= 2; /* pop value and key */ | 800 | L->top -= 2; /* pop value and key */ |
754 | } | 801 | } |
755 | lua_unlock(L); /* lock done by caller */ | 802 | lua_unlock(L); /* lock done by caller */ |
@@ -764,11 +811,16 @@ LUA_API void lua_setglobal (lua_State *L, const char *name) { | |||
764 | 811 | ||
765 | 812 | ||
766 | LUA_API void lua_settable (lua_State *L, int idx) { | 813 | LUA_API void lua_settable (lua_State *L, int idx) { |
767 | StkId t; | 814 | TValue *t; |
815 | const TValue *slot; | ||
768 | lua_lock(L); | 816 | lua_lock(L); |
769 | api_checknelems(L, 2); | 817 | api_checknelems(L, 2); |
770 | t = index2addr(L, idx); | 818 | t = index2value(L, idx); |
771 | luaV_settable(L, t, L->top - 2, L->top - 1); | 819 | if (luaV_fastget(L, t, s2v(L->top - 2), slot, luaH_get)) { |
820 | luaV_finishfastset(L, t, slot, s2v(L->top - 1)); | ||
821 | } | ||
822 | else | ||
823 | luaV_finishset(L, t, s2v(L->top - 2), s2v(L->top - 1), slot); | ||
772 | L->top -= 2; /* pop index and value */ | 824 | L->top -= 2; /* pop index and value */ |
773 | lua_unlock(L); | 825 | lua_unlock(L); |
774 | } | 826 | } |
@@ -776,68 +828,63 @@ LUA_API void lua_settable (lua_State *L, int idx) { | |||
776 | 828 | ||
777 | LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { | 829 | LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { |
778 | lua_lock(L); /* unlock done in 'auxsetstr' */ | 830 | lua_lock(L); /* unlock done in 'auxsetstr' */ |
779 | auxsetstr(L, index2addr(L, idx), k); | 831 | auxsetstr(L, index2value(L, idx), k); |
780 | } | 832 | } |
781 | 833 | ||
782 | 834 | ||
783 | LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { | 835 | LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { |
784 | StkId t; | 836 | TValue *t; |
785 | const TValue *slot; | 837 | const TValue *slot; |
786 | lua_lock(L); | 838 | lua_lock(L); |
787 | api_checknelems(L, 1); | 839 | api_checknelems(L, 1); |
788 | t = index2addr(L, idx); | 840 | t = index2value(L, idx); |
789 | if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1)) | 841 | if (luaV_fastgeti(L, t, n, slot)) { |
790 | L->top--; /* pop value */ | 842 | luaV_finishfastset(L, t, slot, s2v(L->top - 1)); |
843 | } | ||
791 | else { | 844 | else { |
792 | setivalue(L->top, n); | 845 | TValue aux; |
793 | api_incr_top(L); | 846 | setivalue(&aux, n); |
794 | luaV_finishset(L, t, L->top - 1, L->top - 2, slot); | 847 | luaV_finishset(L, t, &aux, s2v(L->top - 1), slot); |
795 | L->top -= 2; /* pop value and key */ | ||
796 | } | 848 | } |
849 | L->top--; /* pop value */ | ||
797 | lua_unlock(L); | 850 | lua_unlock(L); |
798 | } | 851 | } |
799 | 852 | ||
800 | 853 | ||
801 | LUA_API void lua_rawset (lua_State *L, int idx) { | 854 | static void aux_rawset (lua_State *L, int idx, TValue *key, int n) { |
802 | StkId o; | 855 | Table *t; |
803 | TValue *slot; | 856 | TValue *slot; |
804 | lua_lock(L); | 857 | lua_lock(L); |
805 | api_checknelems(L, 2); | 858 | api_checknelems(L, n); |
806 | o = index2addr(L, idx); | 859 | t = gettable(L, idx); |
807 | api_check(L, ttistable(o), "table expected"); | 860 | slot = luaH_set(L, t, key); |
808 | slot = luaH_set(L, hvalue(o), L->top - 2); | 861 | setobj2t(L, slot, s2v(L->top - 1)); |
809 | setobj2t(L, slot, L->top - 1); | 862 | invalidateTMcache(t); |
810 | invalidateTMcache(hvalue(o)); | 863 | luaC_barrierback(L, obj2gco(t), s2v(L->top - 1)); |
811 | luaC_barrierback(L, hvalue(o), L->top-1); | 864 | L->top -= n; |
812 | L->top -= 2; | ||
813 | lua_unlock(L); | 865 | lua_unlock(L); |
814 | } | 866 | } |
815 | 867 | ||
816 | 868 | ||
817 | LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { | 869 | LUA_API void lua_rawset (lua_State *L, int idx) { |
818 | StkId o; | 870 | aux_rawset(L, idx, s2v(L->top - 2), 2); |
819 | lua_lock(L); | ||
820 | api_checknelems(L, 1); | ||
821 | o = index2addr(L, idx); | ||
822 | api_check(L, ttistable(o), "table expected"); | ||
823 | luaH_setint(L, hvalue(o), n, L->top - 1); | ||
824 | luaC_barrierback(L, hvalue(o), L->top-1); | ||
825 | L->top--; | ||
826 | lua_unlock(L); | ||
827 | } | 871 | } |
828 | 872 | ||
829 | 873 | ||
830 | LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { | 874 | LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { |
831 | StkId o; | 875 | TValue k; |
832 | TValue k, *slot; | 876 | setpvalue(&k, cast_voidp(p)); |
877 | aux_rawset(L, idx, &k, 1); | ||
878 | } | ||
879 | |||
880 | |||
881 | LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { | ||
882 | Table *t; | ||
833 | lua_lock(L); | 883 | lua_lock(L); |
834 | api_checknelems(L, 1); | 884 | api_checknelems(L, 1); |
835 | o = index2addr(L, idx); | 885 | t = gettable(L, idx); |
836 | api_check(L, ttistable(o), "table expected"); | 886 | luaH_setint(L, t, n, s2v(L->top - 1)); |
837 | setpvalue(&k, cast(void *, p)); | 887 | luaC_barrierback(L, obj2gco(t), s2v(L->top - 1)); |
838 | slot = luaH_set(L, hvalue(o), &k); | ||
839 | setobj2t(L, slot, L->top - 1); | ||
840 | luaC_barrierback(L, hvalue(o), L->top - 1); | ||
841 | L->top--; | 888 | L->top--; |
842 | lua_unlock(L); | 889 | lua_unlock(L); |
843 | } | 890 | } |
@@ -848,14 +895,14 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
848 | Table *mt; | 895 | Table *mt; |
849 | lua_lock(L); | 896 | lua_lock(L); |
850 | api_checknelems(L, 1); | 897 | api_checknelems(L, 1); |
851 | obj = index2addr(L, objindex); | 898 | obj = index2value(L, objindex); |
852 | if (ttisnil(L->top - 1)) | 899 | if (ttisnil(s2v(L->top - 1))) |
853 | mt = NULL; | 900 | mt = NULL; |
854 | else { | 901 | else { |
855 | api_check(L, ttistable(L->top - 1), "table expected"); | 902 | api_check(L, ttistable(s2v(L->top - 1)), "table expected"); |
856 | mt = hvalue(L->top - 1); | 903 | mt = hvalue(s2v(L->top - 1)); |
857 | } | 904 | } |
858 | switch (ttnov(obj)) { | 905 | switch (ttype(obj)) { |
859 | case LUA_TTABLE: { | 906 | case LUA_TTABLE: { |
860 | hvalue(obj)->metatable = mt; | 907 | hvalue(obj)->metatable = mt; |
861 | if (mt) { | 908 | if (mt) { |
@@ -873,7 +920,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
873 | break; | 920 | break; |
874 | } | 921 | } |
875 | default: { | 922 | default: { |
876 | G(L)->mt[ttnov(obj)] = mt; | 923 | G(L)->mt[ttype(obj)] = mt; |
877 | break; | 924 | break; |
878 | } | 925 | } |
879 | } | 926 | } |
@@ -883,16 +930,23 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
883 | } | 930 | } |
884 | 931 | ||
885 | 932 | ||
886 | LUA_API void lua_setuservalue (lua_State *L, int idx) { | 933 | LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) { |
887 | StkId o; | 934 | TValue *o; |
935 | int res; | ||
888 | lua_lock(L); | 936 | lua_lock(L); |
889 | api_checknelems(L, 1); | 937 | api_checknelems(L, 1); |
890 | o = index2addr(L, idx); | 938 | o = index2value(L, idx); |
891 | api_check(L, ttisfulluserdata(o), "full userdata expected"); | 939 | api_check(L, ttisfulluserdata(o), "full userdata expected"); |
892 | setuservalue(L, uvalue(o), L->top - 1); | 940 | if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue))) |
893 | luaC_barrier(L, gcvalue(o), L->top - 1); | 941 | res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */ |
942 | else { | ||
943 | setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1)); | ||
944 | luaC_barrierback(L, gcvalue(o), s2v(L->top - 1)); | ||
945 | res = 1; | ||
946 | } | ||
894 | L->top--; | 947 | L->top--; |
895 | lua_unlock(L); | 948 | lua_unlock(L); |
949 | return res; | ||
896 | } | 950 | } |
897 | 951 | ||
898 | 952 | ||
@@ -916,7 +970,7 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults, | |||
916 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); | 970 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); |
917 | checkresults(L, nargs, nresults); | 971 | checkresults(L, nargs, nresults); |
918 | func = L->top - (nargs+1); | 972 | func = L->top - (nargs+1); |
919 | if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ | 973 | if (k != NULL && yieldable(L)) { /* need to prepare continuation? */ |
920 | L->ci->u.c.k = k; /* save continuation */ | 974 | L->ci->u.c.k = k; /* save continuation */ |
921 | L->ci->u.c.ctx = ctx; /* save context */ | 975 | L->ci->u.c.ctx = ctx; /* save context */ |
922 | luaD_call(L, func, nresults); /* do the call */ | 976 | luaD_call(L, func, nresults); /* do the call */ |
@@ -959,12 +1013,12 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, | |||
959 | if (errfunc == 0) | 1013 | if (errfunc == 0) |
960 | func = 0; | 1014 | func = 0; |
961 | else { | 1015 | else { |
962 | StkId o = index2addr(L, errfunc); | 1016 | StkId o = index2stack(L, errfunc); |
963 | api_checkstackindex(L, errfunc, o); | 1017 | api_check(L, ttisfunction(s2v(o)), "error handler must be a function"); |
964 | func = savestack(L, o); | 1018 | func = savestack(L, o); |
965 | } | 1019 | } |
966 | c.func = L->top - (nargs+1); /* function to be called */ | 1020 | c.func = L->top - (nargs+1); /* function to be called */ |
967 | if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ | 1021 | if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */ |
968 | c.nresults = nresults; /* do a 'conventional' protected call */ | 1022 | c.nresults = nresults; /* do a 'conventional' protected call */ |
969 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); | 1023 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); |
970 | } | 1024 | } |
@@ -973,7 +1027,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, | |||
973 | ci->u.c.k = k; /* save continuation */ | 1027 | ci->u.c.k = k; /* save continuation */ |
974 | ci->u.c.ctx = ctx; /* save context */ | 1028 | ci->u.c.ctx = ctx; /* save context */ |
975 | /* save information for error recovery */ | 1029 | /* save information for error recovery */ |
976 | ci->extra = savestack(L, c.func); | 1030 | ci->u2.funcidx = cast_int(savestack(L, c.func)); |
977 | ci->u.c.old_errfunc = L->errfunc; | 1031 | ci->u.c.old_errfunc = L->errfunc; |
978 | L->errfunc = func; | 1032 | L->errfunc = func; |
979 | setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ | 1033 | setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ |
@@ -998,14 +1052,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, | |||
998 | luaZ_init(L, &z, reader, data); | 1052 | luaZ_init(L, &z, reader, data); |
999 | status = luaD_protectedparser(L, &z, chunkname, mode); | 1053 | status = luaD_protectedparser(L, &z, chunkname, mode); |
1000 | if (status == LUA_OK) { /* no errors? */ | 1054 | if (status == LUA_OK) { /* no errors? */ |
1001 | LClosure *f = clLvalue(L->top - 1); /* get newly created function */ | 1055 | LClosure *f = clLvalue(s2v(L->top - 1)); /* get newly created function */ |
1002 | if (f->nupvalues >= 1) { /* does it have an upvalue? */ | 1056 | if (f->nupvalues >= 1) { /* does it have an upvalue? */ |
1003 | /* get global table from registry */ | 1057 | /* get global table from registry */ |
1004 | Table *reg = hvalue(&G(L)->l_registry); | 1058 | Table *reg = hvalue(&G(L)->l_registry); |
1005 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); | 1059 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); |
1006 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ | 1060 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ |
1007 | setobj(L, f->upvals[0]->v, gt); | 1061 | setobj(L, f->upvals[0]->v, gt); |
1008 | luaC_upvalbarrier(L, f->upvals[0]); | 1062 | luaC_barrier(L, f->upvals[0], gt); |
1009 | } | 1063 | } |
1010 | } | 1064 | } |
1011 | lua_unlock(L); | 1065 | lua_unlock(L); |
@@ -1018,7 +1072,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { | |||
1018 | TValue *o; | 1072 | TValue *o; |
1019 | lua_lock(L); | 1073 | lua_lock(L); |
1020 | api_checknelems(L, 1); | 1074 | api_checknelems(L, 1); |
1021 | o = L->top - 1; | 1075 | o = s2v(L->top - 1); |
1022 | if (isLfunction(o)) | 1076 | if (isLfunction(o)) |
1023 | status = luaU_dump(L, getproto(o), writer, data, strip); | 1077 | status = luaU_dump(L, getproto(o), writer, data, strip); |
1024 | else | 1078 | else |
@@ -1036,12 +1090,12 @@ LUA_API int lua_status (lua_State *L) { | |||
1036 | /* | 1090 | /* |
1037 | ** Garbage-collection function | 1091 | ** Garbage-collection function |
1038 | */ | 1092 | */ |
1039 | 1093 | LUA_API int lua_gc (lua_State *L, int what, ...) { | |
1040 | LUA_API int lua_gc (lua_State *L, int what, int data) { | 1094 | va_list argp; |
1041 | int res = 0; | 1095 | int res = 0; |
1042 | global_State *g; | 1096 | global_State *g = G(L); |
1043 | lua_lock(L); | 1097 | lua_lock(L); |
1044 | g = G(L); | 1098 | va_start(argp, what); |
1045 | switch (what) { | 1099 | switch (what) { |
1046 | case LUA_GCSTOP: { | 1100 | case LUA_GCSTOP: { |
1047 | g->gcrunning = 0; | 1101 | g->gcrunning = 0; |
@@ -1066,11 +1120,12 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
1066 | break; | 1120 | break; |
1067 | } | 1121 | } |
1068 | case LUA_GCSTEP: { | 1122 | case LUA_GCSTEP: { |
1123 | int data = va_arg(argp, int); | ||
1069 | l_mem debt = 1; /* =1 to signal that it did an actual step */ | 1124 | l_mem debt = 1; /* =1 to signal that it did an actual step */ |
1070 | lu_byte oldrunning = g->gcrunning; | 1125 | lu_byte oldrunning = g->gcrunning; |
1071 | g->gcrunning = 1; /* allow GC to run */ | 1126 | g->gcrunning = 1; /* allow GC to run */ |
1072 | if (data == 0) { | 1127 | if (data == 0) { |
1073 | luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */ | 1128 | luaE_setdebt(g, 0); /* do a basic step */ |
1074 | luaC_step(L); | 1129 | luaC_step(L); |
1075 | } | 1130 | } |
1076 | else { /* add 'data' to total debt */ | 1131 | else { /* add 'data' to total debt */ |
@@ -1084,22 +1139,49 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
1084 | break; | 1139 | break; |
1085 | } | 1140 | } |
1086 | case LUA_GCSETPAUSE: { | 1141 | case LUA_GCSETPAUSE: { |
1087 | res = g->gcpause; | 1142 | int data = va_arg(argp, int); |
1088 | g->gcpause = data; | 1143 | res = getgcparam(g->gcpause); |
1144 | setgcparam(g->gcpause, data); | ||
1089 | break; | 1145 | break; |
1090 | } | 1146 | } |
1091 | case LUA_GCSETSTEPMUL: { | 1147 | case LUA_GCSETSTEPMUL: { |
1092 | res = g->gcstepmul; | 1148 | int data = va_arg(argp, int); |
1093 | if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */ | 1149 | res = getgcparam(g->gcstepmul); |
1094 | g->gcstepmul = data; | 1150 | setgcparam(g->gcstepmul, data); |
1095 | break; | 1151 | break; |
1096 | } | 1152 | } |
1097 | case LUA_GCISRUNNING: { | 1153 | case LUA_GCISRUNNING: { |
1098 | res = g->gcrunning; | 1154 | res = g->gcrunning; |
1099 | break; | 1155 | break; |
1100 | } | 1156 | } |
1157 | case LUA_GCGEN: { | ||
1158 | int minormul = va_arg(argp, int); | ||
1159 | int majormul = va_arg(argp, int); | ||
1160 | res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; | ||
1161 | if (minormul != 0) | ||
1162 | g->genminormul = minormul; | ||
1163 | if (majormul != 0) | ||
1164 | setgcparam(g->genmajormul, majormul); | ||
1165 | luaC_changemode(L, KGC_GEN); | ||
1166 | break; | ||
1167 | } | ||
1168 | case LUA_GCINC: { | ||
1169 | int pause = va_arg(argp, int); | ||
1170 | int stepmul = va_arg(argp, int); | ||
1171 | int stepsize = va_arg(argp, int); | ||
1172 | res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; | ||
1173 | if (pause != 0) | ||
1174 | setgcparam(g->gcpause, pause); | ||
1175 | if (stepmul != 0) | ||
1176 | setgcparam(g->gcstepmul, stepmul); | ||
1177 | if (stepsize != 0) | ||
1178 | g->gcstepsize = stepsize; | ||
1179 | luaC_changemode(L, KGC_INC); | ||
1180 | break; | ||
1181 | } | ||
1101 | default: res = -1; /* invalid option */ | 1182 | default: res = -1; /* invalid option */ |
1102 | } | 1183 | } |
1184 | va_end(argp); | ||
1103 | lua_unlock(L); | 1185 | lua_unlock(L); |
1104 | return res; | 1186 | return res; |
1105 | } | 1187 | } |
@@ -1121,12 +1203,12 @@ LUA_API int lua_error (lua_State *L) { | |||
1121 | 1203 | ||
1122 | 1204 | ||
1123 | LUA_API int lua_next (lua_State *L, int idx) { | 1205 | LUA_API int lua_next (lua_State *L, int idx) { |
1124 | StkId t; | 1206 | Table *t; |
1125 | int more; | 1207 | int more; |
1126 | lua_lock(L); | 1208 | lua_lock(L); |
1127 | t = index2addr(L, idx); | 1209 | api_checknelems(L, 1); |
1128 | api_check(L, ttistable(t), "table expected"); | 1210 | t = gettable(L, idx); |
1129 | more = luaH_next(L, hvalue(t), L->top - 1); | 1211 | more = luaH_next(L, t, L->top - 1); |
1130 | if (more) { | 1212 | if (more) { |
1131 | api_incr_top(L); | 1213 | api_incr_top(L); |
1132 | } | 1214 | } |
@@ -1137,6 +1219,22 @@ LUA_API int lua_next (lua_State *L, int idx) { | |||
1137 | } | 1219 | } |
1138 | 1220 | ||
1139 | 1221 | ||
1222 | LUA_API void lua_toclose (lua_State *L, int idx) { | ||
1223 | int nresults; | ||
1224 | StkId o; | ||
1225 | lua_lock(L); | ||
1226 | o = index2stack(L, idx); | ||
1227 | nresults = L->ci->nresults; | ||
1228 | api_check(L, L->openupval == NULL || uplevel(L->openupval) <= o, | ||
1229 | "marked index below or equal new one"); | ||
1230 | luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */ | ||
1231 | if (!hastocloseCfunc(nresults)) /* function not marked yet? */ | ||
1232 | L->ci->nresults = codeNresults(nresults); /* mark it */ | ||
1233 | lua_assert(hastocloseCfunc(L->ci->nresults)); | ||
1234 | lua_unlock(L); | ||
1235 | } | ||
1236 | |||
1237 | |||
1140 | LUA_API void lua_concat (lua_State *L, int n) { | 1238 | LUA_API void lua_concat (lua_State *L, int n) { |
1141 | lua_lock(L); | 1239 | lua_lock(L); |
1142 | api_checknelems(L, n); | 1240 | api_checknelems(L, n); |
@@ -1154,9 +1252,9 @@ LUA_API void lua_concat (lua_State *L, int n) { | |||
1154 | 1252 | ||
1155 | 1253 | ||
1156 | LUA_API void lua_len (lua_State *L, int idx) { | 1254 | LUA_API void lua_len (lua_State *L, int idx) { |
1157 | StkId t; | 1255 | TValue *t; |
1158 | lua_lock(L); | 1256 | lua_lock(L); |
1159 | t = index2addr(L, idx); | 1257 | t = index2value(L, idx); |
1160 | luaV_objlen(L, L->top, t); | 1258 | luaV_objlen(L, L->top, t); |
1161 | api_incr_top(L); | 1259 | api_incr_top(L); |
1162 | lua_unlock(L); | 1260 | lua_unlock(L); |
@@ -1181,11 +1279,28 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { | |||
1181 | } | 1279 | } |
1182 | 1280 | ||
1183 | 1281 | ||
1184 | LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | 1282 | void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) { |
1283 | lua_lock(L); | ||
1284 | G(L)->ud_warn = ud; | ||
1285 | G(L)->warnf = f; | ||
1286 | lua_unlock(L); | ||
1287 | } | ||
1288 | |||
1289 | |||
1290 | void lua_warning (lua_State *L, const char *msg, int tocont) { | ||
1291 | lua_lock(L); | ||
1292 | luaE_warning(L, msg, tocont); | ||
1293 | lua_unlock(L); | ||
1294 | } | ||
1295 | |||
1296 | |||
1297 | |||
1298 | LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) { | ||
1185 | Udata *u; | 1299 | Udata *u; |
1186 | lua_lock(L); | 1300 | lua_lock(L); |
1187 | u = luaS_newudata(L, size); | 1301 | api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value"); |
1188 | setuvalue(L, L->top, u); | 1302 | u = luaS_newudata(L, size, nuvalue); |
1303 | setuvalue(L, s2v(L->top), u); | ||
1189 | api_incr_top(L); | 1304 | api_incr_top(L); |
1190 | luaC_checkGC(L); | 1305 | luaC_checkGC(L); |
1191 | lua_unlock(L); | 1306 | lua_unlock(L); |
@@ -1194,25 +1309,27 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | |||
1194 | 1309 | ||
1195 | 1310 | ||
1196 | 1311 | ||
1197 | static const char *aux_upvalue (StkId fi, int n, TValue **val, | 1312 | static const char *aux_upvalue (TValue *fi, int n, TValue **val, |
1198 | CClosure **owner, UpVal **uv) { | 1313 | GCObject **owner) { |
1199 | switch (ttype(fi)) { | 1314 | switch (ttypetag(fi)) { |
1200 | case LUA_TCCL: { /* C closure */ | 1315 | case LUA_VCCL: { /* C closure */ |
1201 | CClosure *f = clCvalue(fi); | 1316 | CClosure *f = clCvalue(fi); |
1202 | if (!(1 <= n && n <= f->nupvalues)) return NULL; | 1317 | if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues))) |
1318 | return NULL; /* 'n' not in [1, f->nupvalues] */ | ||
1203 | *val = &f->upvalue[n-1]; | 1319 | *val = &f->upvalue[n-1]; |
1204 | if (owner) *owner = f; | 1320 | if (owner) *owner = obj2gco(f); |
1205 | return ""; | 1321 | return ""; |
1206 | } | 1322 | } |
1207 | case LUA_TLCL: { /* Lua closure */ | 1323 | case LUA_VLCL: { /* Lua closure */ |
1208 | LClosure *f = clLvalue(fi); | 1324 | LClosure *f = clLvalue(fi); |
1209 | TString *name; | 1325 | TString *name; |
1210 | Proto *p = f->p; | 1326 | Proto *p = f->p; |
1211 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | 1327 | if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues))) |
1328 | return NULL; /* 'n' not in [1, p->sizeupvalues] */ | ||
1212 | *val = f->upvals[n-1]->v; | 1329 | *val = f->upvals[n-1]->v; |
1213 | if (uv) *uv = f->upvals[n - 1]; | 1330 | if (owner) *owner = obj2gco(f->upvals[n - 1]); |
1214 | name = p->upvalues[n-1].name; | 1331 | name = p->upvalues[n-1].name; |
1215 | return (name == NULL) ? "(*no name)" : getstr(name); | 1332 | return (name == NULL) ? "(no name)" : getstr(name); |
1216 | } | 1333 | } |
1217 | default: return NULL; /* not a closure */ | 1334 | default: return NULL; /* not a closure */ |
1218 | } | 1335 | } |
@@ -1223,7 +1340,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { | |||
1223 | const char *name; | 1340 | const char *name; |
1224 | TValue *val = NULL; /* to avoid warnings */ | 1341 | TValue *val = NULL; /* to avoid warnings */ |
1225 | lua_lock(L); | 1342 | lua_lock(L); |
1226 | name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL); | 1343 | name = aux_upvalue(index2value(L, funcindex), n, &val, NULL); |
1227 | if (name) { | 1344 | if (name) { |
1228 | setobj2s(L, L->top, val); | 1345 | setobj2s(L, L->top, val); |
1229 | api_incr_top(L); | 1346 | api_incr_top(L); |
@@ -1236,41 +1353,40 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { | |||
1236 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | 1353 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { |
1237 | const char *name; | 1354 | const char *name; |
1238 | TValue *val = NULL; /* to avoid warnings */ | 1355 | TValue *val = NULL; /* to avoid warnings */ |
1239 | CClosure *owner = NULL; | 1356 | GCObject *owner = NULL; /* to avoid warnings */ |
1240 | UpVal *uv = NULL; | 1357 | TValue *fi; |
1241 | StkId fi; | ||
1242 | lua_lock(L); | 1358 | lua_lock(L); |
1243 | fi = index2addr(L, funcindex); | 1359 | fi = index2value(L, funcindex); |
1244 | api_checknelems(L, 1); | 1360 | api_checknelems(L, 1); |
1245 | name = aux_upvalue(fi, n, &val, &owner, &uv); | 1361 | name = aux_upvalue(fi, n, &val, &owner); |
1246 | if (name) { | 1362 | if (name) { |
1247 | L->top--; | 1363 | L->top--; |
1248 | setobj(L, val, L->top); | 1364 | setobj(L, val, s2v(L->top)); |
1249 | if (owner) { luaC_barrier(L, owner, L->top); } | 1365 | luaC_barrier(L, owner, val); |
1250 | else if (uv) { luaC_upvalbarrier(L, uv); } | ||
1251 | } | 1366 | } |
1252 | lua_unlock(L); | 1367 | lua_unlock(L); |
1253 | return name; | 1368 | return name; |
1254 | } | 1369 | } |
1255 | 1370 | ||
1256 | 1371 | ||
1257 | static UpVal **getupvalref (lua_State *L, int fidx, int n) { | 1372 | static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { |
1258 | LClosure *f; | 1373 | LClosure *f; |
1259 | StkId fi = index2addr(L, fidx); | 1374 | TValue *fi = index2value(L, fidx); |
1260 | api_check(L, ttisLclosure(fi), "Lua function expected"); | 1375 | api_check(L, ttisLclosure(fi), "Lua function expected"); |
1261 | f = clLvalue(fi); | 1376 | f = clLvalue(fi); |
1262 | api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); | 1377 | api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); |
1378 | if (pf) *pf = f; | ||
1263 | return &f->upvals[n - 1]; /* get its upvalue pointer */ | 1379 | return &f->upvals[n - 1]; /* get its upvalue pointer */ |
1264 | } | 1380 | } |
1265 | 1381 | ||
1266 | 1382 | ||
1267 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | 1383 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
1268 | StkId fi = index2addr(L, fidx); | 1384 | TValue *fi = index2value(L, fidx); |
1269 | switch (ttype(fi)) { | 1385 | switch (ttypetag(fi)) { |
1270 | case LUA_TLCL: { /* lua closure */ | 1386 | case LUA_VLCL: { /* lua closure */ |
1271 | return *getupvalref(L, fidx, n); | 1387 | return *getupvalref(L, fidx, n, NULL); |
1272 | } | 1388 | } |
1273 | case LUA_TCCL: { /* C closure */ | 1389 | case LUA_VCCL: { /* C closure */ |
1274 | CClosure *f = clCvalue(fi); | 1390 | CClosure *f = clCvalue(fi); |
1275 | api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); | 1391 | api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); |
1276 | return &f->upvalue[n - 1]; | 1392 | return &f->upvalue[n - 1]; |
@@ -1285,15 +1401,11 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | |||
1285 | 1401 | ||
1286 | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, | 1402 | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, |
1287 | int fidx2, int n2) { | 1403 | int fidx2, int n2) { |
1288 | UpVal **up1 = getupvalref(L, fidx1, n1); | 1404 | LClosure *f1; |
1289 | UpVal **up2 = getupvalref(L, fidx2, n2); | 1405 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); |
1290 | if (*up1 == *up2) | 1406 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); |
1291 | return; | ||
1292 | luaC_upvdeccount(L, *up1); | ||
1293 | *up1 = *up2; | 1407 | *up1 = *up2; |
1294 | (*up1)->refcount++; | 1408 | luaC_objbarrier(L, f1, *up1); |
1295 | if (upisopen(*up1)) (*up1)->u.open.touched = 1; | ||
1296 | luaC_upvalbarrier(L, *up1); | ||
1297 | } | 1409 | } |
1298 | 1410 | ||
1299 | 1411 | ||
diff --git a/src/lua/lapi.h b/src/lua/lapi.h new file mode 100644 index 0000000..41216b2 --- /dev/null +++ b/src/lua/lapi.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | ** $Id: lapi.h $ | ||
3 | ** Auxiliary functions from Lua API | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lapi_h | ||
8 | #define lapi_h | ||
9 | |||
10 | |||
11 | #include "llimits.h" | ||
12 | #include "lstate.h" | ||
13 | |||
14 | |||
15 | /* Increments 'L->top', checking for stack overflows */ | ||
16 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ | ||
17 | "stack overflow");} | ||
18 | |||
19 | |||
20 | /* | ||
21 | ** If a call returns too many multiple returns, the callee may not have | ||
22 | ** stack space to accommodate all results. In this case, this macro | ||
23 | ** increases its stack space ('L->ci->top'). | ||
24 | */ | ||
25 | #define adjustresults(L,nres) \ | ||
26 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } | ||
27 | |||
28 | |||
29 | /* Ensure the stack has at least 'n' elements */ | ||
30 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ | ||
31 | "not enough elements in the stack") | ||
32 | |||
33 | |||
34 | /* | ||
35 | ** To reduce the overhead of returning from C functions, the presence of | ||
36 | ** to-be-closed variables in these functions is coded in the CallInfo's | ||
37 | ** field 'nresults', in a way that functions with no to-be-closed variables | ||
38 | ** with zero, one, or "all" wanted results have no overhead. Functions | ||
39 | ** with other number of wanted results, as well as functions with | ||
40 | ** variables to be closed, have an extra check. | ||
41 | */ | ||
42 | |||
43 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) | ||
44 | |||
45 | #define codeNresults(n) (-(n) - 3) | ||
46 | |||
47 | #endif | ||
diff --git a/src/lua-5.3/lauxlib.c b/src/lua/lauxlib.c index 8bdada5..e3d9be3 100644 --- a/src/lua-5.3/lauxlib.c +++ b/src/lua/lauxlib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.289.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lauxlib.c $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -27,6 +27,12 @@ | |||
27 | #include "lauxlib.h" | 27 | #include "lauxlib.h" |
28 | 28 | ||
29 | 29 | ||
30 | #if !defined(MAX_SIZET) | ||
31 | /* maximum value for size_t */ | ||
32 | #define MAX_SIZET ((size_t)(~(size_t)0)) | ||
33 | #endif | ||
34 | |||
35 | |||
30 | /* | 36 | /* |
31 | ** {====================================================== | 37 | ** {====================================================== |
32 | ** Traceback | 38 | ** Traceback |
@@ -40,8 +46,8 @@ | |||
40 | 46 | ||
41 | 47 | ||
42 | /* | 48 | /* |
43 | ** search for 'objidx' in table at index -1. | 49 | ** Search for 'objidx' in table at index -1. ('objidx' must be an |
44 | ** return 1 + string at top if find a good name. | 50 | ** absolute index.) Return 1 + string at top if it found a good name. |
45 | */ | 51 | */ |
46 | static int findfield (lua_State *L, int objidx, int level) { | 52 | static int findfield (lua_State *L, int objidx, int level) { |
47 | if (level == 0 || !lua_istable(L, -1)) | 53 | if (level == 0 || !lua_istable(L, -1)) |
@@ -54,10 +60,10 @@ static int findfield (lua_State *L, int objidx, int level) { | |||
54 | return 1; | 60 | return 1; |
55 | } | 61 | } |
56 | else if (findfield(L, objidx, level - 1)) { /* try recursively */ | 62 | else if (findfield(L, objidx, level - 1)) { /* try recursively */ |
57 | lua_remove(L, -2); /* remove table (but keep name) */ | 63 | /* stack: lib_name, lib_table, field_name (top) */ |
58 | lua_pushliteral(L, "."); | 64 | lua_pushliteral(L, "."); /* place '.' between the two names */ |
59 | lua_insert(L, -2); /* place '.' between the two names */ | 65 | lua_replace(L, -3); /* (in the slot occupied by table) */ |
60 | lua_concat(L, 3); | 66 | lua_concat(L, 3); /* lib_name.field_name */ |
61 | return 1; | 67 | return 1; |
62 | } | 68 | } |
63 | } | 69 | } |
@@ -76,12 +82,12 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { | |||
76 | lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); | 82 | lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); |
77 | if (findfield(L, top + 1, 2)) { | 83 | if (findfield(L, top + 1, 2)) { |
78 | const char *name = lua_tostring(L, -1); | 84 | const char *name = lua_tostring(L, -1); |
79 | if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */ | 85 | if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */ |
80 | lua_pushstring(L, name + 3); /* push name without prefix */ | 86 | lua_pushstring(L, name + 3); /* push name without prefix */ |
81 | lua_remove(L, -2); /* remove original name */ | 87 | lua_remove(L, -2); /* remove original name */ |
82 | } | 88 | } |
83 | lua_copy(L, -1, top + 1); /* move name to proper place */ | 89 | lua_copy(L, -1, top + 1); /* copy name to proper place */ |
84 | lua_pop(L, 2); /* remove pushed values */ | 90 | lua_settop(L, top + 1); /* remove table "loaded" and name copy */ |
85 | return 1; | 91 | return 1; |
86 | } | 92 | } |
87 | else { | 93 | else { |
@@ -124,32 +130,37 @@ static int lastlevel (lua_State *L) { | |||
124 | 130 | ||
125 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, | 131 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, |
126 | const char *msg, int level) { | 132 | const char *msg, int level) { |
133 | luaL_Buffer b; | ||
127 | lua_Debug ar; | 134 | lua_Debug ar; |
128 | int top = lua_gettop(L); | ||
129 | int last = lastlevel(L1); | 135 | int last = lastlevel(L1); |
130 | int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; | 136 | int limit2show = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; |
131 | if (msg) | 137 | luaL_buffinit(L, &b); |
132 | lua_pushfstring(L, "%s\n", msg); | 138 | if (msg) { |
133 | luaL_checkstack(L, 10, NULL); | 139 | luaL_addstring(&b, msg); |
134 | lua_pushliteral(L, "stack traceback:"); | 140 | luaL_addchar(&b, '\n'); |
141 | } | ||
142 | luaL_addstring(&b, "stack traceback:"); | ||
135 | while (lua_getstack(L1, level++, &ar)) { | 143 | while (lua_getstack(L1, level++, &ar)) { |
136 | if (n1-- == 0) { /* too many levels? */ | 144 | if (limit2show-- == 0) { /* too many levels? */ |
137 | lua_pushliteral(L, "\n\t..."); /* add a '...' */ | 145 | int n = last - level - LEVELS2 + 1; /* number of levels to skip */ |
138 | level = last - LEVELS2 + 1; /* and skip to last ones */ | 146 | lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n); |
147 | luaL_addvalue(&b); /* add warning about skip */ | ||
148 | level += n; /* and skip to last levels */ | ||
139 | } | 149 | } |
140 | else { | 150 | else { |
141 | lua_getinfo(L1, "Slnt", &ar); | 151 | lua_getinfo(L1, "Slnt", &ar); |
142 | lua_pushfstring(L, "\n\t%s:", ar.short_src); | 152 | if (ar.currentline <= 0) |
143 | if (ar.currentline > 0) | 153 | lua_pushfstring(L, "\n\t%s: in ", ar.short_src); |
144 | lua_pushfstring(L, "%d:", ar.currentline); | 154 | else |
145 | lua_pushliteral(L, " in "); | 155 | lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline); |
156 | luaL_addvalue(&b); | ||
146 | pushfuncname(L, &ar); | 157 | pushfuncname(L, &ar); |
158 | luaL_addvalue(&b); | ||
147 | if (ar.istailcall) | 159 | if (ar.istailcall) |
148 | lua_pushliteral(L, "\n\t(...tail calls...)"); | 160 | luaL_addstring(&b, "\n\t(...tail calls...)"); |
149 | lua_concat(L, lua_gettop(L) - top); | ||
150 | } | 161 | } |
151 | } | 162 | } |
152 | lua_concat(L, lua_gettop(L) - top); | 163 | luaL_pushresult(&b); |
153 | } | 164 | } |
154 | 165 | ||
155 | /* }====================================================== */ | 166 | /* }====================================================== */ |
@@ -179,7 +190,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { | |||
179 | } | 190 | } |
180 | 191 | ||
181 | 192 | ||
182 | static int typeerror (lua_State *L, int arg, const char *tname) { | 193 | int luaL_typeerror (lua_State *L, int arg, const char *tname) { |
183 | const char *msg; | 194 | const char *msg; |
184 | const char *typearg; /* name for the type of the actual argument */ | 195 | const char *typearg; /* name for the type of the actual argument */ |
185 | if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) | 196 | if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) |
@@ -194,7 +205,7 @@ static int typeerror (lua_State *L, int arg, const char *tname) { | |||
194 | 205 | ||
195 | 206 | ||
196 | static void tag_error (lua_State *L, int arg, int tag) { | 207 | static void tag_error (lua_State *L, int arg, int tag) { |
197 | typeerror(L, arg, lua_typename(L, tag)); | 208 | luaL_typeerror(L, arg, lua_typename(L, tag)); |
198 | } | 209 | } |
199 | 210 | ||
200 | 211 | ||
@@ -238,7 +249,7 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { | |||
238 | return 1; | 249 | return 1; |
239 | } | 250 | } |
240 | else { | 251 | else { |
241 | lua_pushnil(L); | 252 | luaL_pushfail(L); |
242 | if (fname) | 253 | if (fname) |
243 | lua_pushfstring(L, "%s: %s", fname, strerror(en)); | 254 | lua_pushfstring(L, "%s: %s", fname, strerror(en)); |
244 | else | 255 | else |
@@ -273,23 +284,24 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { | |||
273 | 284 | ||
274 | LUALIB_API int luaL_execresult (lua_State *L, int stat) { | 285 | LUALIB_API int luaL_execresult (lua_State *L, int stat) { |
275 | const char *what = "exit"; /* type of termination */ | 286 | const char *what = "exit"; /* type of termination */ |
276 | if (stat == -1) /* error? */ | 287 | if (stat != 0 && errno != 0) /* error with an 'errno'? */ |
277 | return luaL_fileresult(L, 0, NULL); | 288 | return luaL_fileresult(L, 0, NULL); |
278 | else { | 289 | else { |
279 | l_inspectstat(stat, what); /* interpret result */ | 290 | l_inspectstat(stat, what); /* interpret result */ |
280 | if (*what == 'e' && stat == 0) /* successful termination? */ | 291 | if (*what == 'e' && stat == 0) /* successful termination? */ |
281 | lua_pushboolean(L, 1); | 292 | lua_pushboolean(L, 1); |
282 | else | 293 | else |
283 | lua_pushnil(L); | 294 | luaL_pushfail(L); |
284 | lua_pushstring(L, what); | 295 | lua_pushstring(L, what); |
285 | lua_pushinteger(L, stat); | 296 | lua_pushinteger(L, stat); |
286 | return 3; /* return true/nil,what,code */ | 297 | return 3; /* return true/fail,what,code */ |
287 | } | 298 | } |
288 | } | 299 | } |
289 | 300 | ||
290 | /* }====================================================== */ | 301 | /* }====================================================== */ |
291 | 302 | ||
292 | 303 | ||
304 | |||
293 | /* | 305 | /* |
294 | ** {====================================================== | 306 | ** {====================================================== |
295 | ** Userdata's metatable manipulation | 307 | ** Userdata's metatable manipulation |
@@ -332,7 +344,7 @@ LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { | |||
332 | 344 | ||
333 | LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { | 345 | LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { |
334 | void *p = luaL_testudata(L, ud, tname); | 346 | void *p = luaL_testudata(L, ud, tname); |
335 | if (p == NULL) typeerror(L, ud, tname); | 347 | luaL_argexpected(L, p != NULL, ud, tname); |
336 | return p; | 348 | return p; |
337 | } | 349 | } |
338 | 350 | ||
@@ -463,10 +475,8 @@ static void *resizebox (lua_State *L, int idx, size_t newsize) { | |||
463 | lua_Alloc allocf = lua_getallocf(L, &ud); | 475 | lua_Alloc allocf = lua_getallocf(L, &ud); |
464 | UBox *box = (UBox *)lua_touserdata(L, idx); | 476 | UBox *box = (UBox *)lua_touserdata(L, idx); |
465 | void *temp = allocf(ud, box->box, box->bsize, newsize); | 477 | void *temp = allocf(ud, box->box, box->bsize, newsize); |
466 | if (temp == NULL && newsize > 0) { /* allocation error? */ | 478 | if (temp == NULL && newsize > 0) /* allocation error? */ |
467 | resizebox(L, idx, 0); /* free buffer */ | 479 | luaL_error(L, "not enough memory"); |
468 | luaL_error(L, "not enough memory for buffer allocation"); | ||
469 | } | ||
470 | box->box = temp; | 480 | box->box = temp; |
471 | box->bsize = newsize; | 481 | box->bsize = newsize; |
472 | return temp; | 482 | return temp; |
@@ -479,16 +489,20 @@ static int boxgc (lua_State *L) { | |||
479 | } | 489 | } |
480 | 490 | ||
481 | 491 | ||
482 | static void *newbox (lua_State *L, size_t newsize) { | 492 | static const luaL_Reg boxmt[] = { /* box metamethods */ |
483 | UBox *box = (UBox *)lua_newuserdata(L, sizeof(UBox)); | 493 | {"__gc", boxgc}, |
494 | {"__close", boxgc}, | ||
495 | {NULL, NULL} | ||
496 | }; | ||
497 | |||
498 | |||
499 | static void newbox (lua_State *L) { | ||
500 | UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); | ||
484 | box->box = NULL; | 501 | box->box = NULL; |
485 | box->bsize = 0; | 502 | box->bsize = 0; |
486 | if (luaL_newmetatable(L, "LUABOX")) { /* creating metatable? */ | 503 | if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ |
487 | lua_pushcfunction(L, boxgc); | 504 | luaL_setfuncs(L, boxmt, 0); /* set its metamethods */ |
488 | lua_setfield(L, -2, "__gc"); /* metatable.__gc = boxgc */ | ||
489 | } | ||
490 | lua_setmetatable(L, -2); | 505 | lua_setmetatable(L, -2); |
491 | return resizebox(L, -1, newsize); | ||
492 | } | 506 | } |
493 | 507 | ||
494 | 508 | ||
@@ -496,38 +510,64 @@ static void *newbox (lua_State *L, size_t newsize) { | |||
496 | ** check whether buffer is using a userdata on the stack as a temporary | 510 | ** check whether buffer is using a userdata on the stack as a temporary |
497 | ** buffer | 511 | ** buffer |
498 | */ | 512 | */ |
499 | #define buffonstack(B) ((B)->b != (B)->initb) | 513 | #define buffonstack(B) ((B)->b != (B)->init.b) |
500 | 514 | ||
501 | 515 | ||
502 | /* | 516 | /* |
503 | ** returns a pointer to a free area with at least 'sz' bytes | 517 | ** Compute new size for buffer 'B', enough to accommodate extra 'sz' |
518 | ** bytes. | ||
504 | */ | 519 | */ |
505 | LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { | 520 | static size_t newbuffsize (luaL_Buffer *B, size_t sz) { |
506 | lua_State *L = B->L; | 521 | size_t newsize = B->size * 2; /* double buffer size */ |
507 | if (B->size - B->n < sz) { /* not enough space? */ | 522 | if (MAX_SIZET - sz < B->n) /* overflow in (B->n + sz)? */ |
523 | return luaL_error(B->L, "buffer too large"); | ||
524 | if (newsize < B->n + sz) /* double is not big enough? */ | ||
525 | newsize = B->n + sz; | ||
526 | return newsize; | ||
527 | } | ||
528 | |||
529 | |||
530 | /* | ||
531 | ** Returns a pointer to a free area with at least 'sz' bytes in buffer | ||
532 | ** 'B'. 'boxidx' is the relative position in the stack where the | ||
533 | ** buffer's box is or should be. | ||
534 | */ | ||
535 | static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { | ||
536 | if (B->size - B->n >= sz) /* enough space? */ | ||
537 | return B->b + B->n; | ||
538 | else { | ||
539 | lua_State *L = B->L; | ||
508 | char *newbuff; | 540 | char *newbuff; |
509 | size_t newsize = B->size * 2; /* double buffer size */ | 541 | size_t newsize = newbuffsize(B, sz); |
510 | if (newsize - B->n < sz) /* not big enough? */ | ||
511 | newsize = B->n + sz; | ||
512 | if (newsize < B->n || newsize - B->n < sz) | ||
513 | luaL_error(L, "buffer too large"); | ||
514 | /* create larger buffer */ | 542 | /* create larger buffer */ |
515 | if (buffonstack(B)) | 543 | if (buffonstack(B)) /* buffer already has a box? */ |
516 | newbuff = (char *)resizebox(L, -1, newsize); | 544 | newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ |
517 | else { /* no buffer yet */ | 545 | else { /* no box yet */ |
518 | newbuff = (char *)newbox(L, newsize); | 546 | lua_pushnil(L); /* reserve slot for final result */ |
547 | newbox(L); /* create a new box */ | ||
548 | /* move box (and slot) to its intended position */ | ||
549 | lua_rotate(L, boxidx - 1, 2); | ||
550 | lua_toclose(L, boxidx); | ||
551 | newbuff = (char *)resizebox(L, boxidx, newsize); | ||
519 | memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ | 552 | memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ |
520 | } | 553 | } |
521 | B->b = newbuff; | 554 | B->b = newbuff; |
522 | B->size = newsize; | 555 | B->size = newsize; |
556 | return newbuff + B->n; | ||
523 | } | 557 | } |
524 | return &B->b[B->n]; | 558 | } |
559 | |||
560 | /* | ||
561 | ** returns a pointer to a free area with at least 'sz' bytes | ||
562 | */ | ||
563 | LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { | ||
564 | return prepbuffsize(B, sz, -1); | ||
525 | } | 565 | } |
526 | 566 | ||
527 | 567 | ||
528 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { | 568 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { |
529 | if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ | 569 | if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ |
530 | char *b = luaL_prepbuffsize(B, l); | 570 | char *b = prepbuffsize(B, l, -1); |
531 | memcpy(b, s, l * sizeof(char)); | 571 | memcpy(b, s, l * sizeof(char)); |
532 | luaL_addsize(B, l); | 572 | luaL_addsize(B, l); |
533 | } | 573 | } |
@@ -543,8 +583,8 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B) { | |||
543 | lua_State *L = B->L; | 583 | lua_State *L = B->L; |
544 | lua_pushlstring(L, B->b, B->n); | 584 | lua_pushlstring(L, B->b, B->n); |
545 | if (buffonstack(B)) { | 585 | if (buffonstack(B)) { |
546 | resizebox(L, -2, 0); /* delete old buffer */ | 586 | lua_copy(L, -1, -3); /* move string to reserved slot */ |
547 | lua_remove(L, -2); /* remove its header from the stack */ | 587 | lua_pop(L, 2); /* pop string and box (closing the box) */ |
548 | } | 588 | } |
549 | } | 589 | } |
550 | 590 | ||
@@ -555,20 +595,29 @@ LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { | |||
555 | } | 595 | } |
556 | 596 | ||
557 | 597 | ||
598 | /* | ||
599 | ** 'luaL_addvalue' is the only function in the Buffer system where the | ||
600 | ** box (if existent) is not on the top of the stack. So, instead of | ||
601 | ** calling 'luaL_addlstring', it replicates the code using -2 as the | ||
602 | ** last argument to 'prepbuffsize', signaling that the box is (or will | ||
603 | ** be) bellow the string being added to the buffer. (Box creation can | ||
604 | ** trigger an emergency GC, so we should not remove the string from the | ||
605 | ** stack before we have the space guaranteed.) | ||
606 | */ | ||
558 | LUALIB_API void luaL_addvalue (luaL_Buffer *B) { | 607 | LUALIB_API void luaL_addvalue (luaL_Buffer *B) { |
559 | lua_State *L = B->L; | 608 | lua_State *L = B->L; |
560 | size_t l; | 609 | size_t len; |
561 | const char *s = lua_tolstring(L, -1, &l); | 610 | const char *s = lua_tolstring(L, -1, &len); |
562 | if (buffonstack(B)) | 611 | char *b = prepbuffsize(B, len, -2); |
563 | lua_insert(L, -2); /* put value below buffer */ | 612 | memcpy(b, s, len * sizeof(char)); |
564 | luaL_addlstring(B, s, l); | 613 | luaL_addsize(B, len); |
565 | lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ | 614 | lua_pop(L, 1); /* pop string */ |
566 | } | 615 | } |
567 | 616 | ||
568 | 617 | ||
569 | LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { | 618 | LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { |
570 | B->L = L; | 619 | B->L = L; |
571 | B->b = B->initb; | 620 | B->b = B->init.b; |
572 | B->n = 0; | 621 | B->n = 0; |
573 | B->size = LUAL_BUFFERSIZE; | 622 | B->size = LUAL_BUFFERSIZE; |
574 | } | 623 | } |
@@ -576,7 +625,7 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { | |||
576 | 625 | ||
577 | LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { | 626 | LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { |
578 | luaL_buffinit(L, B); | 627 | luaL_buffinit(L, B); |
579 | return luaL_prepbuffsize(B, sz); | 628 | return prepbuffsize(B, sz, -1); |
580 | } | 629 | } |
581 | 630 | ||
582 | /* }====================================================== */ | 631 | /* }====================================================== */ |
@@ -846,87 +895,6 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { | |||
846 | 895 | ||
847 | 896 | ||
848 | /* | 897 | /* |
849 | ** {====================================================== | ||
850 | ** Compatibility with 5.1 module functions | ||
851 | ** ======================================================= | ||
852 | */ | ||
853 | #if defined(LUA_COMPAT_MODULE) | ||
854 | |||
855 | static const char *luaL_findtable (lua_State *L, int idx, | ||
856 | const char *fname, int szhint) { | ||
857 | const char *e; | ||
858 | if (idx) lua_pushvalue(L, idx); | ||
859 | do { | ||
860 | e = strchr(fname, '.'); | ||
861 | if (e == NULL) e = fname + strlen(fname); | ||
862 | lua_pushlstring(L, fname, e - fname); | ||
863 | if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */ | ||
864 | lua_pop(L, 1); /* remove this nil */ | ||
865 | lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ | ||
866 | lua_pushlstring(L, fname, e - fname); | ||
867 | lua_pushvalue(L, -2); | ||
868 | lua_settable(L, -4); /* set new table into field */ | ||
869 | } | ||
870 | else if (!lua_istable(L, -1)) { /* field has a non-table value? */ | ||
871 | lua_pop(L, 2); /* remove table and value */ | ||
872 | return fname; /* return problematic part of the name */ | ||
873 | } | ||
874 | lua_remove(L, -2); /* remove previous table */ | ||
875 | fname = e + 1; | ||
876 | } while (*e == '.'); | ||
877 | return NULL; | ||
878 | } | ||
879 | |||
880 | |||
881 | /* | ||
882 | ** Count number of elements in a luaL_Reg list. | ||
883 | */ | ||
884 | static int libsize (const luaL_Reg *l) { | ||
885 | int size = 0; | ||
886 | for (; l && l->name; l++) size++; | ||
887 | return size; | ||
888 | } | ||
889 | |||
890 | |||
891 | /* | ||
892 | ** Find or create a module table with a given name. The function | ||
893 | ** first looks at the LOADED table and, if that fails, try a | ||
894 | ** global variable with that name. In any case, leaves on the stack | ||
895 | ** the module table. | ||
896 | */ | ||
897 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, | ||
898 | int sizehint) { | ||
899 | luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1); | ||
900 | if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no LOADED[modname]? */ | ||
901 | lua_pop(L, 1); /* remove previous result */ | ||
902 | /* try global variable (and create one if it does not exist) */ | ||
903 | lua_pushglobaltable(L); | ||
904 | if (luaL_findtable(L, 0, modname, sizehint) != NULL) | ||
905 | luaL_error(L, "name conflict for module '%s'", modname); | ||
906 | lua_pushvalue(L, -1); | ||
907 | lua_setfield(L, -3, modname); /* LOADED[modname] = new table */ | ||
908 | } | ||
909 | lua_remove(L, -2); /* remove LOADED table */ | ||
910 | } | ||
911 | |||
912 | |||
913 | LUALIB_API void luaL_openlib (lua_State *L, const char *libname, | ||
914 | const luaL_Reg *l, int nup) { | ||
915 | luaL_checkversion(L); | ||
916 | if (libname) { | ||
917 | luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ | ||
918 | lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ | ||
919 | } | ||
920 | if (l) | ||
921 | luaL_setfuncs(L, l, nup); | ||
922 | else | ||
923 | lua_pop(L, nup); /* remove upvalues */ | ||
924 | } | ||
925 | |||
926 | #endif | ||
927 | /* }====================================================== */ | ||
928 | |||
929 | /* | ||
930 | ** set functions from list 'l' into table at top - 'nup'; each | 898 | ** set functions from list 'l' into table at top - 'nup'; each |
931 | ** function gets the 'nup' elements at the top as upvalues. | 899 | ** function gets the 'nup' elements at the top as upvalues. |
932 | ** Returns with only the table at the stack. | 900 | ** Returns with only the table at the stack. |
@@ -934,10 +902,14 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, | |||
934 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { | 902 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { |
935 | luaL_checkstack(L, nup, "too many upvalues"); | 903 | luaL_checkstack(L, nup, "too many upvalues"); |
936 | for (; l->name != NULL; l++) { /* fill the table with given functions */ | 904 | for (; l->name != NULL; l++) { /* fill the table with given functions */ |
937 | int i; | 905 | if (l->func == NULL) /* place holder? */ |
938 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ | 906 | lua_pushboolean(L, 0); |
939 | lua_pushvalue(L, -nup); | 907 | else { |
940 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ | 908 | int i; |
909 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ | ||
910 | lua_pushvalue(L, -nup); | ||
911 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ | ||
912 | } | ||
941 | lua_setfield(L, -(nup + 2), l->name); | 913 | lua_setfield(L, -(nup + 2), l->name); |
942 | } | 914 | } |
943 | lua_pop(L, nup); /* remove upvalues */ | 915 | lua_pop(L, nup); /* remove upvalues */ |
@@ -988,18 +960,24 @@ LUALIB_API void luaL_requiref (lua_State *L, const char *modname, | |||
988 | } | 960 | } |
989 | 961 | ||
990 | 962 | ||
991 | LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, | 963 | LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, |
992 | const char *r) { | 964 | const char *p, const char *r) { |
993 | const char *wild; | 965 | const char *wild; |
994 | size_t l = strlen(p); | 966 | size_t l = strlen(p); |
995 | luaL_Buffer b; | ||
996 | luaL_buffinit(L, &b); | ||
997 | while ((wild = strstr(s, p)) != NULL) { | 967 | while ((wild = strstr(s, p)) != NULL) { |
998 | luaL_addlstring(&b, s, wild - s); /* push prefix */ | 968 | luaL_addlstring(b, s, wild - s); /* push prefix */ |
999 | luaL_addstring(&b, r); /* push replacement in place of pattern */ | 969 | luaL_addstring(b, r); /* push replacement in place of pattern */ |
1000 | s = wild + l; /* continue after 'p' */ | 970 | s = wild + l; /* continue after 'p' */ |
1001 | } | 971 | } |
1002 | luaL_addstring(&b, s); /* push last suffix */ | 972 | luaL_addstring(b, s); /* push last suffix */ |
973 | } | ||
974 | |||
975 | |||
976 | LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, | ||
977 | const char *p, const char *r) { | ||
978 | luaL_Buffer b; | ||
979 | luaL_buffinit(L, &b); | ||
980 | luaL_addgsub(&b, s, p, r); | ||
1003 | luaL_pushresult(&b); | 981 | luaL_pushresult(&b); |
1004 | return lua_tostring(L, -1); | 982 | return lua_tostring(L, -1); |
1005 | } | 983 | } |
@@ -1017,27 +995,63 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { | |||
1017 | 995 | ||
1018 | 996 | ||
1019 | static int panic (lua_State *L) { | 997 | static int panic (lua_State *L) { |
998 | const char *msg = lua_tostring(L, -1); | ||
999 | if (msg == NULL) msg = "error object is not a string"; | ||
1020 | lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", | 1000 | lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", |
1021 | lua_tostring(L, -1)); | 1001 | msg); |
1022 | return 0; /* return to Lua to abort */ | 1002 | return 0; /* return to Lua to abort */ |
1023 | } | 1003 | } |
1024 | 1004 | ||
1025 | 1005 | ||
1006 | /* | ||
1007 | ** Emit a warning. '*warnstate' means: | ||
1008 | ** 0 - warning system is off; | ||
1009 | ** 1 - ready to start a new message; | ||
1010 | ** 2 - previous message is to be continued. | ||
1011 | */ | ||
1012 | static void warnf (void *ud, const char *message, int tocont) { | ||
1013 | int *warnstate = (int *)ud; | ||
1014 | if (*warnstate != 2 && !tocont && *message == '@') { /* control message? */ | ||
1015 | if (strcmp(message, "@off") == 0) | ||
1016 | *warnstate = 0; | ||
1017 | else if (strcmp(message, "@on") == 0) | ||
1018 | *warnstate = 1; | ||
1019 | return; | ||
1020 | } | ||
1021 | else if (*warnstate == 0) /* warnings off? */ | ||
1022 | return; | ||
1023 | if (*warnstate == 1) /* previous message was the last? */ | ||
1024 | lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ | ||
1025 | lua_writestringerror("%s", message); /* write message */ | ||
1026 | if (tocont) /* not the last part? */ | ||
1027 | *warnstate = 2; /* to be continued */ | ||
1028 | else { /* last part */ | ||
1029 | lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ | ||
1030 | *warnstate = 1; /* ready to start a new message */ | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | |||
1026 | LUALIB_API lua_State *luaL_newstate (void) { | 1035 | LUALIB_API lua_State *luaL_newstate (void) { |
1027 | lua_State *L = lua_newstate(l_alloc, NULL); | 1036 | lua_State *L = lua_newstate(l_alloc, NULL); |
1028 | if (L) lua_atpanic(L, &panic); | 1037 | if (L) { |
1038 | int *warnstate; /* space for warning state */ | ||
1039 | lua_atpanic(L, &panic); | ||
1040 | warnstate = (int *)lua_newuserdatauv(L, sizeof(int), 0); | ||
1041 | luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */ | ||
1042 | *warnstate = 0; /* default is warnings off */ | ||
1043 | lua_setwarnf(L, warnf, warnstate); | ||
1044 | } | ||
1029 | return L; | 1045 | return L; |
1030 | } | 1046 | } |
1031 | 1047 | ||
1032 | 1048 | ||
1033 | LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { | 1049 | LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { |
1034 | const lua_Number *v = lua_version(L); | 1050 | lua_Number v = lua_version(L); |
1035 | if (sz != LUAL_NUMSIZES) /* check numeric types */ | 1051 | if (sz != LUAL_NUMSIZES) /* check numeric types */ |
1036 | luaL_error(L, "core and library have incompatible numeric types"); | 1052 | luaL_error(L, "core and library have incompatible numeric types"); |
1037 | if (v != lua_version(NULL)) | 1053 | else if (v != ver) |
1038 | luaL_error(L, "multiple Lua VMs detected"); | ||
1039 | else if (*v != ver) | ||
1040 | luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", | 1054 | luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", |
1041 | (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v); | 1055 | (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)v); |
1042 | } | 1056 | } |
1043 | 1057 | ||
diff --git a/src/lua-5.3/lauxlib.h b/src/lua/lauxlib.h index 9857d3a..59fef6a 100644 --- a/src/lua-5.3/lauxlib.h +++ b/src/lua/lauxlib.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.h,v 1.131.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lauxlib.h $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -15,6 +15,12 @@ | |||
15 | #include "lua.h" | 15 | #include "lua.h" |
16 | 16 | ||
17 | 17 | ||
18 | /* global table */ | ||
19 | #define LUA_GNAME "_G" | ||
20 | |||
21 | |||
22 | typedef struct luaL_Buffer luaL_Buffer; | ||
23 | |||
18 | 24 | ||
19 | /* extra error code for 'luaL_loadfilex' */ | 25 | /* extra error code for 'luaL_loadfilex' */ |
20 | #define LUA_ERRFILE (LUA_ERRERR+1) | 26 | #define LUA_ERRFILE (LUA_ERRERR+1) |
@@ -44,6 +50,7 @@ LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); | |||
44 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); | 50 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); |
45 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); | 51 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); |
46 | LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); | 52 | LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); |
53 | LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname); | ||
47 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, | 54 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, |
48 | size_t *l); | 55 | size_t *l); |
49 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, | 56 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, |
@@ -73,6 +80,7 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, | |||
73 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); | 80 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); |
74 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); | 81 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); |
75 | 82 | ||
83 | |||
76 | /* predefined references */ | 84 | /* predefined references */ |
77 | #define LUA_NOREF (-2) | 85 | #define LUA_NOREF (-2) |
78 | #define LUA_REFNIL (-1) | 86 | #define LUA_REFNIL (-1) |
@@ -93,8 +101,10 @@ LUALIB_API lua_State *(luaL_newstate) (void); | |||
93 | 101 | ||
94 | LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); | 102 | LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); |
95 | 103 | ||
96 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, | 104 | LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, |
97 | const char *r); | 105 | const char *p, const char *r); |
106 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, | ||
107 | const char *p, const char *r); | ||
98 | 108 | ||
99 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); | 109 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); |
100 | 110 | ||
@@ -121,6 +131,10 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, | |||
121 | 131 | ||
122 | #define luaL_argcheck(L, cond,arg,extramsg) \ | 132 | #define luaL_argcheck(L, cond,arg,extramsg) \ |
123 | ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) | 133 | ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) |
134 | |||
135 | #define luaL_argexpected(L,cond,arg,tname) \ | ||
136 | ((void)((cond) || luaL_typeerror(L, (arg), (tname)))) | ||
137 | |||
124 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) | 138 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) |
125 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) | 139 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) |
126 | 140 | ||
@@ -139,19 +153,30 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, | |||
139 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) | 153 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) |
140 | 154 | ||
141 | 155 | ||
156 | /* push the value used to represent failure/error */ | ||
157 | #define luaL_pushfail(L) lua_pushnil(L) | ||
158 | |||
159 | |||
142 | /* | 160 | /* |
143 | ** {====================================================== | 161 | ** {====================================================== |
144 | ** Generic Buffer manipulation | 162 | ** Generic Buffer manipulation |
145 | ** ======================================================= | 163 | ** ======================================================= |
146 | */ | 164 | */ |
147 | 165 | ||
148 | typedef struct luaL_Buffer { | 166 | struct luaL_Buffer { |
149 | char *b; /* buffer address */ | 167 | char *b; /* buffer address */ |
150 | size_t size; /* buffer size */ | 168 | size_t size; /* buffer size */ |
151 | size_t n; /* number of characters in buffer */ | 169 | size_t n; /* number of characters in buffer */ |
152 | lua_State *L; | 170 | lua_State *L; |
153 | char initb[LUAL_BUFFERSIZE]; /* initial buffer */ | 171 | union { |
154 | } luaL_Buffer; | 172 | LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ |
173 | char b[LUAL_BUFFERSIZE]; /* initial buffer */ | ||
174 | } init; | ||
175 | }; | ||
176 | |||
177 | |||
178 | #define luaL_bufflen(bf) ((bf)->n) | ||
179 | #define luaL_buffaddr(bf) ((bf)->b) | ||
155 | 180 | ||
156 | 181 | ||
157 | #define luaL_addchar(B,c) \ | 182 | #define luaL_addchar(B,c) \ |
@@ -160,6 +185,8 @@ typedef struct luaL_Buffer { | |||
160 | 185 | ||
161 | #define luaL_addsize(B,s) ((B)->n += (s)) | 186 | #define luaL_addsize(B,s) ((B)->n += (s)) |
162 | 187 | ||
188 | #define luaL_buffsub(B,s) ((B)->n -= (s)) | ||
189 | |||
163 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); | 190 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); |
164 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); | 191 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); |
165 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); | 192 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); |
@@ -197,21 +224,6 @@ typedef struct luaL_Stream { | |||
197 | 224 | ||
198 | /* }====================================================== */ | 225 | /* }====================================================== */ |
199 | 226 | ||
200 | |||
201 | |||
202 | /* compatibility with old module system */ | ||
203 | #if defined(LUA_COMPAT_MODULE) | ||
204 | |||
205 | LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, | ||
206 | int sizehint); | ||
207 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, | ||
208 | const luaL_Reg *l, int nup); | ||
209 | |||
210 | #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) | ||
211 | |||
212 | #endif | ||
213 | |||
214 | |||
215 | /* | 227 | /* |
216 | ** {================================================================== | 228 | ** {================================================================== |
217 | ** "Abstraction Layer" for basic report of messages and errors | 229 | ** "Abstraction Layer" for basic report of messages and errors |
diff --git a/src/lua-5.3/lbaselib.c b/src/lua/lbaselib.c index 6460e4f..747fd45 100644 --- a/src/lua-5.3/lbaselib.c +++ b/src/lua/lbaselib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.314.1.1 2017/04/19 17:39:34 roberto Exp $ | 2 | ** $Id: lbaselib.c $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -24,18 +24,12 @@ | |||
24 | static int luaB_print (lua_State *L) { | 24 | static int luaB_print (lua_State *L) { |
25 | int n = lua_gettop(L); /* number of arguments */ | 25 | int n = lua_gettop(L); /* number of arguments */ |
26 | int i; | 26 | int i; |
27 | lua_getglobal(L, "tostring"); | 27 | for (i = 1; i <= n; i++) { /* for each argument */ |
28 | for (i=1; i<=n; i++) { | ||
29 | const char *s; | ||
30 | size_t l; | 28 | size_t l; |
31 | lua_pushvalue(L, -1); /* function to be called */ | 29 | const char *s = luaL_tolstring(L, i, &l); /* convert it to string */ |
32 | lua_pushvalue(L, i); /* value to print */ | 30 | if (i > 1) /* not the first element? */ |
33 | lua_call(L, 1, 1); | 31 | lua_writestring("\t", 1); /* add a tab before it */ |
34 | s = lua_tolstring(L, -1, &l); /* get result */ | 32 | lua_writestring(s, l); /* print it */ |
35 | if (s == NULL) | ||
36 | return luaL_error(L, "'tostring' must return a string to 'print'"); | ||
37 | if (i>1) lua_writestring("\t", 1); | ||
38 | lua_writestring(s, l); | ||
39 | lua_pop(L, 1); /* pop result */ | 33 | lua_pop(L, 1); /* pop result */ |
40 | } | 34 | } |
41 | lua_writeline(); | 35 | lua_writeline(); |
@@ -43,13 +37,31 @@ static int luaB_print (lua_State *L) { | |||
43 | } | 37 | } |
44 | 38 | ||
45 | 39 | ||
40 | /* | ||
41 | ** Creates a warning with all given arguments. | ||
42 | ** Check first for errors; otherwise an error may interrupt | ||
43 | ** the composition of a warning, leaving it unfinished. | ||
44 | */ | ||
45 | static int luaB_warn (lua_State *L) { | ||
46 | int n = lua_gettop(L); /* number of arguments */ | ||
47 | int i; | ||
48 | luaL_checkstring(L, 1); /* at least one argument */ | ||
49 | for (i = 2; i <= n; i++) | ||
50 | luaL_checkstring(L, i); /* make sure all arguments are strings */ | ||
51 | for (i = 1; i < n; i++) /* compose warning */ | ||
52 | lua_warning(L, lua_tostring(L, i), 1); | ||
53 | lua_warning(L, lua_tostring(L, n), 0); /* close warning */ | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | |||
46 | #define SPACECHARS " \f\n\r\t\v" | 58 | #define SPACECHARS " \f\n\r\t\v" |
47 | 59 | ||
48 | static const char *b_str2int (const char *s, int base, lua_Integer *pn) { | 60 | static const char *b_str2int (const char *s, int base, lua_Integer *pn) { |
49 | lua_Unsigned n = 0; | 61 | lua_Unsigned n = 0; |
50 | int neg = 0; | 62 | int neg = 0; |
51 | s += strspn(s, SPACECHARS); /* skip initial spaces */ | 63 | s += strspn(s, SPACECHARS); /* skip initial spaces */ |
52 | if (*s == '-') { s++; neg = 1; } /* handle signal */ | 64 | if (*s == '-') { s++; neg = 1; } /* handle sign */ |
53 | else if (*s == '+') s++; | 65 | else if (*s == '+') s++; |
54 | if (!isalnum((unsigned char)*s)) /* no digit? */ | 66 | if (!isalnum((unsigned char)*s)) /* no digit? */ |
55 | return NULL; | 67 | return NULL; |
@@ -68,7 +80,6 @@ static const char *b_str2int (const char *s, int base, lua_Integer *pn) { | |||
68 | 80 | ||
69 | static int luaB_tonumber (lua_State *L) { | 81 | static int luaB_tonumber (lua_State *L) { |
70 | if (lua_isnoneornil(L, 2)) { /* standard conversion? */ | 82 | if (lua_isnoneornil(L, 2)) { /* standard conversion? */ |
71 | luaL_checkany(L, 1); | ||
72 | if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ | 83 | if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ |
73 | lua_settop(L, 1); /* yes; return it */ | 84 | lua_settop(L, 1); /* yes; return it */ |
74 | return 1; | 85 | return 1; |
@@ -79,6 +90,7 @@ static int luaB_tonumber (lua_State *L) { | |||
79 | if (s != NULL && lua_stringtonumber(L, s) == l + 1) | 90 | if (s != NULL && lua_stringtonumber(L, s) == l + 1) |
80 | return 1; /* successful conversion to number */ | 91 | return 1; /* successful conversion to number */ |
81 | /* else not a number */ | 92 | /* else not a number */ |
93 | luaL_checkany(L, 1); /* (but there must be some parameter) */ | ||
82 | } | 94 | } |
83 | } | 95 | } |
84 | else { | 96 | else { |
@@ -94,7 +106,7 @@ static int luaB_tonumber (lua_State *L) { | |||
94 | return 1; | 106 | return 1; |
95 | } /* else not a number */ | 107 | } /* else not a number */ |
96 | } /* else not a number */ | 108 | } /* else not a number */ |
97 | lua_pushnil(L); /* not a number */ | 109 | luaL_pushfail(L); /* not a number */ |
98 | return 1; | 110 | return 1; |
99 | } | 111 | } |
100 | 112 | ||
@@ -125,8 +137,7 @@ static int luaB_getmetatable (lua_State *L) { | |||
125 | static int luaB_setmetatable (lua_State *L) { | 137 | static int luaB_setmetatable (lua_State *L) { |
126 | int t = lua_type(L, 2); | 138 | int t = lua_type(L, 2); |
127 | luaL_checktype(L, 1, LUA_TTABLE); | 139 | luaL_checktype(L, 1, LUA_TTABLE); |
128 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, | 140 | luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); |
129 | "nil or table expected"); | ||
130 | if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL) | 141 | if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL) |
131 | return luaL_error(L, "cannot change a protected metatable"); | 142 | return luaL_error(L, "cannot change a protected metatable"); |
132 | lua_settop(L, 2); | 143 | lua_settop(L, 2); |
@@ -145,8 +156,8 @@ static int luaB_rawequal (lua_State *L) { | |||
145 | 156 | ||
146 | static int luaB_rawlen (lua_State *L) { | 157 | static int luaB_rawlen (lua_State *L) { |
147 | int t = lua_type(L, 1); | 158 | int t = lua_type(L, 1); |
148 | luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, | 159 | luaL_argexpected(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, |
149 | "table or string expected"); | 160 | "table or string"); |
150 | lua_pushinteger(L, lua_rawlen(L, 1)); | 161 | lua_pushinteger(L, lua_rawlen(L, 1)); |
151 | return 1; | 162 | return 1; |
152 | } | 163 | } |
@@ -170,27 +181,58 @@ static int luaB_rawset (lua_State *L) { | |||
170 | } | 181 | } |
171 | 182 | ||
172 | 183 | ||
184 | static int pushmode (lua_State *L, int oldmode) { | ||
185 | lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" : "generational"); | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | |||
173 | static int luaB_collectgarbage (lua_State *L) { | 190 | static int luaB_collectgarbage (lua_State *L) { |
174 | static const char *const opts[] = {"stop", "restart", "collect", | 191 | static const char *const opts[] = {"stop", "restart", "collect", |
175 | "count", "step", "setpause", "setstepmul", | 192 | "count", "step", "setpause", "setstepmul", |
176 | "isrunning", NULL}; | 193 | "isrunning", "generational", "incremental", NULL}; |
177 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, | 194 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
178 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, | 195 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, |
179 | LUA_GCISRUNNING}; | 196 | LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; |
180 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; | 197 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; |
181 | int ex = (int)luaL_optinteger(L, 2, 0); | ||
182 | int res = lua_gc(L, o, ex); | ||
183 | switch (o) { | 198 | switch (o) { |
184 | case LUA_GCCOUNT: { | 199 | case LUA_GCCOUNT: { |
185 | int b = lua_gc(L, LUA_GCCOUNTB, 0); | 200 | int k = lua_gc(L, o); |
186 | lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024)); | 201 | int b = lua_gc(L, LUA_GCCOUNTB); |
202 | lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024)); | ||
203 | return 1; | ||
204 | } | ||
205 | case LUA_GCSTEP: { | ||
206 | int step = (int)luaL_optinteger(L, 2, 0); | ||
207 | int res = lua_gc(L, o, step); | ||
208 | lua_pushboolean(L, res); | ||
209 | return 1; | ||
210 | } | ||
211 | case LUA_GCSETPAUSE: | ||
212 | case LUA_GCSETSTEPMUL: { | ||
213 | int p = (int)luaL_optinteger(L, 2, 0); | ||
214 | int previous = lua_gc(L, o, p); | ||
215 | lua_pushinteger(L, previous); | ||
187 | return 1; | 216 | return 1; |
188 | } | 217 | } |
189 | case LUA_GCSTEP: case LUA_GCISRUNNING: { | 218 | case LUA_GCISRUNNING: { |
219 | int res = lua_gc(L, o); | ||
190 | lua_pushboolean(L, res); | 220 | lua_pushboolean(L, res); |
191 | return 1; | 221 | return 1; |
192 | } | 222 | } |
223 | case LUA_GCGEN: { | ||
224 | int minormul = (int)luaL_optinteger(L, 2, 0); | ||
225 | int majormul = (int)luaL_optinteger(L, 3, 0); | ||
226 | return pushmode(L, lua_gc(L, o, minormul, majormul)); | ||
227 | } | ||
228 | case LUA_GCINC: { | ||
229 | int pause = (int)luaL_optinteger(L, 2, 0); | ||
230 | int stepmul = (int)luaL_optinteger(L, 3, 0); | ||
231 | int stepsize = (int)luaL_optinteger(L, 4, 0); | ||
232 | return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize)); | ||
233 | } | ||
193 | default: { | 234 | default: { |
235 | int res = lua_gc(L, o); | ||
194 | lua_pushinteger(L, res); | 236 | lua_pushinteger(L, res); |
195 | return 1; | 237 | return 1; |
196 | } | 238 | } |
@@ -206,23 +248,6 @@ static int luaB_type (lua_State *L) { | |||
206 | } | 248 | } |
207 | 249 | ||
208 | 250 | ||
209 | static int pairsmeta (lua_State *L, const char *method, int iszero, | ||
210 | lua_CFunction iter) { | ||
211 | luaL_checkany(L, 1); | ||
212 | if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */ | ||
213 | lua_pushcfunction(L, iter); /* will return generator, */ | ||
214 | lua_pushvalue(L, 1); /* state, */ | ||
215 | if (iszero) lua_pushinteger(L, 0); /* and initial value */ | ||
216 | else lua_pushnil(L); | ||
217 | } | ||
218 | else { | ||
219 | lua_pushvalue(L, 1); /* argument 'self' to metamethod */ | ||
220 | lua_call(L, 1, 3); /* get 3 values from metamethod */ | ||
221 | } | ||
222 | return 3; | ||
223 | } | ||
224 | |||
225 | |||
226 | static int luaB_next (lua_State *L) { | 251 | static int luaB_next (lua_State *L) { |
227 | luaL_checktype(L, 1, LUA_TTABLE); | 252 | luaL_checktype(L, 1, LUA_TTABLE); |
228 | lua_settop(L, 2); /* create a 2nd argument if there isn't one */ | 253 | lua_settop(L, 2); /* create a 2nd argument if there isn't one */ |
@@ -236,7 +261,17 @@ static int luaB_next (lua_State *L) { | |||
236 | 261 | ||
237 | 262 | ||
238 | static int luaB_pairs (lua_State *L) { | 263 | static int luaB_pairs (lua_State *L) { |
239 | return pairsmeta(L, "__pairs", 0, luaB_next); | 264 | luaL_checkany(L, 1); |
265 | if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */ | ||
266 | lua_pushcfunction(L, luaB_next); /* will return generator, */ | ||
267 | lua_pushvalue(L, 1); /* state, */ | ||
268 | lua_pushnil(L); /* and initial value */ | ||
269 | } | ||
270 | else { | ||
271 | lua_pushvalue(L, 1); /* argument 'self' to metamethod */ | ||
272 | lua_call(L, 1, 3); /* get 3 values from metamethod */ | ||
273 | } | ||
274 | return 3; | ||
240 | } | 275 | } |
241 | 276 | ||
242 | 277 | ||
@@ -255,15 +290,11 @@ static int ipairsaux (lua_State *L) { | |||
255 | ** (The given "table" may not be a table.) | 290 | ** (The given "table" may not be a table.) |
256 | */ | 291 | */ |
257 | static int luaB_ipairs (lua_State *L) { | 292 | static int luaB_ipairs (lua_State *L) { |
258 | #if defined(LUA_COMPAT_IPAIRS) | ||
259 | return pairsmeta(L, "__ipairs", 1, ipairsaux); | ||
260 | #else | ||
261 | luaL_checkany(L, 1); | 293 | luaL_checkany(L, 1); |
262 | lua_pushcfunction(L, ipairsaux); /* iteration function */ | 294 | lua_pushcfunction(L, ipairsaux); /* iteration function */ |
263 | lua_pushvalue(L, 1); /* state */ | 295 | lua_pushvalue(L, 1); /* state */ |
264 | lua_pushinteger(L, 0); /* initial value */ | 296 | lua_pushinteger(L, 0); /* initial value */ |
265 | return 3; | 297 | return 3; |
266 | #endif | ||
267 | } | 298 | } |
268 | 299 | ||
269 | 300 | ||
@@ -277,9 +308,9 @@ static int load_aux (lua_State *L, int status, int envidx) { | |||
277 | return 1; | 308 | return 1; |
278 | } | 309 | } |
279 | else { /* error (message is on top of the stack) */ | 310 | else { /* error (message is on top of the stack) */ |
280 | lua_pushnil(L); | 311 | luaL_pushfail(L); |
281 | lua_insert(L, -2); /* put before error message */ | 312 | lua_insert(L, -2); /* put before error message */ |
282 | return 2; /* return nil plus error message */ | 313 | return 2; /* return fail plus error message */ |
283 | } | 314 | } |
284 | } | 315 | } |
285 | 316 | ||
@@ -459,13 +490,11 @@ static const luaL_Reg base_funcs[] = { | |||
459 | {"ipairs", luaB_ipairs}, | 490 | {"ipairs", luaB_ipairs}, |
460 | {"loadfile", luaB_loadfile}, | 491 | {"loadfile", luaB_loadfile}, |
461 | {"load", luaB_load}, | 492 | {"load", luaB_load}, |
462 | #if defined(LUA_COMPAT_LOADSTRING) | ||
463 | {"loadstring", luaB_load}, | ||
464 | #endif | ||
465 | {"next", luaB_next}, | 493 | {"next", luaB_next}, |
466 | {"pairs", luaB_pairs}, | 494 | {"pairs", luaB_pairs}, |
467 | {"pcall", luaB_pcall}, | 495 | {"pcall", luaB_pcall}, |
468 | {"print", luaB_print}, | 496 | {"print", luaB_print}, |
497 | {"warn", luaB_warn}, | ||
469 | {"rawequal", luaB_rawequal}, | 498 | {"rawequal", luaB_rawequal}, |
470 | {"rawlen", luaB_rawlen}, | 499 | {"rawlen", luaB_rawlen}, |
471 | {"rawget", luaB_rawget}, | 500 | {"rawget", luaB_rawget}, |
@@ -477,7 +506,7 @@ static const luaL_Reg base_funcs[] = { | |||
477 | {"type", luaB_type}, | 506 | {"type", luaB_type}, |
478 | {"xpcall", luaB_xpcall}, | 507 | {"xpcall", luaB_xpcall}, |
479 | /* placeholders */ | 508 | /* placeholders */ |
480 | {"_G", NULL}, | 509 | {LUA_GNAME, NULL}, |
481 | {"_VERSION", NULL}, | 510 | {"_VERSION", NULL}, |
482 | {NULL, NULL} | 511 | {NULL, NULL} |
483 | }; | 512 | }; |
@@ -489,7 +518,7 @@ LUAMOD_API int luaopen_base (lua_State *L) { | |||
489 | luaL_setfuncs(L, base_funcs, 0); | 518 | luaL_setfuncs(L, base_funcs, 0); |
490 | /* set global _G */ | 519 | /* set global _G */ |
491 | lua_pushvalue(L, -1); | 520 | lua_pushvalue(L, -1); |
492 | lua_setfield(L, -2, "_G"); | 521 | lua_setfield(L, -2, LUA_GNAME); |
493 | /* set global _VERSION */ | 522 | /* set global _VERSION */ |
494 | lua_pushliteral(L, LUA_VERSION); | 523 | lua_pushliteral(L, LUA_VERSION); |
495 | lua_setfield(L, -2, "_VERSION"); | 524 | lua_setfield(L, -2, "_VERSION"); |
diff --git a/src/lua/lcode.c b/src/lua/lcode.c new file mode 100644 index 0000000..6f241c9 --- /dev/null +++ b/src/lua/lcode.c | |||
@@ -0,0 +1,1814 @@ | |||
1 | /* | ||
2 | ** $Id: lcode.c $ | ||
3 | ** Code generator for Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lcode_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <limits.h> | ||
14 | #include <math.h> | ||
15 | #include <stdlib.h> | ||
16 | |||
17 | #include "lua.h" | ||
18 | |||
19 | #include "lcode.h" | ||
20 | #include "ldebug.h" | ||
21 | #include "ldo.h" | ||
22 | #include "lgc.h" | ||
23 | #include "llex.h" | ||
24 | #include "lmem.h" | ||
25 | #include "lobject.h" | ||
26 | #include "lopcodes.h" | ||
27 | #include "lparser.h" | ||
28 | #include "lstring.h" | ||
29 | #include "ltable.h" | ||
30 | #include "lvm.h" | ||
31 | |||
32 | |||
33 | /* Maximum number of registers in a Lua function (must fit in 8 bits) */ | ||
34 | #define MAXREGS 255 | ||
35 | |||
36 | |||
37 | #define hasjumps(e) ((e)->t != (e)->f) | ||
38 | |||
39 | |||
40 | static int codesJ (FuncState *fs, OpCode o, int sj, int k); | ||
41 | |||
42 | |||
43 | |||
44 | /* semantic error */ | ||
45 | l_noret luaK_semerror (LexState *ls, const char *msg) { | ||
46 | ls->t.token = 0; /* remove "near <token>" from final message */ | ||
47 | luaX_syntaxerror(ls, msg); | ||
48 | } | ||
49 | |||
50 | |||
51 | /* | ||
52 | ** If expression is a numeric constant, fills 'v' with its value | ||
53 | ** and returns 1. Otherwise, returns 0. | ||
54 | */ | ||
55 | static int tonumeral (const expdesc *e, TValue *v) { | ||
56 | if (hasjumps(e)) | ||
57 | return 0; /* not a numeral */ | ||
58 | switch (e->k) { | ||
59 | case VKINT: | ||
60 | if (v) setivalue(v, e->u.ival); | ||
61 | return 1; | ||
62 | case VKFLT: | ||
63 | if (v) setfltvalue(v, e->u.nval); | ||
64 | return 1; | ||
65 | default: return 0; | ||
66 | } | ||
67 | } | ||
68 | |||
69 | |||
70 | /* | ||
71 | ** Get the constant value from a constant expression | ||
72 | */ | ||
73 | static TValue *const2val (FuncState *fs, const expdesc *e) { | ||
74 | lua_assert(e->k == VCONST); | ||
75 | return &fs->ls->dyd->actvar.arr[e->u.info].k; | ||
76 | } | ||
77 | |||
78 | |||
79 | /* | ||
80 | ** If expression is a constant, fills 'v' with its value | ||
81 | ** and returns 1. Otherwise, returns 0. | ||
82 | */ | ||
83 | int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) { | ||
84 | if (hasjumps(e)) | ||
85 | return 0; /* not a constant */ | ||
86 | switch (e->k) { | ||
87 | case VFALSE: | ||
88 | setbfvalue(v); | ||
89 | return 1; | ||
90 | case VTRUE: | ||
91 | setbtvalue(v); | ||
92 | return 1; | ||
93 | case VNIL: | ||
94 | setnilvalue(v); | ||
95 | return 1; | ||
96 | case VKSTR: { | ||
97 | setsvalue(fs->ls->L, v, e->u.strval); | ||
98 | return 1; | ||
99 | } | ||
100 | case VCONST: { | ||
101 | setobj(fs->ls->L, v, const2val(fs, e)); | ||
102 | return 1; | ||
103 | } | ||
104 | default: return tonumeral(e, v); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | |||
109 | /* | ||
110 | ** Return the previous instruction of the current code. If there | ||
111 | ** may be a jump target between the current instruction and the | ||
112 | ** previous one, return an invalid instruction (to avoid wrong | ||
113 | ** optimizations). | ||
114 | */ | ||
115 | static Instruction *previousinstruction (FuncState *fs) { | ||
116 | static const Instruction invalidinstruction = ~(Instruction)0; | ||
117 | if (fs->pc > fs->lasttarget) | ||
118 | return &fs->f->code[fs->pc - 1]; /* previous instruction */ | ||
119 | else | ||
120 | return cast(Instruction*, &invalidinstruction); | ||
121 | } | ||
122 | |||
123 | |||
124 | /* | ||
125 | ** Create a OP_LOADNIL instruction, but try to optimize: if the previous | ||
126 | ** instruction is also OP_LOADNIL and ranges are compatible, adjust | ||
127 | ** range of previous instruction instead of emitting a new one. (For | ||
128 | ** instance, 'local a; local b' will generate a single opcode.) | ||
129 | */ | ||
130 | void luaK_nil (FuncState *fs, int from, int n) { | ||
131 | int l = from + n - 1; /* last register to set nil */ | ||
132 | Instruction *previous = previousinstruction(fs); | ||
133 | if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */ | ||
134 | int pfrom = GETARG_A(*previous); /* get previous range */ | ||
135 | int pl = pfrom + GETARG_B(*previous); | ||
136 | if ((pfrom <= from && from <= pl + 1) || | ||
137 | (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ | ||
138 | if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ | ||
139 | if (pl > l) l = pl; /* l = max(l, pl) */ | ||
140 | SETARG_A(*previous, from); | ||
141 | SETARG_B(*previous, l - from); | ||
142 | return; | ||
143 | } /* else go through */ | ||
144 | } | ||
145 | luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ | ||
146 | } | ||
147 | |||
148 | |||
149 | /* | ||
150 | ** Gets the destination address of a jump instruction. Used to traverse | ||
151 | ** a list of jumps. | ||
152 | */ | ||
153 | static int getjump (FuncState *fs, int pc) { | ||
154 | int offset = GETARG_sJ(fs->f->code[pc]); | ||
155 | if (offset == NO_JUMP) /* point to itself represents end of list */ | ||
156 | return NO_JUMP; /* end of list */ | ||
157 | else | ||
158 | return (pc+1)+offset; /* turn offset into absolute position */ | ||
159 | } | ||
160 | |||
161 | |||
162 | /* | ||
163 | ** Fix jump instruction at position 'pc' to jump to 'dest'. | ||
164 | ** (Jump addresses are relative in Lua) | ||
165 | */ | ||
166 | static void fixjump (FuncState *fs, int pc, int dest) { | ||
167 | Instruction *jmp = &fs->f->code[pc]; | ||
168 | int offset = dest - (pc + 1); | ||
169 | lua_assert(dest != NO_JUMP); | ||
170 | if (!(-OFFSET_sJ <= offset && offset <= MAXARG_sJ - OFFSET_sJ)) | ||
171 | luaX_syntaxerror(fs->ls, "control structure too long"); | ||
172 | lua_assert(GET_OPCODE(*jmp) == OP_JMP); | ||
173 | SETARG_sJ(*jmp, offset); | ||
174 | } | ||
175 | |||
176 | |||
177 | /* | ||
178 | ** Concatenate jump-list 'l2' into jump-list 'l1' | ||
179 | */ | ||
180 | void luaK_concat (FuncState *fs, int *l1, int l2) { | ||
181 | if (l2 == NO_JUMP) return; /* nothing to concatenate? */ | ||
182 | else if (*l1 == NO_JUMP) /* no original list? */ | ||
183 | *l1 = l2; /* 'l1' points to 'l2' */ | ||
184 | else { | ||
185 | int list = *l1; | ||
186 | int next; | ||
187 | while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ | ||
188 | list = next; | ||
189 | fixjump(fs, list, l2); /* last element links to 'l2' */ | ||
190 | } | ||
191 | } | ||
192 | |||
193 | |||
194 | /* | ||
195 | ** Create a jump instruction and return its position, so its destination | ||
196 | ** can be fixed later (with 'fixjump'). | ||
197 | */ | ||
198 | int luaK_jump (FuncState *fs) { | ||
199 | return codesJ(fs, OP_JMP, NO_JUMP, 0); | ||
200 | } | ||
201 | |||
202 | |||
203 | /* | ||
204 | ** Code a 'return' instruction | ||
205 | */ | ||
206 | void luaK_ret (FuncState *fs, int first, int nret) { | ||
207 | OpCode op; | ||
208 | switch (nret) { | ||
209 | case 0: op = OP_RETURN0; break; | ||
210 | case 1: op = OP_RETURN1; break; | ||
211 | default: op = OP_RETURN; break; | ||
212 | } | ||
213 | luaK_codeABC(fs, op, first, nret + 1, 0); | ||
214 | } | ||
215 | |||
216 | |||
217 | /* | ||
218 | ** Code a "conditional jump", that is, a test or comparison opcode | ||
219 | ** followed by a jump. Return jump position. | ||
220 | */ | ||
221 | static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { | ||
222 | luaK_codeABCk(fs, op, A, B, C, k); | ||
223 | return luaK_jump(fs); | ||
224 | } | ||
225 | |||
226 | |||
227 | /* | ||
228 | ** returns current 'pc' and marks it as a jump target (to avoid wrong | ||
229 | ** optimizations with consecutive instructions not in the same basic block). | ||
230 | */ | ||
231 | int luaK_getlabel (FuncState *fs) { | ||
232 | fs->lasttarget = fs->pc; | ||
233 | return fs->pc; | ||
234 | } | ||
235 | |||
236 | |||
237 | /* | ||
238 | ** Returns the position of the instruction "controlling" a given | ||
239 | ** jump (that is, its condition), or the jump itself if it is | ||
240 | ** unconditional. | ||
241 | */ | ||
242 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { | ||
243 | Instruction *pi = &fs->f->code[pc]; | ||
244 | if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) | ||
245 | return pi-1; | ||
246 | else | ||
247 | return pi; | ||
248 | } | ||
249 | |||
250 | |||
251 | /* | ||
252 | ** Patch destination register for a TESTSET instruction. | ||
253 | ** If instruction in position 'node' is not a TESTSET, return 0 ("fails"). | ||
254 | ** Otherwise, if 'reg' is not 'NO_REG', set it as the destination | ||
255 | ** register. Otherwise, change instruction to a simple 'TEST' (produces | ||
256 | ** no register value) | ||
257 | */ | ||
258 | static int patchtestreg (FuncState *fs, int node, int reg) { | ||
259 | Instruction *i = getjumpcontrol(fs, node); | ||
260 | if (GET_OPCODE(*i) != OP_TESTSET) | ||
261 | return 0; /* cannot patch other instructions */ | ||
262 | if (reg != NO_REG && reg != GETARG_B(*i)) | ||
263 | SETARG_A(*i, reg); | ||
264 | else { | ||
265 | /* no register to put value or register already has the value; | ||
266 | change instruction to simple test */ | ||
267 | *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i)); | ||
268 | } | ||
269 | return 1; | ||
270 | } | ||
271 | |||
272 | |||
273 | /* | ||
274 | ** Traverse a list of tests ensuring no one produces a value | ||
275 | */ | ||
276 | static void removevalues (FuncState *fs, int list) { | ||
277 | for (; list != NO_JUMP; list = getjump(fs, list)) | ||
278 | patchtestreg(fs, list, NO_REG); | ||
279 | } | ||
280 | |||
281 | |||
282 | /* | ||
283 | ** Traverse a list of tests, patching their destination address and | ||
284 | ** registers: tests producing values jump to 'vtarget' (and put their | ||
285 | ** values in 'reg'), other tests jump to 'dtarget'. | ||
286 | */ | ||
287 | static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, | ||
288 | int dtarget) { | ||
289 | while (list != NO_JUMP) { | ||
290 | int next = getjump(fs, list); | ||
291 | if (patchtestreg(fs, list, reg)) | ||
292 | fixjump(fs, list, vtarget); | ||
293 | else | ||
294 | fixjump(fs, list, dtarget); /* jump to default target */ | ||
295 | list = next; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | |||
300 | /* | ||
301 | ** Path all jumps in 'list' to jump to 'target'. | ||
302 | ** (The assert means that we cannot fix a jump to a forward address | ||
303 | ** because we only know addresses once code is generated.) | ||
304 | */ | ||
305 | void luaK_patchlist (FuncState *fs, int list, int target) { | ||
306 | lua_assert(target <= fs->pc); | ||
307 | patchlistaux(fs, list, target, NO_REG, target); | ||
308 | } | ||
309 | |||
310 | |||
311 | void luaK_patchtohere (FuncState *fs, int list) { | ||
312 | int hr = luaK_getlabel(fs); /* mark "here" as a jump target */ | ||
313 | luaK_patchlist(fs, list, hr); | ||
314 | } | ||
315 | |||
316 | |||
317 | /* | ||
318 | ** MAXimum number of successive Instructions WiTHout ABSolute line | ||
319 | ** information. | ||
320 | */ | ||
321 | #if !defined(MAXIWTHABS) | ||
322 | #define MAXIWTHABS 120 | ||
323 | #endif | ||
324 | |||
325 | |||
326 | /* limit for difference between lines in relative line info. */ | ||
327 | #define LIMLINEDIFF 0x80 | ||
328 | |||
329 | |||
330 | /* | ||
331 | ** Save line info for a new instruction. If difference from last line | ||
332 | ** does not fit in a byte, of after that many instructions, save a new | ||
333 | ** absolute line info; (in that case, the special value 'ABSLINEINFO' | ||
334 | ** in 'lineinfo' signals the existence of this absolute information.) | ||
335 | ** Otherwise, store the difference from last line in 'lineinfo'. | ||
336 | */ | ||
337 | static void savelineinfo (FuncState *fs, Proto *f, int line) { | ||
338 | int linedif = line - fs->previousline; | ||
339 | int pc = fs->pc - 1; /* last instruction coded */ | ||
340 | if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ > MAXIWTHABS) { | ||
341 | luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, | ||
342 | f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); | ||
343 | f->abslineinfo[fs->nabslineinfo].pc = pc; | ||
344 | f->abslineinfo[fs->nabslineinfo++].line = line; | ||
345 | linedif = ABSLINEINFO; /* signal that there is absolute information */ | ||
346 | fs->iwthabs = 0; /* restart counter */ | ||
347 | } | ||
348 | luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, | ||
349 | MAX_INT, "opcodes"); | ||
350 | f->lineinfo[pc] = linedif; | ||
351 | fs->previousline = line; /* last line saved */ | ||
352 | } | ||
353 | |||
354 | |||
355 | /* | ||
356 | ** Remove line information from the last instruction. | ||
357 | ** If line information for that instruction is absolute, set 'iwthabs' | ||
358 | ** above its max to force the new (replacing) instruction to have | ||
359 | ** absolute line info, too. | ||
360 | */ | ||
361 | static void removelastlineinfo (FuncState *fs) { | ||
362 | Proto *f = fs->f; | ||
363 | int pc = fs->pc - 1; /* last instruction coded */ | ||
364 | if (f->lineinfo[pc] != ABSLINEINFO) { /* relative line info? */ | ||
365 | fs->previousline -= f->lineinfo[pc]; /* correct last line saved */ | ||
366 | fs->iwthabs--; /* undo previous increment */ | ||
367 | } | ||
368 | else { /* absolute line information */ | ||
369 | lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == pc); | ||
370 | fs->nabslineinfo--; /* remove it */ | ||
371 | fs->iwthabs = MAXIWTHABS + 1; /* force next line info to be absolute */ | ||
372 | } | ||
373 | } | ||
374 | |||
375 | |||
376 | /* | ||
377 | ** Remove the last instruction created, correcting line information | ||
378 | ** accordingly. | ||
379 | */ | ||
380 | static void removelastinstruction (FuncState *fs) { | ||
381 | removelastlineinfo(fs); | ||
382 | fs->pc--; | ||
383 | } | ||
384 | |||
385 | |||
386 | /* | ||
387 | ** Emit instruction 'i', checking for array sizes and saving also its | ||
388 | ** line information. Return 'i' position. | ||
389 | */ | ||
390 | int luaK_code (FuncState *fs, Instruction i) { | ||
391 | Proto *f = fs->f; | ||
392 | /* put new instruction in code array */ | ||
393 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, | ||
394 | MAX_INT, "opcodes"); | ||
395 | f->code[fs->pc++] = i; | ||
396 | savelineinfo(fs, f, fs->ls->lastline); | ||
397 | return fs->pc - 1; /* index of new instruction */ | ||
398 | } | ||
399 | |||
400 | |||
401 | /* | ||
402 | ** Format and emit an 'iABC' instruction. (Assertions check consistency | ||
403 | ** of parameters versus opcode.) | ||
404 | */ | ||
405 | int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { | ||
406 | lua_assert(getOpMode(o) == iABC); | ||
407 | lua_assert(a <= MAXARG_A && b <= MAXARG_B && | ||
408 | c <= MAXARG_C && (k & ~1) == 0); | ||
409 | return luaK_code(fs, CREATE_ABCk(o, a, b, c, k)); | ||
410 | } | ||
411 | |||
412 | |||
413 | /* | ||
414 | ** Format and emit an 'iABx' instruction. | ||
415 | */ | ||
416 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | ||
417 | lua_assert(getOpMode(o) == iABx); | ||
418 | lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); | ||
419 | return luaK_code(fs, CREATE_ABx(o, a, bc)); | ||
420 | } | ||
421 | |||
422 | |||
423 | /* | ||
424 | ** Format and emit an 'iAsBx' instruction. | ||
425 | */ | ||
426 | int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) { | ||
427 | unsigned int b = bc + OFFSET_sBx; | ||
428 | lua_assert(getOpMode(o) == iAsBx); | ||
429 | lua_assert(a <= MAXARG_A && b <= MAXARG_Bx); | ||
430 | return luaK_code(fs, CREATE_ABx(o, a, b)); | ||
431 | } | ||
432 | |||
433 | |||
434 | /* | ||
435 | ** Format and emit an 'isJ' instruction. | ||
436 | */ | ||
437 | static int codesJ (FuncState *fs, OpCode o, int sj, int k) { | ||
438 | unsigned int j = sj + OFFSET_sJ; | ||
439 | lua_assert(getOpMode(o) == isJ); | ||
440 | lua_assert(j <= MAXARG_sJ && (k & ~1) == 0); | ||
441 | return luaK_code(fs, CREATE_sJ(o, j, k)); | ||
442 | } | ||
443 | |||
444 | |||
445 | /* | ||
446 | ** Emit an "extra argument" instruction (format 'iAx') | ||
447 | */ | ||
448 | static int codeextraarg (FuncState *fs, int a) { | ||
449 | lua_assert(a <= MAXARG_Ax); | ||
450 | return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); | ||
451 | } | ||
452 | |||
453 | |||
454 | /* | ||
455 | ** Emit a "load constant" instruction, using either 'OP_LOADK' | ||
456 | ** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' | ||
457 | ** instruction with "extra argument". | ||
458 | */ | ||
459 | static int luaK_codek (FuncState *fs, int reg, int k) { | ||
460 | if (k <= MAXARG_Bx) | ||
461 | return luaK_codeABx(fs, OP_LOADK, reg, k); | ||
462 | else { | ||
463 | int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); | ||
464 | codeextraarg(fs, k); | ||
465 | return p; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | |||
470 | /* | ||
471 | ** Check register-stack level, keeping track of its maximum size | ||
472 | ** in field 'maxstacksize' | ||
473 | */ | ||
474 | void luaK_checkstack (FuncState *fs, int n) { | ||
475 | int newstack = fs->freereg + n; | ||
476 | if (newstack > fs->f->maxstacksize) { | ||
477 | if (newstack >= MAXREGS) | ||
478 | luaX_syntaxerror(fs->ls, | ||
479 | "function or expression needs too many registers"); | ||
480 | fs->f->maxstacksize = cast_byte(newstack); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | |||
485 | /* | ||
486 | ** Reserve 'n' registers in register stack | ||
487 | */ | ||
488 | void luaK_reserveregs (FuncState *fs, int n) { | ||
489 | luaK_checkstack(fs, n); | ||
490 | fs->freereg += n; | ||
491 | } | ||
492 | |||
493 | |||
494 | /* | ||
495 | ** Free register 'reg', if it is neither a constant index nor | ||
496 | ** a local variable. | ||
497 | ) | ||
498 | */ | ||
499 | static void freereg (FuncState *fs, int reg) { | ||
500 | if (reg >= luaY_nvarstack(fs)) { | ||
501 | fs->freereg--; | ||
502 | lua_assert(reg == fs->freereg); | ||
503 | } | ||
504 | } | ||
505 | |||
506 | |||
507 | /* | ||
508 | ** Free two registers in proper order | ||
509 | */ | ||
510 | static void freeregs (FuncState *fs, int r1, int r2) { | ||
511 | if (r1 > r2) { | ||
512 | freereg(fs, r1); | ||
513 | freereg(fs, r2); | ||
514 | } | ||
515 | else { | ||
516 | freereg(fs, r2); | ||
517 | freereg(fs, r1); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | |||
522 | /* | ||
523 | ** Free register used by expression 'e' (if any) | ||
524 | */ | ||
525 | static void freeexp (FuncState *fs, expdesc *e) { | ||
526 | if (e->k == VNONRELOC) | ||
527 | freereg(fs, e->u.info); | ||
528 | } | ||
529 | |||
530 | |||
531 | /* | ||
532 | ** Free registers used by expressions 'e1' and 'e2' (if any) in proper | ||
533 | ** order. | ||
534 | */ | ||
535 | static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { | ||
536 | int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; | ||
537 | int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; | ||
538 | freeregs(fs, r1, r2); | ||
539 | } | ||
540 | |||
541 | |||
542 | /* | ||
543 | ** Add constant 'v' to prototype's list of constants (field 'k'). | ||
544 | ** Use scanner's table to cache position of constants in constant list | ||
545 | ** and try to reuse constants. Because some values should not be used | ||
546 | ** as keys (nil cannot be a key, integer keys can collapse with float | ||
547 | ** keys), the caller must provide a useful 'key' for indexing the cache. | ||
548 | */ | ||
549 | static int addk (FuncState *fs, TValue *key, TValue *v) { | ||
550 | lua_State *L = fs->ls->L; | ||
551 | Proto *f = fs->f; | ||
552 | TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ | ||
553 | int k, oldsize; | ||
554 | if (ttisinteger(idx)) { /* is there an index there? */ | ||
555 | k = cast_int(ivalue(idx)); | ||
556 | /* correct value? (warning: must distinguish floats from integers!) */ | ||
557 | if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && | ||
558 | luaV_rawequalobj(&f->k[k], v)) | ||
559 | return k; /* reuse index */ | ||
560 | } | ||
561 | /* constant not found; create a new entry */ | ||
562 | oldsize = f->sizek; | ||
563 | k = fs->nk; | ||
564 | /* numerical value does not need GC barrier; | ||
565 | table has no metatable, so it does not need to invalidate cache */ | ||
566 | setivalue(idx, k); | ||
567 | luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); | ||
568 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); | ||
569 | setobj(L, &f->k[k], v); | ||
570 | fs->nk++; | ||
571 | luaC_barrier(L, f, v); | ||
572 | return k; | ||
573 | } | ||
574 | |||
575 | |||
576 | /* | ||
577 | ** Add a string to list of constants and return its index. | ||
578 | */ | ||
579 | static int stringK (FuncState *fs, TString *s) { | ||
580 | TValue o; | ||
581 | setsvalue(fs->ls->L, &o, s); | ||
582 | return addk(fs, &o, &o); /* use string itself as key */ | ||
583 | } | ||
584 | |||
585 | |||
586 | /* | ||
587 | ** Add an integer to list of constants and return its index. | ||
588 | ** Integers use userdata as keys to avoid collision with floats with | ||
589 | ** same value; conversion to 'void*' is used only for hashing, so there | ||
590 | ** are no "precision" problems. | ||
591 | */ | ||
592 | static int luaK_intK (FuncState *fs, lua_Integer n) { | ||
593 | TValue k, o; | ||
594 | setpvalue(&k, cast_voidp(cast_sizet(n))); | ||
595 | setivalue(&o, n); | ||
596 | return addk(fs, &k, &o); | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | ** Add a float to list of constants and return its index. | ||
601 | */ | ||
602 | static int luaK_numberK (FuncState *fs, lua_Number r) { | ||
603 | TValue o; | ||
604 | setfltvalue(&o, r); | ||
605 | return addk(fs, &o, &o); /* use number itself as key */ | ||
606 | } | ||
607 | |||
608 | |||
609 | /* | ||
610 | ** Add a false to list of constants and return its index. | ||
611 | */ | ||
612 | static int boolF (FuncState *fs) { | ||
613 | TValue o; | ||
614 | setbfvalue(&o); | ||
615 | return addk(fs, &o, &o); /* use boolean itself as key */ | ||
616 | } | ||
617 | |||
618 | |||
619 | /* | ||
620 | ** Add a true to list of constants and return its index. | ||
621 | */ | ||
622 | static int boolT (FuncState *fs) { | ||
623 | TValue o; | ||
624 | setbtvalue(&o); | ||
625 | return addk(fs, &o, &o); /* use boolean itself as key */ | ||
626 | } | ||
627 | |||
628 | |||
629 | /* | ||
630 | ** Add nil to list of constants and return its index. | ||
631 | */ | ||
632 | static int nilK (FuncState *fs) { | ||
633 | TValue k, v; | ||
634 | setnilvalue(&v); | ||
635 | /* cannot use nil as key; instead use table itself to represent nil */ | ||
636 | sethvalue(fs->ls->L, &k, fs->ls->h); | ||
637 | return addk(fs, &k, &v); | ||
638 | } | ||
639 | |||
640 | |||
641 | /* | ||
642 | ** Check whether 'i' can be stored in an 'sC' operand. Equivalent to | ||
643 | ** (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) but without risk of | ||
644 | ** overflows in the hidden addition inside 'int2sC'. | ||
645 | */ | ||
646 | static int fitsC (lua_Integer i) { | ||
647 | return (l_castS2U(i) + OFFSET_sC <= cast_uint(MAXARG_C)); | ||
648 | } | ||
649 | |||
650 | |||
651 | /* | ||
652 | ** Check whether 'i' can be stored in an 'sBx' operand. | ||
653 | */ | ||
654 | static int fitsBx (lua_Integer i) { | ||
655 | return (-OFFSET_sBx <= i && i <= MAXARG_Bx - OFFSET_sBx); | ||
656 | } | ||
657 | |||
658 | |||
659 | void luaK_int (FuncState *fs, int reg, lua_Integer i) { | ||
660 | if (fitsBx(i)) | ||
661 | luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i)); | ||
662 | else | ||
663 | luaK_codek(fs, reg, luaK_intK(fs, i)); | ||
664 | } | ||
665 | |||
666 | |||
667 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { | ||
668 | lua_Integer fi; | ||
669 | if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) | ||
670 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); | ||
671 | else | ||
672 | luaK_codek(fs, reg, luaK_numberK(fs, f)); | ||
673 | } | ||
674 | |||
675 | |||
676 | /* | ||
677 | ** Convert a constant in 'v' into an expression description 'e' | ||
678 | */ | ||
679 | static void const2exp (TValue *v, expdesc *e) { | ||
680 | switch (ttypetag(v)) { | ||
681 | case LUA_VNUMINT: | ||
682 | e->k = VKINT; e->u.ival = ivalue(v); | ||
683 | break; | ||
684 | case LUA_VNUMFLT: | ||
685 | e->k = VKFLT; e->u.nval = fltvalue(v); | ||
686 | break; | ||
687 | case LUA_VFALSE: | ||
688 | e->k = VFALSE; | ||
689 | break; | ||
690 | case LUA_VTRUE: | ||
691 | e->k = VTRUE; | ||
692 | break; | ||
693 | case LUA_VNIL: | ||
694 | e->k = VNIL; | ||
695 | break; | ||
696 | case LUA_VSHRSTR: case LUA_VLNGSTR: | ||
697 | e->k = VKSTR; e->u.strval = tsvalue(v); | ||
698 | break; | ||
699 | default: lua_assert(0); | ||
700 | } | ||
701 | } | ||
702 | |||
703 | |||
704 | /* | ||
705 | ** Fix an expression to return the number of results 'nresults'. | ||
706 | ** 'e' must be a multi-ret expression (function call or vararg). | ||
707 | */ | ||
708 | void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { | ||
709 | Instruction *pc = &getinstruction(fs, e); | ||
710 | if (e->k == VCALL) /* expression is an open function call? */ | ||
711 | SETARG_C(*pc, nresults + 1); | ||
712 | else { | ||
713 | lua_assert(e->k == VVARARG); | ||
714 | SETARG_C(*pc, nresults + 1); | ||
715 | SETARG_A(*pc, fs->freereg); | ||
716 | luaK_reserveregs(fs, 1); | ||
717 | } | ||
718 | } | ||
719 | |||
720 | |||
721 | /* | ||
722 | ** Convert a VKSTR to a VK | ||
723 | */ | ||
724 | static void str2K (FuncState *fs, expdesc *e) { | ||
725 | lua_assert(e->k == VKSTR); | ||
726 | e->u.info = stringK(fs, e->u.strval); | ||
727 | e->k = VK; | ||
728 | } | ||
729 | |||
730 | |||
731 | /* | ||
732 | ** Fix an expression to return one result. | ||
733 | ** If expression is not a multi-ret expression (function call or | ||
734 | ** vararg), it already returns one result, so nothing needs to be done. | ||
735 | ** Function calls become VNONRELOC expressions (as its result comes | ||
736 | ** fixed in the base register of the call), while vararg expressions | ||
737 | ** become VRELOC (as OP_VARARG puts its results where it wants). | ||
738 | ** (Calls are created returning one result, so that does not need | ||
739 | ** to be fixed.) | ||
740 | */ | ||
741 | void luaK_setoneret (FuncState *fs, expdesc *e) { | ||
742 | if (e->k == VCALL) { /* expression is an open function call? */ | ||
743 | /* already returns 1 value */ | ||
744 | lua_assert(GETARG_C(getinstruction(fs, e)) == 2); | ||
745 | e->k = VNONRELOC; /* result has fixed position */ | ||
746 | e->u.info = GETARG_A(getinstruction(fs, e)); | ||
747 | } | ||
748 | else if (e->k == VVARARG) { | ||
749 | SETARG_C(getinstruction(fs, e), 2); | ||
750 | e->k = VRELOC; /* can relocate its simple result */ | ||
751 | } | ||
752 | } | ||
753 | |||
754 | |||
755 | /* | ||
756 | ** Ensure that expression 'e' is not a variable (nor a constant). | ||
757 | ** (Expression still may have jump lists.) | ||
758 | */ | ||
759 | void luaK_dischargevars (FuncState *fs, expdesc *e) { | ||
760 | switch (e->k) { | ||
761 | case VCONST: { | ||
762 | const2exp(const2val(fs, e), e); | ||
763 | break; | ||
764 | } | ||
765 | case VLOCAL: { /* already in a register */ | ||
766 | e->u.info = e->u.var.sidx; | ||
767 | e->k = VNONRELOC; /* becomes a non-relocatable value */ | ||
768 | break; | ||
769 | } | ||
770 | case VUPVAL: { /* move value to some (pending) register */ | ||
771 | e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); | ||
772 | e->k = VRELOC; | ||
773 | break; | ||
774 | } | ||
775 | case VINDEXUP: { | ||
776 | e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx); | ||
777 | e->k = VRELOC; | ||
778 | break; | ||
779 | } | ||
780 | case VINDEXI: { | ||
781 | freereg(fs, e->u.ind.t); | ||
782 | e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx); | ||
783 | e->k = VRELOC; | ||
784 | break; | ||
785 | } | ||
786 | case VINDEXSTR: { | ||
787 | freereg(fs, e->u.ind.t); | ||
788 | e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx); | ||
789 | e->k = VRELOC; | ||
790 | break; | ||
791 | } | ||
792 | case VINDEXED: { | ||
793 | freeregs(fs, e->u.ind.t, e->u.ind.idx); | ||
794 | e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx); | ||
795 | e->k = VRELOC; | ||
796 | break; | ||
797 | } | ||
798 | case VVARARG: case VCALL: { | ||
799 | luaK_setoneret(fs, e); | ||
800 | break; | ||
801 | } | ||
802 | default: break; /* there is one value available (somewhere) */ | ||
803 | } | ||
804 | } | ||
805 | |||
806 | |||
807 | /* | ||
808 | ** Ensures expression value is in register 'reg' (and therefore | ||
809 | ** 'e' will become a non-relocatable expression). | ||
810 | ** (Expression still may have jump lists.) | ||
811 | */ | ||
812 | static void discharge2reg (FuncState *fs, expdesc *e, int reg) { | ||
813 | luaK_dischargevars(fs, e); | ||
814 | switch (e->k) { | ||
815 | case VNIL: { | ||
816 | luaK_nil(fs, reg, 1); | ||
817 | break; | ||
818 | } | ||
819 | case VFALSE: { | ||
820 | luaK_codeABC(fs, OP_LOADFALSE, reg, 0, 0); | ||
821 | break; | ||
822 | } | ||
823 | case VTRUE: { | ||
824 | luaK_codeABC(fs, OP_LOADTRUE, reg, 0, 0); | ||
825 | break; | ||
826 | } | ||
827 | case VKSTR: { | ||
828 | str2K(fs, e); | ||
829 | } /* FALLTHROUGH */ | ||
830 | case VK: { | ||
831 | luaK_codek(fs, reg, e->u.info); | ||
832 | break; | ||
833 | } | ||
834 | case VKFLT: { | ||
835 | luaK_float(fs, reg, e->u.nval); | ||
836 | break; | ||
837 | } | ||
838 | case VKINT: { | ||
839 | luaK_int(fs, reg, e->u.ival); | ||
840 | break; | ||
841 | } | ||
842 | case VRELOC: { | ||
843 | Instruction *pc = &getinstruction(fs, e); | ||
844 | SETARG_A(*pc, reg); /* instruction will put result in 'reg' */ | ||
845 | break; | ||
846 | } | ||
847 | case VNONRELOC: { | ||
848 | if (reg != e->u.info) | ||
849 | luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); | ||
850 | break; | ||
851 | } | ||
852 | default: { | ||
853 | lua_assert(e->k == VJMP); | ||
854 | return; /* nothing to do... */ | ||
855 | } | ||
856 | } | ||
857 | e->u.info = reg; | ||
858 | e->k = VNONRELOC; | ||
859 | } | ||
860 | |||
861 | |||
862 | /* | ||
863 | ** Ensures expression value is in any register. | ||
864 | ** (Expression still may have jump lists.) | ||
865 | */ | ||
866 | static void discharge2anyreg (FuncState *fs, expdesc *e) { | ||
867 | if (e->k != VNONRELOC) { /* no fixed register yet? */ | ||
868 | luaK_reserveregs(fs, 1); /* get a register */ | ||
869 | discharge2reg(fs, e, fs->freereg-1); /* put value there */ | ||
870 | } | ||
871 | } | ||
872 | |||
873 | |||
874 | static int code_loadbool (FuncState *fs, int A, OpCode op) { | ||
875 | luaK_getlabel(fs); /* those instructions may be jump targets */ | ||
876 | return luaK_codeABC(fs, op, A, 0, 0); | ||
877 | } | ||
878 | |||
879 | |||
880 | /* | ||
881 | ** check whether list has any jump that do not produce a value | ||
882 | ** or produce an inverted value | ||
883 | */ | ||
884 | static int need_value (FuncState *fs, int list) { | ||
885 | for (; list != NO_JUMP; list = getjump(fs, list)) { | ||
886 | Instruction i = *getjumpcontrol(fs, list); | ||
887 | if (GET_OPCODE(i) != OP_TESTSET) return 1; | ||
888 | } | ||
889 | return 0; /* not found */ | ||
890 | } | ||
891 | |||
892 | |||
893 | /* | ||
894 | ** Ensures final expression result (which includes results from its | ||
895 | ** jump lists) is in register 'reg'. | ||
896 | ** If expression has jumps, need to patch these jumps either to | ||
897 | ** its final position or to "load" instructions (for those tests | ||
898 | ** that do not produce values). | ||
899 | */ | ||
900 | static void exp2reg (FuncState *fs, expdesc *e, int reg) { | ||
901 | discharge2reg(fs, e, reg); | ||
902 | if (e->k == VJMP) /* expression itself is a test? */ | ||
903 | luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ | ||
904 | if (hasjumps(e)) { | ||
905 | int final; /* position after whole expression */ | ||
906 | int p_f = NO_JUMP; /* position of an eventual LOAD false */ | ||
907 | int p_t = NO_JUMP; /* position of an eventual LOAD true */ | ||
908 | if (need_value(fs, e->t) || need_value(fs, e->f)) { | ||
909 | int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); | ||
910 | p_f = code_loadbool(fs, reg, OP_LFALSESKIP); /* skip next inst. */ | ||
911 | p_t = code_loadbool(fs, reg, OP_LOADTRUE); | ||
912 | /* jump around these booleans if 'e' is not a test */ | ||
913 | luaK_patchtohere(fs, fj); | ||
914 | } | ||
915 | final = luaK_getlabel(fs); | ||
916 | patchlistaux(fs, e->f, final, reg, p_f); | ||
917 | patchlistaux(fs, e->t, final, reg, p_t); | ||
918 | } | ||
919 | e->f = e->t = NO_JUMP; | ||
920 | e->u.info = reg; | ||
921 | e->k = VNONRELOC; | ||
922 | } | ||
923 | |||
924 | |||
925 | /* | ||
926 | ** Ensures final expression result is in next available register. | ||
927 | */ | ||
928 | void luaK_exp2nextreg (FuncState *fs, expdesc *e) { | ||
929 | luaK_dischargevars(fs, e); | ||
930 | freeexp(fs, e); | ||
931 | luaK_reserveregs(fs, 1); | ||
932 | exp2reg(fs, e, fs->freereg - 1); | ||
933 | } | ||
934 | |||
935 | |||
936 | /* | ||
937 | ** Ensures final expression result is in some (any) register | ||
938 | ** and return that register. | ||
939 | */ | ||
940 | int luaK_exp2anyreg (FuncState *fs, expdesc *e) { | ||
941 | luaK_dischargevars(fs, e); | ||
942 | if (e->k == VNONRELOC) { /* expression already has a register? */ | ||
943 | if (!hasjumps(e)) /* no jumps? */ | ||
944 | return e->u.info; /* result is already in a register */ | ||
945 | if (e->u.info >= luaY_nvarstack(fs)) { /* reg. is not a local? */ | ||
946 | exp2reg(fs, e, e->u.info); /* put final result in it */ | ||
947 | return e->u.info; | ||
948 | } | ||
949 | } | ||
950 | luaK_exp2nextreg(fs, e); /* otherwise, use next available register */ | ||
951 | return e->u.info; | ||
952 | } | ||
953 | |||
954 | |||
955 | /* | ||
956 | ** Ensures final expression result is either in a register | ||
957 | ** or in an upvalue. | ||
958 | */ | ||
959 | void luaK_exp2anyregup (FuncState *fs, expdesc *e) { | ||
960 | if (e->k != VUPVAL || hasjumps(e)) | ||
961 | luaK_exp2anyreg(fs, e); | ||
962 | } | ||
963 | |||
964 | |||
965 | /* | ||
966 | ** Ensures final expression result is either in a register | ||
967 | ** or it is a constant. | ||
968 | */ | ||
969 | void luaK_exp2val (FuncState *fs, expdesc *e) { | ||
970 | if (hasjumps(e)) | ||
971 | luaK_exp2anyreg(fs, e); | ||
972 | else | ||
973 | luaK_dischargevars(fs, e); | ||
974 | } | ||
975 | |||
976 | |||
977 | /* | ||
978 | ** Try to make 'e' a K expression with an index in the range of R/K | ||
979 | ** indices. Return true iff succeeded. | ||
980 | */ | ||
981 | static int luaK_exp2K (FuncState *fs, expdesc *e) { | ||
982 | if (!hasjumps(e)) { | ||
983 | int info; | ||
984 | switch (e->k) { /* move constants to 'k' */ | ||
985 | case VTRUE: info = boolT(fs); break; | ||
986 | case VFALSE: info = boolF(fs); break; | ||
987 | case VNIL: info = nilK(fs); break; | ||
988 | case VKINT: info = luaK_intK(fs, e->u.ival); break; | ||
989 | case VKFLT: info = luaK_numberK(fs, e->u.nval); break; | ||
990 | case VKSTR: info = stringK(fs, e->u.strval); break; | ||
991 | case VK: info = e->u.info; break; | ||
992 | default: return 0; /* not a constant */ | ||
993 | } | ||
994 | if (info <= MAXINDEXRK) { /* does constant fit in 'argC'? */ | ||
995 | e->k = VK; /* make expression a 'K' expression */ | ||
996 | e->u.info = info; | ||
997 | return 1; | ||
998 | } | ||
999 | } | ||
1000 | /* else, expression doesn't fit; leave it unchanged */ | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | |||
1005 | /* | ||
1006 | ** Ensures final expression result is in a valid R/K index | ||
1007 | ** (that is, it is either in a register or in 'k' with an index | ||
1008 | ** in the range of R/K indices). | ||
1009 | ** Returns 1 iff expression is K. | ||
1010 | */ | ||
1011 | int luaK_exp2RK (FuncState *fs, expdesc *e) { | ||
1012 | if (luaK_exp2K(fs, e)) | ||
1013 | return 1; | ||
1014 | else { /* not a constant in the right range: put it in a register */ | ||
1015 | luaK_exp2anyreg(fs, e); | ||
1016 | return 0; | ||
1017 | } | ||
1018 | } | ||
1019 | |||
1020 | |||
1021 | static void codeABRK (FuncState *fs, OpCode o, int a, int b, | ||
1022 | expdesc *ec) { | ||
1023 | int k = luaK_exp2RK(fs, ec); | ||
1024 | luaK_codeABCk(fs, o, a, b, ec->u.info, k); | ||
1025 | } | ||
1026 | |||
1027 | |||
1028 | /* | ||
1029 | ** Generate code to store result of expression 'ex' into variable 'var'. | ||
1030 | */ | ||
1031 | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { | ||
1032 | switch (var->k) { | ||
1033 | case VLOCAL: { | ||
1034 | freeexp(fs, ex); | ||
1035 | exp2reg(fs, ex, var->u.var.sidx); /* compute 'ex' into proper place */ | ||
1036 | return; | ||
1037 | } | ||
1038 | case VUPVAL: { | ||
1039 | int e = luaK_exp2anyreg(fs, ex); | ||
1040 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); | ||
1041 | break; | ||
1042 | } | ||
1043 | case VINDEXUP: { | ||
1044 | codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex); | ||
1045 | break; | ||
1046 | } | ||
1047 | case VINDEXI: { | ||
1048 | codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex); | ||
1049 | break; | ||
1050 | } | ||
1051 | case VINDEXSTR: { | ||
1052 | codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex); | ||
1053 | break; | ||
1054 | } | ||
1055 | case VINDEXED: { | ||
1056 | codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex); | ||
1057 | break; | ||
1058 | } | ||
1059 | default: lua_assert(0); /* invalid var kind to store */ | ||
1060 | } | ||
1061 | freeexp(fs, ex); | ||
1062 | } | ||
1063 | |||
1064 | |||
1065 | /* | ||
1066 | ** Emit SELF instruction (convert expression 'e' into 'e:key(e,'). | ||
1067 | */ | ||
1068 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | ||
1069 | int ereg; | ||
1070 | luaK_exp2anyreg(fs, e); | ||
1071 | ereg = e->u.info; /* register where 'e' was placed */ | ||
1072 | freeexp(fs, e); | ||
1073 | e->u.info = fs->freereg; /* base register for op_self */ | ||
1074 | e->k = VNONRELOC; /* self expression has a fixed register */ | ||
1075 | luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ | ||
1076 | codeABRK(fs, OP_SELF, e->u.info, ereg, key); | ||
1077 | freeexp(fs, key); | ||
1078 | } | ||
1079 | |||
1080 | |||
1081 | /* | ||
1082 | ** Negate condition 'e' (where 'e' is a comparison). | ||
1083 | */ | ||
1084 | static void negatecondition (FuncState *fs, expdesc *e) { | ||
1085 | Instruction *pc = getjumpcontrol(fs, e->u.info); | ||
1086 | lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && | ||
1087 | GET_OPCODE(*pc) != OP_TEST); | ||
1088 | SETARG_k(*pc, (GETARG_k(*pc) ^ 1)); | ||
1089 | } | ||
1090 | |||
1091 | |||
1092 | /* | ||
1093 | ** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond' | ||
1094 | ** is true, code will jump if 'e' is true.) Return jump position. | ||
1095 | ** Optimize when 'e' is 'not' something, inverting the condition | ||
1096 | ** and removing the 'not'. | ||
1097 | */ | ||
1098 | static int jumponcond (FuncState *fs, expdesc *e, int cond) { | ||
1099 | if (e->k == VRELOC) { | ||
1100 | Instruction ie = getinstruction(fs, e); | ||
1101 | if (GET_OPCODE(ie) == OP_NOT) { | ||
1102 | removelastinstruction(fs); /* remove previous OP_NOT */ | ||
1103 | return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond); | ||
1104 | } | ||
1105 | /* else go through */ | ||
1106 | } | ||
1107 | discharge2anyreg(fs, e); | ||
1108 | freeexp(fs, e); | ||
1109 | return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond); | ||
1110 | } | ||
1111 | |||
1112 | |||
1113 | /* | ||
1114 | ** Emit code to go through if 'e' is true, jump otherwise. | ||
1115 | */ | ||
1116 | void luaK_goiftrue (FuncState *fs, expdesc *e) { | ||
1117 | int pc; /* pc of new jump */ | ||
1118 | luaK_dischargevars(fs, e); | ||
1119 | switch (e->k) { | ||
1120 | case VJMP: { /* condition? */ | ||
1121 | negatecondition(fs, e); /* jump when it is false */ | ||
1122 | pc = e->u.info; /* save jump position */ | ||
1123 | break; | ||
1124 | } | ||
1125 | case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { | ||
1126 | pc = NO_JUMP; /* always true; do nothing */ | ||
1127 | break; | ||
1128 | } | ||
1129 | default: { | ||
1130 | pc = jumponcond(fs, e, 0); /* jump when false */ | ||
1131 | break; | ||
1132 | } | ||
1133 | } | ||
1134 | luaK_concat(fs, &e->f, pc); /* insert new jump in false list */ | ||
1135 | luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */ | ||
1136 | e->t = NO_JUMP; | ||
1137 | } | ||
1138 | |||
1139 | |||
1140 | /* | ||
1141 | ** Emit code to go through if 'e' is false, jump otherwise. | ||
1142 | */ | ||
1143 | void luaK_goiffalse (FuncState *fs, expdesc *e) { | ||
1144 | int pc; /* pc of new jump */ | ||
1145 | luaK_dischargevars(fs, e); | ||
1146 | switch (e->k) { | ||
1147 | case VJMP: { | ||
1148 | pc = e->u.info; /* already jump if true */ | ||
1149 | break; | ||
1150 | } | ||
1151 | case VNIL: case VFALSE: { | ||
1152 | pc = NO_JUMP; /* always false; do nothing */ | ||
1153 | break; | ||
1154 | } | ||
1155 | default: { | ||
1156 | pc = jumponcond(fs, e, 1); /* jump if true */ | ||
1157 | break; | ||
1158 | } | ||
1159 | } | ||
1160 | luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */ | ||
1161 | luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */ | ||
1162 | e->f = NO_JUMP; | ||
1163 | } | ||
1164 | |||
1165 | |||
1166 | /* | ||
1167 | ** Code 'not e', doing constant folding. | ||
1168 | */ | ||
1169 | static void codenot (FuncState *fs, expdesc *e) { | ||
1170 | switch (e->k) { | ||
1171 | case VNIL: case VFALSE: { | ||
1172 | e->k = VTRUE; /* true == not nil == not false */ | ||
1173 | break; | ||
1174 | } | ||
1175 | case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { | ||
1176 | e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ | ||
1177 | break; | ||
1178 | } | ||
1179 | case VJMP: { | ||
1180 | negatecondition(fs, e); | ||
1181 | break; | ||
1182 | } | ||
1183 | case VRELOC: | ||
1184 | case VNONRELOC: { | ||
1185 | discharge2anyreg(fs, e); | ||
1186 | freeexp(fs, e); | ||
1187 | e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); | ||
1188 | e->k = VRELOC; | ||
1189 | break; | ||
1190 | } | ||
1191 | default: lua_assert(0); /* cannot happen */ | ||
1192 | } | ||
1193 | /* interchange true and false lists */ | ||
1194 | { int temp = e->f; e->f = e->t; e->t = temp; } | ||
1195 | removevalues(fs, e->f); /* values are useless when negated */ | ||
1196 | removevalues(fs, e->t); | ||
1197 | } | ||
1198 | |||
1199 | |||
1200 | /* | ||
1201 | ** Check whether expression 'e' is a small literal string | ||
1202 | */ | ||
1203 | static int isKstr (FuncState *fs, expdesc *e) { | ||
1204 | return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B && | ||
1205 | ttisshrstring(&fs->f->k[e->u.info])); | ||
1206 | } | ||
1207 | |||
1208 | /* | ||
1209 | ** Check whether expression 'e' is a literal integer. | ||
1210 | */ | ||
1211 | int luaK_isKint (expdesc *e) { | ||
1212 | return (e->k == VKINT && !hasjumps(e)); | ||
1213 | } | ||
1214 | |||
1215 | |||
1216 | /* | ||
1217 | ** Check whether expression 'e' is a literal integer in | ||
1218 | ** proper range to fit in register C | ||
1219 | */ | ||
1220 | static int isCint (expdesc *e) { | ||
1221 | return luaK_isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); | ||
1222 | } | ||
1223 | |||
1224 | |||
1225 | /* | ||
1226 | ** Check whether expression 'e' is a literal integer in | ||
1227 | ** proper range to fit in register sC | ||
1228 | */ | ||
1229 | static int isSCint (expdesc *e) { | ||
1230 | return luaK_isKint(e) && fitsC(e->u.ival); | ||
1231 | } | ||
1232 | |||
1233 | |||
1234 | /* | ||
1235 | ** Check whether expression 'e' is a literal integer or float in | ||
1236 | ** proper range to fit in a register (sB or sC). | ||
1237 | */ | ||
1238 | static int isSCnumber (expdesc *e, int *pi, int *isfloat) { | ||
1239 | lua_Integer i; | ||
1240 | if (e->k == VKINT) | ||
1241 | i = e->u.ival; | ||
1242 | else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq)) | ||
1243 | *isfloat = 1; | ||
1244 | else | ||
1245 | return 0; /* not a number */ | ||
1246 | if (!hasjumps(e) && fitsC(i)) { | ||
1247 | *pi = int2sC(cast_int(i)); | ||
1248 | return 1; | ||
1249 | } | ||
1250 | else | ||
1251 | return 0; | ||
1252 | } | ||
1253 | |||
1254 | |||
1255 | /* | ||
1256 | ** Create expression 't[k]'. 't' must have its final result already in a | ||
1257 | ** register or upvalue. Upvalues can only be indexed by literal strings. | ||
1258 | ** Keys can be literal strings in the constant table or arbitrary | ||
1259 | ** values in registers. | ||
1260 | */ | ||
1261 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | ||
1262 | if (k->k == VKSTR) | ||
1263 | str2K(fs, k); | ||
1264 | lua_assert(!hasjumps(t) && | ||
1265 | (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); | ||
1266 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ | ||
1267 | luaK_exp2anyreg(fs, t); /* put it in a register */ | ||
1268 | if (t->k == VUPVAL) { | ||
1269 | t->u.ind.t = t->u.info; /* upvalue index */ | ||
1270 | t->u.ind.idx = k->u.info; /* literal string */ | ||
1271 | t->k = VINDEXUP; | ||
1272 | } | ||
1273 | else { | ||
1274 | /* register index of the table */ | ||
1275 | t->u.ind.t = (t->k == VLOCAL) ? t->u.var.sidx: t->u.info; | ||
1276 | if (isKstr(fs, k)) { | ||
1277 | t->u.ind.idx = k->u.info; /* literal string */ | ||
1278 | t->k = VINDEXSTR; | ||
1279 | } | ||
1280 | else if (isCint(k)) { | ||
1281 | t->u.ind.idx = cast_int(k->u.ival); /* int. constant in proper range */ | ||
1282 | t->k = VINDEXI; | ||
1283 | } | ||
1284 | else { | ||
1285 | t->u.ind.idx = luaK_exp2anyreg(fs, k); /* register */ | ||
1286 | t->k = VINDEXED; | ||
1287 | } | ||
1288 | } | ||
1289 | } | ||
1290 | |||
1291 | |||
1292 | /* | ||
1293 | ** Return false if folding can raise an error. | ||
1294 | ** Bitwise operations need operands convertible to integers; division | ||
1295 | ** operations cannot have 0 as divisor. | ||
1296 | */ | ||
1297 | static int validop (int op, TValue *v1, TValue *v2) { | ||
1298 | switch (op) { | ||
1299 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: | ||
1300 | case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ | ||
1301 | lua_Integer i; | ||
1302 | return (tointegerns(v1, &i) && tointegerns(v2, &i)); | ||
1303 | } | ||
1304 | case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ | ||
1305 | return (nvalue(v2) != 0); | ||
1306 | default: return 1; /* everything else is valid */ | ||
1307 | } | ||
1308 | } | ||
1309 | |||
1310 | |||
1311 | /* | ||
1312 | ** Try to "constant-fold" an operation; return 1 iff successful. | ||
1313 | ** (In this case, 'e1' has the final result.) | ||
1314 | */ | ||
1315 | static int constfolding (FuncState *fs, int op, expdesc *e1, | ||
1316 | const expdesc *e2) { | ||
1317 | TValue v1, v2, res; | ||
1318 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) | ||
1319 | return 0; /* non-numeric operands or not safe to fold */ | ||
1320 | luaO_rawarith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ | ||
1321 | if (ttisinteger(&res)) { | ||
1322 | e1->k = VKINT; | ||
1323 | e1->u.ival = ivalue(&res); | ||
1324 | } | ||
1325 | else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */ | ||
1326 | lua_Number n = fltvalue(&res); | ||
1327 | if (luai_numisnan(n) || n == 0) | ||
1328 | return 0; | ||
1329 | e1->k = VKFLT; | ||
1330 | e1->u.nval = n; | ||
1331 | } | ||
1332 | return 1; | ||
1333 | } | ||
1334 | |||
1335 | |||
1336 | /* | ||
1337 | ** Emit code for unary expressions that "produce values" | ||
1338 | ** (everything but 'not'). | ||
1339 | ** Expression to produce final result will be encoded in 'e'. | ||
1340 | */ | ||
1341 | static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { | ||
1342 | int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */ | ||
1343 | freeexp(fs, e); | ||
1344 | e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */ | ||
1345 | e->k = VRELOC; /* all those operations are relocatable */ | ||
1346 | luaK_fixline(fs, line); | ||
1347 | } | ||
1348 | |||
1349 | |||
1350 | /* | ||
1351 | ** Emit code for binary expressions that "produce values" | ||
1352 | ** (everything but logical operators 'and'/'or' and comparison | ||
1353 | ** operators). | ||
1354 | ** Expression to produce final result will be encoded in 'e1'. | ||
1355 | */ | ||
1356 | static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, | ||
1357 | OpCode op, int v2, int flip, int line, | ||
1358 | OpCode mmop, TMS event) { | ||
1359 | int v1 = luaK_exp2anyreg(fs, e1); | ||
1360 | int pc = luaK_codeABCk(fs, op, 0, v1, v2, 0); | ||
1361 | freeexps(fs, e1, e2); | ||
1362 | e1->u.info = pc; | ||
1363 | e1->k = VRELOC; /* all those operations are relocatable */ | ||
1364 | luaK_fixline(fs, line); | ||
1365 | luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */ | ||
1366 | luaK_fixline(fs, line); | ||
1367 | } | ||
1368 | |||
1369 | |||
1370 | /* | ||
1371 | ** Emit code for binary expressions that "produce values" over | ||
1372 | ** two registers. | ||
1373 | */ | ||
1374 | static void codebinexpval (FuncState *fs, OpCode op, | ||
1375 | expdesc *e1, expdesc *e2, int line) { | ||
1376 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ | ||
1377 | lua_assert(OP_ADD <= op && op <= OP_SHR); | ||
1378 | finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, | ||
1379 | cast(TMS, (op - OP_ADD) + TM_ADD)); | ||
1380 | } | ||
1381 | |||
1382 | |||
1383 | /* | ||
1384 | ** Code binary operators with immediate operands. | ||
1385 | */ | ||
1386 | static void codebini (FuncState *fs, OpCode op, | ||
1387 | expdesc *e1, expdesc *e2, int flip, int line, | ||
1388 | TMS event) { | ||
1389 | int v2 = int2sC(cast_int(e2->u.ival)); /* immediate operand */ | ||
1390 | lua_assert(e2->k == VKINT); | ||
1391 | finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event); | ||
1392 | } | ||
1393 | |||
1394 | |||
1395 | /* Try to code a binary operator negating its second operand. | ||
1396 | ** For the metamethod, 2nd operand must keep its original value. | ||
1397 | */ | ||
1398 | static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, | ||
1399 | OpCode op, int line, TMS event) { | ||
1400 | if (!luaK_isKint(e2)) | ||
1401 | return 0; /* not an integer constant */ | ||
1402 | else { | ||
1403 | lua_Integer i2 = e2->u.ival; | ||
1404 | if (!(fitsC(i2) && fitsC(-i2))) | ||
1405 | return 0; /* not in the proper range */ | ||
1406 | else { /* operating a small integer constant */ | ||
1407 | int v2 = cast_int(i2); | ||
1408 | finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event); | ||
1409 | /* correct metamethod argument */ | ||
1410 | SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2)); | ||
1411 | return 1; /* successfully coded */ | ||
1412 | } | ||
1413 | } | ||
1414 | } | ||
1415 | |||
1416 | |||
1417 | static void swapexps (expdesc *e1, expdesc *e2) { | ||
1418 | expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ | ||
1419 | } | ||
1420 | |||
1421 | |||
1422 | /* | ||
1423 | ** Code arithmetic operators ('+', '-', ...). If second operand is a | ||
1424 | ** constant in the proper range, use variant opcodes with K operands. | ||
1425 | */ | ||
1426 | static void codearith (FuncState *fs, BinOpr opr, | ||
1427 | expdesc *e1, expdesc *e2, int flip, int line) { | ||
1428 | TMS event = cast(TMS, opr + TM_ADD); | ||
1429 | if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ | ||
1430 | int v2 = e2->u.info; /* K index */ | ||
1431 | OpCode op = cast(OpCode, opr + OP_ADDK); | ||
1432 | finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); | ||
1433 | } | ||
1434 | else { /* 'e2' is neither an immediate nor a K operand */ | ||
1435 | OpCode op = cast(OpCode, opr + OP_ADD); | ||
1436 | if (flip) | ||
1437 | swapexps(e1, e2); /* back to original order */ | ||
1438 | codebinexpval(fs, op, e1, e2, line); /* use standard operators */ | ||
1439 | } | ||
1440 | } | ||
1441 | |||
1442 | |||
1443 | /* | ||
1444 | ** Code commutative operators ('+', '*'). If first operand is a | ||
1445 | ** numeric constant, change order of operands to try to use an | ||
1446 | ** immediate or K operator. | ||
1447 | */ | ||
1448 | static void codecommutative (FuncState *fs, BinOpr op, | ||
1449 | expdesc *e1, expdesc *e2, int line) { | ||
1450 | int flip = 0; | ||
1451 | if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ | ||
1452 | swapexps(e1, e2); /* change order */ | ||
1453 | flip = 1; | ||
1454 | } | ||
1455 | if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */ | ||
1456 | codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD); | ||
1457 | else | ||
1458 | codearith(fs, op, e1, e2, flip, line); | ||
1459 | } | ||
1460 | |||
1461 | |||
1462 | /* | ||
1463 | ** Code bitwise operations; they are all associative, so the function | ||
1464 | ** tries to put an integer constant as the 2nd operand (a K operand). | ||
1465 | */ | ||
1466 | static void codebitwise (FuncState *fs, BinOpr opr, | ||
1467 | expdesc *e1, expdesc *e2, int line) { | ||
1468 | int flip = 0; | ||
1469 | int v2; | ||
1470 | OpCode op; | ||
1471 | if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { | ||
1472 | swapexps(e1, e2); /* 'e2' will be the constant operand */ | ||
1473 | flip = 1; | ||
1474 | } | ||
1475 | else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ | ||
1476 | op = cast(OpCode, opr + OP_ADD); | ||
1477 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ | ||
1478 | return; | ||
1479 | } | ||
1480 | v2 = e2->u.info; /* index in K array */ | ||
1481 | op = cast(OpCode, opr + OP_ADDK); | ||
1482 | lua_assert(ttisinteger(&fs->f->k[v2])); | ||
1483 | finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, | ||
1484 | cast(TMS, opr + TM_ADD)); | ||
1485 | } | ||
1486 | |||
1487 | |||
1488 | /* | ||
1489 | ** Emit code for order comparisons. When using an immediate operand, | ||
1490 | ** 'isfloat' tells whether the original value was a float. | ||
1491 | */ | ||
1492 | static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { | ||
1493 | int r1, r2; | ||
1494 | int im; | ||
1495 | int isfloat = 0; | ||
1496 | if (isSCnumber(e2, &im, &isfloat)) { | ||
1497 | /* use immediate operand */ | ||
1498 | r1 = luaK_exp2anyreg(fs, e1); | ||
1499 | r2 = im; | ||
1500 | op = cast(OpCode, (op - OP_LT) + OP_LTI); | ||
1501 | } | ||
1502 | else if (isSCnumber(e1, &im, &isfloat)) { | ||
1503 | /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ | ||
1504 | r1 = luaK_exp2anyreg(fs, e2); | ||
1505 | r2 = im; | ||
1506 | op = (op == OP_LT) ? OP_GTI : OP_GEI; | ||
1507 | } | ||
1508 | else { /* regular case, compare two registers */ | ||
1509 | r1 = luaK_exp2anyreg(fs, e1); | ||
1510 | r2 = luaK_exp2anyreg(fs, e2); | ||
1511 | } | ||
1512 | freeexps(fs, e1, e2); | ||
1513 | e1->u.info = condjump(fs, op, r1, r2, isfloat, 1); | ||
1514 | e1->k = VJMP; | ||
1515 | } | ||
1516 | |||
1517 | |||
1518 | /* | ||
1519 | ** Emit code for equality comparisons ('==', '~='). | ||
1520 | ** 'e1' was already put as RK by 'luaK_infix'. | ||
1521 | */ | ||
1522 | static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | ||
1523 | int r1, r2; | ||
1524 | int im; | ||
1525 | int isfloat = 0; /* not needed here, but kept for symmetry */ | ||
1526 | OpCode op; | ||
1527 | if (e1->k != VNONRELOC) { | ||
1528 | lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); | ||
1529 | swapexps(e1, e2); | ||
1530 | } | ||
1531 | r1 = luaK_exp2anyreg(fs, e1); /* 1st expression must be in register */ | ||
1532 | if (isSCnumber(e2, &im, &isfloat)) { | ||
1533 | op = OP_EQI; | ||
1534 | r2 = im; /* immediate operand */ | ||
1535 | } | ||
1536 | else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */ | ||
1537 | op = OP_EQK; | ||
1538 | r2 = e2->u.info; /* constant index */ | ||
1539 | } | ||
1540 | else { | ||
1541 | op = OP_EQ; /* will compare two registers */ | ||
1542 | r2 = luaK_exp2anyreg(fs, e2); | ||
1543 | } | ||
1544 | freeexps(fs, e1, e2); | ||
1545 | e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ)); | ||
1546 | e1->k = VJMP; | ||
1547 | } | ||
1548 | |||
1549 | |||
1550 | /* | ||
1551 | ** Apply prefix operation 'op' to expression 'e'. | ||
1552 | */ | ||
1553 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | ||
1554 | static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; | ||
1555 | luaK_dischargevars(fs, e); | ||
1556 | switch (op) { | ||
1557 | case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ | ||
1558 | if (constfolding(fs, op + LUA_OPUNM, e, &ef)) | ||
1559 | break; | ||
1560 | /* else */ /* FALLTHROUGH */ | ||
1561 | case OPR_LEN: | ||
1562 | codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line); | ||
1563 | break; | ||
1564 | case OPR_NOT: codenot(fs, e); break; | ||
1565 | default: lua_assert(0); | ||
1566 | } | ||
1567 | } | ||
1568 | |||
1569 | |||
1570 | /* | ||
1571 | ** Process 1st operand 'v' of binary operation 'op' before reading | ||
1572 | ** 2nd operand. | ||
1573 | */ | ||
1574 | void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | ||
1575 | luaK_dischargevars(fs, v); | ||
1576 | switch (op) { | ||
1577 | case OPR_AND: { | ||
1578 | luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */ | ||
1579 | break; | ||
1580 | } | ||
1581 | case OPR_OR: { | ||
1582 | luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */ | ||
1583 | break; | ||
1584 | } | ||
1585 | case OPR_CONCAT: { | ||
1586 | luaK_exp2nextreg(fs, v); /* operand must be on the stack */ | ||
1587 | break; | ||
1588 | } | ||
1589 | case OPR_ADD: case OPR_SUB: | ||
1590 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: | ||
1591 | case OPR_MOD: case OPR_POW: | ||
1592 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | ||
1593 | case OPR_SHL: case OPR_SHR: { | ||
1594 | if (!tonumeral(v, NULL)) | ||
1595 | luaK_exp2anyreg(fs, v); | ||
1596 | /* else keep numeral, which may be folded with 2nd operand */ | ||
1597 | break; | ||
1598 | } | ||
1599 | case OPR_EQ: case OPR_NE: { | ||
1600 | if (!tonumeral(v, NULL)) | ||
1601 | luaK_exp2RK(fs, v); | ||
1602 | /* else keep numeral, which may be an immediate operand */ | ||
1603 | break; | ||
1604 | } | ||
1605 | case OPR_LT: case OPR_LE: | ||
1606 | case OPR_GT: case OPR_GE: { | ||
1607 | int dummy, dummy2; | ||
1608 | if (!isSCnumber(v, &dummy, &dummy2)) | ||
1609 | luaK_exp2anyreg(fs, v); | ||
1610 | /* else keep numeral, which may be an immediate operand */ | ||
1611 | break; | ||
1612 | } | ||
1613 | default: lua_assert(0); | ||
1614 | } | ||
1615 | } | ||
1616 | |||
1617 | /* | ||
1618 | ** Create code for '(e1 .. e2)'. | ||
1619 | ** For '(e1 .. e2.1 .. e2.2)' (which is '(e1 .. (e2.1 .. e2.2))', | ||
1620 | ** because concatenation is right associative), merge both CONCATs. | ||
1621 | */ | ||
1622 | static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int line) { | ||
1623 | Instruction *ie2 = previousinstruction(fs); | ||
1624 | if (GET_OPCODE(*ie2) == OP_CONCAT) { /* is 'e2' a concatenation? */ | ||
1625 | int n = GETARG_B(*ie2); /* # of elements concatenated in 'e2' */ | ||
1626 | lua_assert(e1->u.info + 1 == GETARG_A(*ie2)); | ||
1627 | freeexp(fs, e2); | ||
1628 | SETARG_A(*ie2, e1->u.info); /* correct first element ('e1') */ | ||
1629 | SETARG_B(*ie2, n + 1); /* will concatenate one more element */ | ||
1630 | } | ||
1631 | else { /* 'e2' is not a concatenation */ | ||
1632 | luaK_codeABC(fs, OP_CONCAT, e1->u.info, 2, 0); /* new concat opcode */ | ||
1633 | freeexp(fs, e2); | ||
1634 | luaK_fixline(fs, line); | ||
1635 | } | ||
1636 | } | ||
1637 | |||
1638 | |||
1639 | /* | ||
1640 | ** Finalize code for binary operation, after reading 2nd operand. | ||
1641 | */ | ||
1642 | void luaK_posfix (FuncState *fs, BinOpr opr, | ||
1643 | expdesc *e1, expdesc *e2, int line) { | ||
1644 | luaK_dischargevars(fs, e2); | ||
1645 | if (foldbinop(opr) && constfolding(fs, opr + LUA_OPADD, e1, e2)) | ||
1646 | return; /* done by folding */ | ||
1647 | switch (opr) { | ||
1648 | case OPR_AND: { | ||
1649 | lua_assert(e1->t == NO_JUMP); /* list closed by 'luaK_infix' */ | ||
1650 | luaK_concat(fs, &e2->f, e1->f); | ||
1651 | *e1 = *e2; | ||
1652 | break; | ||
1653 | } | ||
1654 | case OPR_OR: { | ||
1655 | lua_assert(e1->f == NO_JUMP); /* list closed by 'luaK_infix' */ | ||
1656 | luaK_concat(fs, &e2->t, e1->t); | ||
1657 | *e1 = *e2; | ||
1658 | break; | ||
1659 | } | ||
1660 | case OPR_CONCAT: { /* e1 .. e2 */ | ||
1661 | luaK_exp2nextreg(fs, e2); | ||
1662 | codeconcat(fs, e1, e2, line); | ||
1663 | break; | ||
1664 | } | ||
1665 | case OPR_ADD: case OPR_MUL: { | ||
1666 | codecommutative(fs, opr, e1, e2, line); | ||
1667 | break; | ||
1668 | } | ||
1669 | case OPR_SUB: { | ||
1670 | if (finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB)) | ||
1671 | break; /* coded as (r1 + -I) */ | ||
1672 | /* ELSE */ | ||
1673 | } /* FALLTHROUGH */ | ||
1674 | case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { | ||
1675 | codearith(fs, opr, e1, e2, 0, line); | ||
1676 | break; | ||
1677 | } | ||
1678 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { | ||
1679 | codebitwise(fs, opr, e1, e2, line); | ||
1680 | break; | ||
1681 | } | ||
1682 | case OPR_SHL: { | ||
1683 | if (isSCint(e1)) { | ||
1684 | swapexps(e1, e2); | ||
1685 | codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); /* I << r2 */ | ||
1686 | } | ||
1687 | else if (finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL)) { | ||
1688 | /* coded as (r1 >> -I) */; | ||
1689 | } | ||
1690 | else /* regular case (two registers) */ | ||
1691 | codebinexpval(fs, OP_SHL, e1, e2, line); | ||
1692 | break; | ||
1693 | } | ||
1694 | case OPR_SHR: { | ||
1695 | if (isSCint(e2)) | ||
1696 | codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */ | ||
1697 | else /* regular case (two registers) */ | ||
1698 | codebinexpval(fs, OP_SHR, e1, e2, line); | ||
1699 | break; | ||
1700 | } | ||
1701 | case OPR_EQ: case OPR_NE: { | ||
1702 | codeeq(fs, opr, e1, e2); | ||
1703 | break; | ||
1704 | } | ||
1705 | case OPR_LT: case OPR_LE: { | ||
1706 | OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); | ||
1707 | codeorder(fs, op, e1, e2); | ||
1708 | break; | ||
1709 | } | ||
1710 | case OPR_GT: case OPR_GE: { | ||
1711 | /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */ | ||
1712 | OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); | ||
1713 | swapexps(e1, e2); | ||
1714 | codeorder(fs, op, e1, e2); | ||
1715 | break; | ||
1716 | } | ||
1717 | default: lua_assert(0); | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1721 | |||
1722 | /* | ||
1723 | ** Change line information associated with current position, by removing | ||
1724 | ** previous info and adding it again with new line. | ||
1725 | */ | ||
1726 | void luaK_fixline (FuncState *fs, int line) { | ||
1727 | removelastlineinfo(fs); | ||
1728 | savelineinfo(fs, fs->f, line); | ||
1729 | } | ||
1730 | |||
1731 | |||
1732 | void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { | ||
1733 | Instruction *inst = &fs->f->code[pc]; | ||
1734 | int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0; /* hash size */ | ||
1735 | int extra = asize / (MAXARG_C + 1); /* higher bits of array size */ | ||
1736 | int rc = asize % (MAXARG_C + 1); /* lower bits of array size */ | ||
1737 | int k = (extra > 0); /* true iff needs extra argument */ | ||
1738 | *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); | ||
1739 | *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); | ||
1740 | } | ||
1741 | |||
1742 | |||
1743 | /* | ||
1744 | ** Emit a SETLIST instruction. | ||
1745 | ** 'base' is register that keeps table; | ||
1746 | ** 'nelems' is #table plus those to be stored now; | ||
1747 | ** 'tostore' is number of values (in registers 'base + 1',...) to add to | ||
1748 | ** table (or LUA_MULTRET to add up to stack top). | ||
1749 | */ | ||
1750 | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { | ||
1751 | lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); | ||
1752 | if (tostore == LUA_MULTRET) | ||
1753 | tostore = 0; | ||
1754 | if (nelems <= MAXARG_C) | ||
1755 | luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems); | ||
1756 | else { | ||
1757 | int extra = nelems / (MAXARG_C + 1); | ||
1758 | nelems %= (MAXARG_C + 1); | ||
1759 | luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1); | ||
1760 | codeextraarg(fs, extra); | ||
1761 | } | ||
1762 | fs->freereg = base + 1; /* free registers with list values */ | ||
1763 | } | ||
1764 | |||
1765 | |||
1766 | /* | ||
1767 | ** return the final target of a jump (skipping jumps to jumps) | ||
1768 | */ | ||
1769 | static int finaltarget (Instruction *code, int i) { | ||
1770 | int count; | ||
1771 | for (count = 0; count < 100; count++) { /* avoid infinite loops */ | ||
1772 | Instruction pc = code[i]; | ||
1773 | if (GET_OPCODE(pc) != OP_JMP) | ||
1774 | break; | ||
1775 | else | ||
1776 | i += GETARG_sJ(pc) + 1; | ||
1777 | } | ||
1778 | return i; | ||
1779 | } | ||
1780 | |||
1781 | |||
1782 | /* | ||
1783 | ** Do a final pass over the code of a function, doing small peephole | ||
1784 | ** optimizations and adjustments. | ||
1785 | */ | ||
1786 | void luaK_finish (FuncState *fs) { | ||
1787 | int i; | ||
1788 | Proto *p = fs->f; | ||
1789 | for (i = 0; i < fs->pc; i++) { | ||
1790 | Instruction *pc = &p->code[i]; | ||
1791 | lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc)); | ||
1792 | switch (GET_OPCODE(*pc)) { | ||
1793 | case OP_RETURN0: case OP_RETURN1: { | ||
1794 | if (!(fs->needclose || p->is_vararg)) | ||
1795 | break; /* no extra work */ | ||
1796 | /* else use OP_RETURN to do the extra work */ | ||
1797 | SET_OPCODE(*pc, OP_RETURN); | ||
1798 | } /* FALLTHROUGH */ | ||
1799 | case OP_RETURN: case OP_TAILCALL: { | ||
1800 | if (fs->needclose) | ||
1801 | SETARG_k(*pc, 1); /* signal that it needs to close */ | ||
1802 | if (p->is_vararg) | ||
1803 | SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */ | ||
1804 | break; | ||
1805 | } | ||
1806 | case OP_JMP: { | ||
1807 | int target = finaltarget(p->code, i); | ||
1808 | fixjump(fs, i, target); | ||
1809 | break; | ||
1810 | } | ||
1811 | default: break; | ||
1812 | } | ||
1813 | } | ||
1814 | } | ||
diff --git a/src/lua-5.3/lcode.h b/src/lua/lcode.h index 882dc9c..3265824 100644 --- a/src/lua-5.3/lcode.h +++ b/src/lua/lcode.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lcode.h $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -24,40 +24,53 @@ | |||
24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) | 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) |
25 | */ | 25 | */ |
26 | typedef enum BinOpr { | 26 | typedef enum BinOpr { |
27 | /* arithmetic operators */ | ||
27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, | 28 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, |
28 | OPR_DIV, | 29 | OPR_DIV, OPR_IDIV, |
29 | OPR_IDIV, | 30 | /* bitwise operators */ |
30 | OPR_BAND, OPR_BOR, OPR_BXOR, | 31 | OPR_BAND, OPR_BOR, OPR_BXOR, |
31 | OPR_SHL, OPR_SHR, | 32 | OPR_SHL, OPR_SHR, |
33 | /* string operator */ | ||
32 | OPR_CONCAT, | 34 | OPR_CONCAT, |
35 | /* comparison operators */ | ||
33 | OPR_EQ, OPR_LT, OPR_LE, | 36 | OPR_EQ, OPR_LT, OPR_LE, |
34 | OPR_NE, OPR_GT, OPR_GE, | 37 | OPR_NE, OPR_GT, OPR_GE, |
38 | /* logical operators */ | ||
35 | OPR_AND, OPR_OR, | 39 | OPR_AND, OPR_OR, |
36 | OPR_NOBINOPR | 40 | OPR_NOBINOPR |
37 | } BinOpr; | 41 | } BinOpr; |
38 | 42 | ||
39 | 43 | ||
44 | /* true if operation is foldable (that is, it is arithmetic or bitwise) */ | ||
45 | #define foldbinop(op) ((op) <= OPR_SHR) | ||
46 | |||
47 | |||
48 | #define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) | ||
49 | |||
50 | |||
40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | 51 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; |
41 | 52 | ||
42 | 53 | ||
43 | /* get (pointer to) instruction of given 'expdesc' */ | 54 | /* get (pointer to) instruction of given 'expdesc' */ |
44 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) | 55 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) |
45 | 56 | ||
46 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) | ||
47 | 57 | ||
48 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) | 58 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) |
49 | 59 | ||
50 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) | 60 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) |
51 | 61 | ||
62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); | ||
52 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); | 63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
53 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); | 64 | LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx); |
54 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); | 65 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, |
66 | int B, int C, int k); | ||
67 | LUAI_FUNC int luaK_isKint (expdesc *e); | ||
68 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); | ||
55 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); | 69 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); |
56 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); | 70 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); |
57 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); | 71 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); |
58 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); | 72 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); |
59 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); | 73 | LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); |
60 | LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n); | ||
61 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); | 74 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); |
62 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); | 75 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); |
63 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); | 76 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); |
@@ -75,14 +88,17 @@ LUAI_FUNC int luaK_jump (FuncState *fs); | |||
75 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); | 88 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); |
76 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); | 89 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); |
77 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); | 90 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); |
78 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); | ||
79 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); | 91 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); |
80 | LUAI_FUNC int luaK_getlabel (FuncState *fs); | 92 | LUAI_FUNC int luaK_getlabel (FuncState *fs); |
81 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); | 93 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); |
82 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); | 94 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); |
83 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, | 95 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, |
84 | expdesc *v2, int line); | 96 | expdesc *v2, int line); |
97 | LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, | ||
98 | int ra, int asize, int hsize); | ||
85 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); | 99 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); |
100 | LUAI_FUNC void luaK_finish (FuncState *fs); | ||
101 | LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); | ||
86 | 102 | ||
87 | 103 | ||
88 | #endif | 104 | #endif |
diff --git a/src/lua-5.3/lcorolib.c b/src/lua/lcorolib.c index 0b17af9..7d6e585 100644 --- a/src/lua-5.3/lcorolib.c +++ b/src/lua/lcorolib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lcorolib.c $ |
3 | ** Coroutine Library | 3 | ** Coroutine Library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -20,25 +20,24 @@ | |||
20 | 20 | ||
21 | static lua_State *getco (lua_State *L) { | 21 | static lua_State *getco (lua_State *L) { |
22 | lua_State *co = lua_tothread(L, 1); | 22 | lua_State *co = lua_tothread(L, 1); |
23 | luaL_argcheck(L, co, 1, "thread expected"); | 23 | luaL_argexpected(L, co, 1, "thread"); |
24 | return co; | 24 | return co; |
25 | } | 25 | } |
26 | 26 | ||
27 | 27 | ||
28 | /* | ||
29 | ** Resumes a coroutine. Returns the number of results for non-error | ||
30 | ** cases or -1 for errors. | ||
31 | */ | ||
28 | static int auxresume (lua_State *L, lua_State *co, int narg) { | 32 | static int auxresume (lua_State *L, lua_State *co, int narg) { |
29 | int status; | 33 | int status, nres; |
30 | if (!lua_checkstack(co, narg)) { | 34 | if (!lua_checkstack(co, narg)) { |
31 | lua_pushliteral(L, "too many arguments to resume"); | 35 | lua_pushliteral(L, "too many arguments to resume"); |
32 | return -1; /* error flag */ | 36 | return -1; /* error flag */ |
33 | } | 37 | } |
34 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { | ||
35 | lua_pushliteral(L, "cannot resume dead coroutine"); | ||
36 | return -1; /* error flag */ | ||
37 | } | ||
38 | lua_xmove(L, co, narg); | 38 | lua_xmove(L, co, narg); |
39 | status = lua_resume(co, L, narg); | 39 | status = lua_resume(co, L, narg, &nres); |
40 | if (status == LUA_OK || status == LUA_YIELD) { | 40 | if (status == LUA_OK || status == LUA_YIELD) { |
41 | int nres = lua_gettop(co); | ||
42 | if (!lua_checkstack(L, nres + 1)) { | 41 | if (!lua_checkstack(L, nres + 1)) { |
43 | lua_pop(co, nres); /* remove results anyway */ | 42 | lua_pop(co, nres); /* remove results anyway */ |
44 | lua_pushliteral(L, "too many results to resume"); | 43 | lua_pushliteral(L, "too many results to resume"); |
@@ -75,8 +74,11 @@ static int luaB_auxwrap (lua_State *L) { | |||
75 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); | 74 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); |
76 | int r = auxresume(L, co, lua_gettop(L)); | 75 | int r = auxresume(L, co, lua_gettop(L)); |
77 | if (r < 0) { | 76 | if (r < 0) { |
77 | int stat = lua_status(co); | ||
78 | if (stat != LUA_OK && stat != LUA_YIELD) | ||
79 | lua_resetthread(co); /* close variables in case of errors */ | ||
78 | if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ | 80 | if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ |
79 | luaL_where(L, 1); /* add extra info */ | 81 | luaL_where(L, 1); /* add extra info, if available */ |
80 | lua_insert(L, -2); | 82 | lua_insert(L, -2); |
81 | lua_concat(L, 2); | 83 | lua_concat(L, 2); |
82 | } | 84 | } |
@@ -108,35 +110,48 @@ static int luaB_yield (lua_State *L) { | |||
108 | } | 110 | } |
109 | 111 | ||
110 | 112 | ||
111 | static int luaB_costatus (lua_State *L) { | 113 | #define COS_RUN 0 |
112 | lua_State *co = getco(L); | 114 | #define COS_DEAD 1 |
113 | if (L == co) lua_pushliteral(L, "running"); | 115 | #define COS_YIELD 2 |
116 | #define COS_NORM 3 | ||
117 | |||
118 | |||
119 | static const char *const statname[] = | ||
120 | {"running", "dead", "suspended", "normal"}; | ||
121 | |||
122 | |||
123 | static int auxstatus (lua_State *L, lua_State *co) { | ||
124 | if (L == co) return COS_RUN; | ||
114 | else { | 125 | else { |
115 | switch (lua_status(co)) { | 126 | switch (lua_status(co)) { |
116 | case LUA_YIELD: | 127 | case LUA_YIELD: |
117 | lua_pushliteral(L, "suspended"); | 128 | return COS_YIELD; |
118 | break; | ||
119 | case LUA_OK: { | 129 | case LUA_OK: { |
120 | lua_Debug ar; | 130 | lua_Debug ar; |
121 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ | 131 | if (lua_getstack(co, 0, &ar)) /* does it have frames? */ |
122 | lua_pushliteral(L, "normal"); /* it is running */ | 132 | return COS_NORM; /* it is running */ |
123 | else if (lua_gettop(co) == 0) | 133 | else if (lua_gettop(co) == 0) |
124 | lua_pushliteral(L, "dead"); | 134 | return COS_DEAD; |
125 | else | 135 | else |
126 | lua_pushliteral(L, "suspended"); /* initial state */ | 136 | return COS_YIELD; /* initial state */ |
127 | break; | ||
128 | } | 137 | } |
129 | default: /* some error occurred */ | 138 | default: /* some error occurred */ |
130 | lua_pushliteral(L, "dead"); | 139 | return COS_DEAD; |
131 | break; | ||
132 | } | 140 | } |
133 | } | 141 | } |
142 | } | ||
143 | |||
144 | |||
145 | static int luaB_costatus (lua_State *L) { | ||
146 | lua_State *co = getco(L); | ||
147 | lua_pushstring(L, statname[auxstatus(L, co)]); | ||
134 | return 1; | 148 | return 1; |
135 | } | 149 | } |
136 | 150 | ||
137 | 151 | ||
138 | static int luaB_yieldable (lua_State *L) { | 152 | static int luaB_yieldable (lua_State *L) { |
139 | lua_pushboolean(L, lua_isyieldable(L)); | 153 | lua_State *co = lua_isnone(L, 1) ? L : getco(L); |
154 | lua_pushboolean(L, lua_isyieldable(co)); | ||
140 | return 1; | 155 | return 1; |
141 | } | 156 | } |
142 | 157 | ||
@@ -148,6 +163,28 @@ static int luaB_corunning (lua_State *L) { | |||
148 | } | 163 | } |
149 | 164 | ||
150 | 165 | ||
166 | static int luaB_close (lua_State *L) { | ||
167 | lua_State *co = getco(L); | ||
168 | int status = auxstatus(L, co); | ||
169 | switch (status) { | ||
170 | case COS_DEAD: case COS_YIELD: { | ||
171 | status = lua_resetthread(co); | ||
172 | if (status == LUA_OK) { | ||
173 | lua_pushboolean(L, 1); | ||
174 | return 1; | ||
175 | } | ||
176 | else { | ||
177 | lua_pushboolean(L, 0); | ||
178 | lua_xmove(co, L, 1); /* copy error message */ | ||
179 | return 2; | ||
180 | } | ||
181 | } | ||
182 | default: /* normal or running coroutine */ | ||
183 | return luaL_error(L, "cannot close a %s coroutine", statname[status]); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | |||
151 | static const luaL_Reg co_funcs[] = { | 188 | static const luaL_Reg co_funcs[] = { |
152 | {"create", luaB_cocreate}, | 189 | {"create", luaB_cocreate}, |
153 | {"resume", luaB_coresume}, | 190 | {"resume", luaB_coresume}, |
@@ -156,6 +193,7 @@ static const luaL_Reg co_funcs[] = { | |||
156 | {"wrap", luaB_cowrap}, | 193 | {"wrap", luaB_cowrap}, |
157 | {"yield", luaB_yield}, | 194 | {"yield", luaB_yield}, |
158 | {"isyieldable", luaB_yieldable}, | 195 | {"isyieldable", luaB_yieldable}, |
196 | {"close", luaB_close}, | ||
159 | {NULL, NULL} | 197 | {NULL, NULL} |
160 | }; | 198 | }; |
161 | 199 | ||
diff --git a/src/lua-5.3/lctype.c b/src/lua/lctype.c index f8ad7a2..9542280 100644 --- a/src/lua-5.3/lctype.c +++ b/src/lua/lctype.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lctype.c $ |
3 | ** 'ctype' functions for Lua | 3 | ** 'ctype' functions for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -16,6 +16,15 @@ | |||
16 | 16 | ||
17 | #include <limits.h> | 17 | #include <limits.h> |
18 | 18 | ||
19 | |||
20 | #if defined (LUA_UCID) /* accept UniCode IDentifiers? */ | ||
21 | /* consider all non-ascii codepoints to be alphabetic */ | ||
22 | #define NONA 0x01 | ||
23 | #else | ||
24 | #define NONA 0x00 /* default */ | ||
25 | #endif | ||
26 | |||
27 | |||
19 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { | 28 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { |
20 | 0x00, /* EOZ */ | 29 | 0x00, /* EOZ */ |
21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ | 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ |
@@ -34,22 +43,22 @@ LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { | |||
34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, | 43 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, |
35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ | 44 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ |
36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, | 45 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, |
37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ | 46 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ |
38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 47 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, |
39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ | 48 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ |
40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 49 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, |
41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ | 50 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ |
42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 51 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, |
43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ | 52 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ |
44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 53 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, |
45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ | 54 | 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ |
46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 55 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, |
47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ | 56 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ |
48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 57 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, |
49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ | 58 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ |
50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 59 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, |
51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ | 60 | NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ |
52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
53 | }; | 62 | }; |
54 | 63 | ||
55 | #endif /* } */ | 64 | #endif /* } */ |
diff --git a/src/lua-5.3/lctype.h b/src/lua/lctype.h index b09b21a..cbff4d7 100644 --- a/src/lua-5.3/lctype.h +++ b/src/lua/lctype.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $ | 2 | ** $Id: lctype.h $ |
3 | ** 'ctype' functions for Lua | 3 | ** 'ctype' functions for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -68,7 +68,7 @@ | |||
68 | 68 | ||
69 | 69 | ||
70 | /* two more entries for 0 and -1 (EOZ) */ | 70 | /* two more entries for 0 and -1 (EOZ) */ |
71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; | 71 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) |
72 | 72 | ||
73 | 73 | ||
74 | #else /* }{ */ | 74 | #else /* }{ */ |
diff --git a/src/lua-5.3/ldblib.c b/src/lua/ldblib.c index 9d29afb..59eb8f0 100644 --- a/src/lua-5.3/ldblib.c +++ b/src/lua/ldblib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.151.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: ldblib.c $ |
3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -21,10 +21,10 @@ | |||
21 | 21 | ||
22 | 22 | ||
23 | /* | 23 | /* |
24 | ** The hook table at registry[&HOOKKEY] maps threads to their current | 24 | ** The hook table at registry[HOOKKEY] maps threads to their current |
25 | ** hook function. (We only need the unique address of 'HOOKKEY'.) | 25 | ** hook function. |
26 | */ | 26 | */ |
27 | static const int HOOKKEY = 0; | 27 | static const char *const HOOKKEY = "_HOOKKEY"; |
28 | 28 | ||
29 | 29 | ||
30 | /* | 30 | /* |
@@ -55,8 +55,7 @@ static int db_getmetatable (lua_State *L) { | |||
55 | 55 | ||
56 | static int db_setmetatable (lua_State *L) { | 56 | static int db_setmetatable (lua_State *L) { |
57 | int t = lua_type(L, 2); | 57 | int t = lua_type(L, 2); |
58 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, | 58 | luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); |
59 | "nil or table expected"); | ||
60 | lua_settop(L, 2); | 59 | lua_settop(L, 2); |
61 | lua_setmetatable(L, 1); | 60 | lua_setmetatable(L, 1); |
62 | return 1; /* return 1st argument */ | 61 | return 1; /* return 1st argument */ |
@@ -64,19 +63,24 @@ static int db_setmetatable (lua_State *L) { | |||
64 | 63 | ||
65 | 64 | ||
66 | static int db_getuservalue (lua_State *L) { | 65 | static int db_getuservalue (lua_State *L) { |
66 | int n = (int)luaL_optinteger(L, 2, 1); | ||
67 | if (lua_type(L, 1) != LUA_TUSERDATA) | 67 | if (lua_type(L, 1) != LUA_TUSERDATA) |
68 | lua_pushnil(L); | 68 | luaL_pushfail(L); |
69 | else | 69 | else if (lua_getiuservalue(L, 1, n) != LUA_TNONE) { |
70 | lua_getuservalue(L, 1); | 70 | lua_pushboolean(L, 1); |
71 | return 2; | ||
72 | } | ||
71 | return 1; | 73 | return 1; |
72 | } | 74 | } |
73 | 75 | ||
74 | 76 | ||
75 | static int db_setuservalue (lua_State *L) { | 77 | static int db_setuservalue (lua_State *L) { |
78 | int n = (int)luaL_optinteger(L, 3, 1); | ||
76 | luaL_checktype(L, 1, LUA_TUSERDATA); | 79 | luaL_checktype(L, 1, LUA_TUSERDATA); |
77 | luaL_checkany(L, 2); | 80 | luaL_checkany(L, 2); |
78 | lua_settop(L, 2); | 81 | lua_settop(L, 2); |
79 | lua_setuservalue(L, 1); | 82 | if (!lua_setiuservalue(L, 1, n)) |
83 | luaL_pushfail(L); | ||
80 | return 1; | 84 | return 1; |
81 | } | 85 | } |
82 | 86 | ||
@@ -146,7 +150,7 @@ static int db_getinfo (lua_State *L) { | |||
146 | lua_Debug ar; | 150 | lua_Debug ar; |
147 | int arg; | 151 | int arg; |
148 | lua_State *L1 = getthread(L, &arg); | 152 | lua_State *L1 = getthread(L, &arg); |
149 | const char *options = luaL_optstring(L, arg+2, "flnStu"); | 153 | const char *options = luaL_optstring(L, arg+2, "flnSrtu"); |
150 | checkstack(L, L1, 3); | 154 | checkstack(L, L1, 3); |
151 | if (lua_isfunction(L, arg + 1)) { /* info about a function? */ | 155 | if (lua_isfunction(L, arg + 1)) { /* info about a function? */ |
152 | options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ | 156 | options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ |
@@ -155,7 +159,7 @@ static int db_getinfo (lua_State *L) { | |||
155 | } | 159 | } |
156 | else { /* stack level */ | 160 | else { /* stack level */ |
157 | if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { | 161 | if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { |
158 | lua_pushnil(L); /* level out of range */ | 162 | luaL_pushfail(L); /* level out of range */ |
159 | return 1; | 163 | return 1; |
160 | } | 164 | } |
161 | } | 165 | } |
@@ -163,7 +167,8 @@ static int db_getinfo (lua_State *L) { | |||
163 | return luaL_argerror(L, arg+2, "invalid option"); | 167 | return luaL_argerror(L, arg+2, "invalid option"); |
164 | lua_newtable(L); /* table to collect results */ | 168 | lua_newtable(L); /* table to collect results */ |
165 | if (strchr(options, 'S')) { | 169 | if (strchr(options, 'S')) { |
166 | settabss(L, "source", ar.source); | 170 | lua_pushlstring(L, ar.source, ar.srclen); |
171 | lua_setfield(L, -2, "source"); | ||
167 | settabss(L, "short_src", ar.short_src); | 172 | settabss(L, "short_src", ar.short_src); |
168 | settabsi(L, "linedefined", ar.linedefined); | 173 | settabsi(L, "linedefined", ar.linedefined); |
169 | settabsi(L, "lastlinedefined", ar.lastlinedefined); | 174 | settabsi(L, "lastlinedefined", ar.lastlinedefined); |
@@ -180,6 +185,10 @@ static int db_getinfo (lua_State *L) { | |||
180 | settabss(L, "name", ar.name); | 185 | settabss(L, "name", ar.name); |
181 | settabss(L, "namewhat", ar.namewhat); | 186 | settabss(L, "namewhat", ar.namewhat); |
182 | } | 187 | } |
188 | if (strchr(options, 'r')) { | ||
189 | settabsi(L, "ftransfer", ar.ftransfer); | ||
190 | settabsi(L, "ntransfer", ar.ntransfer); | ||
191 | } | ||
183 | if (strchr(options, 't')) | 192 | if (strchr(options, 't')) |
184 | settabsb(L, "istailcall", ar.istailcall); | 193 | settabsb(L, "istailcall", ar.istailcall); |
185 | if (strchr(options, 'L')) | 194 | if (strchr(options, 'L')) |
@@ -193,8 +202,6 @@ static int db_getinfo (lua_State *L) { | |||
193 | static int db_getlocal (lua_State *L) { | 202 | static int db_getlocal (lua_State *L) { |
194 | int arg; | 203 | int arg; |
195 | lua_State *L1 = getthread(L, &arg); | 204 | lua_State *L1 = getthread(L, &arg); |
196 | lua_Debug ar; | ||
197 | const char *name; | ||
198 | int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ | 205 | int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ |
199 | if (lua_isfunction(L, arg + 1)) { /* function argument? */ | 206 | if (lua_isfunction(L, arg + 1)) { /* function argument? */ |
200 | lua_pushvalue(L, arg + 1); /* push function */ | 207 | lua_pushvalue(L, arg + 1); /* push function */ |
@@ -202,6 +209,8 @@ static int db_getlocal (lua_State *L) { | |||
202 | return 1; /* return only name (there is no value) */ | 209 | return 1; /* return only name (there is no value) */ |
203 | } | 210 | } |
204 | else { /* stack-level argument */ | 211 | else { /* stack-level argument */ |
212 | lua_Debug ar; | ||
213 | const char *name; | ||
205 | int level = (int)luaL_checkinteger(L, arg + 1); | 214 | int level = (int)luaL_checkinteger(L, arg + 1); |
206 | if (!lua_getstack(L1, level, &ar)) /* out of range? */ | 215 | if (!lua_getstack(L1, level, &ar)) /* out of range? */ |
207 | return luaL_argerror(L, arg+1, "level out of range"); | 216 | return luaL_argerror(L, arg+1, "level out of range"); |
@@ -214,7 +223,7 @@ static int db_getlocal (lua_State *L) { | |||
214 | return 2; | 223 | return 2; |
215 | } | 224 | } |
216 | else { | 225 | else { |
217 | lua_pushnil(L); /* no name (nor value) */ | 226 | luaL_pushfail(L); /* no name (nor value) */ |
218 | return 1; | 227 | return 1; |
219 | } | 228 | } |
220 | } | 229 | } |
@@ -305,7 +314,7 @@ static int db_upvaluejoin (lua_State *L) { | |||
305 | static void hookf (lua_State *L, lua_Debug *ar) { | 314 | static void hookf (lua_State *L, lua_Debug *ar) { |
306 | static const char *const hooknames[] = | 315 | static const char *const hooknames[] = |
307 | {"call", "return", "line", "count", "tail call"}; | 316 | {"call", "return", "line", "count", "tail call"}; |
308 | lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); | 317 | lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY); |
309 | lua_pushthread(L); | 318 | lua_pushthread(L); |
310 | if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ | 319 | if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ |
311 | lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ | 320 | lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ |
@@ -358,14 +367,12 @@ static int db_sethook (lua_State *L) { | |||
358 | count = (int)luaL_optinteger(L, arg + 3, 0); | 367 | count = (int)luaL_optinteger(L, arg + 3, 0); |
359 | func = hookf; mask = makemask(smask, count); | 368 | func = hookf; mask = makemask(smask, count); |
360 | } | 369 | } |
361 | if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) { | 370 | if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) { |
362 | lua_createtable(L, 0, 2); /* create a hook table */ | 371 | /* table just created; initialize it */ |
363 | lua_pushvalue(L, -1); | ||
364 | lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */ | ||
365 | lua_pushstring(L, "k"); | 372 | lua_pushstring(L, "k"); |
366 | lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ | 373 | lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ |
367 | lua_pushvalue(L, -1); | 374 | lua_pushvalue(L, -1); |
368 | lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ | 375 | lua_setmetatable(L, -2); /* metatable(hooktable) = hooktable */ |
369 | } | 376 | } |
370 | checkstack(L, L1, 1); | 377 | checkstack(L, L1, 1); |
371 | lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ | 378 | lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ |
@@ -382,12 +389,14 @@ static int db_gethook (lua_State *L) { | |||
382 | char buff[5]; | 389 | char buff[5]; |
383 | int mask = lua_gethookmask(L1); | 390 | int mask = lua_gethookmask(L1); |
384 | lua_Hook hook = lua_gethook(L1); | 391 | lua_Hook hook = lua_gethook(L1); |
385 | if (hook == NULL) /* no hook? */ | 392 | if (hook == NULL) { /* no hook? */ |
386 | lua_pushnil(L); | 393 | luaL_pushfail(L); |
394 | return 1; | ||
395 | } | ||
387 | else if (hook != hookf) /* external hook? */ | 396 | else if (hook != hookf) /* external hook? */ |
388 | lua_pushliteral(L, "external hook"); | 397 | lua_pushliteral(L, "external hook"); |
389 | else { /* hook table must exist */ | 398 | else { /* hook table must exist */ |
390 | lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); | 399 | lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY); |
391 | checkstack(L, L1, 1); | 400 | checkstack(L, L1, 1); |
392 | lua_pushthread(L1); lua_xmove(L1, L, 1); | 401 | lua_pushthread(L1); lua_xmove(L1, L, 1); |
393 | lua_rawget(L, -2); /* 1st result = hooktable[L1] */ | 402 | lua_rawget(L, -2); /* 1st result = hooktable[L1] */ |
@@ -408,7 +417,7 @@ static int db_debug (lua_State *L) { | |||
408 | return 0; | 417 | return 0; |
409 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || | 418 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || |
410 | lua_pcall(L, 0, 0, 0)) | 419 | lua_pcall(L, 0, 0, 0)) |
411 | lua_writestringerror("%s\n", lua_tostring(L, -1)); | 420 | lua_writestringerror("%s\n", luaL_tolstring(L, -1, NULL)); |
412 | lua_settop(L, 0); /* remove eventual returns */ | 421 | lua_settop(L, 0); /* remove eventual returns */ |
413 | } | 422 | } |
414 | } | 423 | } |
@@ -428,6 +437,17 @@ static int db_traceback (lua_State *L) { | |||
428 | } | 437 | } |
429 | 438 | ||
430 | 439 | ||
440 | static int db_setcstacklimit (lua_State *L) { | ||
441 | int limit = (int)luaL_checkinteger(L, 1); | ||
442 | int res = lua_setcstacklimit(L, limit); | ||
443 | if (res == 0) | ||
444 | lua_pushboolean(L, 0); | ||
445 | else | ||
446 | lua_pushinteger(L, res); | ||
447 | return 1; | ||
448 | } | ||
449 | |||
450 | |||
431 | static const luaL_Reg dblib[] = { | 451 | static const luaL_Reg dblib[] = { |
432 | {"debug", db_debug}, | 452 | {"debug", db_debug}, |
433 | {"getuservalue", db_getuservalue}, | 453 | {"getuservalue", db_getuservalue}, |
@@ -445,6 +465,7 @@ static const luaL_Reg dblib[] = { | |||
445 | {"setmetatable", db_setmetatable}, | 465 | {"setmetatable", db_setmetatable}, |
446 | {"setupvalue", db_setupvalue}, | 466 | {"setupvalue", db_setupvalue}, |
447 | {"traceback", db_traceback}, | 467 | {"traceback", db_traceback}, |
468 | {"setcstacklimit", db_setcstacklimit}, | ||
448 | {NULL, NULL} | 469 | {NULL, NULL} |
449 | }; | 470 | }; |
450 | 471 | ||
diff --git a/src/lua-5.3/ldebug.c b/src/lua/ldebug.c index e138929..afdc2b7 100644 --- a/src/lua-5.3/ldebug.c +++ b/src/lua/ldebug.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $ | 2 | ** $Id: ldebug.c $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -31,11 +31,11 @@ | |||
31 | 31 | ||
32 | 32 | ||
33 | 33 | ||
34 | #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) | 34 | #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL) |
35 | 35 | ||
36 | 36 | ||
37 | /* Active Lua function (given call info) */ | 37 | /* Active Lua function (given call info) */ |
38 | #define ci_func(ci) (clLvalue((ci)->func)) | 38 | #define ci_func(ci) (clLvalue(s2v((ci)->func))) |
39 | 39 | ||
40 | 40 | ||
41 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | 41 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, |
@@ -48,29 +48,85 @@ static int currentpc (CallInfo *ci) { | |||
48 | } | 48 | } |
49 | 49 | ||
50 | 50 | ||
51 | static int currentline (CallInfo *ci) { | 51 | /* |
52 | return getfuncline(ci_func(ci)->p, currentpc(ci)); | 52 | ** Get a "base line" to find the line corresponding to an instruction. |
53 | ** For that, search the array of absolute line info for the largest saved | ||
54 | ** instruction smaller or equal to the wanted instruction. A special | ||
55 | ** case is when there is no absolute info or the instruction is before | ||
56 | ** the first absolute one. | ||
57 | */ | ||
58 | static int getbaseline (const Proto *f, int pc, int *basepc) { | ||
59 | if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) { | ||
60 | *basepc = -1; /* start from the beginning */ | ||
61 | return f->linedefined; | ||
62 | } | ||
63 | else { | ||
64 | unsigned int i; | ||
65 | if (pc >= f->abslineinfo[f->sizeabslineinfo - 1].pc) | ||
66 | i = f->sizeabslineinfo - 1; /* instruction is after last saved one */ | ||
67 | else { /* binary search */ | ||
68 | unsigned int j = f->sizeabslineinfo - 1; /* pc < anchorlines[j] */ | ||
69 | i = 0; /* abslineinfo[i] <= pc */ | ||
70 | while (i < j - 1) { | ||
71 | unsigned int m = (j + i) / 2; | ||
72 | if (pc >= f->abslineinfo[m].pc) | ||
73 | i = m; | ||
74 | else | ||
75 | j = m; | ||
76 | } | ||
77 | } | ||
78 | *basepc = f->abslineinfo[i].pc; | ||
79 | return f->abslineinfo[i].line; | ||
80 | } | ||
53 | } | 81 | } |
54 | 82 | ||
55 | 83 | ||
56 | /* | 84 | /* |
57 | ** If function yielded, its 'func' can be in the 'extra' field. The | 85 | ** Get the line corresponding to instruction 'pc' in function 'f'; |
58 | ** next function restores 'func' to its correct value for debugging | 86 | ** first gets a base line and from there does the increments until |
59 | ** purposes. (It exchanges 'func' and 'extra'; so, when called again, | 87 | ** the desired instruction. |
60 | ** after debugging, it also "re-restores" ** 'func' to its altered value. | ||
61 | */ | 88 | */ |
62 | static void swapextra (lua_State *L) { | 89 | int luaG_getfuncline (const Proto *f, int pc) { |
63 | if (L->status == LUA_YIELD) { | 90 | if (f->lineinfo == NULL) /* no debug information? */ |
64 | CallInfo *ci = L->ci; /* get function that yielded */ | 91 | return -1; |
65 | StkId temp = ci->func; /* exchange its 'func' and 'extra' values */ | 92 | else { |
66 | ci->func = restorestack(L, ci->extra); | 93 | int basepc; |
67 | ci->extra = savestack(L, temp); | 94 | int baseline = getbaseline(f, pc, &basepc); |
95 | while (basepc++ < pc) { /* walk until given instruction */ | ||
96 | lua_assert(f->lineinfo[basepc] != ABSLINEINFO); | ||
97 | baseline += f->lineinfo[basepc]; /* correct line */ | ||
98 | } | ||
99 | return baseline; | ||
68 | } | 100 | } |
69 | } | 101 | } |
70 | 102 | ||
71 | 103 | ||
104 | static int getcurrentline (CallInfo *ci) { | ||
105 | return luaG_getfuncline(ci_func(ci)->p, currentpc(ci)); | ||
106 | } | ||
107 | |||
108 | |||
72 | /* | 109 | /* |
73 | ** This function can be called asynchronously (e.g. during a signal). | 110 | ** Set 'trap' for all active Lua frames. |
111 | ** This function can be called during a signal, under "reasonable" | ||
112 | ** assumptions. A new 'ci' is completely linked in the list before it | ||
113 | ** becomes part of the "active" list, and we assume that pointers are | ||
114 | ** atomic; see comment in next function. | ||
115 | ** (A compiler doing interprocedural optimizations could, theoretically, | ||
116 | ** reorder memory writes in such a way that the list could be | ||
117 | ** temporarily broken while inserting a new element. We simply assume it | ||
118 | ** has no good reasons to do that.) | ||
119 | */ | ||
120 | static void settraps (CallInfo *ci) { | ||
121 | for (; ci != NULL; ci = ci->previous) | ||
122 | if (isLua(ci)) | ||
123 | ci->u.l.trap = 1; | ||
124 | } | ||
125 | |||
126 | |||
127 | /* | ||
128 | ** This function can be called during a signal, under "reasonable" | ||
129 | ** assumptions. | ||
74 | ** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by | 130 | ** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by |
75 | ** 'resethookcount') are for debug only, and it is no problem if they | 131 | ** 'resethookcount') are for debug only, and it is no problem if they |
76 | ** get arbitrary values (causes at most one wrong hook call). 'hookmask' | 132 | ** get arbitrary values (causes at most one wrong hook call). 'hookmask' |
@@ -89,6 +145,8 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | |||
89 | L->basehookcount = count; | 145 | L->basehookcount = count; |
90 | resethookcount(L); | 146 | resethookcount(L); |
91 | L->hookmask = cast_byte(mask); | 147 | L->hookmask = cast_byte(mask); |
148 | if (mask) | ||
149 | settraps(L->ci); /* to trace inside 'luaV_execute' */ | ||
92 | } | 150 | } |
93 | 151 | ||
94 | 152 | ||
@@ -124,7 +182,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | |||
124 | } | 182 | } |
125 | 183 | ||
126 | 184 | ||
127 | static const char *upvalname (Proto *p, int uv) { | 185 | static const char *upvalname (const Proto *p, int uv) { |
128 | TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); | 186 | TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); |
129 | if (s == NULL) return "?"; | 187 | if (s == NULL) return "?"; |
130 | else return getstr(s); | 188 | else return getstr(s); |
@@ -132,38 +190,37 @@ static const char *upvalname (Proto *p, int uv) { | |||
132 | 190 | ||
133 | 191 | ||
134 | static const char *findvararg (CallInfo *ci, int n, StkId *pos) { | 192 | static const char *findvararg (CallInfo *ci, int n, StkId *pos) { |
135 | int nparams = clLvalue(ci->func)->p->numparams; | 193 | if (clLvalue(s2v(ci->func))->p->is_vararg) { |
136 | if (n >= cast_int(ci->u.l.base - ci->func) - nparams) | 194 | int nextra = ci->u.l.nextraargs; |
137 | return NULL; /* no such vararg */ | 195 | if (n <= nextra) { |
138 | else { | 196 | *pos = ci->func - nextra + (n - 1); |
139 | *pos = ci->func + nparams + n; | 197 | return "(vararg)"; /* generic name for any vararg */ |
140 | return "(*vararg)"; /* generic name for any vararg */ | 198 | } |
141 | } | 199 | } |
200 | return NULL; /* no such vararg */ | ||
142 | } | 201 | } |
143 | 202 | ||
144 | 203 | ||
145 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, | 204 | const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) { |
146 | StkId *pos) { | 205 | StkId base = ci->func + 1; |
147 | const char *name = NULL; | 206 | const char *name = NULL; |
148 | StkId base; | ||
149 | if (isLua(ci)) { | 207 | if (isLua(ci)) { |
150 | if (n < 0) /* access to vararg values? */ | 208 | if (n < 0) /* access to vararg values? */ |
151 | return findvararg(ci, -n, pos); | 209 | return findvararg(ci, -n, pos); |
152 | else { | 210 | else |
153 | base = ci->u.l.base; | ||
154 | name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); | 211 | name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); |
155 | } | ||
156 | } | 212 | } |
157 | else | ||
158 | base = ci->func + 1; | ||
159 | if (name == NULL) { /* no 'standard' name? */ | 213 | if (name == NULL) { /* no 'standard' name? */ |
160 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; | 214 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; |
161 | if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ | 215 | if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */ |
162 | name = "(*temporary)"; /* generic name for any valid slot */ | 216 | /* generic name for any valid slot */ |
217 | name = isLua(ci) ? "(temporary)" : "(C temporary)"; | ||
218 | } | ||
163 | else | 219 | else |
164 | return NULL; /* no name */ | 220 | return NULL; /* no name */ |
165 | } | 221 | } |
166 | *pos = base + (n - 1); | 222 | if (pos) |
223 | *pos = base + (n - 1); | ||
167 | return name; | 224 | return name; |
168 | } | 225 | } |
169 | 226 | ||
@@ -171,22 +228,20 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, | |||
171 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | 228 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { |
172 | const char *name; | 229 | const char *name; |
173 | lua_lock(L); | 230 | lua_lock(L); |
174 | swapextra(L); | ||
175 | if (ar == NULL) { /* information about non-active function? */ | 231 | if (ar == NULL) { /* information about non-active function? */ |
176 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ | 232 | if (!isLfunction(s2v(L->top - 1))) /* not a Lua function? */ |
177 | name = NULL; | 233 | name = NULL; |
178 | else /* consider live variables at function start (parameters) */ | 234 | else /* consider live variables at function start (parameters) */ |
179 | name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); | 235 | name = luaF_getlocalname(clLvalue(s2v(L->top - 1))->p, n, 0); |
180 | } | 236 | } |
181 | else { /* active function; get information through 'ar' */ | 237 | else { /* active function; get information through 'ar' */ |
182 | StkId pos = NULL; /* to avoid warnings */ | 238 | StkId pos = NULL; /* to avoid warnings */ |
183 | name = findlocal(L, ar->i_ci, n, &pos); | 239 | name = luaG_findlocal(L, ar->i_ci, n, &pos); |
184 | if (name) { | 240 | if (name) { |
185 | setobj2s(L, L->top, pos); | 241 | setobjs2s(L, L->top, pos); |
186 | api_incr_top(L); | 242 | api_incr_top(L); |
187 | } | 243 | } |
188 | } | 244 | } |
189 | swapextra(L); | ||
190 | lua_unlock(L); | 245 | lua_unlock(L); |
191 | return name; | 246 | return name; |
192 | } | 247 | } |
@@ -196,13 +251,11 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
196 | StkId pos = NULL; /* to avoid warnings */ | 251 | StkId pos = NULL; /* to avoid warnings */ |
197 | const char *name; | 252 | const char *name; |
198 | lua_lock(L); | 253 | lua_lock(L); |
199 | swapextra(L); | 254 | name = luaG_findlocal(L, ar->i_ci, n, &pos); |
200 | name = findlocal(L, ar->i_ci, n, &pos); | ||
201 | if (name) { | 255 | if (name) { |
202 | setobjs2s(L, pos, L->top - 1); | 256 | setobjs2s(L, pos, L->top - 1); |
203 | L->top--; /* pop value */ | 257 | L->top--; /* pop value */ |
204 | } | 258 | } |
205 | swapextra(L); | ||
206 | lua_unlock(L); | 259 | lua_unlock(L); |
207 | return name; | 260 | return name; |
208 | } | 261 | } |
@@ -211,36 +264,55 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
211 | static void funcinfo (lua_Debug *ar, Closure *cl) { | 264 | static void funcinfo (lua_Debug *ar, Closure *cl) { |
212 | if (noLuaClosure(cl)) { | 265 | if (noLuaClosure(cl)) { |
213 | ar->source = "=[C]"; | 266 | ar->source = "=[C]"; |
267 | ar->srclen = LL("=[C]"); | ||
214 | ar->linedefined = -1; | 268 | ar->linedefined = -1; |
215 | ar->lastlinedefined = -1; | 269 | ar->lastlinedefined = -1; |
216 | ar->what = "C"; | 270 | ar->what = "C"; |
217 | } | 271 | } |
218 | else { | 272 | else { |
219 | Proto *p = cl->l.p; | 273 | const Proto *p = cl->l.p; |
220 | ar->source = p->source ? getstr(p->source) : "=?"; | 274 | if (p->source) { |
275 | ar->source = getstr(p->source); | ||
276 | ar->srclen = tsslen(p->source); | ||
277 | } | ||
278 | else { | ||
279 | ar->source = "=?"; | ||
280 | ar->srclen = LL("=?"); | ||
281 | } | ||
221 | ar->linedefined = p->linedefined; | 282 | ar->linedefined = p->linedefined; |
222 | ar->lastlinedefined = p->lastlinedefined; | 283 | ar->lastlinedefined = p->lastlinedefined; |
223 | ar->what = (ar->linedefined == 0) ? "main" : "Lua"; | 284 | ar->what = (ar->linedefined == 0) ? "main" : "Lua"; |
224 | } | 285 | } |
225 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); | 286 | luaO_chunkid(ar->short_src, ar->source, ar->srclen); |
287 | } | ||
288 | |||
289 | |||
290 | static int nextline (const Proto *p, int currentline, int pc) { | ||
291 | if (p->lineinfo[pc] != ABSLINEINFO) | ||
292 | return currentline + p->lineinfo[pc]; | ||
293 | else | ||
294 | return luaG_getfuncline(p, pc); | ||
226 | } | 295 | } |
227 | 296 | ||
228 | 297 | ||
229 | static void collectvalidlines (lua_State *L, Closure *f) { | 298 | static void collectvalidlines (lua_State *L, Closure *f) { |
230 | if (noLuaClosure(f)) { | 299 | if (noLuaClosure(f)) { |
231 | setnilvalue(L->top); | 300 | setnilvalue(s2v(L->top)); |
232 | api_incr_top(L); | 301 | api_incr_top(L); |
233 | } | 302 | } |
234 | else { | 303 | else { |
235 | int i; | 304 | int i; |
236 | TValue v; | 305 | TValue v; |
237 | int *lineinfo = f->l.p->lineinfo; | 306 | const Proto *p = f->l.p; |
307 | int currentline = p->linedefined; | ||
238 | Table *t = luaH_new(L); /* new table to store active lines */ | 308 | Table *t = luaH_new(L); /* new table to store active lines */ |
239 | sethvalue(L, L->top, t); /* push it on stack */ | 309 | sethvalue2s(L, L->top, t); /* push it on stack */ |
240 | api_incr_top(L); | 310 | api_incr_top(L); |
241 | setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ | 311 | setbtvalue(&v); /* boolean 'true' to be the value of all indices */ |
242 | for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ | 312 | for (i = 0; i < p->sizelineinfo; i++) { /* for all lines with code */ |
243 | luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ | 313 | currentline = nextline(p, currentline, i); |
314 | luaH_setint(L, t, currentline, &v); /* table[line] = true */ | ||
315 | } | ||
244 | } | 316 | } |
245 | } | 317 | } |
246 | 318 | ||
@@ -269,7 +341,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
269 | break; | 341 | break; |
270 | } | 342 | } |
271 | case 'l': { | 343 | case 'l': { |
272 | ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; | 344 | ar->currentline = (ci && isLua(ci)) ? getcurrentline(ci) : -1; |
273 | break; | 345 | break; |
274 | } | 346 | } |
275 | case 'u': { | 347 | case 'u': { |
@@ -296,6 +368,15 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
296 | } | 368 | } |
297 | break; | 369 | break; |
298 | } | 370 | } |
371 | case 'r': { | ||
372 | if (ci == NULL || !(ci->callstatus & CIST_TRAN)) | ||
373 | ar->ftransfer = ar->ntransfer = 0; | ||
374 | else { | ||
375 | ar->ftransfer = ci->u2.transferinfo.ftransfer; | ||
376 | ar->ntransfer = ci->u2.transferinfo.ntransfer; | ||
377 | } | ||
378 | break; | ||
379 | } | ||
299 | case 'L': | 380 | case 'L': |
300 | case 'f': /* handled by lua_getinfo */ | 381 | case 'f': /* handled by lua_getinfo */ |
301 | break; | 382 | break; |
@@ -310,28 +391,26 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
310 | int status; | 391 | int status; |
311 | Closure *cl; | 392 | Closure *cl; |
312 | CallInfo *ci; | 393 | CallInfo *ci; |
313 | StkId func; | 394 | TValue *func; |
314 | lua_lock(L); | 395 | lua_lock(L); |
315 | swapextra(L); | ||
316 | if (*what == '>') { | 396 | if (*what == '>') { |
317 | ci = NULL; | 397 | ci = NULL; |
318 | func = L->top - 1; | 398 | func = s2v(L->top - 1); |
319 | api_check(L, ttisfunction(func), "function expected"); | 399 | api_check(L, ttisfunction(func), "function expected"); |
320 | what++; /* skip the '>' */ | 400 | what++; /* skip the '>' */ |
321 | L->top--; /* pop function */ | 401 | L->top--; /* pop function */ |
322 | } | 402 | } |
323 | else { | 403 | else { |
324 | ci = ar->i_ci; | 404 | ci = ar->i_ci; |
325 | func = ci->func; | 405 | func = s2v(ci->func); |
326 | lua_assert(ttisfunction(ci->func)); | 406 | lua_assert(ttisfunction(func)); |
327 | } | 407 | } |
328 | cl = ttisclosure(func) ? clvalue(func) : NULL; | 408 | cl = ttisclosure(func) ? clvalue(func) : NULL; |
329 | status = auxgetinfo(L, what, ar, cl, ci); | 409 | status = auxgetinfo(L, what, ar, cl, ci); |
330 | if (strchr(what, 'f')) { | 410 | if (strchr(what, 'f')) { |
331 | setobjs2s(L, L->top, func); | 411 | setobj2s(L, L->top, func); |
332 | api_incr_top(L); | 412 | api_incr_top(L); |
333 | } | 413 | } |
334 | swapextra(L); /* correct before option 'L', which can raise a mem. error */ | ||
335 | if (strchr(what, 'L')) | 414 | if (strchr(what, 'L')) |
336 | collectvalidlines(L, cl); | 415 | collectvalidlines(L, cl); |
337 | lua_unlock(L); | 416 | lua_unlock(L); |
@@ -345,30 +424,38 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
345 | ** ======================================================= | 424 | ** ======================================================= |
346 | */ | 425 | */ |
347 | 426 | ||
348 | static const char *getobjname (Proto *p, int lastpc, int reg, | 427 | static const char *getobjname (const Proto *p, int lastpc, int reg, |
349 | const char **name); | 428 | const char **name); |
350 | 429 | ||
351 | 430 | ||
352 | /* | 431 | /* |
353 | ** find a "name" for the RK value 'c' | 432 | ** Find a "name" for the constant 'c'. |
354 | */ | 433 | */ |
355 | static void kname (Proto *p, int pc, int c, const char **name) { | 434 | static void kname (const Proto *p, int c, const char **name) { |
356 | if (ISK(c)) { /* is 'c' a constant? */ | 435 | TValue *kvalue = &p->k[c]; |
357 | TValue *kvalue = &p->k[INDEXK(c)]; | 436 | *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?"; |
358 | if (ttisstring(kvalue)) { /* literal constant? */ | 437 | } |
359 | *name = svalue(kvalue); /* it is its own name */ | 438 | |
360 | return; | 439 | |
361 | } | 440 | /* |
362 | /* else no reasonable name found */ | 441 | ** Find a "name" for the register 'c'. |
363 | } | 442 | */ |
364 | else { /* 'c' is a register */ | 443 | static void rname (const Proto *p, int pc, int c, const char **name) { |
365 | const char *what = getobjname(p, pc, c, name); /* search for 'c' */ | 444 | const char *what = getobjname(p, pc, c, name); /* search for 'c' */ |
366 | if (what && *what == 'c') { /* found a constant name? */ | 445 | if (!(what && *what == 'c')) /* did not find a constant name? */ |
367 | return; /* 'name' already filled */ | 446 | *name = "?"; |
368 | } | 447 | } |
369 | /* else no reasonable name found */ | 448 | |
370 | } | 449 | |
371 | *name = "?"; /* no reasonable name found */ | 450 | /* |
451 | ** Find a "name" for a 'C' value in an RK instruction. | ||
452 | */ | ||
453 | static void rkname (const Proto *p, int pc, Instruction i, const char **name) { | ||
454 | int c = GETARG_C(i); /* key index */ | ||
455 | if (GETARG_k(i)) /* is 'c' a constant? */ | ||
456 | kname(p, c, name); | ||
457 | else /* 'c' is a register */ | ||
458 | rname(p, pc, c, name); | ||
372 | } | 459 | } |
373 | 460 | ||
374 | 461 | ||
@@ -380,55 +467,70 @@ static int filterpc (int pc, int jmptarget) { | |||
380 | 467 | ||
381 | 468 | ||
382 | /* | 469 | /* |
383 | ** try to find last instruction before 'lastpc' that modified register 'reg' | 470 | ** Try to find last instruction before 'lastpc' that modified register 'reg'. |
384 | */ | 471 | */ |
385 | static int findsetreg (Proto *p, int lastpc, int reg) { | 472 | static int findsetreg (const Proto *p, int lastpc, int reg) { |
386 | int pc; | 473 | int pc; |
387 | int setreg = -1; /* keep last instruction that changed 'reg' */ | 474 | int setreg = -1; /* keep last instruction that changed 'reg' */ |
388 | int jmptarget = 0; /* any code before this address is conditional */ | 475 | int jmptarget = 0; /* any code before this address is conditional */ |
476 | if (testMMMode(GET_OPCODE(p->code[lastpc]))) | ||
477 | lastpc--; /* previous instruction was not actually executed */ | ||
389 | for (pc = 0; pc < lastpc; pc++) { | 478 | for (pc = 0; pc < lastpc; pc++) { |
390 | Instruction i = p->code[pc]; | 479 | Instruction i = p->code[pc]; |
391 | OpCode op = GET_OPCODE(i); | 480 | OpCode op = GET_OPCODE(i); |
392 | int a = GETARG_A(i); | 481 | int a = GETARG_A(i); |
482 | int change; /* true if current instruction changed 'reg' */ | ||
393 | switch (op) { | 483 | switch (op) { |
394 | case OP_LOADNIL: { | 484 | case OP_LOADNIL: { /* set registers from 'a' to 'a+b' */ |
395 | int b = GETARG_B(i); | 485 | int b = GETARG_B(i); |
396 | if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ | 486 | change = (a <= reg && reg <= a + b); |
397 | setreg = filterpc(pc, jmptarget); | ||
398 | break; | 487 | break; |
399 | } | 488 | } |
400 | case OP_TFORCALL: { | 489 | case OP_TFORCALL: { /* affect all regs above its base */ |
401 | if (reg >= a + 2) /* affect all regs above its base */ | 490 | change = (reg >= a + 2); |
402 | setreg = filterpc(pc, jmptarget); | ||
403 | break; | 491 | break; |
404 | } | 492 | } |
405 | case OP_CALL: | 493 | case OP_CALL: |
406 | case OP_TAILCALL: { | 494 | case OP_TAILCALL: { /* affect all registers above base */ |
407 | if (reg >= a) /* affect all registers above base */ | 495 | change = (reg >= a); |
408 | setreg = filterpc(pc, jmptarget); | ||
409 | break; | 496 | break; |
410 | } | 497 | } |
411 | case OP_JMP: { | 498 | case OP_JMP: { /* doesn't change registers, but changes 'jmptarget' */ |
412 | int b = GETARG_sBx(i); | 499 | int b = GETARG_sJ(i); |
413 | int dest = pc + 1 + b; | 500 | int dest = pc + 1 + b; |
414 | /* jump is forward and do not skip 'lastpc'? */ | 501 | /* jump does not skip 'lastpc' and is larger than current one? */ |
415 | if (pc < dest && dest <= lastpc) { | 502 | if (dest <= lastpc && dest > jmptarget) |
416 | if (dest > jmptarget) | 503 | jmptarget = dest; /* update 'jmptarget' */ |
417 | jmptarget = dest; /* update 'jmptarget' */ | 504 | change = 0; |
418 | } | ||
419 | break; | 505 | break; |
420 | } | 506 | } |
421 | default: | 507 | default: /* any instruction that sets A */ |
422 | if (testAMode(op) && reg == a) /* any instruction that set A */ | 508 | change = (testAMode(op) && reg == a); |
423 | setreg = filterpc(pc, jmptarget); | ||
424 | break; | 509 | break; |
425 | } | 510 | } |
511 | if (change) | ||
512 | setreg = filterpc(pc, jmptarget); | ||
426 | } | 513 | } |
427 | return setreg; | 514 | return setreg; |
428 | } | 515 | } |
429 | 516 | ||
430 | 517 | ||
431 | static const char *getobjname (Proto *p, int lastpc, int reg, | 518 | /* |
519 | ** Check whether table being indexed by instruction 'i' is the | ||
520 | ** environment '_ENV' | ||
521 | */ | ||
522 | static const char *gxf (const Proto *p, int pc, Instruction i, int isup) { | ||
523 | int t = GETARG_B(i); /* table index */ | ||
524 | const char *name; /* name of indexed variable */ | ||
525 | if (isup) /* is an upvalue? */ | ||
526 | name = upvalname(p, t); | ||
527 | else | ||
528 | getobjname(p, pc, t, &name); | ||
529 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; | ||
530 | } | ||
531 | |||
532 | |||
533 | static const char *getobjname (const Proto *p, int lastpc, int reg, | ||
432 | const char **name) { | 534 | const char **name) { |
433 | int pc; | 535 | int pc; |
434 | *name = luaF_getlocalname(p, reg + 1, lastpc); | 536 | *name = luaF_getlocalname(p, reg + 1, lastpc); |
@@ -446,15 +548,24 @@ static const char *getobjname (Proto *p, int lastpc, int reg, | |||
446 | return getobjname(p, pc, b, name); /* get name for 'b' */ | 548 | return getobjname(p, pc, b, name); /* get name for 'b' */ |
447 | break; | 549 | break; |
448 | } | 550 | } |
449 | case OP_GETTABUP: | 551 | case OP_GETTABUP: { |
552 | int k = GETARG_C(i); /* key index */ | ||
553 | kname(p, k, name); | ||
554 | return gxf(p, pc, i, 1); | ||
555 | } | ||
450 | case OP_GETTABLE: { | 556 | case OP_GETTABLE: { |
451 | int k = GETARG_C(i); /* key index */ | 557 | int k = GETARG_C(i); /* key index */ |
452 | int t = GETARG_B(i); /* table index */ | 558 | rname(p, pc, k, name); |
453 | const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ | 559 | return gxf(p, pc, i, 0); |
454 | ? luaF_getlocalname(p, t + 1, pc) | 560 | } |
455 | : upvalname(p, t); | 561 | case OP_GETI: { |
456 | kname(p, pc, k, name); | 562 | *name = "integer index"; |
457 | return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; | 563 | return "field"; |
564 | } | ||
565 | case OP_GETFIELD: { | ||
566 | int k = GETARG_C(i); /* key index */ | ||
567 | kname(p, k, name); | ||
568 | return gxf(p, pc, i, 0); | ||
458 | } | 569 | } |
459 | case OP_GETUPVAL: { | 570 | case OP_GETUPVAL: { |
460 | *name = upvalname(p, GETARG_B(i)); | 571 | *name = upvalname(p, GETARG_B(i)); |
@@ -471,8 +582,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg, | |||
471 | break; | 582 | break; |
472 | } | 583 | } |
473 | case OP_SELF: { | 584 | case OP_SELF: { |
474 | int k = GETARG_C(i); /* key index */ | 585 | rkname(p, pc, i, name); |
475 | kname(p, pc, k, name); | ||
476 | return "method"; | 586 | return "method"; |
477 | } | 587 | } |
478 | default: break; /* go through to return NULL */ | 588 | default: break; /* go through to return NULL */ |
@@ -491,7 +601,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg, | |||
491 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | 601 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, |
492 | const char **name) { | 602 | const char **name) { |
493 | TMS tm = (TMS)0; /* (initial value avoids warnings) */ | 603 | TMS tm = (TMS)0; /* (initial value avoids warnings) */ |
494 | Proto *p = ci_func(ci)->p; /* calling function */ | 604 | const Proto *p = ci_func(ci)->p; /* calling function */ |
495 | int pc = currentpc(ci); /* calling instruction index */ | 605 | int pc = currentpc(ci); /* calling instruction index */ |
496 | Instruction i = p->code[pc]; /* calling instruction */ | 606 | Instruction i = p->code[pc]; /* calling instruction */ |
497 | if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ | 607 | if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ |
@@ -508,16 +618,14 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | |||
508 | } | 618 | } |
509 | /* other instructions can do calls through metamethods */ | 619 | /* other instructions can do calls through metamethods */ |
510 | case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: | 620 | case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: |
621 | case OP_GETI: case OP_GETFIELD: | ||
511 | tm = TM_INDEX; | 622 | tm = TM_INDEX; |
512 | break; | 623 | break; |
513 | case OP_SETTABUP: case OP_SETTABLE: | 624 | case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD: |
514 | tm = TM_NEWINDEX; | 625 | tm = TM_NEWINDEX; |
515 | break; | 626 | break; |
516 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: | 627 | case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { |
517 | case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: | 628 | tm = cast(TMS, GETARG_C(i)); |
518 | case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { | ||
519 | int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */ | ||
520 | tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */ | ||
521 | break; | 629 | break; |
522 | } | 630 | } |
523 | case OP_UNM: tm = TM_UNM; break; | 631 | case OP_UNM: tm = TM_UNM; break; |
@@ -525,12 +633,16 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | |||
525 | case OP_LEN: tm = TM_LEN; break; | 633 | case OP_LEN: tm = TM_LEN; break; |
526 | case OP_CONCAT: tm = TM_CONCAT; break; | 634 | case OP_CONCAT: tm = TM_CONCAT; break; |
527 | case OP_EQ: tm = TM_EQ; break; | 635 | case OP_EQ: tm = TM_EQ; break; |
528 | case OP_LT: tm = TM_LT; break; | 636 | case OP_LT: case OP_LE: case OP_LTI: case OP_LEI: |
529 | case OP_LE: tm = TM_LE; break; | 637 | *name = "order"; /* '<=' can call '__lt', etc. */ |
638 | return "metamethod"; | ||
639 | case OP_CLOSE: case OP_RETURN: | ||
640 | *name = "close"; | ||
641 | return "metamethod"; | ||
530 | default: | 642 | default: |
531 | return NULL; /* cannot find a reasonable name */ | 643 | return NULL; /* cannot find a reasonable name */ |
532 | } | 644 | } |
533 | *name = getstr(G(L)->tmname[tm]); | 645 | *name = getstr(G(L)->tmname[tm]) + 2; |
534 | return "metamethod"; | 646 | return "metamethod"; |
535 | } | 647 | } |
536 | 648 | ||
@@ -544,8 +656,9 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | |||
544 | ** checks are ISO C and ensure a correct result. | 656 | ** checks are ISO C and ensure a correct result. |
545 | */ | 657 | */ |
546 | static int isinstack (CallInfo *ci, const TValue *o) { | 658 | static int isinstack (CallInfo *ci, const TValue *o) { |
547 | ptrdiff_t i = o - ci->u.l.base; | 659 | StkId base = ci->func + 1; |
548 | return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o); | 660 | ptrdiff_t i = cast(StkId, o) - base; |
661 | return (0 <= i && i < (ci->top - base) && s2v(base + i) == o); | ||
549 | } | 662 | } |
550 | 663 | ||
551 | 664 | ||
@@ -576,7 +689,7 @@ static const char *varinfo (lua_State *L, const TValue *o) { | |||
576 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ | 689 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ |
577 | if (!kind && isinstack(ci, o)) /* no? try a register */ | 690 | if (!kind && isinstack(ci, o)) /* no? try a register */ |
578 | kind = getobjname(ci_func(ci)->p, currentpc(ci), | 691 | kind = getobjname(ci_func(ci)->p, currentpc(ci), |
579 | cast_int(o - ci->u.l.base), &name); | 692 | cast_int(cast(StkId, o) - (ci->func + 1)), &name); |
580 | } | 693 | } |
581 | return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; | 694 | return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; |
582 | } | 695 | } |
@@ -588,6 +701,12 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | |||
588 | } | 701 | } |
589 | 702 | ||
590 | 703 | ||
704 | l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) { | ||
705 | luaG_runerror(L, "bad 'for' %s (number expected, got %s)", | ||
706 | what, luaT_objtypename(L, o)); | ||
707 | } | ||
708 | |||
709 | |||
591 | l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { | 710 | l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { |
592 | if (ttisstring(p1) || cvt2str(p1)) p1 = p2; | 711 | if (ttisstring(p1) || cvt2str(p1)) p1 = p2; |
593 | luaG_typeerror(L, p1, "concatenate"); | 712 | luaG_typeerror(L, p1, "concatenate"); |
@@ -596,8 +715,7 @@ l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { | |||
596 | 715 | ||
597 | l_noret luaG_opinterror (lua_State *L, const TValue *p1, | 716 | l_noret luaG_opinterror (lua_State *L, const TValue *p1, |
598 | const TValue *p2, const char *msg) { | 717 | const TValue *p2, const char *msg) { |
599 | lua_Number temp; | 718 | if (!ttisnumber(p1)) /* first operand is wrong? */ |
600 | if (!tonumber(p1, &temp)) /* first operand is wrong? */ | ||
601 | p2 = p1; /* now second is wrong */ | 719 | p2 = p1; /* now second is wrong */ |
602 | luaG_typeerror(L, p2, msg); | 720 | luaG_typeerror(L, p2, msg); |
603 | } | 721 | } |
@@ -608,7 +726,7 @@ l_noret luaG_opinterror (lua_State *L, const TValue *p1, | |||
608 | */ | 726 | */ |
609 | l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { | 727 | l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { |
610 | lua_Integer temp; | 728 | lua_Integer temp; |
611 | if (!tointeger(p1, &temp)) | 729 | if (!tointegerns(p1, &temp)) |
612 | p2 = p1; | 730 | p2 = p1; |
613 | luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); | 731 | luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); |
614 | } | 732 | } |
@@ -629,7 +747,7 @@ const char *luaG_addinfo (lua_State *L, const char *msg, TString *src, | |||
629 | int line) { | 747 | int line) { |
630 | char buff[LUA_IDSIZE]; | 748 | char buff[LUA_IDSIZE]; |
631 | if (src) | 749 | if (src) |
632 | luaO_chunkid(buff, getstr(src), LUA_IDSIZE); | 750 | luaO_chunkid(buff, getstr(src), tsslen(src)); |
633 | else { /* no source available; use "?" instead */ | 751 | else { /* no source available; use "?" instead */ |
634 | buff[0] = '?'; buff[1] = '\0'; | 752 | buff[0] = '?'; buff[1] = '\0'; |
635 | } | 753 | } |
@@ -640,6 +758,7 @@ const char *luaG_addinfo (lua_State *L, const char *msg, TString *src, | |||
640 | l_noret luaG_errormsg (lua_State *L) { | 758 | l_noret luaG_errormsg (lua_State *L) { |
641 | if (L->errfunc != 0) { /* is there an error handling function? */ | 759 | if (L->errfunc != 0) { /* is there an error handling function? */ |
642 | StkId errfunc = restorestack(L, L->errfunc); | 760 | StkId errfunc = restorestack(L, L->errfunc); |
761 | lua_assert(ttisfunction(s2v(errfunc))); | ||
643 | setobjs2s(L, L->top, L->top - 1); /* move argument */ | 762 | setobjs2s(L, L->top, L->top - 1); /* move argument */ |
644 | setobjs2s(L, L->top - 1, errfunc); /* push function */ | 763 | setobjs2s(L, L->top - 1, errfunc); /* push function */ |
645 | L->top++; /* assume EXTRA_STACK */ | 764 | L->top++; /* assume EXTRA_STACK */ |
@@ -658,42 +777,65 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { | |||
658 | msg = luaO_pushvfstring(L, fmt, argp); /* format message */ | 777 | msg = luaO_pushvfstring(L, fmt, argp); /* format message */ |
659 | va_end(argp); | 778 | va_end(argp); |
660 | if (isLua(ci)) /* if Lua function, add source:line information */ | 779 | if (isLua(ci)) /* if Lua function, add source:line information */ |
661 | luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci)); | 780 | luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci)); |
662 | luaG_errormsg(L); | 781 | luaG_errormsg(L); |
663 | } | 782 | } |
664 | 783 | ||
665 | 784 | ||
666 | void luaG_traceexec (lua_State *L) { | 785 | /* |
786 | ** Check whether new instruction 'newpc' is in a different line from | ||
787 | ** previous instruction 'oldpc'. | ||
788 | */ | ||
789 | static int changedline (const Proto *p, int oldpc, int newpc) { | ||
790 | while (oldpc++ < newpc) { | ||
791 | if (p->lineinfo[oldpc] != 0) | ||
792 | return (luaG_getfuncline(p, oldpc - 1) != luaG_getfuncline(p, newpc)); | ||
793 | } | ||
794 | return 0; /* no line changes in the way */ | ||
795 | } | ||
796 | |||
797 | |||
798 | int luaG_traceexec (lua_State *L, const Instruction *pc) { | ||
667 | CallInfo *ci = L->ci; | 799 | CallInfo *ci = L->ci; |
668 | lu_byte mask = L->hookmask; | 800 | lu_byte mask = L->hookmask; |
669 | int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); | 801 | int counthook; |
802 | if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) { /* no hooks? */ | ||
803 | ci->u.l.trap = 0; /* don't need to stop again */ | ||
804 | return 0; /* turn off 'trap' */ | ||
805 | } | ||
806 | pc++; /* reference is always next instruction */ | ||
807 | ci->u.l.savedpc = pc; /* save 'pc' */ | ||
808 | counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); | ||
670 | if (counthook) | 809 | if (counthook) |
671 | resethookcount(L); /* reset count */ | 810 | resethookcount(L); /* reset count */ |
672 | else if (!(mask & LUA_MASKLINE)) | 811 | else if (!(mask & LUA_MASKLINE)) |
673 | return; /* no line hook and count != 0; nothing to be done */ | 812 | return 1; /* no line hook and count != 0; nothing to be done now */ |
674 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ | 813 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ |
675 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ | 814 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ |
676 | return; /* do not call hook again (VM yielded, so it did not move) */ | 815 | return 1; /* do not call hook again (VM yielded, so it did not move) */ |
677 | } | 816 | } |
817 | if (!isIT(*(ci->u.l.savedpc - 1))) | ||
818 | L->top = ci->top; /* prepare top */ | ||
678 | if (counthook) | 819 | if (counthook) |
679 | luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ | 820 | luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */ |
680 | if (mask & LUA_MASKLINE) { | 821 | if (mask & LUA_MASKLINE) { |
681 | Proto *p = ci_func(ci)->p; | 822 | const Proto *p = ci_func(ci)->p; |
682 | int npc = pcRel(ci->u.l.savedpc, p); | 823 | int npci = pcRel(pc, p); |
683 | int newline = getfuncline(p, npc); | 824 | if (npci == 0 || /* call linehook when enter a new function, */ |
684 | if (npc == 0 || /* call linehook when enter a new function, */ | 825 | pc <= L->oldpc || /* when jump back (loop), or when */ |
685 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ | 826 | changedline(p, pcRel(L->oldpc, p), npci)) { /* enter new line */ |
686 | newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ | 827 | int newline = luaG_getfuncline(p, npci); |
687 | luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ | 828 | luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */ |
688 | } | 829 | } |
689 | L->oldpc = ci->u.l.savedpc; | 830 | L->oldpc = pc; /* 'pc' of last call to line hook */ |
831 | } | ||
690 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 832 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
691 | if (counthook) | 833 | if (counthook) |
692 | L->hookcount = 1; /* undo decrement to zero */ | 834 | L->hookcount = 1; /* undo decrement to zero */ |
693 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ | 835 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ |
694 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ | 836 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ |
695 | ci->func = L->top - 1; /* protect stack below results */ | ||
696 | luaD_throw(L, LUA_YIELD); | 837 | luaD_throw(L, LUA_YIELD); |
697 | } | 838 | } |
839 | return 1; /* keep 'trap' on */ | ||
698 | } | 840 | } |
699 | 841 | ||
diff --git a/src/lua-5.3/ldebug.h b/src/lua/ldebug.h index 8cea0ee..1fe0efa 100644 --- a/src/lua-5.3/ldebug.h +++ b/src/lua/ldebug.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: ldebug.h $ |
3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -11,15 +11,23 @@ | |||
11 | #include "lstate.h" | 11 | #include "lstate.h" |
12 | 12 | ||
13 | 13 | ||
14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) |
15 | |||
16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) | ||
17 | 15 | ||
18 | #define resethookcount(L) (L->hookcount = L->basehookcount) | 16 | #define resethookcount(L) (L->hookcount = L->basehookcount) |
19 | 17 | ||
18 | /* | ||
19 | ** mark for entries in 'lineinfo' array that has absolute information in | ||
20 | ** 'abslineinfo' array | ||
21 | */ | ||
22 | #define ABSLINEINFO (-0x80) | ||
20 | 23 | ||
24 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); | ||
25 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, | ||
26 | StkId *pos); | ||
21 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, | 27 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, |
22 | const char *opname); | 28 | const char *opname); |
29 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, | ||
30 | const char *what); | ||
23 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, | 31 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, |
24 | const TValue *p2); | 32 | const TValue *p2); |
25 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, | 33 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, |
@@ -33,7 +41,7 @@ LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); | |||
33 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, | 41 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, |
34 | TString *src, int line); | 42 | TString *src, int line); |
35 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); | 43 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); |
36 | LUAI_FUNC void luaG_traceexec (lua_State *L); | 44 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); |
37 | 45 | ||
38 | 46 | ||
39 | #endif | 47 | #endif |
diff --git a/src/lua-5.3/ldo.c b/src/lua/ldo.c index 316e45c..c563b1d 100644 --- a/src/lua-5.3/ldo.c +++ b/src/lua/ldo.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: ldo.c $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -88,7 +88,7 @@ struct lua_longjmp { | |||
88 | }; | 88 | }; |
89 | 89 | ||
90 | 90 | ||
91 | static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { | 91 | void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { |
92 | switch (errcode) { | 92 | switch (errcode) { |
93 | case LUA_ERRMEM: { /* memory error? */ | 93 | case LUA_ERRMEM: { /* memory error? */ |
94 | setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ | 94 | setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ |
@@ -98,6 +98,10 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { | |||
98 | setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); | 98 | setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); |
99 | break; | 99 | break; |
100 | } | 100 | } |
101 | case CLOSEPROTECT: { | ||
102 | setnilvalue(s2v(oldtop)); /* no error message */ | ||
103 | break; | ||
104 | } | ||
101 | default: { | 105 | default: { |
102 | setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ | 106 | setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ |
103 | break; | 107 | break; |
@@ -114,6 +118,7 @@ l_noret luaD_throw (lua_State *L, int errcode) { | |||
114 | } | 118 | } |
115 | else { /* thread has no error handler */ | 119 | else { /* thread has no error handler */ |
116 | global_State *g = G(L); | 120 | global_State *g = G(L); |
121 | errcode = luaF_close(L, L->stack, errcode); /* close all upvalues */ | ||
117 | L->status = cast_byte(errcode); /* mark it as dead */ | 122 | L->status = cast_byte(errcode); /* mark it as dead */ |
118 | if (g->mainthread->errorJmp) { /* main thread has a handler? */ | 123 | if (g->mainthread->errorJmp) { /* main thread has a handler? */ |
119 | setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ | 124 | setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ |
@@ -121,7 +126,7 @@ l_noret luaD_throw (lua_State *L, int errcode) { | |||
121 | } | 126 | } |
122 | else { /* no handler at all; abort */ | 127 | else { /* no handler at all; abort */ |
123 | if (g->panic) { /* panic function? */ | 128 | if (g->panic) { /* panic function? */ |
124 | seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ | 129 | luaD_seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ |
125 | if (L->ci->top < L->top) | 130 | if (L->ci->top < L->top) |
126 | L->ci->top = L->top; /* pushing msg. can break this invariant */ | 131 | L->ci->top = L->top; /* pushing msg. can break this invariant */ |
127 | lua_unlock(L); | 132 | lua_unlock(L); |
@@ -134,7 +139,8 @@ l_noret luaD_throw (lua_State *L, int errcode) { | |||
134 | 139 | ||
135 | 140 | ||
136 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | 141 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { |
137 | unsigned short oldnCcalls = L->nCcalls; | 142 | global_State *g = G(L); |
143 | l_uint32 oldnCcalls = g->Cstacklimit - (L->nCcalls + L->nci); | ||
138 | struct lua_longjmp lj; | 144 | struct lua_longjmp lj; |
139 | lj.status = LUA_OK; | 145 | lj.status = LUA_OK; |
140 | lj.previous = L->errorJmp; /* chain new error handler */ | 146 | lj.previous = L->errorJmp; /* chain new error handler */ |
@@ -143,7 +149,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
143 | (*f)(L, ud); | 149 | (*f)(L, ud); |
144 | ); | 150 | ); |
145 | L->errorJmp = lj.previous; /* restore old error handler */ | 151 | L->errorJmp = lj.previous; /* restore old error handler */ |
146 | L->nCcalls = oldnCcalls; | 152 | L->nCcalls = g->Cstacklimit - oldnCcalls - L->nci; |
147 | return lj.status; | 153 | return lj.status; |
148 | } | 154 | } |
149 | 155 | ||
@@ -155,17 +161,19 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
155 | ** Stack reallocation | 161 | ** Stack reallocation |
156 | ** =================================================================== | 162 | ** =================================================================== |
157 | */ | 163 | */ |
158 | static void correctstack (lua_State *L, TValue *oldstack) { | 164 | static void correctstack (lua_State *L, StkId oldstack, StkId newstack) { |
159 | CallInfo *ci; | 165 | CallInfo *ci; |
160 | UpVal *up; | 166 | UpVal *up; |
161 | L->top = (L->top - oldstack) + L->stack; | 167 | if (oldstack == newstack) |
168 | return; /* stack address did not change */ | ||
169 | L->top = (L->top - oldstack) + newstack; | ||
162 | for (up = L->openupval; up != NULL; up = up->u.open.next) | 170 | for (up = L->openupval; up != NULL; up = up->u.open.next) |
163 | up->v = (up->v - oldstack) + L->stack; | 171 | up->v = s2v((uplevel(up) - oldstack) + newstack); |
164 | for (ci = L->ci; ci != NULL; ci = ci->previous) { | 172 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
165 | ci->top = (ci->top - oldstack) + L->stack; | 173 | ci->top = (ci->top - oldstack) + newstack; |
166 | ci->func = (ci->func - oldstack) + L->stack; | 174 | ci->func = (ci->func - oldstack) + newstack; |
167 | if (isLua(ci)) | 175 | if (isLua(ci)) |
168 | ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; | 176 | ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */ |
169 | } | 177 | } |
170 | } | 178 | } |
171 | 179 | ||
@@ -174,36 +182,53 @@ static void correctstack (lua_State *L, TValue *oldstack) { | |||
174 | #define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) | 182 | #define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) |
175 | 183 | ||
176 | 184 | ||
177 | void luaD_reallocstack (lua_State *L, int newsize) { | 185 | int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { |
178 | TValue *oldstack = L->stack; | ||
179 | int lim = L->stacksize; | 186 | int lim = L->stacksize; |
187 | StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue); | ||
180 | lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); | 188 | lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); |
181 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); | 189 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); |
182 | luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); | 190 | if (unlikely(newstack == NULL)) { /* reallocation failed? */ |
191 | if (raiseerror) | ||
192 | luaM_error(L); | ||
193 | else return 0; /* do not raise an error */ | ||
194 | } | ||
183 | for (; lim < newsize; lim++) | 195 | for (; lim < newsize; lim++) |
184 | setnilvalue(L->stack + lim); /* erase new segment */ | 196 | setnilvalue(s2v(newstack + lim)); /* erase new segment */ |
197 | correctstack(L, L->stack, newstack); | ||
198 | L->stack = newstack; | ||
185 | L->stacksize = newsize; | 199 | L->stacksize = newsize; |
186 | L->stack_last = L->stack + newsize - EXTRA_STACK; | 200 | L->stack_last = L->stack + newsize - EXTRA_STACK; |
187 | correctstack(L, oldstack); | 201 | return 1; |
188 | } | 202 | } |
189 | 203 | ||
190 | 204 | ||
191 | void luaD_growstack (lua_State *L, int n) { | 205 | /* |
206 | ** Try to grow the stack by at least 'n' elements. when 'raiseerror' | ||
207 | ** is true, raises any error; otherwise, return 0 in case of errors. | ||
208 | */ | ||
209 | int luaD_growstack (lua_State *L, int n, int raiseerror) { | ||
192 | int size = L->stacksize; | 210 | int size = L->stacksize; |
193 | if (size > LUAI_MAXSTACK) /* error after extra size? */ | 211 | int newsize = 2 * size; /* tentative new size */ |
194 | luaD_throw(L, LUA_ERRERR); | 212 | if (unlikely(size > LUAI_MAXSTACK)) { /* need more space after extra size? */ |
213 | if (raiseerror) | ||
214 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ | ||
215 | else return 0; | ||
216 | } | ||
195 | else { | 217 | else { |
196 | int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; | 218 | int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; |
197 | int newsize = 2 * size; | 219 | if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ |
198 | if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; | 220 | newsize = LUAI_MAXSTACK; |
199 | if (newsize < needed) newsize = needed; | 221 | if (newsize < needed) /* but must respect what was asked for */ |
200 | if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ | 222 | newsize = needed; |
201 | luaD_reallocstack(L, ERRORSTACKSIZE); | 223 | if (unlikely(newsize > LUAI_MAXSTACK)) { /* stack overflow? */ |
202 | luaG_runerror(L, "stack overflow"); | 224 | /* add extra size to be able to handle the error message */ |
225 | luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror); | ||
226 | if (raiseerror) | ||
227 | luaG_runerror(L, "stack overflow"); | ||
228 | else return 0; | ||
203 | } | 229 | } |
204 | else | 230 | } /* else no errors */ |
205 | luaD_reallocstack(L, newsize); | 231 | return luaD_reallocstack(L, newsize, raiseerror); |
206 | } | ||
207 | } | 232 | } |
208 | 233 | ||
209 | 234 | ||
@@ -223,17 +248,14 @@ void luaD_shrinkstack (lua_State *L) { | |||
223 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; | 248 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; |
224 | if (goodsize > LUAI_MAXSTACK) | 249 | if (goodsize > LUAI_MAXSTACK) |
225 | goodsize = LUAI_MAXSTACK; /* respect stack limit */ | 250 | goodsize = LUAI_MAXSTACK; /* respect stack limit */ |
226 | if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */ | ||
227 | luaE_freeCI(L); /* free all CIs (list grew because of an error) */ | ||
228 | else | ||
229 | luaE_shrinkCI(L); /* shrink list */ | ||
230 | /* if thread is currently not handling a stack overflow and its | 251 | /* if thread is currently not handling a stack overflow and its |
231 | good size is smaller than current size, shrink its stack */ | 252 | good size is smaller than current size, shrink its stack */ |
232 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && | 253 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && |
233 | goodsize < L->stacksize) | 254 | goodsize < L->stacksize) |
234 | luaD_reallocstack(L, goodsize); | 255 | luaD_reallocstack(L, goodsize, 0); /* ok if that fails */ |
235 | else /* don't change stack */ | 256 | else /* don't change stack */ |
236 | condmovestack(L,{},{}); /* (change only for debugging) */ | 257 | condmovestack(L,{},{}); /* (change only for debugging) */ |
258 | luaE_shrinkCI(L); /* shrink CI list */ | ||
237 | } | 259 | } |
238 | 260 | ||
239 | 261 | ||
@@ -247,12 +269,14 @@ void luaD_inctop (lua_State *L) { | |||
247 | 269 | ||
248 | /* | 270 | /* |
249 | ** Call a hook for the given event. Make sure there is a hook to be | 271 | ** Call a hook for the given event. Make sure there is a hook to be |
250 | ** called. (Both 'L->hook' and 'L->hookmask', which triggers this | 272 | ** called. (Both 'L->hook' and 'L->hookmask', which trigger this |
251 | ** function, can be changed asynchronously by signals.) | 273 | ** function, can be changed asynchronously by signals.) |
252 | */ | 274 | */ |
253 | void luaD_hook (lua_State *L, int event, int line) { | 275 | void luaD_hook (lua_State *L, int event, int line, |
276 | int ftransfer, int ntransfer) { | ||
254 | lua_Hook hook = L->hook; | 277 | lua_Hook hook = L->hook; |
255 | if (hook && L->allowhook) { /* make sure there is a hook */ | 278 | if (hook && L->allowhook) { /* make sure there is a hook */ |
279 | int mask = CIST_HOOKED; | ||
256 | CallInfo *ci = L->ci; | 280 | CallInfo *ci = L->ci; |
257 | ptrdiff_t top = savestack(L, L->top); | 281 | ptrdiff_t top = savestack(L, L->top); |
258 | ptrdiff_t ci_top = savestack(L, ci->top); | 282 | ptrdiff_t ci_top = savestack(L, ci->top); |
@@ -260,11 +284,16 @@ void luaD_hook (lua_State *L, int event, int line) { | |||
260 | ar.event = event; | 284 | ar.event = event; |
261 | ar.currentline = line; | 285 | ar.currentline = line; |
262 | ar.i_ci = ci; | 286 | ar.i_ci = ci; |
287 | if (ntransfer != 0) { | ||
288 | mask |= CIST_TRAN; /* 'ci' has transfer information */ | ||
289 | ci->u2.transferinfo.ftransfer = ftransfer; | ||
290 | ci->u2.transferinfo.ntransfer = ntransfer; | ||
291 | } | ||
263 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 292 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
264 | ci->top = L->top + LUA_MINSTACK; | 293 | if (L->top + LUA_MINSTACK > ci->top) |
265 | lua_assert(ci->top <= L->stack_last); | 294 | ci->top = L->top + LUA_MINSTACK; |
266 | L->allowhook = 0; /* cannot call hooks inside a hook */ | 295 | L->allowhook = 0; /* cannot call hooks inside a hook */ |
267 | ci->callstatus |= CIST_HOOKED; | 296 | ci->callstatus |= mask; |
268 | lua_unlock(L); | 297 | lua_unlock(L); |
269 | (*hook)(L, &ar); | 298 | (*hook)(L, &ar); |
270 | lua_lock(L); | 299 | lua_lock(L); |
@@ -272,56 +301,66 @@ void luaD_hook (lua_State *L, int event, int line) { | |||
272 | L->allowhook = 1; | 301 | L->allowhook = 1; |
273 | ci->top = restorestack(L, ci_top); | 302 | ci->top = restorestack(L, ci_top); |
274 | L->top = restorestack(L, top); | 303 | L->top = restorestack(L, top); |
275 | ci->callstatus &= ~CIST_HOOKED; | 304 | ci->callstatus &= ~mask; |
276 | } | 305 | } |
277 | } | 306 | } |
278 | 307 | ||
279 | 308 | ||
280 | static void callhook (lua_State *L, CallInfo *ci) { | 309 | /* |
281 | int hook = LUA_HOOKCALL; | 310 | ** Executes a call hook for Lua functions. This function is called |
311 | ** whenever 'hookmask' is not zero, so it checks whether call hooks are | ||
312 | ** active. | ||
313 | */ | ||
314 | void luaD_hookcall (lua_State *L, CallInfo *ci) { | ||
315 | int hook = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL : LUA_HOOKCALL; | ||
316 | Proto *p; | ||
317 | if (!(L->hookmask & LUA_MASKCALL)) /* some other hook? */ | ||
318 | return; /* don't call hook */ | ||
319 | p = clLvalue(s2v(ci->func))->p; | ||
320 | L->top = ci->top; /* prepare top */ | ||
282 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ | 321 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ |
283 | if (isLua(ci->previous) && | 322 | luaD_hook(L, hook, -1, 1, p->numparams); |
284 | GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { | ||
285 | ci->callstatus |= CIST_TAIL; | ||
286 | hook = LUA_HOOKTAILCALL; | ||
287 | } | ||
288 | luaD_hook(L, hook, -1); | ||
289 | ci->u.l.savedpc--; /* correct 'pc' */ | 323 | ci->u.l.savedpc--; /* correct 'pc' */ |
290 | } | 324 | } |
291 | 325 | ||
292 | 326 | ||
293 | static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | 327 | static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { |
294 | int i; | 328 | ptrdiff_t oldtop = savestack(L, L->top); /* hook may change top */ |
295 | int nfixargs = p->numparams; | 329 | int delta = 0; |
296 | StkId base, fixed; | 330 | if (isLuacode(ci)) { |
297 | /* move fixed parameters to final position */ | 331 | Proto *p = clLvalue(s2v(ci->func))->p; |
298 | fixed = L->top - actual; /* first fixed argument */ | 332 | if (p->is_vararg) |
299 | base = L->top; /* final position of first argument */ | 333 | delta = ci->u.l.nextraargs + p->numparams + 1; |
300 | for (i = 0; i < nfixargs && i < actual; i++) { | 334 | if (L->top < ci->top) |
301 | setobjs2s(L, L->top++, fixed + i); | 335 | L->top = ci->top; /* correct top to run hook */ |
302 | setnilvalue(fixed + i); /* erase original copy (for GC) */ | ||
303 | } | 336 | } |
304 | for (; i < nfixargs; i++) | 337 | if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ |
305 | setnilvalue(L->top++); /* complete missing arguments */ | 338 | int ftransfer; |
306 | return base; | 339 | ci->func += delta; /* if vararg, back to virtual 'func' */ |
340 | ftransfer = cast(unsigned short, firstres - ci->func); | ||
341 | luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ | ||
342 | ci->func -= delta; | ||
343 | } | ||
344 | if (isLua(ci->previous)) | ||
345 | L->oldpc = ci->previous->u.l.savedpc; /* update 'oldpc' */ | ||
346 | return restorestack(L, oldtop); | ||
307 | } | 347 | } |
308 | 348 | ||
309 | 349 | ||
310 | /* | 350 | /* |
311 | ** Check whether __call metafield of 'func' is a function. If so, put | 351 | ** Check whether 'func' has a '__call' metafield. If so, put it in the |
312 | ** it in stack below original 'func' so that 'luaD_precall' can call | 352 | ** stack, below original 'func', so that 'luaD_call' can call it. Raise |
313 | ** it. Raise an error if __call metafield is not a function. | 353 | ** an error if there is no '__call' metafield. |
314 | */ | 354 | */ |
315 | static void tryfuncTM (lua_State *L, StkId func) { | 355 | void luaD_tryfuncTM (lua_State *L, StkId func) { |
316 | const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); | 356 | const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); |
317 | StkId p; | 357 | StkId p; |
318 | if (!ttisfunction(tm)) | 358 | if (unlikely(ttisnil(tm))) |
319 | luaG_typeerror(L, func, "call"); | 359 | luaG_typeerror(L, s2v(func), "call"); /* nothing to call */ |
320 | /* Open a hole inside the stack at 'func' */ | 360 | for (p = L->top; p > func; p--) /* open space for metamethod */ |
321 | for (p = L->top; p > func; p--) | ||
322 | setobjs2s(L, p, p-1); | 361 | setobjs2s(L, p, p-1); |
323 | L->top++; /* slot ensured by caller */ | 362 | L->top++; /* stack space pre-allocated by the caller */ |
324 | setobj2s(L, func, tm); /* tag method is the new function to be called */ | 363 | setobj2s(L, func, tm); /* metamethod is the new function to be called */ |
325 | } | 364 | } |
326 | 365 | ||
327 | 366 | ||
@@ -331,183 +370,161 @@ static void tryfuncTM (lua_State *L, StkId func) { | |||
331 | ** expressions, multiple results for tail calls/single parameters) | 370 | ** expressions, multiple results for tail calls/single parameters) |
332 | ** separated. | 371 | ** separated. |
333 | */ | 372 | */ |
334 | static int moveresults (lua_State *L, const TValue *firstResult, StkId res, | 373 | static void moveresults (lua_State *L, StkId res, int nres, int wanted) { |
335 | int nres, int wanted) { | 374 | StkId firstresult; |
375 | int i; | ||
336 | switch (wanted) { /* handle typical cases separately */ | 376 | switch (wanted) { /* handle typical cases separately */ |
337 | case 0: break; /* nothing to move */ | 377 | case 0: /* no values needed */ |
338 | case 1: { /* one result needed */ | 378 | L->top = res; |
379 | return; | ||
380 | case 1: /* one value needed */ | ||
339 | if (nres == 0) /* no results? */ | 381 | if (nres == 0) /* no results? */ |
340 | firstResult = luaO_nilobject; /* adjust with nil */ | 382 | setnilvalue(s2v(res)); /* adjust with nil */ |
341 | setobjs2s(L, res, firstResult); /* move it to proper place */ | 383 | else |
384 | setobjs2s(L, res, L->top - nres); /* move it to proper place */ | ||
385 | L->top = res + 1; | ||
386 | return; | ||
387 | case LUA_MULTRET: | ||
388 | wanted = nres; /* we want all results */ | ||
342 | break; | 389 | break; |
343 | } | 390 | default: /* multiple results (or to-be-closed variables) */ |
344 | case LUA_MULTRET: { | 391 | if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ |
345 | int i; | 392 | ptrdiff_t savedres = savestack(L, res); |
346 | for (i = 0; i < nres; i++) /* move all results to correct place */ | 393 | luaF_close(L, res, LUA_OK); /* may change the stack */ |
347 | setobjs2s(L, res + i, firstResult + i); | 394 | res = restorestack(L, savedres); |
348 | L->top = res + nres; | 395 | wanted = codeNresults(wanted); /* correct value */ |
349 | return 0; /* wanted == LUA_MULTRET */ | 396 | if (wanted == LUA_MULTRET) |
350 | } | 397 | wanted = nres; |
351 | default: { | ||
352 | int i; | ||
353 | if (wanted <= nres) { /* enough results? */ | ||
354 | for (i = 0; i < wanted; i++) /* move wanted results to correct place */ | ||
355 | setobjs2s(L, res + i, firstResult + i); | ||
356 | } | ||
357 | else { /* not enough results; use all of them plus nils */ | ||
358 | for (i = 0; i < nres; i++) /* move all results to correct place */ | ||
359 | setobjs2s(L, res + i, firstResult + i); | ||
360 | for (; i < wanted; i++) /* complete wanted number of results */ | ||
361 | setnilvalue(res + i); | ||
362 | } | 398 | } |
363 | break; | 399 | break; |
364 | } | ||
365 | } | 400 | } |
401 | firstresult = L->top - nres; /* index of first result */ | ||
402 | /* move all results to correct place */ | ||
403 | for (i = 0; i < nres && i < wanted; i++) | ||
404 | setobjs2s(L, res + i, firstresult + i); | ||
405 | for (; i < wanted; i++) /* complete wanted number of results */ | ||
406 | setnilvalue(s2v(res + i)); | ||
366 | L->top = res + wanted; /* top points after the last result */ | 407 | L->top = res + wanted; /* top points after the last result */ |
367 | return 1; | ||
368 | } | 408 | } |
369 | 409 | ||
370 | 410 | ||
371 | /* | 411 | /* |
372 | ** Finishes a function call: calls hook if necessary, removes CallInfo, | 412 | ** Finishes a function call: calls hook if necessary, removes CallInfo, |
373 | ** moves current number of results to proper place; returns 0 iff call | 413 | ** moves current number of results to proper place. |
374 | ** wanted multiple (variable number of) results. | ||
375 | */ | 414 | */ |
376 | int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { | 415 | void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { |
377 | StkId res; | 416 | if (L->hookmask) |
378 | int wanted = ci->nresults; | 417 | L->top = rethook(L, ci, L->top - nres, nres); |
379 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { | ||
380 | if (L->hookmask & LUA_MASKRET) { | ||
381 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | ||
382 | luaD_hook(L, LUA_HOOKRET, -1); | ||
383 | firstResult = restorestack(L, fr); | ||
384 | } | ||
385 | L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ | ||
386 | } | ||
387 | res = ci->func; /* res == final position of 1st result */ | ||
388 | L->ci = ci->previous; /* back to caller */ | 418 | L->ci = ci->previous; /* back to caller */ |
389 | /* move results to proper place */ | 419 | /* move results to proper place */ |
390 | return moveresults(L, firstResult, res, nres, wanted); | 420 | moveresults(L, ci->func, nres, ci->nresults); |
391 | } | 421 | } |
392 | 422 | ||
393 | 423 | ||
394 | 424 | ||
395 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) | 425 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) |
396 | 426 | ||
397 | 427 | ||
398 | /* macro to check stack size, preserving 'p' */ | 428 | /* |
399 | #define checkstackp(L,n,p) \ | 429 | ** Prepare a function for a tail call, building its call info on top |
400 | luaD_checkstackaux(L, n, \ | 430 | ** of the current call info. 'narg1' is the number of arguments plus 1 |
401 | ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ | 431 | ** (so that it includes the function itself). |
402 | luaC_checkGC(L), /* stack grow uses memory */ \ | 432 | */ |
403 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ | 433 | void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { |
434 | Proto *p = clLvalue(s2v(func))->p; | ||
435 | int fsize = p->maxstacksize; /* frame size */ | ||
436 | int nfixparams = p->numparams; | ||
437 | int i; | ||
438 | for (i = 0; i < narg1; i++) /* move down function and arguments */ | ||
439 | setobjs2s(L, ci->func + i, func + i); | ||
440 | checkstackGC(L, fsize); | ||
441 | func = ci->func; /* moved-down function */ | ||
442 | for (; narg1 <= nfixparams; narg1++) | ||
443 | setnilvalue(s2v(func + narg1)); /* complete missing arguments */ | ||
444 | ci->top = func + 1 + fsize; /* top for new function */ | ||
445 | lua_assert(ci->top <= L->stack_last); | ||
446 | ci->u.l.savedpc = p->code; /* starting point */ | ||
447 | ci->callstatus |= CIST_TAIL; | ||
448 | L->top = func + narg1; /* set top */ | ||
449 | } | ||
404 | 450 | ||
405 | 451 | ||
406 | /* | 452 | /* |
407 | ** Prepares a function call: checks the stack, creates a new CallInfo | 453 | ** Call a function (C or Lua). The function to be called is at *func. |
408 | ** entry, fills in the relevant information, calls hook if needed. | 454 | ** The arguments are on the stack, right after the function. |
409 | ** If function is a C function, does the call, too. (Otherwise, leave | 455 | ** When returns, all the results are on the stack, starting at the original |
410 | ** the execution ('luaV_execute') to the caller, to allow stackless | 456 | ** function position. |
411 | ** calls.) Returns true iff function has been executed (C function). | ||
412 | */ | 457 | */ |
413 | int luaD_precall (lua_State *L, StkId func, int nresults) { | 458 | void luaD_call (lua_State *L, StkId func, int nresults) { |
414 | lua_CFunction f; | 459 | lua_CFunction f; |
415 | CallInfo *ci; | 460 | retry: |
416 | switch (ttype(func)) { | 461 | switch (ttypetag(s2v(func))) { |
417 | case LUA_TCCL: /* C closure */ | 462 | case LUA_VCCL: /* C closure */ |
418 | f = clCvalue(func)->f; | 463 | f = clCvalue(s2v(func))->f; |
419 | goto Cfunc; | 464 | goto Cfunc; |
420 | case LUA_TLCF: /* light C function */ | 465 | case LUA_VLCF: /* light C function */ |
421 | f = fvalue(func); | 466 | f = fvalue(s2v(func)); |
422 | Cfunc: { | 467 | Cfunc: { |
423 | int n; /* number of returns */ | 468 | int n; /* number of returns */ |
469 | CallInfo *ci = next_ci(L); | ||
424 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | 470 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
425 | ci = next_ci(L); /* now 'enter' new function */ | ||
426 | ci->nresults = nresults; | 471 | ci->nresults = nresults; |
427 | ci->func = func; | 472 | ci->callstatus = CIST_C; |
428 | ci->top = L->top + LUA_MINSTACK; | 473 | ci->top = L->top + LUA_MINSTACK; |
474 | ci->func = func; | ||
475 | L->ci = ci; | ||
429 | lua_assert(ci->top <= L->stack_last); | 476 | lua_assert(ci->top <= L->stack_last); |
430 | ci->callstatus = 0; | 477 | if (L->hookmask & LUA_MASKCALL) { |
431 | if (L->hookmask & LUA_MASKCALL) | 478 | int narg = cast_int(L->top - func) - 1; |
432 | luaD_hook(L, LUA_HOOKCALL, -1); | 479 | luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); |
480 | } | ||
433 | lua_unlock(L); | 481 | lua_unlock(L); |
434 | n = (*f)(L); /* do the actual call */ | 482 | n = (*f)(L); /* do the actual call */ |
435 | lua_lock(L); | 483 | lua_lock(L); |
436 | api_checknelems(L, n); | 484 | api_checknelems(L, n); |
437 | luaD_poscall(L, ci, L->top - n, n); | 485 | luaD_poscall(L, ci, n); |
438 | return 1; | 486 | break; |
439 | } | 487 | } |
440 | case LUA_TLCL: { /* Lua function: prepare its call */ | 488 | case LUA_VLCL: { /* Lua function */ |
441 | StkId base; | 489 | CallInfo *ci = next_ci(L); |
442 | Proto *p = clLvalue(func)->p; | 490 | Proto *p = clLvalue(s2v(func))->p; |
443 | int n = cast_int(L->top - func) - 1; /* number of real arguments */ | 491 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ |
492 | int nfixparams = p->numparams; | ||
444 | int fsize = p->maxstacksize; /* frame size */ | 493 | int fsize = p->maxstacksize; /* frame size */ |
445 | checkstackp(L, fsize, func); | 494 | checkstackp(L, fsize, func); |
446 | if (p->is_vararg) | ||
447 | base = adjust_varargs(L, p, n); | ||
448 | else { /* non vararg function */ | ||
449 | for (; n < p->numparams; n++) | ||
450 | setnilvalue(L->top++); /* complete missing arguments */ | ||
451 | base = func + 1; | ||
452 | } | ||
453 | ci = next_ci(L); /* now 'enter' new function */ | ||
454 | ci->nresults = nresults; | 495 | ci->nresults = nresults; |
496 | ci->u.l.savedpc = p->code; /* starting point */ | ||
497 | ci->callstatus = 0; | ||
498 | ci->top = func + 1 + fsize; | ||
455 | ci->func = func; | 499 | ci->func = func; |
456 | ci->u.l.base = base; | 500 | L->ci = ci; |
457 | L->top = ci->top = base + fsize; | 501 | for (; narg < nfixparams; narg++) |
502 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | ||
458 | lua_assert(ci->top <= L->stack_last); | 503 | lua_assert(ci->top <= L->stack_last); |
459 | ci->u.l.savedpc = p->code; /* starting point */ | 504 | luaV_execute(L, ci); /* run the function */ |
460 | ci->callstatus = CIST_LUA; | 505 | break; |
461 | if (L->hookmask & LUA_MASKCALL) | ||
462 | callhook(L, ci); | ||
463 | return 0; | ||
464 | } | 506 | } |
465 | default: { /* not a function */ | 507 | default: { /* not a function */ |
466 | checkstackp(L, 1, func); /* ensure space for metamethod */ | 508 | checkstackp(L, 1, func); /* space for metamethod */ |
467 | tryfuncTM(L, func); /* try to get '__call' metamethod */ | 509 | luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ |
468 | return luaD_precall(L, func, nresults); /* now it must be a function */ | 510 | goto retry; /* try again with metamethod */ |
469 | } | 511 | } |
470 | } | 512 | } |
471 | } | 513 | } |
472 | 514 | ||
473 | 515 | ||
474 | /* | 516 | /* |
475 | ** Check appropriate error for stack overflow ("regular" overflow or | 517 | ** Similar to 'luaD_call', but does not allow yields during the call. |
476 | ** overflow while handling stack overflow). If 'nCalls' is larger than | 518 | ** If there is a stack overflow, freeing all CI structures will |
477 | ** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but | 519 | ** force the subsequent call to invoke 'luaE_extendCI', which then |
478 | ** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to | 520 | ** will raise any errors. |
479 | ** allow overflow handling to work) | ||
480 | */ | ||
481 | static void stackerror (lua_State *L) { | ||
482 | if (L->nCcalls == LUAI_MAXCCALLS) | ||
483 | luaG_runerror(L, "C stack overflow"); | ||
484 | else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) | ||
485 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | ||
486 | } | ||
487 | |||
488 | |||
489 | /* | ||
490 | ** Call a function (C or Lua). The function to be called is at *func. | ||
491 | ** The arguments are on the stack, right after the function. | ||
492 | ** When returns, all the results are on the stack, starting at the original | ||
493 | ** function position. | ||
494 | */ | ||
495 | void luaD_call (lua_State *L, StkId func, int nResults) { | ||
496 | if (++L->nCcalls >= LUAI_MAXCCALLS) | ||
497 | stackerror(L); | ||
498 | if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ | ||
499 | luaV_execute(L); /* call it */ | ||
500 | L->nCcalls--; | ||
501 | } | ||
502 | |||
503 | |||
504 | /* | ||
505 | ** Similar to 'luaD_call', but does not allow yields during the call | ||
506 | */ | 521 | */ |
507 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { | 522 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { |
508 | L->nny++; | 523 | incXCcalls(L); |
524 | if (getCcalls(L) <= CSTACKERR) /* possible stack overflow? */ | ||
525 | luaE_freeCI(L); | ||
509 | luaD_call(L, func, nResults); | 526 | luaD_call(L, func, nResults); |
510 | L->nny--; | 527 | decXCcalls(L); |
511 | } | 528 | } |
512 | 529 | ||
513 | 530 | ||
@@ -519,7 +536,7 @@ static void finishCcall (lua_State *L, int status) { | |||
519 | CallInfo *ci = L->ci; | 536 | CallInfo *ci = L->ci; |
520 | int n; | 537 | int n; |
521 | /* must have a continuation and must be able to call it */ | 538 | /* must have a continuation and must be able to call it */ |
522 | lua_assert(ci->u.c.k != NULL && L->nny == 0); | 539 | lua_assert(ci->u.c.k != NULL && yieldable(L)); |
523 | /* error status can only happen in a protected call */ | 540 | /* error status can only happen in a protected call */ |
524 | lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); | 541 | lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); |
525 | if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ | 542 | if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ |
@@ -533,7 +550,7 @@ static void finishCcall (lua_State *L, int status) { | |||
533 | n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ | 550 | n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ |
534 | lua_lock(L); | 551 | lua_lock(L); |
535 | api_checknelems(L, n); | 552 | api_checknelems(L, n); |
536 | luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ | 553 | luaD_poscall(L, ci, n); /* finish 'luaD_call' */ |
537 | } | 554 | } |
538 | 555 | ||
539 | 556 | ||
@@ -546,14 +563,15 @@ static void finishCcall (lua_State *L, int status) { | |||
546 | ** status is LUA_YIELD). | 563 | ** status is LUA_YIELD). |
547 | */ | 564 | */ |
548 | static void unroll (lua_State *L, void *ud) { | 565 | static void unroll (lua_State *L, void *ud) { |
566 | CallInfo *ci; | ||
549 | if (ud != NULL) /* error status? */ | 567 | if (ud != NULL) /* error status? */ |
550 | finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ | 568 | finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ |
551 | while (L->ci != &L->base_ci) { /* something in the stack */ | 569 | while ((ci = L->ci) != &L->base_ci) { /* something in the stack */ |
552 | if (!isLua(L->ci)) /* C function? */ | 570 | if (!isLua(ci)) /* C function? */ |
553 | finishCcall(L, LUA_YIELD); /* complete its execution */ | 571 | finishCcall(L, LUA_YIELD); /* complete its execution */ |
554 | else { /* Lua function */ | 572 | else { /* Lua function */ |
555 | luaV_finishOp(L); /* finish interrupted instruction */ | 573 | luaV_finishOp(L); /* finish interrupted instruction */ |
556 | luaV_execute(L); /* execute down to higher C 'boundary' */ | 574 | luaV_execute(L, ci); /* execute down to higher C 'boundary' */ |
557 | } | 575 | } |
558 | } | 576 | } |
559 | } | 577 | } |
@@ -583,12 +601,12 @@ static int recover (lua_State *L, int status) { | |||
583 | CallInfo *ci = findpcall(L); | 601 | CallInfo *ci = findpcall(L); |
584 | if (ci == NULL) return 0; /* no recovery point */ | 602 | if (ci == NULL) return 0; /* no recovery point */ |
585 | /* "finish" luaD_pcall */ | 603 | /* "finish" luaD_pcall */ |
586 | oldtop = restorestack(L, ci->extra); | 604 | oldtop = restorestack(L, ci->u2.funcidx); |
587 | luaF_close(L, oldtop); | 605 | luaF_close(L, oldtop, status); /* may change the stack */ |
588 | seterrorobj(L, status, oldtop); | 606 | oldtop = restorestack(L, ci->u2.funcidx); |
607 | luaD_seterrorobj(L, status, oldtop); | ||
589 | L->ci = ci; | 608 | L->ci = ci; |
590 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ | 609 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ |
591 | L->nny = 0; /* should be zero to be yieldable */ | ||
592 | luaD_shrinkstack(L); | 610 | luaD_shrinkstack(L); |
593 | L->errfunc = ci->u.c.old_errfunc; | 611 | L->errfunc = ci->u.c.old_errfunc; |
594 | return 1; /* continue running the coroutine */ | 612 | return 1; /* continue running the coroutine */ |
@@ -621,71 +639,68 @@ static void resume (lua_State *L, void *ud) { | |||
621 | StkId firstArg = L->top - n; /* first argument */ | 639 | StkId firstArg = L->top - n; /* first argument */ |
622 | CallInfo *ci = L->ci; | 640 | CallInfo *ci = L->ci; |
623 | if (L->status == LUA_OK) { /* starting a coroutine? */ | 641 | if (L->status == LUA_OK) { /* starting a coroutine? */ |
624 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ | 642 | luaD_call(L, firstArg - 1, LUA_MULTRET); |
625 | luaV_execute(L); /* call it */ | ||
626 | } | 643 | } |
627 | else { /* resuming from previous yield */ | 644 | else { /* resuming from previous yield */ |
628 | lua_assert(L->status == LUA_YIELD); | 645 | lua_assert(L->status == LUA_YIELD); |
629 | L->status = LUA_OK; /* mark that it is running (again) */ | 646 | L->status = LUA_OK; /* mark that it is running (again) */ |
630 | ci->func = restorestack(L, ci->extra); | ||
631 | if (isLua(ci)) /* yielded inside a hook? */ | 647 | if (isLua(ci)) /* yielded inside a hook? */ |
632 | luaV_execute(L); /* just continue running Lua code */ | 648 | luaV_execute(L, ci); /* just continue running Lua code */ |
633 | else { /* 'common' yield */ | 649 | else { /* 'common' yield */ |
634 | if (ci->u.c.k != NULL) { /* does it have a continuation function? */ | 650 | if (ci->u.c.k != NULL) { /* does it have a continuation function? */ |
635 | lua_unlock(L); | 651 | lua_unlock(L); |
636 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ | 652 | n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ |
637 | lua_lock(L); | 653 | lua_lock(L); |
638 | api_checknelems(L, n); | 654 | api_checknelems(L, n); |
639 | firstArg = L->top - n; /* yield results come from continuation */ | ||
640 | } | 655 | } |
641 | luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ | 656 | luaD_poscall(L, ci, n); /* finish 'luaD_call' */ |
642 | } | 657 | } |
643 | unroll(L, NULL); /* run continuation */ | 658 | unroll(L, NULL); /* run continuation */ |
644 | } | 659 | } |
645 | } | 660 | } |
646 | 661 | ||
647 | 662 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |
648 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { | 663 | int *nresults) { |
649 | int status; | 664 | int status; |
650 | unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ | ||
651 | lua_lock(L); | 665 | lua_lock(L); |
652 | if (L->status == LUA_OK) { /* may be starting a coroutine */ | 666 | if (L->status == LUA_OK) { /* may be starting a coroutine */ |
653 | if (L->ci != &L->base_ci) /* not in base level? */ | 667 | if (L->ci != &L->base_ci) /* not in base level? */ |
654 | return resume_error(L, "cannot resume non-suspended coroutine", nargs); | 668 | return resume_error(L, "cannot resume non-suspended coroutine", nargs); |
669 | else if (L->top - (L->ci->func + 1) == nargs) /* no function? */ | ||
670 | return resume_error(L, "cannot resume dead coroutine", nargs); | ||
655 | } | 671 | } |
656 | else if (L->status != LUA_YIELD) | 672 | else if (L->status != LUA_YIELD) /* ended with errors? */ |
657 | return resume_error(L, "cannot resume dead coroutine", nargs); | 673 | return resume_error(L, "cannot resume dead coroutine", nargs); |
658 | L->nCcalls = (from) ? from->nCcalls + 1 : 1; | 674 | if (from == NULL) |
659 | if (L->nCcalls >= LUAI_MAXCCALLS) | 675 | L->nCcalls = CSTACKTHREAD; |
676 | else /* correct 'nCcalls' for this thread */ | ||
677 | L->nCcalls = getCcalls(from) + from->nci - L->nci - CSTACKCF; | ||
678 | if (L->nCcalls <= CSTACKERR) | ||
660 | return resume_error(L, "C stack overflow", nargs); | 679 | return resume_error(L, "C stack overflow", nargs); |
661 | luai_userstateresume(L, nargs); | 680 | luai_userstateresume(L, nargs); |
662 | L->nny = 0; /* allow yields */ | ||
663 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | 681 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
664 | status = luaD_rawrunprotected(L, resume, &nargs); | 682 | status = luaD_rawrunprotected(L, resume, &nargs); |
665 | if (status == -1) /* error calling 'lua_resume'? */ | 683 | /* continue running after recoverable errors */ |
666 | status = LUA_ERRRUN; | 684 | while (errorstatus(status) && recover(L, status)) { |
667 | else { /* continue running after recoverable errors */ | 685 | /* unroll continuation */ |
668 | while (errorstatus(status) && recover(L, status)) { | 686 | status = luaD_rawrunprotected(L, unroll, &status); |
669 | /* unroll continuation */ | 687 | } |
670 | status = luaD_rawrunprotected(L, unroll, &status); | 688 | if (likely(!errorstatus(status))) |
671 | } | 689 | lua_assert(status == L->status); /* normal end or yield */ |
672 | if (errorstatus(status)) { /* unrecoverable error? */ | 690 | else { /* unrecoverable error */ |
673 | L->status = cast_byte(status); /* mark thread as 'dead' */ | 691 | L->status = cast_byte(status); /* mark thread as 'dead' */ |
674 | seterrorobj(L, status, L->top); /* push error message */ | 692 | luaD_seterrorobj(L, status, L->top); /* push error message */ |
675 | L->ci->top = L->top; | 693 | L->ci->top = L->top; |
676 | } | ||
677 | else lua_assert(status == L->status); /* normal end or yield */ | ||
678 | } | 694 | } |
679 | L->nny = oldnny; /* restore 'nny' */ | 695 | *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield |
680 | L->nCcalls--; | 696 | : cast_int(L->top - (L->ci->func + 1)); |
681 | lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); | ||
682 | lua_unlock(L); | 697 | lua_unlock(L); |
683 | return status; | 698 | return status; |
684 | } | 699 | } |
685 | 700 | ||
686 | 701 | ||
687 | LUA_API int lua_isyieldable (lua_State *L) { | 702 | LUA_API int lua_isyieldable (lua_State *L) { |
688 | return (L->nny == 0); | 703 | return yieldable(L); |
689 | } | 704 | } |
690 | 705 | ||
691 | 706 | ||
@@ -695,21 +710,22 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
695 | luai_userstateyield(L, nresults); | 710 | luai_userstateyield(L, nresults); |
696 | lua_lock(L); | 711 | lua_lock(L); |
697 | api_checknelems(L, nresults); | 712 | api_checknelems(L, nresults); |
698 | if (L->nny > 0) { | 713 | if (unlikely(!yieldable(L))) { |
699 | if (L != G(L)->mainthread) | 714 | if (L != G(L)->mainthread) |
700 | luaG_runerror(L, "attempt to yield across a C-call boundary"); | 715 | luaG_runerror(L, "attempt to yield across a C-call boundary"); |
701 | else | 716 | else |
702 | luaG_runerror(L, "attempt to yield from outside a coroutine"); | 717 | luaG_runerror(L, "attempt to yield from outside a coroutine"); |
703 | } | 718 | } |
704 | L->status = LUA_YIELD; | 719 | L->status = LUA_YIELD; |
705 | ci->extra = savestack(L, ci->func); /* save current 'func' */ | ||
706 | if (isLua(ci)) { /* inside a hook? */ | 720 | if (isLua(ci)) { /* inside a hook? */ |
721 | lua_assert(!isLuacode(ci)); | ||
707 | api_check(L, k == NULL, "hooks cannot continue after yielding"); | 722 | api_check(L, k == NULL, "hooks cannot continue after yielding"); |
723 | ci->u2.nyield = 0; /* no results */ | ||
708 | } | 724 | } |
709 | else { | 725 | else { |
710 | if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ | 726 | if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ |
711 | ci->u.c.ctx = ctx; /* save context */ | 727 | ci->u.c.ctx = ctx; /* save context */ |
712 | ci->func = L->top - nresults - 1; /* protect stack below results */ | 728 | ci->u2.nyield = nresults; /* save number of results */ |
713 | luaD_throw(L, LUA_YIELD); | 729 | luaD_throw(L, LUA_YIELD); |
714 | } | 730 | } |
715 | lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ | 731 | lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ |
@@ -718,22 +734,26 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
718 | } | 734 | } |
719 | 735 | ||
720 | 736 | ||
737 | /* | ||
738 | ** Call the C function 'func' in protected mode, restoring basic | ||
739 | ** thread information ('allowhook', etc.) and in particular | ||
740 | ** its stack level in case of errors. | ||
741 | */ | ||
721 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 742 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
722 | ptrdiff_t old_top, ptrdiff_t ef) { | 743 | ptrdiff_t old_top, ptrdiff_t ef) { |
723 | int status; | 744 | int status; |
724 | CallInfo *old_ci = L->ci; | 745 | CallInfo *old_ci = L->ci; |
725 | lu_byte old_allowhooks = L->allowhook; | 746 | lu_byte old_allowhooks = L->allowhook; |
726 | unsigned short old_nny = L->nny; | ||
727 | ptrdiff_t old_errfunc = L->errfunc; | 747 | ptrdiff_t old_errfunc = L->errfunc; |
728 | L->errfunc = ef; | 748 | L->errfunc = ef; |
729 | status = luaD_rawrunprotected(L, func, u); | 749 | status = luaD_rawrunprotected(L, func, u); |
730 | if (status != LUA_OK) { /* an error occurred? */ | 750 | if (unlikely(status != LUA_OK)) { /* an error occurred? */ |
731 | StkId oldtop = restorestack(L, old_top); | 751 | StkId oldtop = restorestack(L, old_top); |
732 | luaF_close(L, oldtop); /* close possible pending closures */ | ||
733 | seterrorobj(L, status, oldtop); | ||
734 | L->ci = old_ci; | 752 | L->ci = old_ci; |
735 | L->allowhook = old_allowhooks; | 753 | L->allowhook = old_allowhooks; |
736 | L->nny = old_nny; | 754 | status = luaF_close(L, oldtop, status); |
755 | oldtop = restorestack(L, old_top); /* previous call may change stack */ | ||
756 | luaD_seterrorobj(L, status, oldtop); | ||
737 | luaD_shrinkstack(L); | 757 | luaD_shrinkstack(L); |
738 | } | 758 | } |
739 | L->errfunc = old_errfunc; | 759 | L->errfunc = old_errfunc; |
@@ -784,7 +804,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | |||
784 | const char *mode) { | 804 | const char *mode) { |
785 | struct SParser p; | 805 | struct SParser p; |
786 | int status; | 806 | int status; |
787 | L->nny++; /* cannot yield during parsing */ | 807 | incnny(L); /* cannot yield during parsing */ |
788 | p.z = z; p.name = name; p.mode = mode; | 808 | p.z = z; p.name = name; p.mode = mode; |
789 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; | 809 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; |
790 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; | 810 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; |
@@ -795,7 +815,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | |||
795 | luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); | 815 | luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); |
796 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); | 816 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); |
797 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); | 817 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); |
798 | L->nny--; | 818 | decnny(L); |
799 | return status; | 819 | return status; |
800 | } | 820 | } |
801 | 821 | ||
diff --git a/src/lua-5.3/ldo.h b/src/lua/ldo.h index 3b2983a..7760f85 100644 --- a/src/lua-5.3/ldo.h +++ b/src/lua/ldo.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: ldo.h $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -22,7 +22,8 @@ | |||
22 | */ | 22 | */ |
23 | #define luaD_checkstackaux(L,n,pre,pos) \ | 23 | #define luaD_checkstackaux(L,n,pre,pos) \ |
24 | if (L->stack_last - L->top <= (n)) \ | 24 | if (L->stack_last - L->top <= (n)) \ |
25 | { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } | 25 | { pre; luaD_growstack(L, n, 1); pos; } \ |
26 | else { condmovestack(L,pre,pos); } | ||
26 | 27 | ||
27 | /* In general, 'pre'/'pos' are empty (nothing to save) */ | 28 | /* In general, 'pre'/'pos' are empty (nothing to save) */ |
28 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) | 29 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) |
@@ -30,24 +31,40 @@ | |||
30 | 31 | ||
31 | 32 | ||
32 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) | 33 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) |
33 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) | 34 | #define restorestack(L,n) ((StkId)((char *)L->stack + (n))) |
35 | |||
36 | |||
37 | /* macro to check stack size, preserving 'p' */ | ||
38 | #define checkstackp(L,n,p) \ | ||
39 | luaD_checkstackaux(L, n, \ | ||
40 | ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ | ||
41 | luaC_checkGC(L), /* stack grow uses memory */ \ | ||
42 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ | ||
43 | |||
44 | |||
45 | /* macro to check stack size and GC */ | ||
46 | #define checkstackGC(L,fsize) \ | ||
47 | luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L)) | ||
34 | 48 | ||
35 | 49 | ||
36 | /* type of protected functions, to be ran by 'runprotected' */ | 50 | /* type of protected functions, to be ran by 'runprotected' */ |
37 | typedef void (*Pfunc) (lua_State *L, void *ud); | 51 | typedef void (*Pfunc) (lua_State *L, void *ud); |
38 | 52 | ||
53 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); | ||
39 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | 54 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, |
40 | const char *mode); | 55 | const char *mode); |
41 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); | 56 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, |
42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); | 57 | int fTransfer, int nTransfer); |
58 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); | ||
59 | LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); | ||
43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | 60 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); |
44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | 61 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); |
62 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); | ||
45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | 63 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, |
46 | ptrdiff_t oldtop, ptrdiff_t ef); | 64 | ptrdiff_t oldtop, ptrdiff_t ef); |
47 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, | 65 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); |
48 | int nres); | 66 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); |
49 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); | 67 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); |
50 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); | ||
51 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); | 68 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); |
52 | LUAI_FUNC void luaD_inctop (lua_State *L); | 69 | LUAI_FUNC void luaD_inctop (lua_State *L); |
53 | 70 | ||
diff --git a/src/lua/ldump.c b/src/lua/ldump.c new file mode 100644 index 0000000..f848b66 --- /dev/null +++ b/src/lua/ldump.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | ** $Id: ldump.c $ | ||
3 | ** save precompiled Lua chunks | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define ldump_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stddef.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "lobject.h" | ||
18 | #include "lstate.h" | ||
19 | #include "lundump.h" | ||
20 | |||
21 | |||
22 | typedef struct { | ||
23 | lua_State *L; | ||
24 | lua_Writer writer; | ||
25 | void *data; | ||
26 | int strip; | ||
27 | int status; | ||
28 | } DumpState; | ||
29 | |||
30 | |||
31 | /* | ||
32 | ** All high-level dumps go through dumpVector; you can change it to | ||
33 | ** change the endianness of the result | ||
34 | */ | ||
35 | #define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) | ||
36 | |||
37 | #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) | ||
38 | |||
39 | |||
40 | static void dumpBlock (DumpState *D, const void *b, size_t size) { | ||
41 | if (D->status == 0 && size > 0) { | ||
42 | lua_unlock(D->L); | ||
43 | D->status = (*D->writer)(D->L, b, size, D->data); | ||
44 | lua_lock(D->L); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | |||
49 | #define dumpVar(D,x) dumpVector(D,&x,1) | ||
50 | |||
51 | |||
52 | static void dumpByte (DumpState *D, int y) { | ||
53 | lu_byte x = (lu_byte)y; | ||
54 | dumpVar(D, x); | ||
55 | } | ||
56 | |||
57 | |||
58 | /* dumpInt Buff Size */ | ||
59 | #define DIBS ((sizeof(size_t) * 8 / 7) + 1) | ||
60 | |||
61 | static void dumpSize (DumpState *D, size_t x) { | ||
62 | lu_byte buff[DIBS]; | ||
63 | int n = 0; | ||
64 | do { | ||
65 | buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ | ||
66 | x >>= 7; | ||
67 | } while (x != 0); | ||
68 | buff[DIBS - 1] |= 0x80; /* mark last byte */ | ||
69 | dumpVector(D, buff + DIBS - n, n); | ||
70 | } | ||
71 | |||
72 | |||
73 | static void dumpInt (DumpState *D, int x) { | ||
74 | dumpSize(D, x); | ||
75 | } | ||
76 | |||
77 | |||
78 | static void dumpNumber (DumpState *D, lua_Number x) { | ||
79 | dumpVar(D, x); | ||
80 | } | ||
81 | |||
82 | |||
83 | static void dumpInteger (DumpState *D, lua_Integer x) { | ||
84 | dumpVar(D, x); | ||
85 | } | ||
86 | |||
87 | |||
88 | static void dumpString (DumpState *D, const TString *s) { | ||
89 | if (s == NULL) | ||
90 | dumpSize(D, 0); | ||
91 | else { | ||
92 | size_t size = tsslen(s); | ||
93 | const char *str = getstr(s); | ||
94 | dumpSize(D, size + 1); | ||
95 | dumpVector(D, str, size); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | |||
100 | static void dumpCode (DumpState *D, const Proto *f) { | ||
101 | dumpInt(D, f->sizecode); | ||
102 | dumpVector(D, f->code, f->sizecode); | ||
103 | } | ||
104 | |||
105 | |||
106 | static void dumpFunction(DumpState *D, const Proto *f, TString *psource); | ||
107 | |||
108 | static void dumpConstants (DumpState *D, const Proto *f) { | ||
109 | int i; | ||
110 | int n = f->sizek; | ||
111 | dumpInt(D, n); | ||
112 | for (i = 0; i < n; i++) { | ||
113 | const TValue *o = &f->k[i]; | ||
114 | int tt = ttypetag(o); | ||
115 | dumpByte(D, tt); | ||
116 | switch (tt) { | ||
117 | case LUA_VNUMFLT: | ||
118 | dumpNumber(D, fltvalue(o)); | ||
119 | break; | ||
120 | case LUA_VNUMINT: | ||
121 | dumpInteger(D, ivalue(o)); | ||
122 | break; | ||
123 | case LUA_VSHRSTR: | ||
124 | case LUA_VLNGSTR: | ||
125 | dumpString(D, tsvalue(o)); | ||
126 | break; | ||
127 | default: | ||
128 | lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | |||
134 | static void dumpProtos (DumpState *D, const Proto *f) { | ||
135 | int i; | ||
136 | int n = f->sizep; | ||
137 | dumpInt(D, n); | ||
138 | for (i = 0; i < n; i++) | ||
139 | dumpFunction(D, f->p[i], f->source); | ||
140 | } | ||
141 | |||
142 | |||
143 | static void dumpUpvalues (DumpState *D, const Proto *f) { | ||
144 | int i, n = f->sizeupvalues; | ||
145 | dumpInt(D, n); | ||
146 | for (i = 0; i < n; i++) { | ||
147 | dumpByte(D, f->upvalues[i].instack); | ||
148 | dumpByte(D, f->upvalues[i].idx); | ||
149 | dumpByte(D, f->upvalues[i].kind); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | |||
154 | static void dumpDebug (DumpState *D, const Proto *f) { | ||
155 | int i, n; | ||
156 | n = (D->strip) ? 0 : f->sizelineinfo; | ||
157 | dumpInt(D, n); | ||
158 | dumpVector(D, f->lineinfo, n); | ||
159 | n = (D->strip) ? 0 : f->sizeabslineinfo; | ||
160 | dumpInt(D, n); | ||
161 | for (i = 0; i < n; i++) { | ||
162 | dumpInt(D, f->abslineinfo[i].pc); | ||
163 | dumpInt(D, f->abslineinfo[i].line); | ||
164 | } | ||
165 | n = (D->strip) ? 0 : f->sizelocvars; | ||
166 | dumpInt(D, n); | ||
167 | for (i = 0; i < n; i++) { | ||
168 | dumpString(D, f->locvars[i].varname); | ||
169 | dumpInt(D, f->locvars[i].startpc); | ||
170 | dumpInt(D, f->locvars[i].endpc); | ||
171 | } | ||
172 | n = (D->strip) ? 0 : f->sizeupvalues; | ||
173 | dumpInt(D, n); | ||
174 | for (i = 0; i < n; i++) | ||
175 | dumpString(D, f->upvalues[i].name); | ||
176 | } | ||
177 | |||
178 | |||
179 | static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { | ||
180 | if (D->strip || f->source == psource) | ||
181 | dumpString(D, NULL); /* no debug info or same source as its parent */ | ||
182 | else | ||
183 | dumpString(D, f->source); | ||
184 | dumpInt(D, f->linedefined); | ||
185 | dumpInt(D, f->lastlinedefined); | ||
186 | dumpByte(D, f->numparams); | ||
187 | dumpByte(D, f->is_vararg); | ||
188 | dumpByte(D, f->maxstacksize); | ||
189 | dumpCode(D, f); | ||
190 | dumpConstants(D, f); | ||
191 | dumpUpvalues(D, f); | ||
192 | dumpProtos(D, f); | ||
193 | dumpDebug(D, f); | ||
194 | } | ||
195 | |||
196 | |||
197 | static void dumpHeader (DumpState *D) { | ||
198 | dumpLiteral(D, LUA_SIGNATURE); | ||
199 | dumpByte(D, LUAC_VERSION); | ||
200 | dumpByte(D, LUAC_FORMAT); | ||
201 | dumpLiteral(D, LUAC_DATA); | ||
202 | dumpByte(D, sizeof(Instruction)); | ||
203 | dumpByte(D, sizeof(lua_Integer)); | ||
204 | dumpByte(D, sizeof(lua_Number)); | ||
205 | dumpInteger(D, LUAC_INT); | ||
206 | dumpNumber(D, LUAC_NUM); | ||
207 | } | ||
208 | |||
209 | |||
210 | /* | ||
211 | ** dump Lua function as precompiled chunk | ||
212 | */ | ||
213 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, | ||
214 | int strip) { | ||
215 | DumpState D; | ||
216 | D.L = L; | ||
217 | D.writer = w; | ||
218 | D.data = data; | ||
219 | D.strip = strip; | ||
220 | D.status = 0; | ||
221 | dumpHeader(&D); | ||
222 | dumpByte(&D, f->sizeupvalues); | ||
223 | dumpFunction(&D, f, NULL); | ||
224 | return D.status; | ||
225 | } | ||
226 | |||
diff --git a/src/lua/lfunc.c b/src/lua/lfunc.c new file mode 100644 index 0000000..10100e5 --- /dev/null +++ b/src/lua/lfunc.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /* | ||
2 | ** $Id: lfunc.c $ | ||
3 | ** Auxiliary functions to manipulate prototypes and closures | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lfunc_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stddef.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lfunc.h" | ||
20 | #include "lgc.h" | ||
21 | #include "lmem.h" | ||
22 | #include "lobject.h" | ||
23 | #include "lstate.h" | ||
24 | |||
25 | |||
26 | |||
27 | CClosure *luaF_newCclosure (lua_State *L, int nupvals) { | ||
28 | GCObject *o = luaC_newobj(L, LUA_VCCL, sizeCclosure(nupvals)); | ||
29 | CClosure *c = gco2ccl(o); | ||
30 | c->nupvalues = cast_byte(nupvals); | ||
31 | return c; | ||
32 | } | ||
33 | |||
34 | |||
35 | LClosure *luaF_newLclosure (lua_State *L, int nupvals) { | ||
36 | GCObject *o = luaC_newobj(L, LUA_VLCL, sizeLclosure(nupvals)); | ||
37 | LClosure *c = gco2lcl(o); | ||
38 | c->p = NULL; | ||
39 | c->nupvalues = cast_byte(nupvals); | ||
40 | while (nupvals--) c->upvals[nupvals] = NULL; | ||
41 | return c; | ||
42 | } | ||
43 | |||
44 | |||
45 | /* | ||
46 | ** fill a closure with new closed upvalues | ||
47 | */ | ||
48 | void luaF_initupvals (lua_State *L, LClosure *cl) { | ||
49 | int i; | ||
50 | for (i = 0; i < cl->nupvalues; i++) { | ||
51 | GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); | ||
52 | UpVal *uv = gco2upv(o); | ||
53 | uv->v = &uv->u.value; /* make it closed */ | ||
54 | setnilvalue(uv->v); | ||
55 | cl->upvals[i] = uv; | ||
56 | luaC_objbarrier(L, cl, o); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | |||
61 | /* | ||
62 | ** Create a new upvalue at the given level, and link it to the list of | ||
63 | ** open upvalues of 'L' after entry 'prev'. | ||
64 | **/ | ||
65 | static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) { | ||
66 | GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); | ||
67 | UpVal *uv = gco2upv(o); | ||
68 | UpVal *next = *prev; | ||
69 | uv->v = s2v(level); /* current value lives in the stack */ | ||
70 | uv->tbc = tbc; | ||
71 | uv->u.open.next = next; /* link it to list of open upvalues */ | ||
72 | uv->u.open.previous = prev; | ||
73 | if (next) | ||
74 | next->u.open.previous = &uv->u.open.next; | ||
75 | *prev = uv; | ||
76 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ | ||
77 | L->twups = G(L)->twups; /* link it to the list */ | ||
78 | G(L)->twups = L; | ||
79 | } | ||
80 | return uv; | ||
81 | } | ||
82 | |||
83 | |||
84 | /* | ||
85 | ** Find and reuse, or create if it does not exist, an upvalue | ||
86 | ** at the given level. | ||
87 | */ | ||
88 | UpVal *luaF_findupval (lua_State *L, StkId level) { | ||
89 | UpVal **pp = &L->openupval; | ||
90 | UpVal *p; | ||
91 | lua_assert(isintwups(L) || L->openupval == NULL); | ||
92 | while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ | ||
93 | lua_assert(!isdead(G(L), p)); | ||
94 | if (uplevel(p) == level) /* corresponding upvalue? */ | ||
95 | return p; /* return it */ | ||
96 | pp = &p->u.open.next; | ||
97 | } | ||
98 | /* not found: create a new upvalue after 'pp' */ | ||
99 | return newupval(L, 0, level, pp); | ||
100 | } | ||
101 | |||
102 | |||
103 | static void callclose (lua_State *L, void *ud) { | ||
104 | UNUSED(ud); | ||
105 | luaD_callnoyield(L, L->top - 3, 0); | ||
106 | } | ||
107 | |||
108 | |||
109 | /* | ||
110 | ** Prepare closing method plus its arguments for object 'obj' with | ||
111 | ** error message 'err'. (This function assumes EXTRA_STACK.) | ||
112 | */ | ||
113 | static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) { | ||
114 | StkId top = L->top; | ||
115 | const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); | ||
116 | if (ttisnil(tm)) /* no metamethod? */ | ||
117 | return 0; /* nothing to call */ | ||
118 | setobj2s(L, top, tm); /* will call metamethod... */ | ||
119 | setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */ | ||
120 | setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */ | ||
121 | L->top = top + 3; /* add function and arguments */ | ||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | |||
126 | /* | ||
127 | ** Raise an error with message 'msg', inserting the name of the | ||
128 | ** local variable at position 'level' in the stack. | ||
129 | */ | ||
130 | static void varerror (lua_State *L, StkId level, const char *msg) { | ||
131 | int idx = cast_int(level - L->ci->func); | ||
132 | const char *vname = luaG_findlocal(L, L->ci, idx, NULL); | ||
133 | if (vname == NULL) vname = "?"; | ||
134 | luaG_runerror(L, msg, vname); | ||
135 | } | ||
136 | |||
137 | |||
138 | /* | ||
139 | ** Prepare and call a closing method. If status is OK, code is still | ||
140 | ** inside the original protected call, and so any error will be handled | ||
141 | ** there. Otherwise, a previous error already activated the original | ||
142 | ** protected call, and so the call to the closing method must be | ||
143 | ** protected here. (A status == CLOSEPROTECT behaves like a previous | ||
144 | ** error, to also run the closing method in protected mode). | ||
145 | ** If status is OK, the call to the closing method will be pushed | ||
146 | ** at the top of the stack. Otherwise, values are pushed after | ||
147 | ** the 'level' of the upvalue being closed, as everything after | ||
148 | ** that won't be used again. | ||
149 | */ | ||
150 | static int callclosemth (lua_State *L, StkId level, int status) { | ||
151 | TValue *uv = s2v(level); /* value being closed */ | ||
152 | if (likely(status == LUA_OK)) { | ||
153 | if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */ | ||
154 | callclose(L, NULL); /* call closing method */ | ||
155 | else if (!l_isfalse(uv)) /* non-closable non-false value? */ | ||
156 | varerror(L, level, "attempt to close non-closable variable '%s'"); | ||
157 | } | ||
158 | else { /* must close the object in protected mode */ | ||
159 | ptrdiff_t oldtop; | ||
160 | level++; /* space for error message */ | ||
161 | oldtop = savestack(L, level + 1); /* top will be after that */ | ||
162 | luaD_seterrorobj(L, status, level); /* set error message */ | ||
163 | if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */ | ||
164 | int newstatus = luaD_pcall(L, callclose, NULL, oldtop, 0); | ||
165 | if (newstatus != LUA_OK && status == CLOSEPROTECT) /* first error? */ | ||
166 | status = newstatus; /* this will be the new error */ | ||
167 | else { | ||
168 | if (newstatus != LUA_OK) /* suppressed error? */ | ||
169 | luaE_warnerror(L, "__close metamethod"); | ||
170 | /* leave original error (or nil) on top */ | ||
171 | L->top = restorestack(L, oldtop); | ||
172 | } | ||
173 | } | ||
174 | /* else no metamethod; ignore this case and keep original error */ | ||
175 | } | ||
176 | return status; | ||
177 | } | ||
178 | |||
179 | |||
180 | /* | ||
181 | ** Try to create a to-be-closed upvalue | ||
182 | ** (can raise a memory-allocation error) | ||
183 | */ | ||
184 | static void trynewtbcupval (lua_State *L, void *ud) { | ||
185 | newupval(L, 1, cast(StkId, ud), &L->openupval); | ||
186 | } | ||
187 | |||
188 | |||
189 | /* | ||
190 | ** Create a to-be-closed upvalue. If there is a memory error | ||
191 | ** when creating the upvalue, the closing method must be called here, | ||
192 | ** as there is no upvalue to call it later. | ||
193 | */ | ||
194 | void luaF_newtbcupval (lua_State *L, StkId level) { | ||
195 | TValue *obj = s2v(level); | ||
196 | lua_assert(L->openupval == NULL || uplevel(L->openupval) < level); | ||
197 | if (!l_isfalse(obj)) { /* false doesn't need to be closed */ | ||
198 | int status; | ||
199 | const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); | ||
200 | if (ttisnil(tm)) /* no metamethod? */ | ||
201 | varerror(L, level, "variable '%s' got a non-closable value"); | ||
202 | status = luaD_rawrunprotected(L, trynewtbcupval, level); | ||
203 | if (unlikely(status != LUA_OK)) { /* memory error creating upvalue? */ | ||
204 | lua_assert(status == LUA_ERRMEM); | ||
205 | luaD_seterrorobj(L, LUA_ERRMEM, level + 1); /* save error message */ | ||
206 | /* next call must succeed, as object is closable */ | ||
207 | prepclosingmethod(L, s2v(level), s2v(level + 1)); | ||
208 | callclose(L, NULL); /* call closing method */ | ||
209 | luaD_throw(L, LUA_ERRMEM); /* throw memory error */ | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | |||
214 | |||
215 | void luaF_unlinkupval (UpVal *uv) { | ||
216 | lua_assert(upisopen(uv)); | ||
217 | *uv->u.open.previous = uv->u.open.next; | ||
218 | if (uv->u.open.next) | ||
219 | uv->u.open.next->u.open.previous = uv->u.open.previous; | ||
220 | } | ||
221 | |||
222 | |||
223 | int luaF_close (lua_State *L, StkId level, int status) { | ||
224 | UpVal *uv; | ||
225 | while ((uv = L->openupval) != NULL && uplevel(uv) >= level) { | ||
226 | TValue *slot = &uv->u.value; /* new position for value */ | ||
227 | lua_assert(uplevel(uv) < L->top); | ||
228 | if (uv->tbc && status != NOCLOSINGMETH) { | ||
229 | /* must run closing method, which may change the stack */ | ||
230 | ptrdiff_t levelrel = savestack(L, level); | ||
231 | status = callclosemth(L, uplevel(uv), status); | ||
232 | level = restorestack(L, levelrel); | ||
233 | } | ||
234 | luaF_unlinkupval(uv); | ||
235 | setobj(L, slot, uv->v); /* move value to upvalue slot */ | ||
236 | uv->v = slot; /* now current value lives here */ | ||
237 | if (!iswhite(uv)) | ||
238 | gray2black(uv); /* closed upvalues cannot be gray */ | ||
239 | luaC_barrier(L, uv, slot); | ||
240 | } | ||
241 | return status; | ||
242 | } | ||
243 | |||
244 | |||
245 | Proto *luaF_newproto (lua_State *L) { | ||
246 | GCObject *o = luaC_newobj(L, LUA_VPROTO, sizeof(Proto)); | ||
247 | Proto *f = gco2p(o); | ||
248 | f->k = NULL; | ||
249 | f->sizek = 0; | ||
250 | f->p = NULL; | ||
251 | f->sizep = 0; | ||
252 | f->code = NULL; | ||
253 | f->sizecode = 0; | ||
254 | f->lineinfo = NULL; | ||
255 | f->sizelineinfo = 0; | ||
256 | f->abslineinfo = NULL; | ||
257 | f->sizeabslineinfo = 0; | ||
258 | f->upvalues = NULL; | ||
259 | f->sizeupvalues = 0; | ||
260 | f->numparams = 0; | ||
261 | f->is_vararg = 0; | ||
262 | f->maxstacksize = 0; | ||
263 | f->locvars = NULL; | ||
264 | f->sizelocvars = 0; | ||
265 | f->linedefined = 0; | ||
266 | f->lastlinedefined = 0; | ||
267 | f->source = NULL; | ||
268 | return f; | ||
269 | } | ||
270 | |||
271 | |||
272 | void luaF_freeproto (lua_State *L, Proto *f) { | ||
273 | luaM_freearray(L, f->code, f->sizecode); | ||
274 | luaM_freearray(L, f->p, f->sizep); | ||
275 | luaM_freearray(L, f->k, f->sizek); | ||
276 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); | ||
277 | luaM_freearray(L, f->abslineinfo, f->sizeabslineinfo); | ||
278 | luaM_freearray(L, f->locvars, f->sizelocvars); | ||
279 | luaM_freearray(L, f->upvalues, f->sizeupvalues); | ||
280 | luaM_free(L, f); | ||
281 | } | ||
282 | |||
283 | |||
284 | /* | ||
285 | ** Look for n-th local variable at line 'line' in function 'func'. | ||
286 | ** Returns NULL if not found. | ||
287 | */ | ||
288 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { | ||
289 | int i; | ||
290 | for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { | ||
291 | if (pc < f->locvars[i].endpc) { /* is variable active? */ | ||
292 | local_number--; | ||
293 | if (local_number == 0) | ||
294 | return getstr(f->locvars[i].varname); | ||
295 | } | ||
296 | } | ||
297 | return NULL; /* not found */ | ||
298 | } | ||
299 | |||
diff --git a/src/lua/lfunc.h b/src/lua/lfunc.h new file mode 100644 index 0000000..8d6f965 --- /dev/null +++ b/src/lua/lfunc.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | ** $Id: lfunc.h $ | ||
3 | ** Auxiliary functions to manipulate prototypes and closures | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lfunc_h | ||
8 | #define lfunc_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | |||
13 | |||
14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ | ||
15 | cast_int(sizeof(TValue)) * (n)) | ||
16 | |||
17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ | ||
18 | cast_int(sizeof(TValue *)) * (n)) | ||
19 | |||
20 | |||
21 | /* test whether thread is in 'twups' list */ | ||
22 | #define isintwups(L) (L->twups != L) | ||
23 | |||
24 | |||
25 | /* | ||
26 | ** maximum number of upvalues in a closure (both C and Lua). (Value | ||
27 | ** must fit in a VM register.) | ||
28 | */ | ||
29 | #define MAXUPVAL 255 | ||
30 | |||
31 | |||
32 | #define upisopen(up) ((up)->v != &(up)->u.value) | ||
33 | |||
34 | |||
35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) | ||
36 | |||
37 | |||
38 | /* | ||
39 | ** maximum number of misses before giving up the cache of closures | ||
40 | ** in prototypes | ||
41 | */ | ||
42 | #define MAXMISS 10 | ||
43 | |||
44 | |||
45 | /* | ||
46 | ** Special "status" for 'luaF_close' | ||
47 | */ | ||
48 | |||
49 | /* close upvalues without running their closing methods */ | ||
50 | #define NOCLOSINGMETH (-1) | ||
51 | |||
52 | /* close upvalues running all closing methods in protected mode */ | ||
53 | #define CLOSEPROTECT (-2) | ||
54 | |||
55 | |||
56 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); | ||
57 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); | ||
58 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); | ||
59 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); | ||
60 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); | ||
61 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); | ||
62 | LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status); | ||
63 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); | ||
64 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); | ||
65 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, | ||
66 | int pc); | ||
67 | |||
68 | |||
69 | #endif | ||
diff --git a/src/lua/lgc.c b/src/lua/lgc.c new file mode 100644 index 0000000..f26c921 --- /dev/null +++ b/src/lua/lgc.c | |||
@@ -0,0 +1,1616 @@ | |||
1 | /* | ||
2 | ** $Id: lgc.c $ | ||
3 | ** Garbage Collector | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lgc_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | #include <stdio.h> | ||
13 | #include <string.h> | ||
14 | |||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "ldebug.h" | ||
19 | #include "ldo.h" | ||
20 | #include "lfunc.h" | ||
21 | #include "lgc.h" | ||
22 | #include "lmem.h" | ||
23 | #include "lobject.h" | ||
24 | #include "lstate.h" | ||
25 | #include "lstring.h" | ||
26 | #include "ltable.h" | ||
27 | #include "ltm.h" | ||
28 | |||
29 | |||
30 | /* | ||
31 | ** Maximum number of elements to sweep in each single step. | ||
32 | ** (Large enough to dissipate fixed overheads but small enough | ||
33 | ** to allow small steps for the collector.) | ||
34 | */ | ||
35 | #define GCSWEEPMAX 100 | ||
36 | |||
37 | /* | ||
38 | ** Maximum number of finalizers to call in each single step. | ||
39 | */ | ||
40 | #define GCFINMAX 10 | ||
41 | |||
42 | |||
43 | /* | ||
44 | ** Cost of calling one finalizer. | ||
45 | */ | ||
46 | #define GCFINALIZECOST 50 | ||
47 | |||
48 | |||
49 | /* | ||
50 | ** The equivalent, in bytes, of one unit of "work" (visiting a slot, | ||
51 | ** sweeping an object, etc.) | ||
52 | */ | ||
53 | #define WORK2MEM sizeof(TValue) | ||
54 | |||
55 | |||
56 | /* | ||
57 | ** macro to adjust 'pause': 'pause' is actually used like | ||
58 | ** 'pause / PAUSEADJ' (value chosen by tests) | ||
59 | */ | ||
60 | #define PAUSEADJ 100 | ||
61 | |||
62 | |||
63 | /* mask to erase all color bits (plus gen. related stuff) */ | ||
64 | #define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS | AGEBITS)) | ||
65 | |||
66 | |||
67 | /* macro to erase all color bits then sets only the current white bit */ | ||
68 | #define makewhite(g,x) \ | ||
69 | (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) | ||
70 | |||
71 | #define white2gray(x) resetbits(x->marked, WHITEBITS) | ||
72 | #define black2gray(x) resetbit(x->marked, BLACKBIT) | ||
73 | |||
74 | |||
75 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | ||
76 | |||
77 | #define keyiswhite(n) (keyiscollectable(n) && iswhite(gckey(n))) | ||
78 | |||
79 | |||
80 | #define checkconsistency(obj) \ | ||
81 | lua_longassert(!iscollectable(obj) || righttt(obj)) | ||
82 | |||
83 | /* | ||
84 | ** Protected access to objects in values | ||
85 | */ | ||
86 | #define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) | ||
87 | |||
88 | |||
89 | #define markvalue(g,o) { checkconsistency(o); \ | ||
90 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } | ||
91 | |||
92 | #define markkey(g, n) { if keyiswhite(n) reallymarkobject(g,gckey(n)); } | ||
93 | |||
94 | #define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } | ||
95 | |||
96 | /* | ||
97 | ** mark an object that can be NULL (either because it is really optional, | ||
98 | ** or it was stripped as debug info, or inside an uncompleted structure) | ||
99 | */ | ||
100 | #define markobjectN(g,t) { if (t) markobject(g,t); } | ||
101 | |||
102 | static void reallymarkobject (global_State *g, GCObject *o); | ||
103 | static lu_mem atomic (lua_State *L); | ||
104 | static void entersweep (lua_State *L); | ||
105 | |||
106 | |||
107 | /* | ||
108 | ** {====================================================== | ||
109 | ** Generic functions | ||
110 | ** ======================================================= | ||
111 | */ | ||
112 | |||
113 | |||
114 | /* | ||
115 | ** one after last element in a hash array | ||
116 | */ | ||
117 | #define gnodelast(h) gnode(h, cast_sizet(sizenode(h))) | ||
118 | |||
119 | |||
120 | static GCObject **getgclist (GCObject *o) { | ||
121 | switch (o->tt) { | ||
122 | case LUA_VTABLE: return &gco2t(o)->gclist; | ||
123 | case LUA_VLCL: return &gco2lcl(o)->gclist; | ||
124 | case LUA_VCCL: return &gco2ccl(o)->gclist; | ||
125 | case LUA_VTHREAD: return &gco2th(o)->gclist; | ||
126 | case LUA_VPROTO: return &gco2p(o)->gclist; | ||
127 | case LUA_VUSERDATA: { | ||
128 | Udata *u = gco2u(o); | ||
129 | lua_assert(u->nuvalue > 0); | ||
130 | return &u->gclist; | ||
131 | } | ||
132 | default: lua_assert(0); return 0; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | |||
137 | /* | ||
138 | ** Link a collectable object 'o' with a known type into list pointed by 'p'. | ||
139 | */ | ||
140 | #define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o)) | ||
141 | |||
142 | |||
143 | /* | ||
144 | ** Link a generic collectable object 'o' into list pointed by 'p'. | ||
145 | */ | ||
146 | #define linkobjgclist(o,p) (*getgclist(o) = (p), (p) = obj2gco(o)) | ||
147 | |||
148 | |||
149 | |||
150 | /* | ||
151 | ** Clear keys for empty entries in tables. If entry is empty | ||
152 | ** and its key is not marked, mark its entry as dead. This allows the | ||
153 | ** collection of the key, but keeps its entry in the table (its removal | ||
154 | ** could break a chain). The main feature of a dead key is that it must | ||
155 | ** be different from any other value, to do not disturb searches. | ||
156 | ** Other places never manipulate dead keys, because its associated empty | ||
157 | ** value is enough to signal that the entry is logically empty. | ||
158 | */ | ||
159 | static void clearkey (Node *n) { | ||
160 | lua_assert(isempty(gval(n))); | ||
161 | if (keyiswhite(n)) | ||
162 | setdeadkey(n); /* unused and unmarked key; remove it */ | ||
163 | } | ||
164 | |||
165 | |||
166 | /* | ||
167 | ** tells whether a key or value can be cleared from a weak | ||
168 | ** table. Non-collectable objects are never removed from weak | ||
169 | ** tables. Strings behave as 'values', so are never removed too. for | ||
170 | ** other objects: if really collected, cannot keep them; for objects | ||
171 | ** being finalized, keep them in keys, but not in values | ||
172 | */ | ||
173 | static int iscleared (global_State *g, const GCObject *o) { | ||
174 | if (o == NULL) return 0; /* non-collectable value */ | ||
175 | else if (novariant(o->tt) == LUA_TSTRING) { | ||
176 | markobject(g, o); /* strings are 'values', so are never weak */ | ||
177 | return 0; | ||
178 | } | ||
179 | else return iswhite(o); | ||
180 | } | ||
181 | |||
182 | |||
183 | /* | ||
184 | ** barrier that moves collector forward, that is, mark the white object | ||
185 | ** 'v' being pointed by the black object 'o'. (If in sweep phase, clear | ||
186 | ** the black object to white [sweep it] to avoid other barrier calls for | ||
187 | ** this same object.) In the generational mode, 'v' must also become | ||
188 | ** old, if 'o' is old; however, it cannot be changed directly to OLD, | ||
189 | ** because it may still point to non-old objects. So, it is marked as | ||
190 | ** OLD0. In the next cycle it will become OLD1, and in the next it | ||
191 | ** will finally become OLD (regular old). | ||
192 | */ | ||
193 | void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { | ||
194 | global_State *g = G(L); | ||
195 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | ||
196 | if (keepinvariant(g)) { /* must keep invariant? */ | ||
197 | reallymarkobject(g, v); /* restore invariant */ | ||
198 | if (isold(o)) { | ||
199 | lua_assert(!isold(v)); /* white object could not be old */ | ||
200 | setage(v, G_OLD0); /* restore generational invariant */ | ||
201 | } | ||
202 | } | ||
203 | else { /* sweep phase */ | ||
204 | lua_assert(issweepphase(g)); | ||
205 | makewhite(g, o); /* mark main obj. as white to avoid other barriers */ | ||
206 | } | ||
207 | } | ||
208 | |||
209 | |||
210 | /* | ||
211 | ** barrier that moves collector backward, that is, mark the black object | ||
212 | ** pointing to a white object as gray again. | ||
213 | */ | ||
214 | void luaC_barrierback_ (lua_State *L, GCObject *o) { | ||
215 | global_State *g = G(L); | ||
216 | lua_assert(isblack(o) && !isdead(g, o)); | ||
217 | lua_assert(g->gckind != KGC_GEN || (isold(o) && getage(o) != G_TOUCHED1)); | ||
218 | if (getage(o) != G_TOUCHED2) /* not already in gray list? */ | ||
219 | linkobjgclist(o, g->grayagain); /* link it in 'grayagain' */ | ||
220 | black2gray(o); /* make object gray (again) */ | ||
221 | setage(o, G_TOUCHED1); /* touched in current cycle */ | ||
222 | } | ||
223 | |||
224 | |||
225 | void luaC_fix (lua_State *L, GCObject *o) { | ||
226 | global_State *g = G(L); | ||
227 | lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ | ||
228 | white2gray(o); /* they will be gray forever */ | ||
229 | setage(o, G_OLD); /* and old forever */ | ||
230 | g->allgc = o->next; /* remove object from 'allgc' list */ | ||
231 | o->next = g->fixedgc; /* link it to 'fixedgc' list */ | ||
232 | g->fixedgc = o; | ||
233 | } | ||
234 | |||
235 | |||
236 | /* | ||
237 | ** create a new collectable object (with given type and size) and link | ||
238 | ** it to 'allgc' list. | ||
239 | */ | ||
240 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { | ||
241 | global_State *g = G(L); | ||
242 | GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); | ||
243 | o->marked = luaC_white(g); | ||
244 | o->tt = tt; | ||
245 | o->next = g->allgc; | ||
246 | g->allgc = o; | ||
247 | return o; | ||
248 | } | ||
249 | |||
250 | /* }====================================================== */ | ||
251 | |||
252 | |||
253 | |||
254 | /* | ||
255 | ** {====================================================== | ||
256 | ** Mark functions | ||
257 | ** ======================================================= | ||
258 | */ | ||
259 | |||
260 | |||
261 | /* | ||
262 | ** Mark an object. Userdata, strings, and closed upvalues are visited | ||
263 | ** and turned black here. Other objects are marked gray and added | ||
264 | ** to appropriate list to be visited (and turned black) later. (Open | ||
265 | ** upvalues are already linked in 'headuv' list. They are kept gray | ||
266 | ** to avoid barriers, as their values will be revisited by the thread.) | ||
267 | */ | ||
268 | static void reallymarkobject (global_State *g, GCObject *o) { | ||
269 | white2gray(o); | ||
270 | switch (o->tt) { | ||
271 | case LUA_VSHRSTR: | ||
272 | case LUA_VLNGSTR: { | ||
273 | gray2black(o); | ||
274 | break; | ||
275 | } | ||
276 | case LUA_VUPVAL: { | ||
277 | UpVal *uv = gco2upv(o); | ||
278 | if (!upisopen(uv)) /* open upvalues are kept gray */ | ||
279 | gray2black(o); | ||
280 | markvalue(g, uv->v); /* mark its content */ | ||
281 | break; | ||
282 | } | ||
283 | case LUA_VUSERDATA: { | ||
284 | Udata *u = gco2u(o); | ||
285 | if (u->nuvalue == 0) { /* no user values? */ | ||
286 | markobjectN(g, u->metatable); /* mark its metatable */ | ||
287 | gray2black(o); /* nothing else to mark */ | ||
288 | break; | ||
289 | } | ||
290 | /* else... */ | ||
291 | } /* FALLTHROUGH */ | ||
292 | case LUA_VLCL: case LUA_VCCL: case LUA_VTABLE: | ||
293 | case LUA_VTHREAD: case LUA_VPROTO: { | ||
294 | linkobjgclist(o, g->gray); | ||
295 | break; | ||
296 | } | ||
297 | default: lua_assert(0); break; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | |||
302 | /* | ||
303 | ** mark metamethods for basic types | ||
304 | */ | ||
305 | static void markmt (global_State *g) { | ||
306 | int i; | ||
307 | for (i=0; i < LUA_NUMTAGS; i++) | ||
308 | markobjectN(g, g->mt[i]); | ||
309 | } | ||
310 | |||
311 | |||
312 | /* | ||
313 | ** mark all objects in list of being-finalized | ||
314 | */ | ||
315 | static lu_mem markbeingfnz (global_State *g) { | ||
316 | GCObject *o; | ||
317 | lu_mem count = 0; | ||
318 | for (o = g->tobefnz; o != NULL; o = o->next) { | ||
319 | count++; | ||
320 | markobject(g, o); | ||
321 | } | ||
322 | return count; | ||
323 | } | ||
324 | |||
325 | |||
326 | /* | ||
327 | ** Mark all values stored in marked open upvalues from non-marked threads. | ||
328 | ** (Values from marked threads were already marked when traversing the | ||
329 | ** thread.) Remove from the list threads that no longer have upvalues and | ||
330 | ** not-marked threads. | ||
331 | */ | ||
332 | static int remarkupvals (global_State *g) { | ||
333 | lua_State *thread; | ||
334 | lua_State **p = &g->twups; | ||
335 | int work = 0; | ||
336 | while ((thread = *p) != NULL) { | ||
337 | work++; | ||
338 | lua_assert(!isblack(thread)); /* threads are never black */ | ||
339 | if (isgray(thread) && thread->openupval != NULL) | ||
340 | p = &thread->twups; /* keep marked thread with upvalues in the list */ | ||
341 | else { /* thread is not marked or without upvalues */ | ||
342 | UpVal *uv; | ||
343 | *p = thread->twups; /* remove thread from the list */ | ||
344 | thread->twups = thread; /* mark that it is out of list */ | ||
345 | for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { | ||
346 | work++; | ||
347 | if (!iswhite(uv)) /* upvalue already visited? */ | ||
348 | markvalue(g, uv->v); /* mark its value */ | ||
349 | } | ||
350 | } | ||
351 | } | ||
352 | return work; | ||
353 | } | ||
354 | |||
355 | |||
356 | /* | ||
357 | ** mark root set and reset all gray lists, to start a new collection | ||
358 | */ | ||
359 | static void restartcollection (global_State *g) { | ||
360 | g->gray = g->grayagain = NULL; | ||
361 | g->weak = g->allweak = g->ephemeron = NULL; | ||
362 | markobject(g, g->mainthread); | ||
363 | markvalue(g, &g->l_registry); | ||
364 | markmt(g); | ||
365 | markbeingfnz(g); /* mark any finalizing object left from previous cycle */ | ||
366 | } | ||
367 | |||
368 | /* }====================================================== */ | ||
369 | |||
370 | |||
371 | /* | ||
372 | ** {====================================================== | ||
373 | ** Traverse functions | ||
374 | ** ======================================================= | ||
375 | */ | ||
376 | |||
377 | /* | ||
378 | ** Traverse a table with weak values and link it to proper list. During | ||
379 | ** propagate phase, keep it in 'grayagain' list, to be revisited in the | ||
380 | ** atomic phase. In the atomic phase, if table has any white value, | ||
381 | ** put it in 'weak' list, to be cleared. | ||
382 | */ | ||
383 | static void traverseweakvalue (global_State *g, Table *h) { | ||
384 | Node *n, *limit = gnodelast(h); | ||
385 | /* if there is array part, assume it may have white values (it is not | ||
386 | worth traversing it now just to check) */ | ||
387 | int hasclears = (h->alimit > 0); | ||
388 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ | ||
389 | if (isempty(gval(n))) /* entry is empty? */ | ||
390 | clearkey(n); /* clear its key */ | ||
391 | else { | ||
392 | lua_assert(!keyisnil(n)); | ||
393 | markkey(g, n); | ||
394 | if (!hasclears && iscleared(g, gcvalueN(gval(n)))) /* a white value? */ | ||
395 | hasclears = 1; /* table will have to be cleared */ | ||
396 | } | ||
397 | } | ||
398 | if (g->gcstate == GCSatomic && hasclears) | ||
399 | linkgclist(h, g->weak); /* has to be cleared later */ | ||
400 | else | ||
401 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ | ||
402 | } | ||
403 | |||
404 | |||
405 | /* | ||
406 | ** Traverse an ephemeron table and link it to proper list. Returns true | ||
407 | ** iff any object was marked during this traversal (which implies that | ||
408 | ** convergence has to continue). During propagation phase, keep table | ||
409 | ** in 'grayagain' list, to be visited again in the atomic phase. In | ||
410 | ** the atomic phase, if table has any white->white entry, it has to | ||
411 | ** be revisited during ephemeron convergence (as that key may turn | ||
412 | ** black). Otherwise, if it has any white key, table has to be cleared | ||
413 | ** (in the atomic phase). In generational mode, it (like all visited | ||
414 | ** tables) must be kept in some gray list for post-processing. | ||
415 | */ | ||
416 | static int traverseephemeron (global_State *g, Table *h, int inv) { | ||
417 | int marked = 0; /* true if an object is marked in this traversal */ | ||
418 | int hasclears = 0; /* true if table has white keys */ | ||
419 | int hasww = 0; /* true if table has entry "white-key -> white-value" */ | ||
420 | unsigned int i; | ||
421 | unsigned int asize = luaH_realasize(h); | ||
422 | unsigned int nsize = sizenode(h); | ||
423 | /* traverse array part */ | ||
424 | for (i = 0; i < asize; i++) { | ||
425 | if (valiswhite(&h->array[i])) { | ||
426 | marked = 1; | ||
427 | reallymarkobject(g, gcvalue(&h->array[i])); | ||
428 | } | ||
429 | } | ||
430 | /* traverse hash part; if 'inv', traverse descending | ||
431 | (see 'convergeephemerons') */ | ||
432 | for (i = 0; i < nsize; i++) { | ||
433 | Node *n = inv ? gnode(h, nsize - 1 - i) : gnode(h, i); | ||
434 | if (isempty(gval(n))) /* entry is empty? */ | ||
435 | clearkey(n); /* clear its key */ | ||
436 | else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */ | ||
437 | hasclears = 1; /* table must be cleared */ | ||
438 | if (valiswhite(gval(n))) /* value not marked yet? */ | ||
439 | hasww = 1; /* white-white entry */ | ||
440 | } | ||
441 | else if (valiswhite(gval(n))) { /* value not marked yet? */ | ||
442 | marked = 1; | ||
443 | reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ | ||
444 | } | ||
445 | } | ||
446 | /* link table into proper list */ | ||
447 | if (g->gcstate == GCSpropagate) | ||
448 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ | ||
449 | else if (hasww) /* table has white->white entries? */ | ||
450 | linkgclist(h, g->ephemeron); /* have to propagate again */ | ||
451 | else if (hasclears) /* table has white keys? */ | ||
452 | linkgclist(h, g->allweak); /* may have to clean white keys */ | ||
453 | else if (g->gckind == KGC_GEN) | ||
454 | linkgclist(h, g->grayagain); /* keep it in some list */ | ||
455 | else | ||
456 | gray2black(h); | ||
457 | return marked; | ||
458 | } | ||
459 | |||
460 | |||
461 | static void traversestrongtable (global_State *g, Table *h) { | ||
462 | Node *n, *limit = gnodelast(h); | ||
463 | unsigned int i; | ||
464 | unsigned int asize = luaH_realasize(h); | ||
465 | for (i = 0; i < asize; i++) /* traverse array part */ | ||
466 | markvalue(g, &h->array[i]); | ||
467 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ | ||
468 | if (isempty(gval(n))) /* entry is empty? */ | ||
469 | clearkey(n); /* clear its key */ | ||
470 | else { | ||
471 | lua_assert(!keyisnil(n)); | ||
472 | markkey(g, n); | ||
473 | markvalue(g, gval(n)); | ||
474 | } | ||
475 | } | ||
476 | if (g->gckind == KGC_GEN) { | ||
477 | linkgclist(h, g->grayagain); /* keep it in some gray list */ | ||
478 | black2gray(h); | ||
479 | } | ||
480 | } | ||
481 | |||
482 | |||
483 | static lu_mem traversetable (global_State *g, Table *h) { | ||
484 | const char *weakkey, *weakvalue; | ||
485 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); | ||
486 | markobjectN(g, h->metatable); | ||
487 | if (mode && ttisstring(mode) && /* is there a weak mode? */ | ||
488 | (cast_void(weakkey = strchr(svalue(mode), 'k')), | ||
489 | cast_void(weakvalue = strchr(svalue(mode), 'v')), | ||
490 | (weakkey || weakvalue))) { /* is really weak? */ | ||
491 | black2gray(h); /* keep table gray */ | ||
492 | if (!weakkey) /* strong keys? */ | ||
493 | traverseweakvalue(g, h); | ||
494 | else if (!weakvalue) /* strong values? */ | ||
495 | traverseephemeron(g, h, 0); | ||
496 | else /* all weak */ | ||
497 | linkgclist(h, g->allweak); /* nothing to traverse now */ | ||
498 | } | ||
499 | else /* not weak */ | ||
500 | traversestrongtable(g, h); | ||
501 | return 1 + h->alimit + 2 * allocsizenode(h); | ||
502 | } | ||
503 | |||
504 | |||
505 | static int traverseudata (global_State *g, Udata *u) { | ||
506 | int i; | ||
507 | markobjectN(g, u->metatable); /* mark its metatable */ | ||
508 | for (i = 0; i < u->nuvalue; i++) | ||
509 | markvalue(g, &u->uv[i].uv); | ||
510 | if (g->gckind == KGC_GEN) { | ||
511 | linkgclist(u, g->grayagain); /* keep it in some gray list */ | ||
512 | black2gray(u); | ||
513 | } | ||
514 | return 1 + u->nuvalue; | ||
515 | } | ||
516 | |||
517 | |||
518 | /* | ||
519 | ** Traverse a prototype. (While a prototype is being build, its | ||
520 | ** arrays can be larger than needed; the extra slots are filled with | ||
521 | ** NULL, so the use of 'markobjectN') | ||
522 | */ | ||
523 | static int traverseproto (global_State *g, Proto *f) { | ||
524 | int i; | ||
525 | markobjectN(g, f->source); | ||
526 | for (i = 0; i < f->sizek; i++) /* mark literals */ | ||
527 | markvalue(g, &f->k[i]); | ||
528 | for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ | ||
529 | markobjectN(g, f->upvalues[i].name); | ||
530 | for (i = 0; i < f->sizep; i++) /* mark nested protos */ | ||
531 | markobjectN(g, f->p[i]); | ||
532 | for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ | ||
533 | markobjectN(g, f->locvars[i].varname); | ||
534 | return 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; | ||
535 | } | ||
536 | |||
537 | |||
538 | static int traverseCclosure (global_State *g, CClosure *cl) { | ||
539 | int i; | ||
540 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ | ||
541 | markvalue(g, &cl->upvalue[i]); | ||
542 | return 1 + cl->nupvalues; | ||
543 | } | ||
544 | |||
545 | /* | ||
546 | ** Traverse a Lua closure, marking its prototype and its upvalues. | ||
547 | ** (Both can be NULL while closure is being created.) | ||
548 | */ | ||
549 | static int traverseLclosure (global_State *g, LClosure *cl) { | ||
550 | int i; | ||
551 | markobjectN(g, cl->p); /* mark its prototype */ | ||
552 | for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */ | ||
553 | UpVal *uv = cl->upvals[i]; | ||
554 | markobjectN(g, uv); /* mark upvalue */ | ||
555 | } | ||
556 | return 1 + cl->nupvalues; | ||
557 | } | ||
558 | |||
559 | |||
560 | /* | ||
561 | ** Traverse a thread, marking the elements in the stack up to its top | ||
562 | ** and cleaning the rest of the stack in the final traversal. | ||
563 | ** That ensures that the entire stack have valid (non-dead) objects. | ||
564 | */ | ||
565 | static int traversethread (global_State *g, lua_State *th) { | ||
566 | UpVal *uv; | ||
567 | StkId o = th->stack; | ||
568 | if (o == NULL) | ||
569 | return 1; /* stack not completely built yet */ | ||
570 | lua_assert(g->gcstate == GCSatomic || | ||
571 | th->openupval == NULL || isintwups(th)); | ||
572 | for (; o < th->top; o++) /* mark live elements in the stack */ | ||
573 | markvalue(g, s2v(o)); | ||
574 | for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) | ||
575 | markobject(g, uv); /* open upvalues cannot be collected */ | ||
576 | if (g->gcstate == GCSatomic) { /* final traversal? */ | ||
577 | StkId lim = th->stack + th->stacksize; /* real end of stack */ | ||
578 | for (; o < lim; o++) /* clear not-marked stack slice */ | ||
579 | setnilvalue(s2v(o)); | ||
580 | /* 'remarkupvals' may have removed thread from 'twups' list */ | ||
581 | if (!isintwups(th) && th->openupval != NULL) { | ||
582 | th->twups = g->twups; /* link it back to the list */ | ||
583 | g->twups = th; | ||
584 | } | ||
585 | } | ||
586 | else if (!g->gcemergency) | ||
587 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ | ||
588 | return 1 + th->stacksize; | ||
589 | } | ||
590 | |||
591 | |||
592 | /* | ||
593 | ** traverse one gray object, turning it to black (except for threads, | ||
594 | ** which are always gray). | ||
595 | */ | ||
596 | static lu_mem propagatemark (global_State *g) { | ||
597 | GCObject *o = g->gray; | ||
598 | gray2black(o); | ||
599 | g->gray = *getgclist(o); /* remove from 'gray' list */ | ||
600 | switch (o->tt) { | ||
601 | case LUA_VTABLE: return traversetable(g, gco2t(o)); | ||
602 | case LUA_VUSERDATA: return traverseudata(g, gco2u(o)); | ||
603 | case LUA_VLCL: return traverseLclosure(g, gco2lcl(o)); | ||
604 | case LUA_VCCL: return traverseCclosure(g, gco2ccl(o)); | ||
605 | case LUA_VPROTO: return traverseproto(g, gco2p(o)); | ||
606 | case LUA_VTHREAD: { | ||
607 | lua_State *th = gco2th(o); | ||
608 | linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ | ||
609 | black2gray(o); | ||
610 | return traversethread(g, th); | ||
611 | } | ||
612 | default: lua_assert(0); return 0; | ||
613 | } | ||
614 | } | ||
615 | |||
616 | |||
617 | static lu_mem propagateall (global_State *g) { | ||
618 | lu_mem tot = 0; | ||
619 | while (g->gray) | ||
620 | tot += propagatemark(g); | ||
621 | return tot; | ||
622 | } | ||
623 | |||
624 | |||
625 | /* | ||
626 | ** Traverse all ephemeron tables propagating marks from keys to values. | ||
627 | ** Repeat until it converges, that is, nothing new is marked. 'dir' | ||
628 | ** inverts the direction of the traversals, trying to speed up | ||
629 | ** convergence on chains in the same table. | ||
630 | ** | ||
631 | */ | ||
632 | static void convergeephemerons (global_State *g) { | ||
633 | int changed; | ||
634 | int dir = 0; | ||
635 | do { | ||
636 | GCObject *w; | ||
637 | GCObject *next = g->ephemeron; /* get ephemeron list */ | ||
638 | g->ephemeron = NULL; /* tables may return to this list when traversed */ | ||
639 | changed = 0; | ||
640 | while ((w = next) != NULL) { /* for each ephemeron table */ | ||
641 | next = gco2t(w)->gclist; /* list is rebuilt during loop */ | ||
642 | if (traverseephemeron(g, gco2t(w), dir)) { /* marked some value? */ | ||
643 | propagateall(g); /* propagate changes */ | ||
644 | changed = 1; /* will have to revisit all ephemeron tables */ | ||
645 | } | ||
646 | } | ||
647 | dir = !dir; /* invert direction next time */ | ||
648 | } while (changed); /* repeat until no more changes */ | ||
649 | } | ||
650 | |||
651 | /* }====================================================== */ | ||
652 | |||
653 | |||
654 | /* | ||
655 | ** {====================================================== | ||
656 | ** Sweep Functions | ||
657 | ** ======================================================= | ||
658 | */ | ||
659 | |||
660 | |||
661 | /* | ||
662 | ** clear entries with unmarked keys from all weaktables in list 'l' | ||
663 | */ | ||
664 | static void clearbykeys (global_State *g, GCObject *l) { | ||
665 | for (; l; l = gco2t(l)->gclist) { | ||
666 | Table *h = gco2t(l); | ||
667 | Node *limit = gnodelast(h); | ||
668 | Node *n; | ||
669 | for (n = gnode(h, 0); n < limit; n++) { | ||
670 | if (iscleared(g, gckeyN(n))) /* unmarked key? */ | ||
671 | setempty(gval(n)); /* remove entry */ | ||
672 | if (isempty(gval(n))) /* is entry empty? */ | ||
673 | clearkey(n); /* clear its key */ | ||
674 | } | ||
675 | } | ||
676 | } | ||
677 | |||
678 | |||
679 | /* | ||
680 | ** clear entries with unmarked values from all weaktables in list 'l' up | ||
681 | ** to element 'f' | ||
682 | */ | ||
683 | static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { | ||
684 | for (; l != f; l = gco2t(l)->gclist) { | ||
685 | Table *h = gco2t(l); | ||
686 | Node *n, *limit = gnodelast(h); | ||
687 | unsigned int i; | ||
688 | unsigned int asize = luaH_realasize(h); | ||
689 | for (i = 0; i < asize; i++) { | ||
690 | TValue *o = &h->array[i]; | ||
691 | if (iscleared(g, gcvalueN(o))) /* value was collected? */ | ||
692 | setempty(o); /* remove entry */ | ||
693 | } | ||
694 | for (n = gnode(h, 0); n < limit; n++) { | ||
695 | if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ | ||
696 | setempty(gval(n)); /* remove entry */ | ||
697 | if (isempty(gval(n))) /* is entry empty? */ | ||
698 | clearkey(n); /* clear its key */ | ||
699 | } | ||
700 | } | ||
701 | } | ||
702 | |||
703 | |||
704 | static void freeupval (lua_State *L, UpVal *uv) { | ||
705 | if (upisopen(uv)) | ||
706 | luaF_unlinkupval(uv); | ||
707 | luaM_free(L, uv); | ||
708 | } | ||
709 | |||
710 | |||
711 | static void freeobj (lua_State *L, GCObject *o) { | ||
712 | switch (o->tt) { | ||
713 | case LUA_VPROTO: | ||
714 | luaF_freeproto(L, gco2p(o)); | ||
715 | break; | ||
716 | case LUA_VUPVAL: | ||
717 | freeupval(L, gco2upv(o)); | ||
718 | break; | ||
719 | case LUA_VLCL: | ||
720 | luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); | ||
721 | break; | ||
722 | case LUA_VCCL: | ||
723 | luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); | ||
724 | break; | ||
725 | case LUA_VTABLE: | ||
726 | luaH_free(L, gco2t(o)); | ||
727 | break; | ||
728 | case LUA_VTHREAD: | ||
729 | luaE_freethread(L, gco2th(o)); | ||
730 | break; | ||
731 | case LUA_VUSERDATA: { | ||
732 | Udata *u = gco2u(o); | ||
733 | luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); | ||
734 | break; | ||
735 | } | ||
736 | case LUA_VSHRSTR: | ||
737 | luaS_remove(L, gco2ts(o)); /* remove it from hash table */ | ||
738 | luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen)); | ||
739 | break; | ||
740 | case LUA_VLNGSTR: | ||
741 | luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen)); | ||
742 | break; | ||
743 | default: lua_assert(0); | ||
744 | } | ||
745 | } | ||
746 | |||
747 | |||
748 | /* | ||
749 | ** sweep at most 'countin' elements from a list of GCObjects erasing dead | ||
750 | ** objects, where a dead object is one marked with the old (non current) | ||
751 | ** white; change all non-dead objects back to white, preparing for next | ||
752 | ** collection cycle. Return where to continue the traversal or NULL if | ||
753 | ** list is finished. ('*countout' gets the number of elements traversed.) | ||
754 | */ | ||
755 | static GCObject **sweeplist (lua_State *L, GCObject **p, int countin, | ||
756 | int *countout) { | ||
757 | global_State *g = G(L); | ||
758 | int ow = otherwhite(g); | ||
759 | int i; | ||
760 | int white = luaC_white(g); /* current white */ | ||
761 | for (i = 0; *p != NULL && i < countin; i++) { | ||
762 | GCObject *curr = *p; | ||
763 | int marked = curr->marked; | ||
764 | if (isdeadm(ow, marked)) { /* is 'curr' dead? */ | ||
765 | *p = curr->next; /* remove 'curr' from list */ | ||
766 | freeobj(L, curr); /* erase 'curr' */ | ||
767 | } | ||
768 | else { /* change mark to 'white' */ | ||
769 | curr->marked = cast_byte((marked & maskcolors) | white); | ||
770 | p = &curr->next; /* go to next element */ | ||
771 | } | ||
772 | } | ||
773 | if (countout) | ||
774 | *countout = i; /* number of elements traversed */ | ||
775 | return (*p == NULL) ? NULL : p; | ||
776 | } | ||
777 | |||
778 | |||
779 | /* | ||
780 | ** sweep a list until a live object (or end of list) | ||
781 | */ | ||
782 | static GCObject **sweeptolive (lua_State *L, GCObject **p) { | ||
783 | GCObject **old = p; | ||
784 | do { | ||
785 | p = sweeplist(L, p, 1, NULL); | ||
786 | } while (p == old); | ||
787 | return p; | ||
788 | } | ||
789 | |||
790 | /* }====================================================== */ | ||
791 | |||
792 | |||
793 | /* | ||
794 | ** {====================================================== | ||
795 | ** Finalization | ||
796 | ** ======================================================= | ||
797 | */ | ||
798 | |||
799 | /* | ||
800 | ** If possible, shrink string table. | ||
801 | */ | ||
802 | static void checkSizes (lua_State *L, global_State *g) { | ||
803 | if (!g->gcemergency) { | ||
804 | if (g->strt.nuse < g->strt.size / 4) { /* string table too big? */ | ||
805 | l_mem olddebt = g->GCdebt; | ||
806 | luaS_resize(L, g->strt.size / 2); | ||
807 | g->GCestimate += g->GCdebt - olddebt; /* correct estimate */ | ||
808 | } | ||
809 | } | ||
810 | } | ||
811 | |||
812 | |||
813 | /* | ||
814 | ** Get the next udata to be finalized from the 'tobefnz' list, and | ||
815 | ** link it back into the 'allgc' list. | ||
816 | */ | ||
817 | static GCObject *udata2finalize (global_State *g) { | ||
818 | GCObject *o = g->tobefnz; /* get first element */ | ||
819 | lua_assert(tofinalize(o)); | ||
820 | g->tobefnz = o->next; /* remove it from 'tobefnz' list */ | ||
821 | o->next = g->allgc; /* return it to 'allgc' list */ | ||
822 | g->allgc = o; | ||
823 | resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ | ||
824 | if (issweepphase(g)) | ||
825 | makewhite(g, o); /* "sweep" object */ | ||
826 | return o; | ||
827 | } | ||
828 | |||
829 | |||
830 | static void dothecall (lua_State *L, void *ud) { | ||
831 | UNUSED(ud); | ||
832 | luaD_callnoyield(L, L->top - 2, 0); | ||
833 | } | ||
834 | |||
835 | |||
836 | static void GCTM (lua_State *L) { | ||
837 | global_State *g = G(L); | ||
838 | const TValue *tm; | ||
839 | TValue v; | ||
840 | lua_assert(!g->gcemergency); | ||
841 | setgcovalue(L, &v, udata2finalize(g)); | ||
842 | tm = luaT_gettmbyobj(L, &v, TM_GC); | ||
843 | if (!notm(tm)) { /* is there a finalizer? */ | ||
844 | int status; | ||
845 | lu_byte oldah = L->allowhook; | ||
846 | int running = g->gcrunning; | ||
847 | L->allowhook = 0; /* stop debug hooks during GC metamethod */ | ||
848 | g->gcrunning = 0; /* avoid GC steps */ | ||
849 | setobj2s(L, L->top++, tm); /* push finalizer... */ | ||
850 | setobj2s(L, L->top++, &v); /* ... and its argument */ | ||
851 | L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ | ||
852 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); | ||
853 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ | ||
854 | L->allowhook = oldah; /* restore hooks */ | ||
855 | g->gcrunning = running; /* restore state */ | ||
856 | if (unlikely(status != LUA_OK)) { /* error while running __gc? */ | ||
857 | luaE_warnerror(L, "__gc metamethod"); | ||
858 | L->top--; /* pops error object */ | ||
859 | } | ||
860 | } | ||
861 | } | ||
862 | |||
863 | |||
864 | /* | ||
865 | ** Call a few finalizers | ||
866 | */ | ||
867 | static int runafewfinalizers (lua_State *L, int n) { | ||
868 | global_State *g = G(L); | ||
869 | int i; | ||
870 | for (i = 0; i < n && g->tobefnz; i++) | ||
871 | GCTM(L); /* call one finalizer */ | ||
872 | return i; | ||
873 | } | ||
874 | |||
875 | |||
876 | /* | ||
877 | ** call all pending finalizers | ||
878 | */ | ||
879 | static void callallpendingfinalizers (lua_State *L) { | ||
880 | global_State *g = G(L); | ||
881 | while (g->tobefnz) | ||
882 | GCTM(L); | ||
883 | } | ||
884 | |||
885 | |||
886 | /* | ||
887 | ** find last 'next' field in list 'p' list (to add elements in its end) | ||
888 | */ | ||
889 | static GCObject **findlast (GCObject **p) { | ||
890 | while (*p != NULL) | ||
891 | p = &(*p)->next; | ||
892 | return p; | ||
893 | } | ||
894 | |||
895 | |||
896 | /* | ||
897 | ** Move all unreachable objects (or 'all' objects) that need | ||
898 | ** finalization from list 'finobj' to list 'tobefnz' (to be finalized). | ||
899 | ** (Note that objects after 'finobjold' cannot be white, so they | ||
900 | ** don't need to be traversed. In incremental mode, 'finobjold' is NULL, | ||
901 | ** so the whole list is traversed.) | ||
902 | */ | ||
903 | static void separatetobefnz (global_State *g, int all) { | ||
904 | GCObject *curr; | ||
905 | GCObject **p = &g->finobj; | ||
906 | GCObject **lastnext = findlast(&g->tobefnz); | ||
907 | while ((curr = *p) != g->finobjold) { /* traverse all finalizable objects */ | ||
908 | lua_assert(tofinalize(curr)); | ||
909 | if (!(iswhite(curr) || all)) /* not being collected? */ | ||
910 | p = &curr->next; /* don't bother with it */ | ||
911 | else { | ||
912 | if (curr == g->finobjsur) /* removing 'finobjsur'? */ | ||
913 | g->finobjsur = curr->next; /* correct it */ | ||
914 | *p = curr->next; /* remove 'curr' from 'finobj' list */ | ||
915 | curr->next = *lastnext; /* link at the end of 'tobefnz' list */ | ||
916 | *lastnext = curr; | ||
917 | lastnext = &curr->next; | ||
918 | } | ||
919 | } | ||
920 | } | ||
921 | |||
922 | |||
923 | /* | ||
924 | ** if object 'o' has a finalizer, remove it from 'allgc' list (must | ||
925 | ** search the list to find it) and link it in 'finobj' list. | ||
926 | */ | ||
927 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | ||
928 | global_State *g = G(L); | ||
929 | if (tofinalize(o) || /* obj. is already marked... */ | ||
930 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ | ||
931 | return; /* nothing to be done */ | ||
932 | else { /* move 'o' to 'finobj' list */ | ||
933 | GCObject **p; | ||
934 | if (issweepphase(g)) { | ||
935 | makewhite(g, o); /* "sweep" object 'o' */ | ||
936 | if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ | ||
937 | g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ | ||
938 | } | ||
939 | else { /* correct pointers into 'allgc' list, if needed */ | ||
940 | if (o == g->survival) | ||
941 | g->survival = o->next; | ||
942 | if (o == g->old) | ||
943 | g->old = o->next; | ||
944 | if (o == g->reallyold) | ||
945 | g->reallyold = o->next; | ||
946 | } | ||
947 | /* search for pointer pointing to 'o' */ | ||
948 | for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } | ||
949 | *p = o->next; /* remove 'o' from 'allgc' list */ | ||
950 | o->next = g->finobj; /* link it in 'finobj' list */ | ||
951 | g->finobj = o; | ||
952 | l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ | ||
953 | } | ||
954 | } | ||
955 | |||
956 | /* }====================================================== */ | ||
957 | |||
958 | |||
959 | /* | ||
960 | ** {====================================================== | ||
961 | ** Generational Collector | ||
962 | ** ======================================================= | ||
963 | */ | ||
964 | |||
965 | static void setpause (global_State *g); | ||
966 | |||
967 | |||
968 | /* mask to erase all color bits, not changing gen-related stuff */ | ||
969 | #define maskgencolors (~(bitmask(BLACKBIT) | WHITEBITS)) | ||
970 | |||
971 | |||
972 | /* | ||
973 | ** Sweep a list of objects, deleting dead ones and turning | ||
974 | ** the non dead to old (without changing their colors). | ||
975 | */ | ||
976 | static void sweep2old (lua_State *L, GCObject **p) { | ||
977 | GCObject *curr; | ||
978 | while ((curr = *p) != NULL) { | ||
979 | if (iswhite(curr)) { /* is 'curr' dead? */ | ||
980 | lua_assert(isdead(G(L), curr)); | ||
981 | *p = curr->next; /* remove 'curr' from list */ | ||
982 | freeobj(L, curr); /* erase 'curr' */ | ||
983 | } | ||
984 | else { /* all surviving objects become old */ | ||
985 | setage(curr, G_OLD); | ||
986 | p = &curr->next; /* go to next element */ | ||
987 | } | ||
988 | } | ||
989 | } | ||
990 | |||
991 | |||
992 | /* | ||
993 | ** Sweep for generational mode. Delete dead objects. (Because the | ||
994 | ** collection is not incremental, there are no "new white" objects | ||
995 | ** during the sweep. So, any white object must be dead.) For | ||
996 | ** non-dead objects, advance their ages and clear the color of | ||
997 | ** new objects. (Old objects keep their colors.) | ||
998 | */ | ||
999 | static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, | ||
1000 | GCObject *limit) { | ||
1001 | static const lu_byte nextage[] = { | ||
1002 | G_SURVIVAL, /* from G_NEW */ | ||
1003 | G_OLD1, /* from G_SURVIVAL */ | ||
1004 | G_OLD1, /* from G_OLD0 */ | ||
1005 | G_OLD, /* from G_OLD1 */ | ||
1006 | G_OLD, /* from G_OLD (do not change) */ | ||
1007 | G_TOUCHED1, /* from G_TOUCHED1 (do not change) */ | ||
1008 | G_TOUCHED2 /* from G_TOUCHED2 (do not change) */ | ||
1009 | }; | ||
1010 | int white = luaC_white(g); | ||
1011 | GCObject *curr; | ||
1012 | while ((curr = *p) != limit) { | ||
1013 | if (iswhite(curr)) { /* is 'curr' dead? */ | ||
1014 | lua_assert(!isold(curr) && isdead(g, curr)); | ||
1015 | *p = curr->next; /* remove 'curr' from list */ | ||
1016 | freeobj(L, curr); /* erase 'curr' */ | ||
1017 | } | ||
1018 | else { /* correct mark and age */ | ||
1019 | if (getage(curr) == G_NEW) | ||
1020 | curr->marked = cast_byte((curr->marked & maskgencolors) | white); | ||
1021 | setage(curr, nextage[getage(curr)]); | ||
1022 | p = &curr->next; /* go to next element */ | ||
1023 | } | ||
1024 | } | ||
1025 | return p; | ||
1026 | } | ||
1027 | |||
1028 | |||
1029 | /* | ||
1030 | ** Traverse a list making all its elements white and clearing their | ||
1031 | ** age. | ||
1032 | */ | ||
1033 | static void whitelist (global_State *g, GCObject *p) { | ||
1034 | int white = luaC_white(g); | ||
1035 | for (; p != NULL; p = p->next) | ||
1036 | p->marked = cast_byte((p->marked & maskcolors) | white); | ||
1037 | } | ||
1038 | |||
1039 | |||
1040 | /* | ||
1041 | ** Correct a list of gray objects. | ||
1042 | ** Because this correction is done after sweeping, young objects might | ||
1043 | ** be turned white and still be in the list. They are only removed. | ||
1044 | ** For tables and userdata, advance 'touched1' to 'touched2'; 'touched2' | ||
1045 | ** objects become regular old and are removed from the list. | ||
1046 | ** For threads, just remove white ones from the list. | ||
1047 | */ | ||
1048 | static GCObject **correctgraylist (GCObject **p) { | ||
1049 | GCObject *curr; | ||
1050 | while ((curr = *p) != NULL) { | ||
1051 | switch (curr->tt) { | ||
1052 | case LUA_VTABLE: case LUA_VUSERDATA: { | ||
1053 | GCObject **next = getgclist(curr); | ||
1054 | if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ | ||
1055 | lua_assert(isgray(curr)); | ||
1056 | gray2black(curr); /* make it black, for next barrier */ | ||
1057 | changeage(curr, G_TOUCHED1, G_TOUCHED2); | ||
1058 | p = next; /* go to next element */ | ||
1059 | } | ||
1060 | else { /* not touched in this cycle */ | ||
1061 | if (!iswhite(curr)) { /* not white? */ | ||
1062 | lua_assert(isold(curr)); | ||
1063 | if (getage(curr) == G_TOUCHED2) /* advance from G_TOUCHED2... */ | ||
1064 | changeage(curr, G_TOUCHED2, G_OLD); /* ... to G_OLD */ | ||
1065 | gray2black(curr); /* make it black */ | ||
1066 | } | ||
1067 | /* else, object is white: just remove it from this list */ | ||
1068 | *p = *next; /* remove 'curr' from gray list */ | ||
1069 | } | ||
1070 | break; | ||
1071 | } | ||
1072 | case LUA_VTHREAD: { | ||
1073 | lua_State *th = gco2th(curr); | ||
1074 | lua_assert(!isblack(th)); | ||
1075 | if (iswhite(th)) /* new object? */ | ||
1076 | *p = th->gclist; /* remove from gray list */ | ||
1077 | else /* old threads remain gray */ | ||
1078 | p = &th->gclist; /* go to next element */ | ||
1079 | break; | ||
1080 | } | ||
1081 | default: lua_assert(0); /* nothing more could be gray here */ | ||
1082 | } | ||
1083 | } | ||
1084 | return p; | ||
1085 | } | ||
1086 | |||
1087 | |||
1088 | /* | ||
1089 | ** Correct all gray lists, coalescing them into 'grayagain'. | ||
1090 | */ | ||
1091 | static void correctgraylists (global_State *g) { | ||
1092 | GCObject **list = correctgraylist(&g->grayagain); | ||
1093 | *list = g->weak; g->weak = NULL; | ||
1094 | list = correctgraylist(list); | ||
1095 | *list = g->allweak; g->allweak = NULL; | ||
1096 | list = correctgraylist(list); | ||
1097 | *list = g->ephemeron; g->ephemeron = NULL; | ||
1098 | correctgraylist(list); | ||
1099 | } | ||
1100 | |||
1101 | |||
1102 | /* | ||
1103 | ** Mark 'OLD1' objects when starting a new young collection. | ||
1104 | ** Gray objects are already in some gray list, and so will be visited | ||
1105 | ** in the atomic step. | ||
1106 | */ | ||
1107 | static void markold (global_State *g, GCObject *from, GCObject *to) { | ||
1108 | GCObject *p; | ||
1109 | for (p = from; p != to; p = p->next) { | ||
1110 | if (getage(p) == G_OLD1) { | ||
1111 | lua_assert(!iswhite(p)); | ||
1112 | if (isblack(p)) { | ||
1113 | black2gray(p); /* should be '2white', but gray works too */ | ||
1114 | reallymarkobject(g, p); | ||
1115 | } | ||
1116 | } | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | |||
1121 | /* | ||
1122 | ** Finish a young-generation collection. | ||
1123 | */ | ||
1124 | static void finishgencycle (lua_State *L, global_State *g) { | ||
1125 | correctgraylists(g); | ||
1126 | checkSizes(L, g); | ||
1127 | g->gcstate = GCSpropagate; /* skip restart */ | ||
1128 | if (!g->gcemergency) | ||
1129 | callallpendingfinalizers(L); | ||
1130 | } | ||
1131 | |||
1132 | |||
1133 | /* | ||
1134 | ** Does a young collection. First, mark 'OLD1' objects. (Only survival | ||
1135 | ** and "recent old" lists can contain 'OLD1' objects. New lists cannot | ||
1136 | ** contain 'OLD1' objects, at most 'OLD0' objects that were already | ||
1137 | ** visited when marked old.) Then does the atomic step. Then, | ||
1138 | ** sweep all lists and advance pointers. Finally, finish the collection. | ||
1139 | */ | ||
1140 | static void youngcollection (lua_State *L, global_State *g) { | ||
1141 | GCObject **psurvival; /* to point to first non-dead survival object */ | ||
1142 | lua_assert(g->gcstate == GCSpropagate); | ||
1143 | markold(g, g->survival, g->reallyold); | ||
1144 | markold(g, g->finobj, g->finobjrold); | ||
1145 | atomic(L); | ||
1146 | |||
1147 | /* sweep nursery and get a pointer to its last live element */ | ||
1148 | psurvival = sweepgen(L, g, &g->allgc, g->survival); | ||
1149 | /* sweep 'survival' and 'old' */ | ||
1150 | sweepgen(L, g, psurvival, g->reallyold); | ||
1151 | g->reallyold = g->old; | ||
1152 | g->old = *psurvival; /* 'survival' survivals are old now */ | ||
1153 | g->survival = g->allgc; /* all news are survivals */ | ||
1154 | |||
1155 | /* repeat for 'finobj' lists */ | ||
1156 | psurvival = sweepgen(L, g, &g->finobj, g->finobjsur); | ||
1157 | /* sweep 'survival' and 'old' */ | ||
1158 | sweepgen(L, g, psurvival, g->finobjrold); | ||
1159 | g->finobjrold = g->finobjold; | ||
1160 | g->finobjold = *psurvival; /* 'survival' survivals are old now */ | ||
1161 | g->finobjsur = g->finobj; /* all news are survivals */ | ||
1162 | |||
1163 | sweepgen(L, g, &g->tobefnz, NULL); | ||
1164 | |||
1165 | finishgencycle(L, g); | ||
1166 | } | ||
1167 | |||
1168 | |||
1169 | static void atomic2gen (lua_State *L, global_State *g) { | ||
1170 | /* sweep all elements making them old */ | ||
1171 | sweep2old(L, &g->allgc); | ||
1172 | /* everything alive now is old */ | ||
1173 | g->reallyold = g->old = g->survival = g->allgc; | ||
1174 | |||
1175 | /* repeat for 'finobj' lists */ | ||
1176 | sweep2old(L, &g->finobj); | ||
1177 | g->finobjrold = g->finobjold = g->finobjsur = g->finobj; | ||
1178 | |||
1179 | sweep2old(L, &g->tobefnz); | ||
1180 | |||
1181 | g->gckind = KGC_GEN; | ||
1182 | g->lastatomic = 0; | ||
1183 | g->GCestimate = gettotalbytes(g); /* base for memory control */ | ||
1184 | finishgencycle(L, g); | ||
1185 | } | ||
1186 | |||
1187 | |||
1188 | /* | ||
1189 | ** Enter generational mode. Must go until the end of an atomic cycle | ||
1190 | ** to ensure that all threads and weak tables are in the gray lists. | ||
1191 | ** Then, turn all objects into old and finishes the collection. | ||
1192 | */ | ||
1193 | static lu_mem entergen (lua_State *L, global_State *g) { | ||
1194 | lu_mem numobjs; | ||
1195 | luaC_runtilstate(L, bitmask(GCSpause)); /* prepare to start a new cycle */ | ||
1196 | luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ | ||
1197 | numobjs = atomic(L); /* propagates all and then do the atomic stuff */ | ||
1198 | atomic2gen(L, g); | ||
1199 | return numobjs; | ||
1200 | } | ||
1201 | |||
1202 | |||
1203 | /* | ||
1204 | ** Enter incremental mode. Turn all objects white, make all | ||
1205 | ** intermediate lists point to NULL (to avoid invalid pointers), | ||
1206 | ** and go to the pause state. | ||
1207 | */ | ||
1208 | static void enterinc (global_State *g) { | ||
1209 | whitelist(g, g->allgc); | ||
1210 | g->reallyold = g->old = g->survival = NULL; | ||
1211 | whitelist(g, g->finobj); | ||
1212 | whitelist(g, g->tobefnz); | ||
1213 | g->finobjrold = g->finobjold = g->finobjsur = NULL; | ||
1214 | g->gcstate = GCSpause; | ||
1215 | g->gckind = KGC_INC; | ||
1216 | g->lastatomic = 0; | ||
1217 | } | ||
1218 | |||
1219 | |||
1220 | /* | ||
1221 | ** Change collector mode to 'newmode'. | ||
1222 | */ | ||
1223 | void luaC_changemode (lua_State *L, int newmode) { | ||
1224 | global_State *g = G(L); | ||
1225 | if (newmode != g->gckind) { | ||
1226 | if (newmode == KGC_GEN) /* entering generational mode? */ | ||
1227 | entergen(L, g); | ||
1228 | else | ||
1229 | enterinc(g); /* entering incremental mode */ | ||
1230 | } | ||
1231 | g->lastatomic = 0; | ||
1232 | } | ||
1233 | |||
1234 | |||
1235 | /* | ||
1236 | ** Does a full collection in generational mode. | ||
1237 | */ | ||
1238 | static lu_mem fullgen (lua_State *L, global_State *g) { | ||
1239 | enterinc(g); | ||
1240 | return entergen(L, g); | ||
1241 | } | ||
1242 | |||
1243 | |||
1244 | /* | ||
1245 | ** Set debt for the next minor collection, which will happen when | ||
1246 | ** memory grows 'genminormul'%. | ||
1247 | */ | ||
1248 | static void setminordebt (global_State *g) { | ||
1249 | luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul)); | ||
1250 | } | ||
1251 | |||
1252 | |||
1253 | /* | ||
1254 | ** Does a major collection after last collection was a "bad collection". | ||
1255 | ** | ||
1256 | ** When the program is building a big structure, it allocates lots of | ||
1257 | ** memory but generates very little garbage. In those scenarios, | ||
1258 | ** the generational mode just wastes time doing small collections, and | ||
1259 | ** major collections are frequently what we call a "bad collection", a | ||
1260 | ** collection that frees too few objects. To avoid the cost of switching | ||
1261 | ** between generational mode and the incremental mode needed for full | ||
1262 | ** (major) collections, the collector tries to stay in incremental mode | ||
1263 | ** after a bad collection, and to switch back to generational mode only | ||
1264 | ** after a "good" collection (one that traverses less than 9/8 objects | ||
1265 | ** of the previous one). | ||
1266 | ** The collector must choose whether to stay in incremental mode or to | ||
1267 | ** switch back to generational mode before sweeping. At this point, it | ||
1268 | ** does not know the real memory in use, so it cannot use memory to | ||
1269 | ** decide whether to return to generational mode. Instead, it uses the | ||
1270 | ** number of objects traversed (returned by 'atomic') as a proxy. The | ||
1271 | ** field 'g->lastatomic' keeps this count from the last collection. | ||
1272 | ** ('g->lastatomic != 0' also means that the last collection was bad.) | ||
1273 | */ | ||
1274 | static void stepgenfull (lua_State *L, global_State *g) { | ||
1275 | lu_mem newatomic; /* count of traversed objects */ | ||
1276 | lu_mem lastatomic = g->lastatomic; /* count from last collection */ | ||
1277 | if (g->gckind == KGC_GEN) /* still in generational mode? */ | ||
1278 | enterinc(g); /* enter incremental mode */ | ||
1279 | luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ | ||
1280 | newatomic = atomic(L); /* mark everybody */ | ||
1281 | if (newatomic < lastatomic + (lastatomic >> 3)) { /* good collection? */ | ||
1282 | atomic2gen(L, g); /* return to generational mode */ | ||
1283 | setminordebt(g); | ||
1284 | } | ||
1285 | else { /* another bad collection; stay in incremental mode */ | ||
1286 | g->GCestimate = gettotalbytes(g); /* first estimate */; | ||
1287 | entersweep(L); | ||
1288 | luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ | ||
1289 | setpause(g); | ||
1290 | g->lastatomic = newatomic; | ||
1291 | } | ||
1292 | } | ||
1293 | |||
1294 | |||
1295 | /* | ||
1296 | ** Does a generational "step". | ||
1297 | ** Usually, this means doing a minor collection and setting the debt to | ||
1298 | ** make another collection when memory grows 'genminormul'% larger. | ||
1299 | ** | ||
1300 | ** However, there are exceptions. If memory grows 'genmajormul'% | ||
1301 | ** larger than it was at the end of the last major collection (kept | ||
1302 | ** in 'g->GCestimate'), the function does a major collection. At the | ||
1303 | ** end, it checks whether the major collection was able to free a | ||
1304 | ** decent amount of memory (at least half the growth in memory since | ||
1305 | ** previous major collection). If so, the collector keeps its state, | ||
1306 | ** and the next collection will probably be minor again. Otherwise, | ||
1307 | ** we have what we call a "bad collection". In that case, set the field | ||
1308 | ** 'g->lastatomic' to signal that fact, so that the next collection will | ||
1309 | ** go to 'stepgenfull'. | ||
1310 | ** | ||
1311 | ** 'GCdebt <= 0' means an explicit call to GC step with "size" zero; | ||
1312 | ** in that case, do a minor collection. | ||
1313 | */ | ||
1314 | static void genstep (lua_State *L, global_State *g) { | ||
1315 | if (g->lastatomic != 0) /* last collection was a bad one? */ | ||
1316 | stepgenfull(L, g); /* do a full step */ | ||
1317 | else { | ||
1318 | lu_mem majorbase = g->GCestimate; /* memory after last major collection */ | ||
1319 | lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); | ||
1320 | if (g->GCdebt > 0 && gettotalbytes(g) > majorbase + majorinc) { | ||
1321 | lu_mem numobjs = fullgen(L, g); /* do a major collection */ | ||
1322 | if (gettotalbytes(g) < majorbase + (majorinc / 2)) { | ||
1323 | /* collected at least half of memory growth since last major | ||
1324 | collection; keep doing minor collections */ | ||
1325 | setminordebt(g); | ||
1326 | } | ||
1327 | else { /* bad collection */ | ||
1328 | g->lastatomic = numobjs; /* signal that last collection was bad */ | ||
1329 | setpause(g); /* do a long wait for next (major) collection */ | ||
1330 | } | ||
1331 | } | ||
1332 | else { /* regular case; do a minor collection */ | ||
1333 | youngcollection(L, g); | ||
1334 | setminordebt(g); | ||
1335 | g->GCestimate = majorbase; /* preserve base value */ | ||
1336 | } | ||
1337 | } | ||
1338 | lua_assert(isdecGCmodegen(g)); | ||
1339 | } | ||
1340 | |||
1341 | /* }====================================================== */ | ||
1342 | |||
1343 | |||
1344 | /* | ||
1345 | ** {====================================================== | ||
1346 | ** GC control | ||
1347 | ** ======================================================= | ||
1348 | */ | ||
1349 | |||
1350 | |||
1351 | /* | ||
1352 | ** Set the "time" to wait before starting a new GC cycle; cycle will | ||
1353 | ** start when memory use hits the threshold of ('estimate' * pause / | ||
1354 | ** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero, | ||
1355 | ** because Lua cannot even start with less than PAUSEADJ bytes). | ||
1356 | */ | ||
1357 | static void setpause (global_State *g) { | ||
1358 | l_mem threshold, debt; | ||
1359 | int pause = getgcparam(g->gcpause); | ||
1360 | l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ | ||
1361 | lua_assert(estimate > 0); | ||
1362 | threshold = (pause < MAX_LMEM / estimate) /* overflow? */ | ||
1363 | ? estimate * pause /* no overflow */ | ||
1364 | : MAX_LMEM; /* overflow; truncate to maximum */ | ||
1365 | debt = gettotalbytes(g) - threshold; | ||
1366 | if (debt > 0) debt = 0; | ||
1367 | luaE_setdebt(g, debt); | ||
1368 | } | ||
1369 | |||
1370 | |||
1371 | /* | ||
1372 | ** Enter first sweep phase. | ||
1373 | ** The call to 'sweeptolive' makes the pointer point to an object | ||
1374 | ** inside the list (instead of to the header), so that the real sweep do | ||
1375 | ** not need to skip objects created between "now" and the start of the | ||
1376 | ** real sweep. | ||
1377 | */ | ||
1378 | static void entersweep (lua_State *L) { | ||
1379 | global_State *g = G(L); | ||
1380 | g->gcstate = GCSswpallgc; | ||
1381 | lua_assert(g->sweepgc == NULL); | ||
1382 | g->sweepgc = sweeptolive(L, &g->allgc); | ||
1383 | } | ||
1384 | |||
1385 | |||
1386 | /* | ||
1387 | ** Delete all objects in list 'p' until (but not including) object | ||
1388 | ** 'limit'. | ||
1389 | */ | ||
1390 | static void deletelist (lua_State *L, GCObject *p, GCObject *limit) { | ||
1391 | while (p != limit) { | ||
1392 | GCObject *next = p->next; | ||
1393 | freeobj(L, p); | ||
1394 | p = next; | ||
1395 | } | ||
1396 | } | ||
1397 | |||
1398 | |||
1399 | /* | ||
1400 | ** Call all finalizers of the objects in the given Lua state, and | ||
1401 | ** then free all objects, except for the main thread. | ||
1402 | */ | ||
1403 | void luaC_freeallobjects (lua_State *L) { | ||
1404 | global_State *g = G(L); | ||
1405 | luaC_changemode(L, KGC_INC); | ||
1406 | separatetobefnz(g, 1); /* separate all objects with finalizers */ | ||
1407 | lua_assert(g->finobj == NULL); | ||
1408 | callallpendingfinalizers(L); | ||
1409 | deletelist(L, g->allgc, obj2gco(g->mainthread)); | ||
1410 | deletelist(L, g->finobj, NULL); | ||
1411 | deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ | ||
1412 | lua_assert(g->strt.nuse == 0); | ||
1413 | } | ||
1414 | |||
1415 | |||
1416 | static lu_mem atomic (lua_State *L) { | ||
1417 | global_State *g = G(L); | ||
1418 | lu_mem work = 0; | ||
1419 | GCObject *origweak, *origall; | ||
1420 | GCObject *grayagain = g->grayagain; /* save original list */ | ||
1421 | g->grayagain = NULL; | ||
1422 | lua_assert(g->ephemeron == NULL && g->weak == NULL); | ||
1423 | lua_assert(!iswhite(g->mainthread)); | ||
1424 | g->gcstate = GCSatomic; | ||
1425 | markobject(g, L); /* mark running thread */ | ||
1426 | /* registry and global metatables may be changed by API */ | ||
1427 | markvalue(g, &g->l_registry); | ||
1428 | markmt(g); /* mark global metatables */ | ||
1429 | work += propagateall(g); /* empties 'gray' list */ | ||
1430 | /* remark occasional upvalues of (maybe) dead threads */ | ||
1431 | work += remarkupvals(g); | ||
1432 | work += propagateall(g); /* propagate changes */ | ||
1433 | g->gray = grayagain; | ||
1434 | work += propagateall(g); /* traverse 'grayagain' list */ | ||
1435 | convergeephemerons(g); | ||
1436 | /* at this point, all strongly accessible objects are marked. */ | ||
1437 | /* Clear values from weak tables, before checking finalizers */ | ||
1438 | clearbyvalues(g, g->weak, NULL); | ||
1439 | clearbyvalues(g, g->allweak, NULL); | ||
1440 | origweak = g->weak; origall = g->allweak; | ||
1441 | separatetobefnz(g, 0); /* separate objects to be finalized */ | ||
1442 | work += markbeingfnz(g); /* mark objects that will be finalized */ | ||
1443 | work += propagateall(g); /* remark, to propagate 'resurrection' */ | ||
1444 | convergeephemerons(g); | ||
1445 | /* at this point, all resurrected objects are marked. */ | ||
1446 | /* remove dead objects from weak tables */ | ||
1447 | clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ | ||
1448 | clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */ | ||
1449 | /* clear values from resurrected weak tables */ | ||
1450 | clearbyvalues(g, g->weak, origweak); | ||
1451 | clearbyvalues(g, g->allweak, origall); | ||
1452 | luaS_clearcache(g); | ||
1453 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | ||
1454 | lua_assert(g->gray == NULL); | ||
1455 | return work; /* estimate of slots marked by 'atomic' */ | ||
1456 | } | ||
1457 | |||
1458 | |||
1459 | static int sweepstep (lua_State *L, global_State *g, | ||
1460 | int nextstate, GCObject **nextlist) { | ||
1461 | if (g->sweepgc) { | ||
1462 | l_mem olddebt = g->GCdebt; | ||
1463 | int count; | ||
1464 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX, &count); | ||
1465 | g->GCestimate += g->GCdebt - olddebt; /* update estimate */ | ||
1466 | return count; | ||
1467 | } | ||
1468 | else { /* enter next state */ | ||
1469 | g->gcstate = nextstate; | ||
1470 | g->sweepgc = nextlist; | ||
1471 | return 0; /* no work done */ | ||
1472 | } | ||
1473 | } | ||
1474 | |||
1475 | |||
1476 | static lu_mem singlestep (lua_State *L) { | ||
1477 | global_State *g = G(L); | ||
1478 | switch (g->gcstate) { | ||
1479 | case GCSpause: { | ||
1480 | restartcollection(g); | ||
1481 | g->gcstate = GCSpropagate; | ||
1482 | return 1; | ||
1483 | } | ||
1484 | case GCSpropagate: { | ||
1485 | if (g->gray == NULL) { /* no more gray objects? */ | ||
1486 | g->gcstate = GCSenteratomic; /* finish propagate phase */ | ||
1487 | return 0; | ||
1488 | } | ||
1489 | else | ||
1490 | return propagatemark(g); /* traverse one gray object */ | ||
1491 | } | ||
1492 | case GCSenteratomic: { | ||
1493 | lu_mem work = atomic(L); /* work is what was traversed by 'atomic' */ | ||
1494 | entersweep(L); | ||
1495 | g->GCestimate = gettotalbytes(g); /* first estimate */; | ||
1496 | return work; | ||
1497 | } | ||
1498 | case GCSswpallgc: { /* sweep "regular" objects */ | ||
1499 | return sweepstep(L, g, GCSswpfinobj, &g->finobj); | ||
1500 | } | ||
1501 | case GCSswpfinobj: { /* sweep objects with finalizers */ | ||
1502 | return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); | ||
1503 | } | ||
1504 | case GCSswptobefnz: { /* sweep objects to be finalized */ | ||
1505 | return sweepstep(L, g, GCSswpend, NULL); | ||
1506 | } | ||
1507 | case GCSswpend: { /* finish sweeps */ | ||
1508 | checkSizes(L, g); | ||
1509 | g->gcstate = GCScallfin; | ||
1510 | return 0; | ||
1511 | } | ||
1512 | case GCScallfin: { /* call remaining finalizers */ | ||
1513 | if (g->tobefnz && !g->gcemergency) { | ||
1514 | int n = runafewfinalizers(L, GCFINMAX); | ||
1515 | return n * GCFINALIZECOST; | ||
1516 | } | ||
1517 | else { /* emergency mode or no more finalizers */ | ||
1518 | g->gcstate = GCSpause; /* finish collection */ | ||
1519 | return 0; | ||
1520 | } | ||
1521 | } | ||
1522 | default: lua_assert(0); return 0; | ||
1523 | } | ||
1524 | } | ||
1525 | |||
1526 | |||
1527 | /* | ||
1528 | ** advances the garbage collector until it reaches a state allowed | ||
1529 | ** by 'statemask' | ||
1530 | */ | ||
1531 | void luaC_runtilstate (lua_State *L, int statesmask) { | ||
1532 | global_State *g = G(L); | ||
1533 | while (!testbit(statesmask, g->gcstate)) | ||
1534 | singlestep(L); | ||
1535 | } | ||
1536 | |||
1537 | |||
1538 | /* | ||
1539 | ** Performs a basic incremental step. The debt and step size are | ||
1540 | ** converted from bytes to "units of work"; then the function loops | ||
1541 | ** running single steps until adding that many units of work or | ||
1542 | ** finishing a cycle (pause state). Finally, it sets the debt that | ||
1543 | ** controls when next step will be performed. | ||
1544 | */ | ||
1545 | static void incstep (lua_State *L, global_State *g) { | ||
1546 | int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */ | ||
1547 | l_mem debt = (g->GCdebt / WORK2MEM) * stepmul; | ||
1548 | l_mem stepsize = (g->gcstepsize <= log2maxs(l_mem)) | ||
1549 | ? ((cast(l_mem, 1) << g->gcstepsize) / WORK2MEM) * stepmul | ||
1550 | : MAX_LMEM; /* overflow; keep maximum value */ | ||
1551 | do { /* repeat until pause or enough "credit" (negative debt) */ | ||
1552 | lu_mem work = singlestep(L); /* perform one single step */ | ||
1553 | debt -= work; | ||
1554 | } while (debt > -stepsize && g->gcstate != GCSpause); | ||
1555 | if (g->gcstate == GCSpause) | ||
1556 | setpause(g); /* pause until next cycle */ | ||
1557 | else { | ||
1558 | debt = (debt / stepmul) * WORK2MEM; /* convert 'work units' to bytes */ | ||
1559 | luaE_setdebt(g, debt); | ||
1560 | } | ||
1561 | } | ||
1562 | |||
1563 | /* | ||
1564 | ** performs a basic GC step if collector is running | ||
1565 | */ | ||
1566 | void luaC_step (lua_State *L) { | ||
1567 | global_State *g = G(L); | ||
1568 | lua_assert(!g->gcemergency); | ||
1569 | if (g->gcrunning) { /* running? */ | ||
1570 | if(isdecGCmodegen(g)) | ||
1571 | genstep(L, g); | ||
1572 | else | ||
1573 | incstep(L, g); | ||
1574 | } | ||
1575 | } | ||
1576 | |||
1577 | |||
1578 | /* | ||
1579 | ** Perform a full collection in incremental mode. | ||
1580 | ** Before running the collection, check 'keepinvariant'; if it is true, | ||
1581 | ** there may be some objects marked as black, so the collector has | ||
1582 | ** to sweep all objects to turn them back to white (as white has not | ||
1583 | ** changed, nothing will be collected). | ||
1584 | */ | ||
1585 | static void fullinc (lua_State *L, global_State *g) { | ||
1586 | if (keepinvariant(g)) /* black objects? */ | ||
1587 | entersweep(L); /* sweep everything to turn them back to white */ | ||
1588 | /* finish any pending sweep phase to start a new cycle */ | ||
1589 | luaC_runtilstate(L, bitmask(GCSpause)); | ||
1590 | luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ | ||
1591 | /* estimate must be correct after a full GC cycle */ | ||
1592 | lua_assert(g->GCestimate == gettotalbytes(g)); | ||
1593 | luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ | ||
1594 | setpause(g); | ||
1595 | } | ||
1596 | |||
1597 | |||
1598 | /* | ||
1599 | ** Performs a full GC cycle; if 'isemergency', set a flag to avoid | ||
1600 | ** some operations which could change the interpreter state in some | ||
1601 | ** unexpected ways (running finalizers and shrinking some structures). | ||
1602 | */ | ||
1603 | void luaC_fullgc (lua_State *L, int isemergency) { | ||
1604 | global_State *g = G(L); | ||
1605 | lua_assert(!g->gcemergency); | ||
1606 | g->gcemergency = isemergency; /* set flag */ | ||
1607 | if (g->gckind == KGC_INC) | ||
1608 | fullinc(L, g); | ||
1609 | else | ||
1610 | fullgen(L, g); | ||
1611 | g->gcemergency = 0; | ||
1612 | } | ||
1613 | |||
1614 | /* }====================================================== */ | ||
1615 | |||
1616 | |||
diff --git a/src/lua-5.3/lgc.h b/src/lua/lgc.h index 425cd7c..b972472 100644 --- a/src/lua-5.3/lgc.h +++ b/src/lua/lgc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $ | 2 | ** $Id: lgc.h $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -25,25 +25,18 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | 27 | ||
28 | |||
29 | /* how much to allocate before next GC step */ | ||
30 | #if !defined(GCSTEPSIZE) | ||
31 | /* ~100 small strings */ | ||
32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) | ||
33 | #endif | ||
34 | |||
35 | |||
36 | /* | 28 | /* |
37 | ** Possible states of the Garbage Collector | 29 | ** Possible states of the Garbage Collector |
38 | */ | 30 | */ |
39 | #define GCSpropagate 0 | 31 | #define GCSpropagate 0 |
40 | #define GCSatomic 1 | 32 | #define GCSenteratomic 1 |
41 | #define GCSswpallgc 2 | 33 | #define GCSatomic 2 |
42 | #define GCSswpfinobj 3 | 34 | #define GCSswpallgc 3 |
43 | #define GCSswptobefnz 4 | 35 | #define GCSswpfinobj 4 |
44 | #define GCSswpend 5 | 36 | #define GCSswptobefnz 5 |
45 | #define GCScallfin 6 | 37 | #define GCSswpend 6 |
46 | #define GCSpause 7 | 38 | #define GCScallfin 7 |
39 | #define GCSpause 8 | ||
47 | 40 | ||
48 | 41 | ||
49 | #define issweepphase(g) \ | 42 | #define issweepphase(g) \ |
@@ -64,7 +57,7 @@ | |||
64 | /* | 57 | /* |
65 | ** some useful bit tricks | 58 | ** some useful bit tricks |
66 | */ | 59 | */ |
67 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) | 60 | #define resetbits(x,m) ((x) &= cast_byte(~(m))) |
68 | #define setbits(x,m) ((x) |= (m)) | 61 | #define setbits(x,m) ((x) |= (m)) |
69 | #define testbits(x,m) ((x) & (m)) | 62 | #define testbits(x,m) ((x) & (m)) |
70 | #define bitmask(b) (1<<(b)) | 63 | #define bitmask(b) (1<<(b)) |
@@ -74,12 +67,17 @@ | |||
74 | #define testbit(x,b) testbits(x, bitmask(b)) | 67 | #define testbit(x,b) testbits(x, bitmask(b)) |
75 | 68 | ||
76 | 69 | ||
77 | /* Layout for bit use in 'marked' field: */ | 70 | /* |
78 | #define WHITE0BIT 0 /* object is white (type 0) */ | 71 | ** Layout for bit use in 'marked' field. First three bits are |
79 | #define WHITE1BIT 1 /* object is white (type 1) */ | 72 | ** used for object "age" in generational mode. Last bit is free |
80 | #define BLACKBIT 2 /* object is black */ | 73 | ** to be used by respective objects. |
81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ | 74 | */ |
82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ | 75 | #define WHITE0BIT 3 /* object is white (type 0) */ |
76 | #define WHITE1BIT 4 /* object is white (type 1) */ | ||
77 | #define BLACKBIT 5 /* object is black */ | ||
78 | #define FINALIZEDBIT 6 /* object has been marked for finalization */ | ||
79 | |||
80 | |||
83 | 81 | ||
84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | 82 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
85 | 83 | ||
@@ -92,15 +90,61 @@ | |||
92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) | 90 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) |
93 | 91 | ||
94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) | 92 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) |
95 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) | 93 | #define isdeadm(ow,m) ((m) & (ow)) |
96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) | 94 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) |
97 | 95 | ||
98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) | 96 | #define changewhite(x) ((x)->marked ^= WHITEBITS) |
99 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) | 97 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) |
100 | 98 | ||
101 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | 99 | #define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) |
100 | |||
101 | |||
102 | /* object age in generational mode */ | ||
103 | #define G_NEW 0 /* created in current cycle */ | ||
104 | #define G_SURVIVAL 1 /* created in previous cycle */ | ||
105 | #define G_OLD0 2 /* marked old by frw. barrier in this cycle */ | ||
106 | #define G_OLD1 3 /* first full cycle as old */ | ||
107 | #define G_OLD 4 /* really old object (not to be visited) */ | ||
108 | #define G_TOUCHED1 5 /* old object touched this cycle */ | ||
109 | #define G_TOUCHED2 6 /* old object touched in previous cycle */ | ||
110 | |||
111 | #define AGEBITS 7 /* all age bits (111) */ | ||
112 | |||
113 | #define getage(o) ((o)->marked & AGEBITS) | ||
114 | #define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) | ||
115 | #define isold(o) (getage(o) > G_SURVIVAL) | ||
116 | |||
117 | #define changeage(o,f,t) \ | ||
118 | check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) | ||
102 | 119 | ||
103 | 120 | ||
121 | /* Default Values for GC parameters */ | ||
122 | #define LUAI_GENMAJORMUL 100 | ||
123 | #define LUAI_GENMINORMUL 20 | ||
124 | |||
125 | /* wait memory to double before starting new cycle */ | ||
126 | #define LUAI_GCPAUSE 200 | ||
127 | |||
128 | /* | ||
129 | ** some gc parameters are stored divided by 4 to allow a maximum value | ||
130 | ** up to 1023 in a 'lu_byte'. | ||
131 | */ | ||
132 | #define getgcparam(p) ((p) * 4) | ||
133 | #define setgcparam(p,v) ((p) = (v) / 4) | ||
134 | |||
135 | #define LUAI_GCMUL 100 | ||
136 | |||
137 | /* how much to allocate before next GC step (log2) */ | ||
138 | #define LUAI_GCSTEPSIZE 13 /* 8 KB */ | ||
139 | |||
140 | |||
141 | /* | ||
142 | ** Check whether the declared GC mode is generational. While in | ||
143 | ** generational mode, the collector can go temporarily to incremental | ||
144 | ** mode to improve performance. This is signaled by 'g->lastatomic != 0'. | ||
145 | */ | ||
146 | #define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) | ||
147 | |||
104 | /* | 148 | /* |
105 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' | 149 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' |
106 | ** allows some adjustments to be done only when needed. macro | 150 | ** allows some adjustments to be done only when needed. macro |
@@ -127,10 +171,6 @@ | |||
127 | (isblack(p) && iswhite(o)) ? \ | 171 | (isblack(p) && iswhite(o)) ? \ |
128 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) | 172 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) |
129 | 173 | ||
130 | #define luaC_upvalbarrier(L,uv) ( \ | ||
131 | (iscollectable((uv)->v) && !upisopen(uv)) ? \ | ||
132 | luaC_upvalbarrier_(L,uv) : cast_void(0)) | ||
133 | |||
134 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); | 174 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); |
135 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); | 175 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
136 | LUAI_FUNC void luaC_step (lua_State *L); | 176 | LUAI_FUNC void luaC_step (lua_State *L); |
@@ -138,10 +178,9 @@ LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); | |||
138 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 178 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
139 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); | 179 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); |
140 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); | 180 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); |
141 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); | 181 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); |
142 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); | ||
143 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); | 182 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); |
144 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); | 183 | LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); |
145 | 184 | ||
146 | 185 | ||
147 | #endif | 186 | #endif |
diff --git a/src/lua-5.3/linit.c b/src/lua/linit.c index 480da52..69808f8 100644 --- a/src/lua-5.3/linit.c +++ b/src/lua/linit.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: linit.c $ |
3 | ** Initialization of libraries for lua.c and other clients | 3 | ** Initialization of libraries for lua.c and other clients |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -40,7 +40,7 @@ | |||
40 | ** program | 40 | ** program |
41 | */ | 41 | */ |
42 | static const luaL_Reg loadedlibs[] = { | 42 | static const luaL_Reg loadedlibs[] = { |
43 | {"_G", luaopen_base}, | 43 | {LUA_GNAME, luaopen_base}, |
44 | {LUA_LOADLIBNAME, luaopen_package}, | 44 | {LUA_LOADLIBNAME, luaopen_package}, |
45 | {LUA_COLIBNAME, luaopen_coroutine}, | 45 | {LUA_COLIBNAME, luaopen_coroutine}, |
46 | {LUA_TABLIBNAME, luaopen_table}, | 46 | {LUA_TABLIBNAME, luaopen_table}, |
@@ -50,9 +50,6 @@ static const luaL_Reg loadedlibs[] = { | |||
50 | {LUA_MATHLIBNAME, luaopen_math}, | 50 | {LUA_MATHLIBNAME, luaopen_math}, |
51 | {LUA_UTF8LIBNAME, luaopen_utf8}, | 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, |
52 | {LUA_DBLIBNAME, luaopen_debug}, | 52 | {LUA_DBLIBNAME, luaopen_debug}, |
53 | #if defined(LUA_COMPAT_BITLIB) | ||
54 | {LUA_BITLIBNAME, luaopen_bit32}, | ||
55 | #endif | ||
56 | {NULL, NULL} | 53 | {NULL, NULL} |
57 | }; | 54 | }; |
58 | 55 | ||
diff --git a/src/lua-5.3/liolib.c b/src/lua/liolib.c index 8a9e75c..7ac3444 100644 --- a/src/lua-5.3/liolib.c +++ b/src/lua/liolib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $ | 2 | ** $Id: liolib.c $ |
3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -39,7 +39,7 @@ | |||
39 | /* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ | 39 | /* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ |
40 | static int l_checkmode (const char *mode) { | 40 | static int l_checkmode (const char *mode) { |
41 | return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && | 41 | return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && |
42 | (*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ | 42 | (*mode != '+' || ((void)(++mode), 1)) && /* skip if char is '+' */ |
43 | (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ | 43 | (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ |
44 | } | 44 | } |
45 | 45 | ||
@@ -68,7 +68,7 @@ static int l_checkmode (const char *mode) { | |||
68 | 68 | ||
69 | /* ISO C definitions */ | 69 | /* ISO C definitions */ |
70 | #define l_popen(L,c,m) \ | 70 | #define l_popen(L,c,m) \ |
71 | ((void)((void)c, m), \ | 71 | ((void)c, (void)m, \ |
72 | luaL_error(L, "'popen' not supported"), \ | 72 | luaL_error(L, "'popen' not supported"), \ |
73 | (FILE*)0) | 73 | (FILE*)0) |
74 | #define l_pclose(L,file) ((void)L, (void)file, -1) | 74 | #define l_pclose(L,file) ((void)L, (void)file, -1) |
@@ -133,6 +133,7 @@ static int l_checkmode (const char *mode) { | |||
133 | /* }====================================================== */ | 133 | /* }====================================================== */ |
134 | 134 | ||
135 | 135 | ||
136 | |||
136 | #define IO_PREFIX "_IO_" | 137 | #define IO_PREFIX "_IO_" |
137 | #define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) | 138 | #define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) |
138 | #define IO_INPUT (IO_PREFIX "input") | 139 | #define IO_INPUT (IO_PREFIX "input") |
@@ -152,7 +153,7 @@ static int io_type (lua_State *L) { | |||
152 | luaL_checkany(L, 1); | 153 | luaL_checkany(L, 1); |
153 | p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); | 154 | p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); |
154 | if (p == NULL) | 155 | if (p == NULL) |
155 | lua_pushnil(L); /* not a file */ | 156 | luaL_pushfail(L); /* not a file */ |
156 | else if (isclosed(p)) | 157 | else if (isclosed(p)) |
157 | lua_pushliteral(L, "closed file"); | 158 | lua_pushliteral(L, "closed file"); |
158 | else | 159 | else |
@@ -186,7 +187,7 @@ static FILE *tofile (lua_State *L) { | |||
186 | ** handle is in a consistent state. | 187 | ** handle is in a consistent state. |
187 | */ | 188 | */ |
188 | static LStream *newprefile (lua_State *L) { | 189 | static LStream *newprefile (lua_State *L) { |
189 | LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); | 190 | LStream *p = (LStream *)lua_newuserdatauv(L, sizeof(LStream), 0); |
190 | p->closef = NULL; /* mark file handle as 'closed' */ | 191 | p->closef = NULL; /* mark file handle as 'closed' */ |
191 | luaL_setmetatable(L, LUA_FILEHANDLE); | 192 | luaL_setmetatable(L, LUA_FILEHANDLE); |
192 | return p; | 193 | return p; |
@@ -214,7 +215,7 @@ static int f_close (lua_State *L) { | |||
214 | 215 | ||
215 | static int io_close (lua_State *L) { | 216 | static int io_close (lua_State *L) { |
216 | if (lua_isnone(L, 1)) /* no argument? */ | 217 | if (lua_isnone(L, 1)) /* no argument? */ |
217 | lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ | 218 | lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use default output */ |
218 | return f_close(L); | 219 | return f_close(L); |
219 | } | 220 | } |
220 | 221 | ||
@@ -269,6 +270,7 @@ static int io_open (lua_State *L) { | |||
269 | */ | 270 | */ |
270 | static int io_pclose (lua_State *L) { | 271 | static int io_pclose (lua_State *L) { |
271 | LStream *p = tolstream(L); | 272 | LStream *p = tolstream(L); |
273 | errno = 0; | ||
272 | return luaL_execresult(L, l_pclose(L, p->f)); | 274 | return luaL_execresult(L, l_pclose(L, p->f)); |
273 | } | 275 | } |
274 | 276 | ||
@@ -295,7 +297,7 @@ static FILE *getiofile (lua_State *L, const char *findex) { | |||
295 | lua_getfield(L, LUA_REGISTRYINDEX, findex); | 297 | lua_getfield(L, LUA_REGISTRYINDEX, findex); |
296 | p = (LStream *)lua_touserdata(L, -1); | 298 | p = (LStream *)lua_touserdata(L, -1); |
297 | if (isclosed(p)) | 299 | if (isclosed(p)) |
298 | luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN); | 300 | luaL_error(L, "default %s file is closed", findex + IOPREF_LEN); |
299 | return p->f; | 301 | return p->f; |
300 | } | 302 | } |
301 | 303 | ||
@@ -336,12 +338,22 @@ static int io_readline (lua_State *L); | |||
336 | */ | 338 | */ |
337 | #define MAXARGLINE 250 | 339 | #define MAXARGLINE 250 |
338 | 340 | ||
341 | /* | ||
342 | ** Auxiliary function to create the iteration function for 'lines'. | ||
343 | ** The iteration function is a closure over 'io_readline', with | ||
344 | ** the following upvalues: | ||
345 | ** 1) The file being read (first value in the stack) | ||
346 | ** 2) the number of arguments to read | ||
347 | ** 3) a boolean, true iff file has to be closed when finished ('toclose') | ||
348 | ** *) a variable number of format arguments (rest of the stack) | ||
349 | */ | ||
339 | static void aux_lines (lua_State *L, int toclose) { | 350 | static void aux_lines (lua_State *L, int toclose) { |
340 | int n = lua_gettop(L) - 1; /* number of arguments to read */ | 351 | int n = lua_gettop(L) - 1; /* number of arguments to read */ |
341 | luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); | 352 | luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); |
353 | lua_pushvalue(L, 1); /* file */ | ||
342 | lua_pushinteger(L, n); /* number of arguments to read */ | 354 | lua_pushinteger(L, n); /* number of arguments to read */ |
343 | lua_pushboolean(L, toclose); /* close/not close file when finished */ | 355 | lua_pushboolean(L, toclose); /* close/not close file when finished */ |
344 | lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */ | 356 | lua_rotate(L, 2, 3); /* move the three values to their positions */ |
345 | lua_pushcclosure(L, io_readline, 3 + n); | 357 | lua_pushcclosure(L, io_readline, 3 + n); |
346 | } | 358 | } |
347 | 359 | ||
@@ -353,6 +365,11 @@ static int f_lines (lua_State *L) { | |||
353 | } | 365 | } |
354 | 366 | ||
355 | 367 | ||
368 | /* | ||
369 | ** Return an iteration function for 'io.lines'. If file has to be | ||
370 | ** closed, also returns the file itself as a second result (to be | ||
371 | ** closed as the state at the exit of a generic for). | ||
372 | */ | ||
356 | static int io_lines (lua_State *L) { | 373 | static int io_lines (lua_State *L) { |
357 | int toclose; | 374 | int toclose; |
358 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ | 375 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ |
@@ -368,8 +385,15 @@ static int io_lines (lua_State *L) { | |||
368 | lua_replace(L, 1); /* put file at index 1 */ | 385 | lua_replace(L, 1); /* put file at index 1 */ |
369 | toclose = 1; /* close it after iteration */ | 386 | toclose = 1; /* close it after iteration */ |
370 | } | 387 | } |
371 | aux_lines(L, toclose); | 388 | aux_lines(L, toclose); /* push iteration function */ |
372 | return 1; | 389 | if (toclose) { |
390 | lua_pushnil(L); /* state */ | ||
391 | lua_pushnil(L); /* control */ | ||
392 | lua_pushvalue(L, 1); /* file is the to-be-closed variable (4th result) */ | ||
393 | return 4; | ||
394 | } | ||
395 | else | ||
396 | return 1; | ||
373 | } | 397 | } |
374 | 398 | ||
375 | 399 | ||
@@ -435,7 +459,7 @@ static int readdigits (RN *rn, int hex) { | |||
435 | /* | 459 | /* |
436 | ** Read a number: first reads a valid prefix of a numeral into a buffer. | 460 | ** Read a number: first reads a valid prefix of a numeral into a buffer. |
437 | ** Then it calls 'lua_stringtonumber' to check whether the format is | 461 | ** Then it calls 'lua_stringtonumber' to check whether the format is |
438 | ** correct and to convert it to a Lua number | 462 | ** correct and to convert it to a Lua number. |
439 | */ | 463 | */ |
440 | static int read_number (lua_State *L, FILE *f) { | 464 | static int read_number (lua_State *L, FILE *f) { |
441 | RN rn; | 465 | RN rn; |
@@ -447,7 +471,7 @@ static int read_number (lua_State *L, FILE *f) { | |||
447 | decp[1] = '.'; /* always accept a dot */ | 471 | decp[1] = '.'; /* always accept a dot */ |
448 | l_lockfile(rn.f); | 472 | l_lockfile(rn.f); |
449 | do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ | 473 | do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ |
450 | test2(&rn, "-+"); /* optional signal */ | 474 | test2(&rn, "-+"); /* optional sign */ |
451 | if (test2(&rn, "00")) { | 475 | if (test2(&rn, "00")) { |
452 | if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ | 476 | if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ |
453 | else count = 1; /* count initial '0' as a valid digit */ | 477 | else count = 1; /* count initial '0' as a valid digit */ |
@@ -456,7 +480,7 @@ static int read_number (lua_State *L, FILE *f) { | |||
456 | if (test2(&rn, decp)) /* decimal point? */ | 480 | if (test2(&rn, decp)) /* decimal point? */ |
457 | count += readdigits(&rn, hex); /* fractional part */ | 481 | count += readdigits(&rn, hex); /* fractional part */ |
458 | if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ | 482 | if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ |
459 | test2(&rn, "-+"); /* exponent signal */ | 483 | test2(&rn, "-+"); /* exponent sign */ |
460 | readdigits(&rn, 0); /* exponent digits */ | 484 | readdigits(&rn, 0); /* exponent digits */ |
461 | } | 485 | } |
462 | ungetc(rn.c, rn.f); /* unread look-ahead char */ | 486 | ungetc(rn.c, rn.f); /* unread look-ahead char */ |
@@ -481,17 +505,17 @@ static int test_eof (lua_State *L, FILE *f) { | |||
481 | 505 | ||
482 | static int read_line (lua_State *L, FILE *f, int chop) { | 506 | static int read_line (lua_State *L, FILE *f, int chop) { |
483 | luaL_Buffer b; | 507 | luaL_Buffer b; |
484 | int c = '\0'; | 508 | int c; |
485 | luaL_buffinit(L, &b); | 509 | luaL_buffinit(L, &b); |
486 | while (c != EOF && c != '\n') { /* repeat until end of line */ | 510 | do { /* may need to read several chunks to get whole line */ |
487 | char *buff = luaL_prepbuffer(&b); /* preallocate buffer */ | 511 | char *buff = luaL_prepbuffer(&b); /* preallocate buffer space */ |
488 | int i = 0; | 512 | int i = 0; |
489 | l_lockfile(f); /* no memory errors can happen inside the lock */ | 513 | l_lockfile(f); /* no memory errors can happen inside the lock */ |
490 | while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') | 514 | while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') |
491 | buff[i++] = c; | 515 | buff[i++] = c; /* read up to end of line or buffer limit */ |
492 | l_unlockfile(f); | 516 | l_unlockfile(f); |
493 | luaL_addsize(&b, i); | 517 | luaL_addsize(&b, i); |
494 | } | 518 | } while (c != EOF && c != '\n'); /* repeat until end of line */ |
495 | if (!chop && c == '\n') /* want a newline and have one? */ | 519 | if (!chop && c == '\n') /* want a newline and have one? */ |
496 | luaL_addchar(&b, c); /* add ending newline to result */ | 520 | luaL_addchar(&b, c); /* add ending newline to result */ |
497 | luaL_pushresult(&b); /* close buffer */ | 521 | luaL_pushresult(&b); /* close buffer */ |
@@ -528,14 +552,14 @@ static int read_chars (lua_State *L, FILE *f, size_t n) { | |||
528 | 552 | ||
529 | static int g_read (lua_State *L, FILE *f, int first) { | 553 | static int g_read (lua_State *L, FILE *f, int first) { |
530 | int nargs = lua_gettop(L) - 1; | 554 | int nargs = lua_gettop(L) - 1; |
531 | int success; | 555 | int n, success; |
532 | int n; | ||
533 | clearerr(f); | 556 | clearerr(f); |
534 | if (nargs == 0) { /* no arguments? */ | 557 | if (nargs == 0) { /* no arguments? */ |
535 | success = read_line(L, f, 1); | 558 | success = read_line(L, f, 1); |
536 | n = first+1; /* to return 1 result */ | 559 | n = first + 1; /* to return 1 result */ |
537 | } | 560 | } |
538 | else { /* ensure stack space for all results and for auxlib's buffer */ | 561 | else { |
562 | /* ensure stack space for all results and for auxlib's buffer */ | ||
539 | luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); | 563 | luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); |
540 | success = 1; | 564 | success = 1; |
541 | for (n = first; nargs-- && success; n++) { | 565 | for (n = first; nargs-- && success; n++) { |
@@ -570,7 +594,7 @@ static int g_read (lua_State *L, FILE *f, int first) { | |||
570 | return luaL_fileresult(L, 0, NULL); | 594 | return luaL_fileresult(L, 0, NULL); |
571 | if (!success) { | 595 | if (!success) { |
572 | lua_pop(L, 1); /* remove last result */ | 596 | lua_pop(L, 1); /* remove last result */ |
573 | lua_pushnil(L); /* push nil instead */ | 597 | luaL_pushfail(L); /* push nil instead */ |
574 | } | 598 | } |
575 | return n - first; | 599 | return n - first; |
576 | } | 600 | } |
@@ -586,6 +610,9 @@ static int f_read (lua_State *L) { | |||
586 | } | 610 | } |
587 | 611 | ||
588 | 612 | ||
613 | /* | ||
614 | ** Iteration function for 'lines'. | ||
615 | */ | ||
589 | static int io_readline (lua_State *L) { | 616 | static int io_readline (lua_State *L) { |
590 | LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); | 617 | LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); |
591 | int i; | 618 | int i; |
@@ -600,14 +627,14 @@ static int io_readline (lua_State *L) { | |||
600 | lua_assert(n > 0); /* should return at least a nil */ | 627 | lua_assert(n > 0); /* should return at least a nil */ |
601 | if (lua_toboolean(L, -n)) /* read at least one value? */ | 628 | if (lua_toboolean(L, -n)) /* read at least one value? */ |
602 | return n; /* return them */ | 629 | return n; /* return them */ |
603 | else { /* first result is nil: EOF or error */ | 630 | else { /* first result is false: EOF or error */ |
604 | if (n > 1) { /* is there error information? */ | 631 | if (n > 1) { /* is there error information? */ |
605 | /* 2nd result is error message */ | 632 | /* 2nd result is error message */ |
606 | return luaL_error(L, "%s", lua_tostring(L, -n + 1)); | 633 | return luaL_error(L, "%s", lua_tostring(L, -n + 1)); |
607 | } | 634 | } |
608 | if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ | 635 | if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ |
609 | lua_settop(L, 0); | 636 | lua_settop(L, 0); /* clear stack */ |
610 | lua_pushvalue(L, lua_upvalueindex(1)); | 637 | lua_pushvalue(L, lua_upvalueindex(1)); /* push file at index 1 */ |
611 | aux_close(L); /* close it */ | 638 | aux_close(L); /* close it */ |
612 | } | 639 | } |
613 | return 0; | 640 | return 0; |
@@ -716,26 +743,37 @@ static const luaL_Reg iolib[] = { | |||
716 | /* | 743 | /* |
717 | ** methods for file handles | 744 | ** methods for file handles |
718 | */ | 745 | */ |
719 | static const luaL_Reg flib[] = { | 746 | static const luaL_Reg meth[] = { |
720 | {"close", f_close}, | ||
721 | {"flush", f_flush}, | ||
722 | {"lines", f_lines}, | ||
723 | {"read", f_read}, | 747 | {"read", f_read}, |
748 | {"write", f_write}, | ||
749 | {"lines", f_lines}, | ||
750 | {"flush", f_flush}, | ||
724 | {"seek", f_seek}, | 751 | {"seek", f_seek}, |
752 | {"close", f_close}, | ||
725 | {"setvbuf", f_setvbuf}, | 753 | {"setvbuf", f_setvbuf}, |
726 | {"write", f_write}, | 754 | {NULL, NULL} |
755 | }; | ||
756 | |||
757 | |||
758 | /* | ||
759 | ** metamethods for file handles | ||
760 | */ | ||
761 | static const luaL_Reg metameth[] = { | ||
762 | {"__index", NULL}, /* place holder */ | ||
727 | {"__gc", f_gc}, | 763 | {"__gc", f_gc}, |
764 | {"__close", f_gc}, | ||
728 | {"__tostring", f_tostring}, | 765 | {"__tostring", f_tostring}, |
729 | {NULL, NULL} | 766 | {NULL, NULL} |
730 | }; | 767 | }; |
731 | 768 | ||
732 | 769 | ||
733 | static void createmeta (lua_State *L) { | 770 | static void createmeta (lua_State *L) { |
734 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ | 771 | luaL_newmetatable(L, LUA_FILEHANDLE); /* metatable for file handles */ |
735 | lua_pushvalue(L, -1); /* push metatable */ | 772 | luaL_setfuncs(L, metameth, 0); /* add metamethods to new metatable */ |
736 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ | 773 | luaL_newlibtable(L, meth); /* create method table */ |
737 | luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ | 774 | luaL_setfuncs(L, meth, 0); /* add file methods to method table */ |
738 | lua_pop(L, 1); /* pop new metatable */ | 775 | lua_setfield(L, -2, "__index"); /* metatable.__index = method table */ |
776 | lua_pop(L, 1); /* pop metatable */ | ||
739 | } | 777 | } |
740 | 778 | ||
741 | 779 | ||
@@ -745,7 +783,7 @@ static void createmeta (lua_State *L) { | |||
745 | static int io_noclose (lua_State *L) { | 783 | static int io_noclose (lua_State *L) { |
746 | LStream *p = tolstream(L); | 784 | LStream *p = tolstream(L); |
747 | p->closef = &io_noclose; /* keep file opened */ | 785 | p->closef = &io_noclose; /* keep file opened */ |
748 | lua_pushnil(L); | 786 | luaL_pushfail(L); |
749 | lua_pushliteral(L, "cannot close standard file"); | 787 | lua_pushliteral(L, "cannot close standard file"); |
750 | return 2; | 788 | return 2; |
751 | } | 789 | } |
diff --git a/src/lua/ljumptab.h b/src/lua/ljumptab.h new file mode 100644 index 0000000..8306f25 --- /dev/null +++ b/src/lua/ljumptab.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | ** $Id: ljumptab.h $ | ||
3 | ** Jump Table for the Lua interpreter | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #undef vmdispatch | ||
9 | #undef vmcase | ||
10 | #undef vmbreak | ||
11 | |||
12 | #define vmdispatch(x) goto *disptab[x]; | ||
13 | |||
14 | #define vmcase(l) L_##l: | ||
15 | |||
16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); | ||
17 | |||
18 | |||
19 | static const void *const disptab[NUM_OPCODES] = { | ||
20 | |||
21 | #if 0 | ||
22 | ** you can update the following list with this command: | ||
23 | ** | ||
24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h | ||
25 | ** | ||
26 | #endif | ||
27 | |||
28 | &&L_OP_MOVE, | ||
29 | &&L_OP_LOADI, | ||
30 | &&L_OP_LOADF, | ||
31 | &&L_OP_LOADK, | ||
32 | &&L_OP_LOADKX, | ||
33 | &&L_OP_LOADFALSE, | ||
34 | &&L_OP_LFALSESKIP, | ||
35 | &&L_OP_LOADTRUE, | ||
36 | &&L_OP_LOADNIL, | ||
37 | &&L_OP_GETUPVAL, | ||
38 | &&L_OP_SETUPVAL, | ||
39 | &&L_OP_GETTABUP, | ||
40 | &&L_OP_GETTABLE, | ||
41 | &&L_OP_GETI, | ||
42 | &&L_OP_GETFIELD, | ||
43 | &&L_OP_SETTABUP, | ||
44 | &&L_OP_SETTABLE, | ||
45 | &&L_OP_SETI, | ||
46 | &&L_OP_SETFIELD, | ||
47 | &&L_OP_NEWTABLE, | ||
48 | &&L_OP_SELF, | ||
49 | &&L_OP_ADDI, | ||
50 | &&L_OP_ADDK, | ||
51 | &&L_OP_SUBK, | ||
52 | &&L_OP_MULK, | ||
53 | &&L_OP_MODK, | ||
54 | &&L_OP_POWK, | ||
55 | &&L_OP_DIVK, | ||
56 | &&L_OP_IDIVK, | ||
57 | &&L_OP_BANDK, | ||
58 | &&L_OP_BORK, | ||
59 | &&L_OP_BXORK, | ||
60 | &&L_OP_SHRI, | ||
61 | &&L_OP_SHLI, | ||
62 | &&L_OP_ADD, | ||
63 | &&L_OP_SUB, | ||
64 | &&L_OP_MUL, | ||
65 | &&L_OP_MOD, | ||
66 | &&L_OP_POW, | ||
67 | &&L_OP_DIV, | ||
68 | &&L_OP_IDIV, | ||
69 | &&L_OP_BAND, | ||
70 | &&L_OP_BOR, | ||
71 | &&L_OP_BXOR, | ||
72 | &&L_OP_SHL, | ||
73 | &&L_OP_SHR, | ||
74 | &&L_OP_MMBIN, | ||
75 | &&L_OP_MMBINI, | ||
76 | &&L_OP_MMBINK, | ||
77 | &&L_OP_UNM, | ||
78 | &&L_OP_BNOT, | ||
79 | &&L_OP_NOT, | ||
80 | &&L_OP_LEN, | ||
81 | &&L_OP_CONCAT, | ||
82 | &&L_OP_CLOSE, | ||
83 | &&L_OP_TBC, | ||
84 | &&L_OP_JMP, | ||
85 | &&L_OP_EQ, | ||
86 | &&L_OP_LT, | ||
87 | &&L_OP_LE, | ||
88 | &&L_OP_EQK, | ||
89 | &&L_OP_EQI, | ||
90 | &&L_OP_LTI, | ||
91 | &&L_OP_LEI, | ||
92 | &&L_OP_GTI, | ||
93 | &&L_OP_GEI, | ||
94 | &&L_OP_TEST, | ||
95 | &&L_OP_TESTSET, | ||
96 | &&L_OP_CALL, | ||
97 | &&L_OP_TAILCALL, | ||
98 | &&L_OP_RETURN, | ||
99 | &&L_OP_RETURN0, | ||
100 | &&L_OP_RETURN1, | ||
101 | &&L_OP_FORLOOP, | ||
102 | &&L_OP_FORPREP, | ||
103 | &&L_OP_TFORPREP, | ||
104 | &&L_OP_TFORCALL, | ||
105 | &&L_OP_TFORLOOP, | ||
106 | &&L_OP_SETLIST, | ||
107 | &&L_OP_CLOSURE, | ||
108 | &&L_OP_VARARG, | ||
109 | &&L_OP_VARARGPREP, | ||
110 | &&L_OP_EXTRAARG | ||
111 | |||
112 | }; | ||
diff --git a/src/lua-5.3/llex.c b/src/lua/llex.c index b6d9a46..90a7951 100644 --- a/src/lua-5.3/llex.c +++ b/src/lua/llex.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: llex.c $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | 30 | ||
31 | 31 | ||
32 | #define next(ls) (ls->current = zgetc(ls->z)) | 32 | #define next(ls) (ls->current = zgetc(ls->z)) |
33 | 33 | ||
34 | 34 | ||
35 | 35 | ||
@@ -63,7 +63,7 @@ static void save (LexState *ls, int c) { | |||
63 | newsize = luaZ_sizebuffer(b) * 2; | 63 | newsize = luaZ_sizebuffer(b) * 2; |
64 | luaZ_resizebuffer(ls->L, b, newsize); | 64 | luaZ_resizebuffer(ls->L, b, newsize); |
65 | } | 65 | } |
66 | b->buffer[luaZ_bufflen(b)++] = cast(char, c); | 66 | b->buffer[luaZ_bufflen(b)++] = cast_char(c); |
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
@@ -82,7 +82,10 @@ void luaX_init (lua_State *L) { | |||
82 | const char *luaX_token2str (LexState *ls, int token) { | 82 | const char *luaX_token2str (LexState *ls, int token) { |
83 | if (token < FIRST_RESERVED) { /* single-byte symbols? */ | 83 | if (token < FIRST_RESERVED) { /* single-byte symbols? */ |
84 | lua_assert(token == cast_uchar(token)); | 84 | lua_assert(token == cast_uchar(token)); |
85 | return luaO_pushfstring(ls->L, "'%c'", token); | 85 | if (lisprint(token)) |
86 | return luaO_pushfstring(ls->L, "'%c'", token); | ||
87 | else /* control character */ | ||
88 | return luaO_pushfstring(ls->L, "'<\\%d>'", token); | ||
86 | } | 89 | } |
87 | else { | 90 | else { |
88 | const char *s = luaX_tokens[token - FIRST_RESERVED]; | 91 | const char *s = luaX_tokens[token - FIRST_RESERVED]; |
@@ -129,15 +132,15 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) { | |||
129 | TValue *o; /* entry for 'str' */ | 132 | TValue *o; /* entry for 'str' */ |
130 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ | 133 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ |
131 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ | 134 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ |
132 | o = luaH_set(L, ls->h, L->top - 1); | 135 | o = luaH_set(L, ls->h, s2v(L->top - 1)); |
133 | if (ttisnil(o)) { /* not in use yet? */ | 136 | if (isempty(o)) { /* not in use yet? */ |
134 | /* boolean value does not need GC barrier; | 137 | /* boolean value does not need GC barrier; |
135 | table has no metatable, so it does not need to invalidate cache */ | 138 | table is not a metatable, so it does not need to invalidate cache */ |
136 | setbvalue(o, 1); /* t[string] = true */ | 139 | setbtvalue(o); /* t[string] = true */ |
137 | luaC_checkGC(L); | 140 | luaC_checkGC(L); |
138 | } | 141 | } |
139 | else { /* string already present */ | 142 | else { /* string already present */ |
140 | ts = tsvalue(keyfromval(o)); /* re-use value previously stored */ | 143 | ts = keystrval(nodefromval(o)); /* re-use value previously stored */ |
141 | } | 144 | } |
142 | L->top--; /* remove string from stack */ | 145 | L->top--; /* remove string from stack */ |
143 | return ts; | 146 | return ts; |
@@ -208,8 +211,16 @@ static int check_next2 (LexState *ls, const char *set) { | |||
208 | 211 | ||
209 | /* LUA_NUMBER */ | 212 | /* LUA_NUMBER */ |
210 | /* | 213 | /* |
211 | ** this function is quite liberal in what it accepts, as 'luaO_str2num' | 214 | ** This function is quite liberal in what it accepts, as 'luaO_str2num' |
212 | ** will reject ill-formed numerals. | 215 | ** will reject ill-formed numerals. Roughly, it accepts the following |
216 | ** pattern: | ||
217 | ** | ||
218 | ** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))* | ||
219 | ** | ||
220 | ** The only tricky part is to accept [+-] only after a valid exponent | ||
221 | ** mark, to avoid reading '3-4' or '0xe+1' as a single number. | ||
222 | ** | ||
223 | ** The caller might have already read an initial dot. | ||
213 | */ | 224 | */ |
214 | static int read_numeral (LexState *ls, SemInfo *seminfo) { | 225 | static int read_numeral (LexState *ls, SemInfo *seminfo) { |
215 | TValue obj; | 226 | TValue obj; |
@@ -220,14 +231,14 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) { | |||
220 | if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */ | 231 | if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */ |
221 | expo = "Pp"; | 232 | expo = "Pp"; |
222 | for (;;) { | 233 | for (;;) { |
223 | if (check_next2(ls, expo)) /* exponent part? */ | 234 | if (check_next2(ls, expo)) /* exponent mark? */ |
224 | check_next2(ls, "-+"); /* optional exponent sign */ | 235 | check_next2(ls, "-+"); /* optional exponent sign */ |
225 | if (lisxdigit(ls->current)) | 236 | else if (lisxdigit(ls->current) || ls->current == '.') /* '%x|%.' */ |
226 | save_and_next(ls); | ||
227 | else if (ls->current == '.') | ||
228 | save_and_next(ls); | 237 | save_and_next(ls); |
229 | else break; | 238 | else break; |
230 | } | 239 | } |
240 | if (lislalpha(ls->current)) /* is numeral touching a letter? */ | ||
241 | save_and_next(ls); /* force an error */ | ||
231 | save(ls, '\0'); | 242 | save(ls, '\0'); |
232 | if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */ | 243 | if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */ |
233 | lexerror(ls, "malformed number", TK_FLT); | 244 | lexerror(ls, "malformed number", TK_FLT); |
@@ -260,7 +271,6 @@ static size_t skip_sep (LexState *ls) { | |||
260 | return (ls->current == s) ? count + 2 | 271 | return (ls->current == s) ? count + 2 |
261 | : (count == 0) ? 1 | 272 | : (count == 0) ? 1 |
262 | : 0; | 273 | : 0; |
263 | |||
264 | } | 274 | } |
265 | 275 | ||
266 | 276 | ||
@@ -333,10 +343,10 @@ static unsigned long readutf8esc (LexState *ls) { | |||
333 | save_and_next(ls); /* skip 'u' */ | 343 | save_and_next(ls); /* skip 'u' */ |
334 | esccheck(ls, ls->current == '{', "missing '{'"); | 344 | esccheck(ls, ls->current == '{', "missing '{'"); |
335 | r = gethexa(ls); /* must have at least one digit */ | 345 | r = gethexa(ls); /* must have at least one digit */ |
336 | while ((save_and_next(ls), lisxdigit(ls->current))) { | 346 | while (cast_void(save_and_next(ls)), lisxdigit(ls->current)) { |
337 | i++; | 347 | i++; |
348 | esccheck(ls, r <= (0x7FFFFFFFu >> 4), "UTF-8 value too large"); | ||
338 | r = (r << 4) + luaO_hexavalue(ls->current); | 349 | r = (r << 4) + luaO_hexavalue(ls->current); |
339 | esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large"); | ||
340 | } | 350 | } |
341 | esccheck(ls, ls->current == '}', "missing '}'"); | 351 | esccheck(ls, ls->current == '}', "missing '}'"); |
342 | next(ls); /* skip '}' */ | 352 | next(ls); /* skip '}' */ |
@@ -466,7 +476,7 @@ static int llex (LexState *ls, SemInfo *seminfo) { | |||
466 | read_long_string(ls, seminfo, sep); | 476 | read_long_string(ls, seminfo, sep); |
467 | return TK_STRING; | 477 | return TK_STRING; |
468 | } | 478 | } |
469 | else if (sep == 0) /* '[=...' missing second bracket */ | 479 | else if (sep == 0) /* '[=...' missing second bracket? */ |
470 | lexerror(ls, "invalid long string delimiter", TK_STRING); | 480 | lexerror(ls, "invalid long string delimiter", TK_STRING); |
471 | return '['; | 481 | return '['; |
472 | } | 482 | } |
diff --git a/src/lua-5.3/llex.h b/src/lua/llex.h index 2ed0af6..d1a4cba 100644 --- a/src/lua-5.3/llex.h +++ b/src/lua/llex.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: llex.h $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -37,7 +37,7 @@ enum RESERVED { | |||
37 | }; | 37 | }; |
38 | 38 | ||
39 | /* number of reserved words */ | 39 | /* number of reserved words */ |
40 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) | 40 | #define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) |
41 | 41 | ||
42 | 42 | ||
43 | typedef union { | 43 | typedef union { |
diff --git a/src/lua-5.3/llimits.h b/src/lua/llimits.h index d1036f6..b86d345 100644 --- a/src/lua-5.3/llimits.h +++ b/src/lua/llimits.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llimits.h,v 1.141.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: llimits.h $ |
3 | ** Limits, basic types, and some other 'installation-dependent' definitions | 3 | ** Limits, basic types, and some other 'installation-dependent' definitions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include "lua.h" | 15 | #include "lua.h" |
16 | 16 | ||
17 | |||
17 | /* | 18 | /* |
18 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count | 19 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count |
19 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and | 20 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and |
@@ -22,7 +23,7 @@ | |||
22 | #if defined(LUAI_MEM) /* { external definitions? */ | 23 | #if defined(LUAI_MEM) /* { external definitions? */ |
23 | typedef LUAI_UMEM lu_mem; | 24 | typedef LUAI_UMEM lu_mem; |
24 | typedef LUAI_MEM l_mem; | 25 | typedef LUAI_MEM l_mem; |
25 | #elif LUAI_BITSINT >= 32 /* }{ */ | 26 | #elif LUAI_IS32INT /* }{ */ |
26 | typedef size_t lu_mem; | 27 | typedef size_t lu_mem; |
27 | typedef ptrdiff_t l_mem; | 28 | typedef ptrdiff_t l_mem; |
28 | #else /* 16-bit ints */ /* }{ */ | 29 | #else /* 16-bit ints */ /* }{ */ |
@@ -33,12 +34,13 @@ typedef long l_mem; | |||
33 | 34 | ||
34 | /* chars used as small naturals (so that 'char' is reserved for characters) */ | 35 | /* chars used as small naturals (so that 'char' is reserved for characters) */ |
35 | typedef unsigned char lu_byte; | 36 | typedef unsigned char lu_byte; |
37 | typedef signed char ls_byte; | ||
36 | 38 | ||
37 | 39 | ||
38 | /* maximum value for size_t */ | 40 | /* maximum value for size_t */ |
39 | #define MAX_SIZET ((size_t)(~(size_t)0)) | 41 | #define MAX_SIZET ((size_t)(~(size_t)0)) |
40 | 42 | ||
41 | /* maximum size visible for Lua (must be representable in a lua_Integer */ | 43 | /* maximum size visible for Lua (must be representable in a lua_Integer) */ |
42 | #define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ | 44 | #define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ |
43 | : (size_t)(LUA_MAXINTEGER)) | 45 | : (size_t)(LUA_MAXINTEGER)) |
44 | 46 | ||
@@ -52,6 +54,23 @@ typedef unsigned char lu_byte; | |||
52 | 54 | ||
53 | 55 | ||
54 | /* | 56 | /* |
57 | ** floor of the log2 of the maximum signed value for integral type 't'. | ||
58 | ** (That is, maximum 'n' such that '2^n' fits in the given signed type.) | ||
59 | */ | ||
60 | #define log2maxs(t) (sizeof(t) * 8 - 2) | ||
61 | |||
62 | |||
63 | /* | ||
64 | ** test whether an unsigned value is a power of 2 (or zero) | ||
65 | */ | ||
66 | #define ispow2(x) (((x) & ((x) - 1)) == 0) | ||
67 | |||
68 | |||
69 | /* number of chars of a literal string without the ending \0 */ | ||
70 | #define LL(x) (sizeof(x)/sizeof(char) - 1) | ||
71 | |||
72 | |||
73 | /* | ||
55 | ** conversion of pointer to unsigned integer: | 74 | ** conversion of pointer to unsigned integer: |
56 | ** this is for hashing only; there is no problem if the integer | 75 | ** this is for hashing only; there is no problem if the integer |
57 | ** cannot hold the whole pointer value | 76 | ** cannot hold the whole pointer value |
@@ -60,21 +79,6 @@ typedef unsigned char lu_byte; | |||
60 | 79 | ||
61 | 80 | ||
62 | 81 | ||
63 | /* type to ensure maximum alignment */ | ||
64 | #if defined(LUAI_USER_ALIGNMENT_T) | ||
65 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; | ||
66 | #else | ||
67 | typedef union { | ||
68 | lua_Number n; | ||
69 | double u; | ||
70 | void *s; | ||
71 | lua_Integer i; | ||
72 | long l; | ||
73 | } L_Umaxalign; | ||
74 | #endif | ||
75 | |||
76 | |||
77 | |||
78 | /* types of 'usual argument conversions' for lua_Number and lua_Integer */ | 82 | /* types of 'usual argument conversions' for lua_Number and lua_Integer */ |
79 | typedef LUAI_UACNUMBER l_uacNumber; | 83 | typedef LUAI_UACNUMBER l_uacNumber; |
80 | typedef LUAI_UACINT l_uacInt; | 84 | typedef LUAI_UACINT l_uacInt; |
@@ -95,7 +99,7 @@ typedef LUAI_UACINT l_uacInt; | |||
95 | ** assertion for checking API calls | 99 | ** assertion for checking API calls |
96 | */ | 100 | */ |
97 | #if !defined(luai_apicheck) | 101 | #if !defined(luai_apicheck) |
98 | #define luai_apicheck(l,e) lua_assert(e) | 102 | #define luai_apicheck(l,e) ((void)l, lua_assert(e)) |
99 | #endif | 103 | #endif |
100 | 104 | ||
101 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) | 105 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) |
@@ -111,10 +115,15 @@ typedef LUAI_UACINT l_uacInt; | |||
111 | #define cast(t, exp) ((t)(exp)) | 115 | #define cast(t, exp) ((t)(exp)) |
112 | 116 | ||
113 | #define cast_void(i) cast(void, (i)) | 117 | #define cast_void(i) cast(void, (i)) |
114 | #define cast_byte(i) cast(lu_byte, (i)) | 118 | #define cast_voidp(i) cast(void *, (i)) |
115 | #define cast_num(i) cast(lua_Number, (i)) | 119 | #define cast_num(i) cast(lua_Number, (i)) |
116 | #define cast_int(i) cast(int, (i)) | 120 | #define cast_int(i) cast(int, (i)) |
121 | #define cast_uint(i) cast(unsigned int, (i)) | ||
122 | #define cast_byte(i) cast(lu_byte, (i)) | ||
117 | #define cast_uchar(i) cast(unsigned char, (i)) | 123 | #define cast_uchar(i) cast(unsigned char, (i)) |
124 | #define cast_char(i) cast(char, (i)) | ||
125 | #define cast_charp(i) cast(char *, (i)) | ||
126 | #define cast_sizet(i) cast(size_t, (i)) | ||
118 | 127 | ||
119 | 128 | ||
120 | /* cast a signed lua_Integer to lua_Unsigned */ | 129 | /* cast a signed lua_Integer to lua_Unsigned */ |
@@ -133,38 +142,49 @@ typedef LUAI_UACINT l_uacInt; | |||
133 | 142 | ||
134 | 143 | ||
135 | /* | 144 | /* |
136 | ** non-return type | 145 | ** macros to improve jump prediction (used mainly for error handling) |
137 | */ | 146 | */ |
147 | #if !defined(likely) | ||
148 | |||
138 | #if defined(__GNUC__) | 149 | #if defined(__GNUC__) |
139 | #define l_noret void __attribute__((noreturn)) | 150 | #define likely(x) (__builtin_expect(((x) != 0), 1)) |
140 | #elif defined(_MSC_VER) && _MSC_VER >= 1200 | 151 | #define unlikely(x) (__builtin_expect(((x) != 0), 0)) |
141 | #define l_noret void __declspec(noreturn) | ||
142 | #else | 152 | #else |
143 | #define l_noret void | 153 | #define likely(x) (x) |
154 | #define unlikely(x) (x) | ||
144 | #endif | 155 | #endif |
145 | 156 | ||
157 | #endif | ||
146 | 158 | ||
147 | 159 | ||
148 | /* | 160 | /* |
149 | ** maximum depth for nested C calls and syntactical nested non-terminals | 161 | ** non-return type |
150 | ** in a program. (Value must fit in an unsigned short int.) | ||
151 | */ | 162 | */ |
152 | #if !defined(LUAI_MAXCCALLS) | 163 | #if !defined(l_noret) |
153 | #define LUAI_MAXCCALLS 200 | 164 | |
165 | #if defined(__GNUC__) | ||
166 | #define l_noret void __attribute__((noreturn)) | ||
167 | #elif defined(_MSC_VER) && _MSC_VER >= 1200 | ||
168 | #define l_noret void __declspec(noreturn) | ||
169 | #else | ||
170 | #define l_noret void | ||
154 | #endif | 171 | #endif |
155 | 172 | ||
173 | #endif | ||
156 | 174 | ||
157 | 175 | ||
158 | /* | 176 | /* |
159 | ** type for virtual-machine instructions; | 177 | ** type for virtual-machine instructions; |
160 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) | 178 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) |
161 | */ | 179 | */ |
162 | #if LUAI_BITSINT >= 32 | 180 | #if LUAI_IS32INT |
163 | typedef unsigned int Instruction; | 181 | typedef unsigned int l_uint32; |
164 | #else | 182 | #else |
165 | typedef unsigned long Instruction; | 183 | typedef unsigned long l_uint32; |
166 | #endif | 184 | #endif |
167 | 185 | ||
186 | typedef l_uint32 Instruction; | ||
187 | |||
168 | 188 | ||
169 | 189 | ||
170 | /* | 190 | /* |
@@ -225,8 +245,7 @@ typedef unsigned long Instruction; | |||
225 | 245 | ||
226 | 246 | ||
227 | /* | 247 | /* |
228 | ** these macros allow user-specific actions on threads when you defined | 248 | ** these macros allow user-specific actions when a thread is |
229 | ** LUAI_EXTRASPACE and need to do something extra when a thread is | ||
230 | ** created/deleted/resumed/yielded. | 249 | ** created/deleted/resumed/yielded. |
231 | */ | 250 | */ |
232 | #if !defined(luai_userstateopen) | 251 | #if !defined(luai_userstateopen) |
@@ -270,15 +289,20 @@ typedef unsigned long Instruction; | |||
270 | #endif | 289 | #endif |
271 | 290 | ||
272 | /* | 291 | /* |
273 | ** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when | 292 | ** modulo: defined as 'a - floor(a/b)*b'; the direct computation |
274 | ** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of | 293 | ** using this definition has several problems with rounding errors, |
275 | ** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b) | 294 | ** so it is better to use 'fmod'. 'fmod' gives the result of |
276 | ** ~= floor(a/b)'. That happens when the division has a non-integer | 295 | ** 'a - trunc(a/b)*b', and therefore must be corrected when |
277 | ** negative result, which is equivalent to the test below. | 296 | ** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a |
297 | ** non-integer negative result: non-integer result is equivalent to | ||
298 | ** a non-zero remainder 'm'; negative result is equivalent to 'a' and | ||
299 | ** 'b' with different signs, or 'm' and 'b' with different signs | ||
300 | ** (as the result 'm' of 'fmod' has the same sign of 'a'). | ||
278 | */ | 301 | */ |
279 | #if !defined(luai_nummod) | 302 | #if !defined(luai_nummod) |
280 | #define luai_nummod(L,a,b,m) \ | 303 | #define luai_nummod(L,a,b,m) \ |
281 | { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); } | 304 | { (void)L; (m) = l_mathop(fmod)(a,b); \ |
305 | if (((m) > 0) ? (b) < 0 : ((m) < 0 && (b) > 0)) (m) += (b); } | ||
282 | #endif | 306 | #endif |
283 | 307 | ||
284 | /* exponentiation */ | 308 | /* exponentiation */ |
@@ -295,6 +319,8 @@ typedef unsigned long Instruction; | |||
295 | #define luai_numeq(a,b) ((a)==(b)) | 319 | #define luai_numeq(a,b) ((a)==(b)) |
296 | #define luai_numlt(a,b) ((a)<(b)) | 320 | #define luai_numlt(a,b) ((a)<(b)) |
297 | #define luai_numle(a,b) ((a)<=(b)) | 321 | #define luai_numle(a,b) ((a)<=(b)) |
322 | #define luai_numgt(a,b) ((a)>(b)) | ||
323 | #define luai_numge(a,b) ((a)>=(b)) | ||
298 | #define luai_numisnan(a) (!luai_numeq((a), (a))) | 324 | #define luai_numisnan(a) (!luai_numeq((a), (a))) |
299 | #endif | 325 | #endif |
300 | 326 | ||
@@ -310,7 +336,7 @@ typedef unsigned long Instruction; | |||
310 | #else | 336 | #else |
311 | /* realloc stack keeping its size */ | 337 | /* realloc stack keeping its size */ |
312 | #define condmovestack(L,pre,pos) \ | 338 | #define condmovestack(L,pre,pos) \ |
313 | { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_); pos; } | 339 | { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_, 0); pos; } |
314 | #endif | 340 | #endif |
315 | 341 | ||
316 | #if !defined(HARDMEMTESTS) | 342 | #if !defined(HARDMEMTESTS) |
diff --git a/src/lua/lmathlib.c b/src/lua/lmathlib.c new file mode 100644 index 0000000..86def47 --- /dev/null +++ b/src/lua/lmathlib.c | |||
@@ -0,0 +1,763 @@ | |||
1 | /* | ||
2 | ** $Id: lmathlib.c $ | ||
3 | ** Standard mathematical library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lmathlib_c | ||
8 | #define LUA_LIB | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <float.h> | ||
14 | #include <limits.h> | ||
15 | #include <math.h> | ||
16 | #include <stdlib.h> | ||
17 | #include <time.h> | ||
18 | |||
19 | #include "lua.h" | ||
20 | |||
21 | #include "lauxlib.h" | ||
22 | #include "lualib.h" | ||
23 | |||
24 | |||
25 | #undef PI | ||
26 | #define PI (l_mathop(3.141592653589793238462643383279502884)) | ||
27 | |||
28 | |||
29 | static int math_abs (lua_State *L) { | ||
30 | if (lua_isinteger(L, 1)) { | ||
31 | lua_Integer n = lua_tointeger(L, 1); | ||
32 | if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); | ||
33 | lua_pushinteger(L, n); | ||
34 | } | ||
35 | else | ||
36 | lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); | ||
37 | return 1; | ||
38 | } | ||
39 | |||
40 | static int math_sin (lua_State *L) { | ||
41 | lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); | ||
42 | return 1; | ||
43 | } | ||
44 | |||
45 | static int math_cos (lua_State *L) { | ||
46 | lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | static int math_tan (lua_State *L) { | ||
51 | lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); | ||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | static int math_asin (lua_State *L) { | ||
56 | lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); | ||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | static int math_acos (lua_State *L) { | ||
61 | lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); | ||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | static int math_atan (lua_State *L) { | ||
66 | lua_Number y = luaL_checknumber(L, 1); | ||
67 | lua_Number x = luaL_optnumber(L, 2, 1); | ||
68 | lua_pushnumber(L, l_mathop(atan2)(y, x)); | ||
69 | return 1; | ||
70 | } | ||
71 | |||
72 | |||
73 | static int math_toint (lua_State *L) { | ||
74 | int valid; | ||
75 | lua_Integer n = lua_tointegerx(L, 1, &valid); | ||
76 | if (valid) | ||
77 | lua_pushinteger(L, n); | ||
78 | else { | ||
79 | luaL_checkany(L, 1); | ||
80 | luaL_pushfail(L); /* value is not convertible to integer */ | ||
81 | } | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | |||
86 | static void pushnumint (lua_State *L, lua_Number d) { | ||
87 | lua_Integer n; | ||
88 | if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ | ||
89 | lua_pushinteger(L, n); /* result is integer */ | ||
90 | else | ||
91 | lua_pushnumber(L, d); /* result is float */ | ||
92 | } | ||
93 | |||
94 | |||
95 | static int math_floor (lua_State *L) { | ||
96 | if (lua_isinteger(L, 1)) | ||
97 | lua_settop(L, 1); /* integer is its own floor */ | ||
98 | else { | ||
99 | lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); | ||
100 | pushnumint(L, d); | ||
101 | } | ||
102 | return 1; | ||
103 | } | ||
104 | |||
105 | |||
106 | static int math_ceil (lua_State *L) { | ||
107 | if (lua_isinteger(L, 1)) | ||
108 | lua_settop(L, 1); /* integer is its own ceil */ | ||
109 | else { | ||
110 | lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); | ||
111 | pushnumint(L, d); | ||
112 | } | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | |||
117 | static int math_fmod (lua_State *L) { | ||
118 | if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { | ||
119 | lua_Integer d = lua_tointeger(L, 2); | ||
120 | if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ | ||
121 | luaL_argcheck(L, d != 0, 2, "zero"); | ||
122 | lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ | ||
123 | } | ||
124 | else | ||
125 | lua_pushinteger(L, lua_tointeger(L, 1) % d); | ||
126 | } | ||
127 | else | ||
128 | lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), | ||
129 | luaL_checknumber(L, 2))); | ||
130 | return 1; | ||
131 | } | ||
132 | |||
133 | |||
134 | /* | ||
135 | ** next function does not use 'modf', avoiding problems with 'double*' | ||
136 | ** (which is not compatible with 'float*') when lua_Number is not | ||
137 | ** 'double'. | ||
138 | */ | ||
139 | static int math_modf (lua_State *L) { | ||
140 | if (lua_isinteger(L ,1)) { | ||
141 | lua_settop(L, 1); /* number is its own integer part */ | ||
142 | lua_pushnumber(L, 0); /* no fractional part */ | ||
143 | } | ||
144 | else { | ||
145 | lua_Number n = luaL_checknumber(L, 1); | ||
146 | /* integer part (rounds toward zero) */ | ||
147 | lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); | ||
148 | pushnumint(L, ip); | ||
149 | /* fractional part (test needed for inf/-inf) */ | ||
150 | lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); | ||
151 | } | ||
152 | return 2; | ||
153 | } | ||
154 | |||
155 | |||
156 | static int math_sqrt (lua_State *L) { | ||
157 | lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); | ||
158 | return 1; | ||
159 | } | ||
160 | |||
161 | |||
162 | static int math_ult (lua_State *L) { | ||
163 | lua_Integer a = luaL_checkinteger(L, 1); | ||
164 | lua_Integer b = luaL_checkinteger(L, 2); | ||
165 | lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | static int math_log (lua_State *L) { | ||
170 | lua_Number x = luaL_checknumber(L, 1); | ||
171 | lua_Number res; | ||
172 | if (lua_isnoneornil(L, 2)) | ||
173 | res = l_mathop(log)(x); | ||
174 | else { | ||
175 | lua_Number base = luaL_checknumber(L, 2); | ||
176 | #if !defined(LUA_USE_C89) | ||
177 | if (base == l_mathop(2.0)) | ||
178 | res = l_mathop(log2)(x); else | ||
179 | #endif | ||
180 | if (base == l_mathop(10.0)) | ||
181 | res = l_mathop(log10)(x); | ||
182 | else | ||
183 | res = l_mathop(log)(x)/l_mathop(log)(base); | ||
184 | } | ||
185 | lua_pushnumber(L, res); | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | static int math_exp (lua_State *L) { | ||
190 | lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); | ||
191 | return 1; | ||
192 | } | ||
193 | |||
194 | static int math_deg (lua_State *L) { | ||
195 | lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); | ||
196 | return 1; | ||
197 | } | ||
198 | |||
199 | static int math_rad (lua_State *L) { | ||
200 | lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); | ||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | |||
205 | static int math_min (lua_State *L) { | ||
206 | int n = lua_gettop(L); /* number of arguments */ | ||
207 | int imin = 1; /* index of current minimum value */ | ||
208 | int i; | ||
209 | luaL_argcheck(L, n >= 1, 1, "value expected"); | ||
210 | for (i = 2; i <= n; i++) { | ||
211 | if (lua_compare(L, i, imin, LUA_OPLT)) | ||
212 | imin = i; | ||
213 | } | ||
214 | lua_pushvalue(L, imin); | ||
215 | return 1; | ||
216 | } | ||
217 | |||
218 | |||
219 | static int math_max (lua_State *L) { | ||
220 | int n = lua_gettop(L); /* number of arguments */ | ||
221 | int imax = 1; /* index of current maximum value */ | ||
222 | int i; | ||
223 | luaL_argcheck(L, n >= 1, 1, "value expected"); | ||
224 | for (i = 2; i <= n; i++) { | ||
225 | if (lua_compare(L, imax, i, LUA_OPLT)) | ||
226 | imax = i; | ||
227 | } | ||
228 | lua_pushvalue(L, imax); | ||
229 | return 1; | ||
230 | } | ||
231 | |||
232 | |||
233 | static int math_type (lua_State *L) { | ||
234 | if (lua_type(L, 1) == LUA_TNUMBER) | ||
235 | lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float"); | ||
236 | else { | ||
237 | luaL_checkany(L, 1); | ||
238 | luaL_pushfail(L); | ||
239 | } | ||
240 | return 1; | ||
241 | } | ||
242 | |||
243 | |||
244 | |||
245 | /* | ||
246 | ** {================================================================== | ||
247 | ** Pseudo-Random Number Generator based on 'xoshiro256**'. | ||
248 | ** =================================================================== | ||
249 | */ | ||
250 | |||
251 | /* number of binary digits in the mantissa of a float */ | ||
252 | #define FIGS l_floatatt(MANT_DIG) | ||
253 | |||
254 | #if FIGS > 64 | ||
255 | /* there are only 64 random bits; use them all */ | ||
256 | #undef FIGS | ||
257 | #define FIGS 64 | ||
258 | #endif | ||
259 | |||
260 | |||
261 | /* | ||
262 | ** LUA_RAND32 forces the use of 32-bit integers in the implementation | ||
263 | ** of the PRN generator (mainly for testing). | ||
264 | */ | ||
265 | #if !defined(LUA_RAND32) && !defined(Rand64) | ||
266 | |||
267 | /* try to find an integer type with at least 64 bits */ | ||
268 | |||
269 | #if (ULONG_MAX >> 31 >> 31) >= 3 | ||
270 | |||
271 | /* 'long' has at least 64 bits */ | ||
272 | #define Rand64 unsigned long | ||
273 | |||
274 | #elif !defined(LUA_USE_C89) && defined(LLONG_MAX) | ||
275 | |||
276 | /* there is a 'long long' type (which must have at least 64 bits) */ | ||
277 | #define Rand64 unsigned long long | ||
278 | |||
279 | #elif (LUA_MAXUNSIGNED >> 31 >> 31) >= 3 | ||
280 | |||
281 | /* 'lua_Integer' has at least 64 bits */ | ||
282 | #define Rand64 lua_Unsigned | ||
283 | |||
284 | #endif | ||
285 | |||
286 | #endif | ||
287 | |||
288 | |||
289 | #if defined(Rand64) /* { */ | ||
290 | |||
291 | /* | ||
292 | ** Standard implementation, using 64-bit integers. | ||
293 | ** If 'Rand64' has more than 64 bits, the extra bits do not interfere | ||
294 | ** with the 64 initial bits, except in a right shift. Moreover, the | ||
295 | ** final result has to discard the extra bits. | ||
296 | */ | ||
297 | |||
298 | /* avoid using extra bits when needed */ | ||
299 | #define trim64(x) ((x) & 0xffffffffffffffffu) | ||
300 | |||
301 | |||
302 | /* rotate left 'x' by 'n' bits */ | ||
303 | static Rand64 rotl (Rand64 x, int n) { | ||
304 | return (x << n) | (trim64(x) >> (64 - n)); | ||
305 | } | ||
306 | |||
307 | static Rand64 nextrand (Rand64 *state) { | ||
308 | Rand64 state0 = state[0]; | ||
309 | Rand64 state1 = state[1]; | ||
310 | Rand64 state2 = state[2] ^ state0; | ||
311 | Rand64 state3 = state[3] ^ state1; | ||
312 | Rand64 res = rotl(state1 * 5, 7) * 9; | ||
313 | state[0] = state0 ^ state3; | ||
314 | state[1] = state1 ^ state2; | ||
315 | state[2] = state2 ^ (state1 << 17); | ||
316 | state[3] = rotl(state3, 45); | ||
317 | return res; | ||
318 | } | ||
319 | |||
320 | |||
321 | /* must take care to not shift stuff by more than 63 slots */ | ||
322 | |||
323 | |||
324 | /* | ||
325 | ** Convert bits from a random integer into a float in the | ||
326 | ** interval [0,1), getting the higher FIG bits from the | ||
327 | ** random unsigned integer and converting that to a float. | ||
328 | */ | ||
329 | |||
330 | /* must throw out the extra (64 - FIGS) bits */ | ||
331 | #define shift64_FIG (64 - FIGS) | ||
332 | |||
333 | /* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */ | ||
334 | #define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) | ||
335 | |||
336 | static lua_Number I2d (Rand64 x) { | ||
337 | return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG; | ||
338 | } | ||
339 | |||
340 | /* convert a 'Rand64' to a 'lua_Unsigned' */ | ||
341 | #define I2UInt(x) ((lua_Unsigned)trim64(x)) | ||
342 | |||
343 | /* convert a 'lua_Unsigned' to a 'Rand64' */ | ||
344 | #define Int2I(x) ((Rand64)(x)) | ||
345 | |||
346 | |||
347 | #else /* no 'Rand64' }{ */ | ||
348 | |||
349 | /* get an integer with at least 32 bits */ | ||
350 | #if LUAI_IS32INT | ||
351 | typedef unsigned int lu_int32; | ||
352 | #else | ||
353 | typedef unsigned long lu_int32; | ||
354 | #endif | ||
355 | |||
356 | |||
357 | /* | ||
358 | ** Use two 32-bit integers to represent a 64-bit quantity. | ||
359 | */ | ||
360 | typedef struct Rand64 { | ||
361 | lu_int32 h; /* higher half */ | ||
362 | lu_int32 l; /* lower half */ | ||
363 | } Rand64; | ||
364 | |||
365 | |||
366 | /* | ||
367 | ** If 'lu_int32' has more than 32 bits, the extra bits do not interfere | ||
368 | ** with the 32 initial bits, except in a right shift and comparisons. | ||
369 | ** Moreover, the final result has to discard the extra bits. | ||
370 | */ | ||
371 | |||
372 | /* avoid using extra bits when needed */ | ||
373 | #define trim32(x) ((x) & 0xffffffffu) | ||
374 | |||
375 | |||
376 | /* | ||
377 | ** basic operations on 'Rand64' values | ||
378 | */ | ||
379 | |||
380 | /* build a new Rand64 value */ | ||
381 | static Rand64 packI (lu_int32 h, lu_int32 l) { | ||
382 | Rand64 result; | ||
383 | result.h = h; | ||
384 | result.l = l; | ||
385 | return result; | ||
386 | } | ||
387 | |||
388 | /* return i << n */ | ||
389 | static Rand64 Ishl (Rand64 i, int n) { | ||
390 | lua_assert(n > 0 && n < 32); | ||
391 | return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n); | ||
392 | } | ||
393 | |||
394 | /* i1 ^= i2 */ | ||
395 | static void Ixor (Rand64 *i1, Rand64 i2) { | ||
396 | i1->h ^= i2.h; | ||
397 | i1->l ^= i2.l; | ||
398 | } | ||
399 | |||
400 | /* return i1 + i2 */ | ||
401 | static Rand64 Iadd (Rand64 i1, Rand64 i2) { | ||
402 | Rand64 result = packI(i1.h + i2.h, i1.l + i2.l); | ||
403 | if (trim32(result.l) < trim32(i1.l)) /* carry? */ | ||
404 | result.h++; | ||
405 | return result; | ||
406 | } | ||
407 | |||
408 | /* return i * 5 */ | ||
409 | static Rand64 times5 (Rand64 i) { | ||
410 | return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */ | ||
411 | } | ||
412 | |||
413 | /* return i * 9 */ | ||
414 | static Rand64 times9 (Rand64 i) { | ||
415 | return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */ | ||
416 | } | ||
417 | |||
418 | /* return 'i' rotated left 'n' bits */ | ||
419 | static Rand64 rotl (Rand64 i, int n) { | ||
420 | lua_assert(n > 0 && n < 32); | ||
421 | return packI((i.h << n) | (trim32(i.l) >> (32 - n)), | ||
422 | (trim32(i.h) >> (32 - n)) | (i.l << n)); | ||
423 | } | ||
424 | |||
425 | /* for offsets larger than 32, rotate right by 64 - offset */ | ||
426 | static Rand64 rotl1 (Rand64 i, int n) { | ||
427 | lua_assert(n > 32 && n < 64); | ||
428 | n = 64 - n; | ||
429 | return packI((trim32(i.h) >> n) | (i.l << (32 - n)), | ||
430 | (i.h << (32 - n)) | (trim32(i.l) >> n)); | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | ** implementation of 'xoshiro256**' algorithm on 'Rand64' values | ||
435 | */ | ||
436 | static Rand64 nextrand (Rand64 *state) { | ||
437 | Rand64 res = times9(rotl(times5(state[1]), 7)); | ||
438 | Rand64 t = Ishl(state[1], 17); | ||
439 | Ixor(&state[2], state[0]); | ||
440 | Ixor(&state[3], state[1]); | ||
441 | Ixor(&state[1], state[2]); | ||
442 | Ixor(&state[0], state[3]); | ||
443 | Ixor(&state[2], t); | ||
444 | state[3] = rotl1(state[3], 45); | ||
445 | return res; | ||
446 | } | ||
447 | |||
448 | |||
449 | /* | ||
450 | ** Converts a 'Rand64' into a float. | ||
451 | */ | ||
452 | |||
453 | /* an unsigned 1 with proper type */ | ||
454 | #define UONE ((lu_int32)1) | ||
455 | |||
456 | |||
457 | #if FIGS <= 32 | ||
458 | |||
459 | /* 2^(-FIGS) */ | ||
460 | #define scaleFIG (l_mathop(0.5) / (UONE << (FIGS - 1))) | ||
461 | |||
462 | /* | ||
463 | ** get up to 32 bits from higher half, shifting right to | ||
464 | ** throw out the extra bits. | ||
465 | */ | ||
466 | static lua_Number I2d (Rand64 x) { | ||
467 | lua_Number h = (lua_Number)(trim32(x.h) >> (32 - FIGS)); | ||
468 | return h * scaleFIG; | ||
469 | } | ||
470 | |||
471 | #else /* 32 < FIGS <= 64 */ | ||
472 | |||
473 | /* must take care to not shift stuff by more than 31 slots */ | ||
474 | |||
475 | /* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ | ||
476 | #define scaleFIG \ | ||
477 | ((lua_Number)1.0 / (UONE << 30) / 8.0 / (UONE << (FIGS - 33))) | ||
478 | |||
479 | /* | ||
480 | ** use FIGS - 32 bits from lower half, throwing out the other | ||
481 | ** (32 - (FIGS - 32)) = (64 - FIGS) bits | ||
482 | */ | ||
483 | #define shiftLOW (64 - FIGS) | ||
484 | |||
485 | /* | ||
486 | ** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32) | ||
487 | */ | ||
488 | #define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * 2.0) | ||
489 | |||
490 | |||
491 | static lua_Number I2d (Rand64 x) { | ||
492 | lua_Number h = (lua_Number)trim32(x.h) * shiftHI; | ||
493 | lua_Number l = (lua_Number)(trim32(x.l) >> shiftLOW); | ||
494 | return (h + l) * scaleFIG; | ||
495 | } | ||
496 | |||
497 | #endif | ||
498 | |||
499 | |||
500 | /* convert a 'Rand64' to a 'lua_Unsigned' */ | ||
501 | static lua_Unsigned I2UInt (Rand64 x) { | ||
502 | return ((lua_Unsigned)trim32(x.h) << 31 << 1) | (lua_Unsigned)trim32(x.l); | ||
503 | } | ||
504 | |||
505 | /* convert a 'lua_Unsigned' to a 'Rand64' */ | ||
506 | static Rand64 Int2I (lua_Unsigned n) { | ||
507 | return packI((lu_int32)(n >> 31 >> 1), (lu_int32)n); | ||
508 | } | ||
509 | |||
510 | #endif /* } */ | ||
511 | |||
512 | |||
513 | /* | ||
514 | ** A state uses four 'Rand64' values. | ||
515 | */ | ||
516 | typedef struct { | ||
517 | Rand64 s[4]; | ||
518 | } RanState; | ||
519 | |||
520 | |||
521 | /* | ||
522 | ** Project the random integer 'ran' into the interval [0, n]. | ||
523 | ** Because 'ran' has 2^B possible values, the projection can only be | ||
524 | ** uniform when the size of the interval is a power of 2 (exact | ||
525 | ** division). Otherwise, to get a uniform projection into [0, n], we | ||
526 | ** first compute 'lim', the smallest Mersenne number not smaller than | ||
527 | ** 'n'. We then project 'ran' into the interval [0, lim]. If the result | ||
528 | ** is inside [0, n], we are done. Otherwise, we try with another 'ran', | ||
529 | ** until we have a result inside the interval. | ||
530 | */ | ||
531 | static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, | ||
532 | RanState *state) { | ||
533 | if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */ | ||
534 | return ran & n; /* no bias */ | ||
535 | else { | ||
536 | lua_Unsigned lim = n; | ||
537 | /* compute the smallest (2^b - 1) not smaller than 'n' */ | ||
538 | lim |= (lim >> 1); | ||
539 | lim |= (lim >> 2); | ||
540 | lim |= (lim >> 4); | ||
541 | lim |= (lim >> 8); | ||
542 | lim |= (lim >> 16); | ||
543 | #if (LUA_MAXUNSIGNED >> 31) >= 3 | ||
544 | lim |= (lim >> 32); /* integer type has more than 32 bits */ | ||
545 | #endif | ||
546 | lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ | ||
547 | && lim >= n /* not smaller than 'n', */ | ||
548 | && (lim >> 1) < n); /* and it is the smallest one */ | ||
549 | while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ | ||
550 | ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ | ||
551 | return ran; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | |||
556 | static int math_random (lua_State *L) { | ||
557 | lua_Integer low, up; | ||
558 | lua_Unsigned p; | ||
559 | RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); | ||
560 | Rand64 rv = nextrand(state->s); /* next pseudo-random value */ | ||
561 | switch (lua_gettop(L)) { /* check number of arguments */ | ||
562 | case 0: { /* no arguments */ | ||
563 | lua_pushnumber(L, I2d(rv)); /* float between 0 and 1 */ | ||
564 | return 1; | ||
565 | } | ||
566 | case 1: { /* only upper limit */ | ||
567 | low = 1; | ||
568 | up = luaL_checkinteger(L, 1); | ||
569 | if (up == 0) { /* single 0 as argument? */ | ||
570 | lua_pushinteger(L, I2UInt(rv)); /* full random integer */ | ||
571 | return 1; | ||
572 | } | ||
573 | break; | ||
574 | } | ||
575 | case 2: { /* lower and upper limits */ | ||
576 | low = luaL_checkinteger(L, 1); | ||
577 | up = luaL_checkinteger(L, 2); | ||
578 | break; | ||
579 | } | ||
580 | default: return luaL_error(L, "wrong number of arguments"); | ||
581 | } | ||
582 | /* random integer in the interval [low, up] */ | ||
583 | luaL_argcheck(L, low <= up, 1, "interval is empty"); | ||
584 | /* project random integer into the interval [0, up - low] */ | ||
585 | p = project(I2UInt(rv), (lua_Unsigned)up - (lua_Unsigned)low, state); | ||
586 | lua_pushinteger(L, p + (lua_Unsigned)low); | ||
587 | return 1; | ||
588 | } | ||
589 | |||
590 | |||
591 | static void setseed (lua_State *L, Rand64 *state, | ||
592 | lua_Unsigned n1, lua_Unsigned n2) { | ||
593 | int i; | ||
594 | state[0] = Int2I(n1); | ||
595 | state[1] = Int2I(0xff); /* avoid a zero state */ | ||
596 | state[2] = Int2I(n2); | ||
597 | state[3] = Int2I(0); | ||
598 | for (i = 0; i < 16; i++) | ||
599 | nextrand(state); /* discard initial values to "spread" seed */ | ||
600 | lua_pushinteger(L, n1); | ||
601 | lua_pushinteger(L, n2); | ||
602 | } | ||
603 | |||
604 | |||
605 | /* | ||
606 | ** Set a "random" seed. To get some randomness, use the current time | ||
607 | ** and the address of 'L' (in case the machine does address space layout | ||
608 | ** randomization). | ||
609 | */ | ||
610 | static void randseed (lua_State *L, RanState *state) { | ||
611 | lua_Unsigned seed1 = (lua_Unsigned)time(NULL); | ||
612 | lua_Unsigned seed2 = (lua_Unsigned)(size_t)L; | ||
613 | setseed(L, state->s, seed1, seed2); | ||
614 | } | ||
615 | |||
616 | |||
617 | static int math_randomseed (lua_State *L) { | ||
618 | RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); | ||
619 | if (lua_isnone(L, 1)) { | ||
620 | randseed(L, state); | ||
621 | } | ||
622 | else { | ||
623 | lua_Integer n1 = luaL_checkinteger(L, 1); | ||
624 | lua_Integer n2 = luaL_optinteger(L, 2, 0); | ||
625 | setseed(L, state->s, n1, n2); | ||
626 | } | ||
627 | return 2; /* return seeds */ | ||
628 | } | ||
629 | |||
630 | |||
631 | static const luaL_Reg randfuncs[] = { | ||
632 | {"random", math_random}, | ||
633 | {"randomseed", math_randomseed}, | ||
634 | {NULL, NULL} | ||
635 | }; | ||
636 | |||
637 | |||
638 | /* | ||
639 | ** Register the random functions and initialize their state. | ||
640 | */ | ||
641 | static void setrandfunc (lua_State *L) { | ||
642 | RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); | ||
643 | randseed(L, state); /* initialize with a "random" seed */ | ||
644 | lua_pop(L, 2); /* remove pushed seeds */ | ||
645 | luaL_setfuncs(L, randfuncs, 1); | ||
646 | } | ||
647 | |||
648 | /* }================================================================== */ | ||
649 | |||
650 | |||
651 | /* | ||
652 | ** {================================================================== | ||
653 | ** Deprecated functions (for compatibility only) | ||
654 | ** =================================================================== | ||
655 | */ | ||
656 | #if defined(LUA_COMPAT_MATHLIB) | ||
657 | |||
658 | static int math_cosh (lua_State *L) { | ||
659 | lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); | ||
660 | return 1; | ||
661 | } | ||
662 | |||
663 | static int math_sinh (lua_State *L) { | ||
664 | lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); | ||
665 | return 1; | ||
666 | } | ||
667 | |||
668 | static int math_tanh (lua_State *L) { | ||
669 | lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); | ||
670 | return 1; | ||
671 | } | ||
672 | |||
673 | static int math_pow (lua_State *L) { | ||
674 | lua_Number x = luaL_checknumber(L, 1); | ||
675 | lua_Number y = luaL_checknumber(L, 2); | ||
676 | lua_pushnumber(L, l_mathop(pow)(x, y)); | ||
677 | return 1; | ||
678 | } | ||
679 | |||
680 | static int math_frexp (lua_State *L) { | ||
681 | int e; | ||
682 | lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); | ||
683 | lua_pushinteger(L, e); | ||
684 | return 2; | ||
685 | } | ||
686 | |||
687 | static int math_ldexp (lua_State *L) { | ||
688 | lua_Number x = luaL_checknumber(L, 1); | ||
689 | int ep = (int)luaL_checkinteger(L, 2); | ||
690 | lua_pushnumber(L, l_mathop(ldexp)(x, ep)); | ||
691 | return 1; | ||
692 | } | ||
693 | |||
694 | static int math_log10 (lua_State *L) { | ||
695 | lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); | ||
696 | return 1; | ||
697 | } | ||
698 | |||
699 | #endif | ||
700 | /* }================================================================== */ | ||
701 | |||
702 | |||
703 | |||
704 | static const luaL_Reg mathlib[] = { | ||
705 | {"abs", math_abs}, | ||
706 | {"acos", math_acos}, | ||
707 | {"asin", math_asin}, | ||
708 | {"atan", math_atan}, | ||
709 | {"ceil", math_ceil}, | ||
710 | {"cos", math_cos}, | ||
711 | {"deg", math_deg}, | ||
712 | {"exp", math_exp}, | ||
713 | {"tointeger", math_toint}, | ||
714 | {"floor", math_floor}, | ||
715 | {"fmod", math_fmod}, | ||
716 | {"ult", math_ult}, | ||
717 | {"log", math_log}, | ||
718 | {"max", math_max}, | ||
719 | {"min", math_min}, | ||
720 | {"modf", math_modf}, | ||
721 | {"rad", math_rad}, | ||
722 | {"sin", math_sin}, | ||
723 | {"sqrt", math_sqrt}, | ||
724 | {"tan", math_tan}, | ||
725 | {"type", math_type}, | ||
726 | #if defined(LUA_COMPAT_MATHLIB) | ||
727 | {"atan2", math_atan}, | ||
728 | {"cosh", math_cosh}, | ||
729 | {"sinh", math_sinh}, | ||
730 | {"tanh", math_tanh}, | ||
731 | {"pow", math_pow}, | ||
732 | {"frexp", math_frexp}, | ||
733 | {"ldexp", math_ldexp}, | ||
734 | {"log10", math_log10}, | ||
735 | #endif | ||
736 | /* placeholders */ | ||
737 | {"random", NULL}, | ||
738 | {"randomseed", NULL}, | ||
739 | {"pi", NULL}, | ||
740 | {"huge", NULL}, | ||
741 | {"maxinteger", NULL}, | ||
742 | {"mininteger", NULL}, | ||
743 | {NULL, NULL} | ||
744 | }; | ||
745 | |||
746 | |||
747 | /* | ||
748 | ** Open math library | ||
749 | */ | ||
750 | LUAMOD_API int luaopen_math (lua_State *L) { | ||
751 | luaL_newlib(L, mathlib); | ||
752 | lua_pushnumber(L, PI); | ||
753 | lua_setfield(L, -2, "pi"); | ||
754 | lua_pushnumber(L, (lua_Number)HUGE_VAL); | ||
755 | lua_setfield(L, -2, "huge"); | ||
756 | lua_pushinteger(L, LUA_MAXINTEGER); | ||
757 | lua_setfield(L, -2, "maxinteger"); | ||
758 | lua_pushinteger(L, LUA_MININTEGER); | ||
759 | lua_setfield(L, -2, "mininteger"); | ||
760 | setrandfunc(L); | ||
761 | return 1; | ||
762 | } | ||
763 | |||
diff --git a/src/lua/lmem.c b/src/lua/lmem.c new file mode 100644 index 0000000..65bfa52 --- /dev/null +++ b/src/lua/lmem.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | ** $Id: lmem.c $ | ||
3 | ** Interface to Memory Manager | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lmem_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <stddef.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lgc.h" | ||
20 | #include "lmem.h" | ||
21 | #include "lobject.h" | ||
22 | #include "lstate.h" | ||
23 | |||
24 | |||
25 | #if defined(HARDMEMTESTS) | ||
26 | /* | ||
27 | ** First allocation will fail whenever not building initial state | ||
28 | ** and not shrinking a block. (This fail will trigger 'tryagain' and | ||
29 | ** a full GC cycle at every allocation.) | ||
30 | */ | ||
31 | static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { | ||
32 | if (ttisnil(&g->nilvalue) && ns > os) | ||
33 | return NULL; /* fail */ | ||
34 | else /* normal allocation */ | ||
35 | return (*g->frealloc)(g->ud, block, os, ns); | ||
36 | } | ||
37 | #else | ||
38 | #define firsttry(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) | ||
39 | #endif | ||
40 | |||
41 | |||
42 | |||
43 | |||
44 | |||
45 | /* | ||
46 | ** About the realloc function: | ||
47 | ** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize); | ||
48 | ** ('osize' is the old size, 'nsize' is the new size) | ||
49 | ** | ||
50 | ** - frealloc(ud, p, x, 0) frees the block 'p' and returns NULL. | ||
51 | ** Particularly, frealloc(ud, NULL, 0, 0) does nothing, | ||
52 | ** which is equivalent to free(NULL) in ISO C. | ||
53 | ** | ||
54 | ** - frealloc(ud, NULL, x, s) creates a new block of size 's' | ||
55 | ** (no matter 'x'). Returns NULL if it cannot create the new block. | ||
56 | ** | ||
57 | ** - otherwise, frealloc(ud, b, x, y) reallocates the block 'b' from | ||
58 | ** size 'x' to size 'y'. Returns NULL if it cannot reallocate the | ||
59 | ** block to the new size. | ||
60 | */ | ||
61 | |||
62 | |||
63 | |||
64 | |||
65 | /* | ||
66 | ** {================================================================== | ||
67 | ** Functions to allocate/deallocate arrays for the Parser | ||
68 | ** =================================================================== | ||
69 | */ | ||
70 | |||
71 | /* | ||
72 | ** Minimum size for arrays during parsing, to avoid overhead of | ||
73 | ** reallocating to size 1, then 2, and then 4. All these arrays | ||
74 | ** will be reallocated to exact sizes or erased when parsing ends. | ||
75 | */ | ||
76 | #define MINSIZEARRAY 4 | ||
77 | |||
78 | |||
79 | void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, | ||
80 | int size_elems, int limit, const char *what) { | ||
81 | void *newblock; | ||
82 | int size = *psize; | ||
83 | if (nelems + 1 <= size) /* does one extra element still fit? */ | ||
84 | return block; /* nothing to be done */ | ||
85 | if (size >= limit / 2) { /* cannot double it? */ | ||
86 | if (unlikely(size >= limit)) /* cannot grow even a little? */ | ||
87 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); | ||
88 | size = limit; /* still have at least one free place */ | ||
89 | } | ||
90 | else { | ||
91 | size *= 2; | ||
92 | if (size < MINSIZEARRAY) | ||
93 | size = MINSIZEARRAY; /* minimum size */ | ||
94 | } | ||
95 | lua_assert(nelems + 1 <= size && size <= limit); | ||
96 | /* 'limit' ensures that multiplication will not overflow */ | ||
97 | newblock = luaM_saferealloc_(L, block, cast_sizet(*psize) * size_elems, | ||
98 | cast_sizet(size) * size_elems); | ||
99 | *psize = size; /* update only when everything else is OK */ | ||
100 | return newblock; | ||
101 | } | ||
102 | |||
103 | |||
104 | /* | ||
105 | ** In prototypes, the size of the array is also its number of | ||
106 | ** elements (to save memory). So, if it cannot shrink an array | ||
107 | ** to its number of elements, the only option is to raise an | ||
108 | ** error. | ||
109 | */ | ||
110 | void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, | ||
111 | int final_n, int size_elem) { | ||
112 | void *newblock; | ||
113 | size_t oldsize = cast_sizet((*size) * size_elem); | ||
114 | size_t newsize = cast_sizet(final_n * size_elem); | ||
115 | lua_assert(newsize <= oldsize); | ||
116 | newblock = luaM_saferealloc_(L, block, oldsize, newsize); | ||
117 | *size = final_n; | ||
118 | return newblock; | ||
119 | } | ||
120 | |||
121 | /* }================================================================== */ | ||
122 | |||
123 | |||
124 | l_noret luaM_toobig (lua_State *L) { | ||
125 | luaG_runerror(L, "memory allocation error: block too big"); | ||
126 | } | ||
127 | |||
128 | |||
129 | /* | ||
130 | ** Free memory | ||
131 | */ | ||
132 | void luaM_free_ (lua_State *L, void *block, size_t osize) { | ||
133 | global_State *g = G(L); | ||
134 | lua_assert((osize == 0) == (block == NULL)); | ||
135 | (*g->frealloc)(g->ud, block, osize, 0); | ||
136 | g->GCdebt -= osize; | ||
137 | } | ||
138 | |||
139 | |||
140 | /* | ||
141 | ** In case of allocation fail, this function will call the GC to try | ||
142 | ** to free some memory and then try the allocation again. | ||
143 | ** (It should not be called when shrinking a block, because then the | ||
144 | ** interpreter may be in the middle of a collection step.) | ||
145 | */ | ||
146 | static void *tryagain (lua_State *L, void *block, | ||
147 | size_t osize, size_t nsize) { | ||
148 | global_State *g = G(L); | ||
149 | if (ttisnil(&g->nilvalue)) { /* is state fully build? */ | ||
150 | luaC_fullgc(L, 1); /* try to free some memory... */ | ||
151 | return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ | ||
152 | } | ||
153 | else return NULL; /* cannot free any memory without a full state */ | ||
154 | } | ||
155 | |||
156 | |||
157 | /* | ||
158 | ** Generic allocation routine. | ||
159 | ** If allocation fails while shrinking a block, do not try again; the | ||
160 | ** GC shrinks some blocks and it is not reentrant. | ||
161 | */ | ||
162 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { | ||
163 | void *newblock; | ||
164 | global_State *g = G(L); | ||
165 | lua_assert((osize == 0) == (block == NULL)); | ||
166 | newblock = firsttry(g, block, osize, nsize); | ||
167 | if (unlikely(newblock == NULL && nsize > 0)) { | ||
168 | if (nsize > osize) /* not shrinking a block? */ | ||
169 | newblock = tryagain(L, block, osize, nsize); | ||
170 | if (newblock == NULL) /* still no memory? */ | ||
171 | return NULL; /* do not update 'GCdebt' */ | ||
172 | } | ||
173 | lua_assert((nsize == 0) == (newblock == NULL)); | ||
174 | g->GCdebt = (g->GCdebt + nsize) - osize; | ||
175 | return newblock; | ||
176 | } | ||
177 | |||
178 | |||
179 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, | ||
180 | size_t nsize) { | ||
181 | void *newblock = luaM_realloc_(L, block, osize, nsize); | ||
182 | if (unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ | ||
183 | luaM_error(L); | ||
184 | return newblock; | ||
185 | } | ||
186 | |||
187 | |||
188 | void *luaM_malloc_ (lua_State *L, size_t size, int tag) { | ||
189 | if (size == 0) | ||
190 | return NULL; /* that's all */ | ||
191 | else { | ||
192 | global_State *g = G(L); | ||
193 | void *newblock = firsttry(g, NULL, tag, size); | ||
194 | if (unlikely(newblock == NULL)) { | ||
195 | newblock = tryagain(L, NULL, tag, size); | ||
196 | if (newblock == NULL) | ||
197 | luaM_error(L); | ||
198 | } | ||
199 | g->GCdebt += size; | ||
200 | return newblock; | ||
201 | } | ||
202 | } | ||
diff --git a/src/lua/lmem.h b/src/lua/lmem.h new file mode 100644 index 0000000..8c75a44 --- /dev/null +++ b/src/lua/lmem.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | ** $Id: lmem.h $ | ||
3 | ** Interface to Memory Manager | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lmem_h | ||
8 | #define lmem_h | ||
9 | |||
10 | |||
11 | #include <stddef.h> | ||
12 | |||
13 | #include "llimits.h" | ||
14 | #include "lua.h" | ||
15 | |||
16 | |||
17 | #define luaM_error(L) luaD_throw(L, LUA_ERRMEM) | ||
18 | |||
19 | |||
20 | /* | ||
21 | ** This macro tests whether it is safe to multiply 'n' by the size of | ||
22 | ** type 't' without overflows. Because 'e' is always constant, it avoids | ||
23 | ** the runtime division MAX_SIZET/(e). | ||
24 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' | ||
25 | ** comparison avoids a runtime comparison when overflow cannot occur. | ||
26 | ** The compiler should be able to optimize the real test by itself, but | ||
27 | ** when it does it, it may give a warning about "comparison is always | ||
28 | ** false due to limited range of data type"; the +1 tricks the compiler, | ||
29 | ** avoiding this warning but also this optimization.) | ||
30 | */ | ||
31 | #define luaM_testsize(n,e) \ | ||
32 | (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) | ||
33 | |||
34 | #define luaM_checksize(L,n,e) \ | ||
35 | (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) | ||
36 | |||
37 | |||
38 | /* | ||
39 | ** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that | ||
40 | ** the result is not larger than 'n' and cannot overflow a 'size_t' | ||
41 | ** when multiplied by the size of type 't'. (Assumes that 'n' is an | ||
42 | ** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) | ||
43 | */ | ||
44 | #define luaM_limitN(n,t) \ | ||
45 | ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ | ||
46 | cast_uint((MAX_SIZET/sizeof(t)))) | ||
47 | |||
48 | |||
49 | /* | ||
50 | ** Arrays of chars do not need any test | ||
51 | */ | ||
52 | #define luaM_reallocvchar(L,b,on,n) \ | ||
53 | cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) | ||
54 | |||
55 | #define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) | ||
56 | #define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) | ||
57 | #define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) | ||
58 | |||
59 | #define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) | ||
60 | #define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) | ||
61 | #define luaM_newvectorchecked(L,n,t) \ | ||
62 | (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) | ||
63 | |||
64 | #define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) | ||
65 | |||
66 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ | ||
67 | ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ | ||
68 | luaM_limitN(limit,t),e))) | ||
69 | |||
70 | #define luaM_reallocvector(L, v,oldn,n,t) \ | ||
71 | (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ | ||
72 | cast_sizet(n) * sizeof(t)))) | ||
73 | |||
74 | #define luaM_shrinkvector(L,v,size,fs,t) \ | ||
75 | ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) | ||
76 | |||
77 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); | ||
78 | |||
79 | /* not to be called directly */ | ||
80 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, | ||
81 | size_t size); | ||
82 | LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, | ||
83 | size_t size); | ||
84 | LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); | ||
85 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, | ||
86 | int *size, int size_elem, int limit, | ||
87 | const char *what); | ||
88 | LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, | ||
89 | int final_n, int size_elem); | ||
90 | LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); | ||
91 | |||
92 | #endif | ||
93 | |||
diff --git a/src/lua-5.3/loadlib.c b/src/lua/loadlib.c index 45f44d3..c0ec9a1 100644 --- a/src/lua-5.3/loadlib.c +++ b/src/lua/loadlib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: loadlib.c,v 1.130.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: loadlib.c $ |
3 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | ** | 5 | ** |
@@ -56,10 +56,10 @@ | |||
56 | 56 | ||
57 | 57 | ||
58 | /* | 58 | /* |
59 | ** unique key for table in the registry that keeps handles | 59 | ** key for table in the registry that keeps handles |
60 | ** for all loaded C libraries | 60 | ** for all loaded C libraries |
61 | */ | 61 | */ |
62 | static const int CLIBS = 0; | 62 | static const char *const CLIBS = "_CLIBS"; |
63 | 63 | ||
64 | #define LIB_FAIL "open" | 64 | #define LIB_FAIL "open" |
65 | 65 | ||
@@ -68,6 +68,13 @@ static const int CLIBS = 0; | |||
68 | 68 | ||
69 | 69 | ||
70 | /* | 70 | /* |
71 | ** Special type equivalent to '(void*)' for functions in gcc | ||
72 | ** (to suppress warnings when converting function pointers) | ||
73 | */ | ||
74 | typedef void (*voidf)(void); | ||
75 | |||
76 | |||
77 | /* | ||
71 | ** system-dependent functions | 78 | ** system-dependent functions |
72 | */ | 79 | */ |
73 | 80 | ||
@@ -206,7 +213,7 @@ static void *lsys_load (lua_State *L, const char *path, int seeglb) { | |||
206 | 213 | ||
207 | 214 | ||
208 | static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { | 215 | static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { |
209 | lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); | 216 | lua_CFunction f = (lua_CFunction)(voidf)GetProcAddress((HMODULE)lib, sym); |
210 | if (f == NULL) pusherror(L); | 217 | if (f == NULL) pusherror(L); |
211 | return f; | 218 | return f; |
212 | } | 219 | } |
@@ -269,8 +276,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { | |||
269 | #endif | 276 | #endif |
270 | 277 | ||
271 | 278 | ||
272 | #define AUXMARK "\1" /* auxiliary mark */ | ||
273 | |||
274 | 279 | ||
275 | /* | 280 | /* |
276 | ** return registry.LUA_NOENV as a boolean | 281 | ** return registry.LUA_NOENV as a boolean |
@@ -290,22 +295,33 @@ static int noenv (lua_State *L) { | |||
290 | static void setpath (lua_State *L, const char *fieldname, | 295 | static void setpath (lua_State *L, const char *fieldname, |
291 | const char *envname, | 296 | const char *envname, |
292 | const char *dft) { | 297 | const char *dft) { |
298 | const char *dftmark; | ||
293 | const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX); | 299 | const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX); |
294 | const char *path = getenv(nver); /* use versioned name */ | 300 | const char *path = getenv(nver); /* try versioned name */ |
295 | if (path == NULL) /* no environment variable? */ | 301 | if (path == NULL) /* no versioned environment variable? */ |
296 | path = getenv(envname); /* try unversioned name */ | 302 | path = getenv(envname); /* try unversioned name */ |
297 | if (path == NULL || noenv(L)) /* no environment variable? */ | 303 | if (path == NULL || noenv(L)) /* no environment variable? */ |
298 | lua_pushstring(L, dft); /* use default */ | 304 | lua_pushstring(L, dft); /* use default */ |
299 | else { | 305 | else if ((dftmark = strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL) |
300 | /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ | 306 | lua_pushstring(L, path); /* nothing to change */ |
301 | path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, | 307 | else { /* path contains a ";;": insert default path in its place */ |
302 | LUA_PATH_SEP AUXMARK LUA_PATH_SEP); | 308 | size_t len = strlen(path); |
303 | luaL_gsub(L, path, AUXMARK, dft); | 309 | luaL_Buffer b; |
304 | lua_remove(L, -2); /* remove result from 1st 'gsub' */ | 310 | luaL_buffinit(L, &b); |
311 | if (path < dftmark) { /* is there a prefix before ';;'? */ | ||
312 | luaL_addlstring(&b, path, dftmark - path); /* add it */ | ||
313 | luaL_addchar(&b, *LUA_PATH_SEP); | ||
314 | } | ||
315 | luaL_addstring(&b, dft); /* add default */ | ||
316 | if (dftmark < path + len - 2) { /* is there a suffix after ';;'? */ | ||
317 | luaL_addchar(&b, *LUA_PATH_SEP); | ||
318 | luaL_addlstring(&b, dftmark + 2, (path + len - 2) - dftmark); | ||
319 | } | ||
320 | luaL_pushresult(&b); | ||
305 | } | 321 | } |
306 | setprogdir(L); | 322 | setprogdir(L); |
307 | lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ | 323 | lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ |
308 | lua_pop(L, 1); /* pop versioned variable name */ | 324 | lua_pop(L, 1); /* pop versioned variable name ('nver') */ |
309 | } | 325 | } |
310 | 326 | ||
311 | /* }================================================================== */ | 327 | /* }================================================================== */ |
@@ -316,7 +332,7 @@ static void setpath (lua_State *L, const char *fieldname, | |||
316 | */ | 332 | */ |
317 | static void *checkclib (lua_State *L, const char *path) { | 333 | static void *checkclib (lua_State *L, const char *path) { |
318 | void *plib; | 334 | void *plib; |
319 | lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS); | 335 | lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); |
320 | lua_getfield(L, -1, path); | 336 | lua_getfield(L, -1, path); |
321 | plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ | 337 | plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ |
322 | lua_pop(L, 2); /* pop CLIBS table and 'plib' */ | 338 | lua_pop(L, 2); /* pop CLIBS table and 'plib' */ |
@@ -329,7 +345,7 @@ static void *checkclib (lua_State *L, const char *path) { | |||
329 | ** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries | 345 | ** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries |
330 | */ | 346 | */ |
331 | static void addtoclib (lua_State *L, const char *path, void *plib) { | 347 | static void addtoclib (lua_State *L, const char *path, void *plib) { |
332 | lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS); | 348 | lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); |
333 | lua_pushlightuserdata(L, plib); | 349 | lua_pushlightuserdata(L, plib); |
334 | lua_pushvalue(L, -1); | 350 | lua_pushvalue(L, -1); |
335 | lua_setfield(L, -3, path); /* CLIBS[path] = plib */ | 351 | lua_setfield(L, -3, path); /* CLIBS[path] = plib */ |
@@ -397,10 +413,10 @@ static int ll_loadlib (lua_State *L) { | |||
397 | if (stat == 0) /* no errors? */ | 413 | if (stat == 0) /* no errors? */ |
398 | return 1; /* return the loaded function */ | 414 | return 1; /* return the loaded function */ |
399 | else { /* error; error message is on stack top */ | 415 | else { /* error; error message is on stack top */ |
400 | lua_pushnil(L); | 416 | luaL_pushfail(L); |
401 | lua_insert(L, -2); | 417 | lua_insert(L, -2); |
402 | lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); | 418 | lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); |
403 | return 3; /* return nil, error message, and where */ | 419 | return 3; /* return fail, error message, and where */ |
404 | } | 420 | } |
405 | } | 421 | } |
406 | 422 | ||
@@ -421,14 +437,42 @@ static int readable (const char *filename) { | |||
421 | } | 437 | } |
422 | 438 | ||
423 | 439 | ||
424 | static const char *pushnexttemplate (lua_State *L, const char *path) { | 440 | /* |
425 | const char *l; | 441 | ** Get the next name in '*path' = 'name1;name2;name3;...', changing |
426 | while (*path == *LUA_PATH_SEP) path++; /* skip separators */ | 442 | ** the ending ';' to '\0' to create a zero-terminated string. Return |
427 | if (*path == '\0') return NULL; /* no more templates */ | 443 | ** NULL when list ends. |
428 | l = strchr(path, *LUA_PATH_SEP); /* find next separator */ | 444 | */ |
429 | if (l == NULL) l = path + strlen(path); | 445 | static const char *getnextfilename (char **path, char *end) { |
430 | lua_pushlstring(L, path, l - path); /* template */ | 446 | char *sep; |
431 | return l; | 447 | char *name = *path; |
448 | if (name == end) | ||
449 | return NULL; /* no more names */ | ||
450 | else if (*name == '\0') { /* from previous iteration? */ | ||
451 | *name = *LUA_PATH_SEP; /* restore separator */ | ||
452 | name++; /* skip it */ | ||
453 | } | ||
454 | sep = strchr(name, *LUA_PATH_SEP); /* find next separator */ | ||
455 | if (sep == NULL) /* separator not found? */ | ||
456 | sep = end; /* name goes until the end */ | ||
457 | *sep = '\0'; /* finish file name */ | ||
458 | *path = sep; /* will start next search from here */ | ||
459 | return name; | ||
460 | } | ||
461 | |||
462 | |||
463 | /* | ||
464 | ** Given a path such as ";blabla.so;blublu.so", pushes the string | ||
465 | ** | ||
466 | ** no file 'blabla.so' | ||
467 | ** no file 'blublu.so' | ||
468 | */ | ||
469 | static void pusherrornotfound (lua_State *L, const char *path) { | ||
470 | luaL_Buffer b; | ||
471 | luaL_buffinit(L, &b); | ||
472 | luaL_addstring(&b, "no file '"); | ||
473 | luaL_addgsub(&b, path, LUA_PATH_SEP, "'\n\tno file '"); | ||
474 | luaL_addstring(&b, "'"); | ||
475 | luaL_pushresult(&b); | ||
432 | } | 476 | } |
433 | 477 | ||
434 | 478 | ||
@@ -436,21 +480,25 @@ static const char *searchpath (lua_State *L, const char *name, | |||
436 | const char *path, | 480 | const char *path, |
437 | const char *sep, | 481 | const char *sep, |
438 | const char *dirsep) { | 482 | const char *dirsep) { |
439 | luaL_Buffer msg; /* to build error message */ | 483 | luaL_Buffer buff; |
440 | luaL_buffinit(L, &msg); | 484 | char *pathname; /* path with name inserted */ |
441 | if (*sep != '\0') /* non-empty separator? */ | 485 | char *endpathname; /* its end */ |
486 | const char *filename; | ||
487 | /* separator is non-empty and appears in 'name'? */ | ||
488 | if (*sep != '\0' && strchr(name, *sep) != NULL) | ||
442 | name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ | 489 | name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ |
443 | while ((path = pushnexttemplate(L, path)) != NULL) { | 490 | luaL_buffinit(L, &buff); |
444 | const char *filename = luaL_gsub(L, lua_tostring(L, -1), | 491 | /* add path to the buffer, replacing marks ('?') with the file name */ |
445 | LUA_PATH_MARK, name); | 492 | luaL_addgsub(&buff, path, LUA_PATH_MARK, name); |
446 | lua_remove(L, -2); /* remove path template */ | 493 | luaL_addchar(&buff, '\0'); |
494 | pathname = luaL_buffaddr(&buff); /* writable list of file names */ | ||
495 | endpathname = pathname + luaL_bufflen(&buff) - 1; | ||
496 | while ((filename = getnextfilename(&pathname, endpathname)) != NULL) { | ||
447 | if (readable(filename)) /* does file exist and is readable? */ | 497 | if (readable(filename)) /* does file exist and is readable? */ |
448 | return filename; /* return that file name */ | 498 | return lua_pushstring(L, filename); /* save and return name */ |
449 | lua_pushfstring(L, "\n\tno file '%s'", filename); | ||
450 | lua_remove(L, -2); /* remove file name */ | ||
451 | luaL_addvalue(&msg); /* concatenate error msg. entry */ | ||
452 | } | 499 | } |
453 | luaL_pushresult(&msg); /* create error message */ | 500 | luaL_pushresult(&buff); /* push path to create error message */ |
501 | pusherrornotfound(L, lua_tostring(L, -1)); /* create error message */ | ||
454 | return NULL; /* not found */ | 502 | return NULL; /* not found */ |
455 | } | 503 | } |
456 | 504 | ||
@@ -462,9 +510,9 @@ static int ll_searchpath (lua_State *L) { | |||
462 | luaL_optstring(L, 4, LUA_DIRSEP)); | 510 | luaL_optstring(L, 4, LUA_DIRSEP)); |
463 | if (f != NULL) return 1; | 511 | if (f != NULL) return 1; |
464 | else { /* error message is on top of the stack */ | 512 | else { /* error message is on top of the stack */ |
465 | lua_pushnil(L); | 513 | luaL_pushfail(L); |
466 | lua_insert(L, -2); | 514 | lua_insert(L, -2); |
467 | return 2; /* return nil + error message */ | 515 | return 2; /* return fail + error message */ |
468 | } | 516 | } |
469 | } | 517 | } |
470 | 518 | ||
@@ -548,7 +596,7 @@ static int searcher_Croot (lua_State *L) { | |||
548 | if (stat != ERRFUNC) | 596 | if (stat != ERRFUNC) |
549 | return checkload(L, 0, filename); /* real error */ | 597 | return checkload(L, 0, filename); /* real error */ |
550 | else { /* open function not found */ | 598 | else { /* open function not found */ |
551 | lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename); | 599 | lua_pushfstring(L, "no module '%s' in file '%s'", name, filename); |
552 | return 1; | 600 | return 1; |
553 | } | 601 | } |
554 | } | 602 | } |
@@ -560,23 +608,30 @@ static int searcher_Croot (lua_State *L) { | |||
560 | static int searcher_preload (lua_State *L) { | 608 | static int searcher_preload (lua_State *L) { |
561 | const char *name = luaL_checkstring(L, 1); | 609 | const char *name = luaL_checkstring(L, 1); |
562 | lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); | 610 | lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); |
563 | if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */ | 611 | if (lua_getfield(L, -1, name) == LUA_TNIL) { /* not found? */ |
564 | lua_pushfstring(L, "\n\tno field package.preload['%s']", name); | 612 | lua_pushfstring(L, "no field package.preload['%s']", name); |
565 | return 1; | 613 | return 1; |
614 | } | ||
615 | else { | ||
616 | lua_pushliteral(L, ":preload:"); | ||
617 | return 2; | ||
618 | } | ||
566 | } | 619 | } |
567 | 620 | ||
568 | 621 | ||
569 | static void findloader (lua_State *L, const char *name) { | 622 | static void findloader (lua_State *L, const char *name) { |
570 | int i; | 623 | int i; |
571 | luaL_Buffer msg; /* to build error message */ | 624 | luaL_Buffer msg; /* to build error message */ |
572 | luaL_buffinit(L, &msg); | ||
573 | /* push 'package.searchers' to index 3 in the stack */ | 625 | /* push 'package.searchers' to index 3 in the stack */ |
574 | if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE) | 626 | if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE) |
575 | luaL_error(L, "'package.searchers' must be a table"); | 627 | luaL_error(L, "'package.searchers' must be a table"); |
628 | luaL_buffinit(L, &msg); | ||
576 | /* iterate over available searchers to find a loader */ | 629 | /* iterate over available searchers to find a loader */ |
577 | for (i = 1; ; i++) { | 630 | for (i = 1; ; i++) { |
631 | luaL_addstring(&msg, "\n\t"); /* error-message prefix */ | ||
578 | if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */ | 632 | if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */ |
579 | lua_pop(L, 1); /* remove nil */ | 633 | lua_pop(L, 1); /* remove nil */ |
634 | luaL_buffsub(&msg, 2); /* remove prefix */ | ||
580 | luaL_pushresult(&msg); /* create error message */ | 635 | luaL_pushresult(&msg); /* create error message */ |
581 | luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); | 636 | luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); |
582 | } | 637 | } |
@@ -588,8 +643,10 @@ static void findloader (lua_State *L, const char *name) { | |||
588 | lua_pop(L, 1); /* remove extra return */ | 643 | lua_pop(L, 1); /* remove extra return */ |
589 | luaL_addvalue(&msg); /* concatenate error message */ | 644 | luaL_addvalue(&msg); /* concatenate error message */ |
590 | } | 645 | } |
591 | else | 646 | else { /* no error message */ |
592 | lua_pop(L, 2); /* remove both returns */ | 647 | lua_pop(L, 2); /* remove both returns */ |
648 | luaL_buffsub(&msg, 2); /* remove prefix */ | ||
649 | } | ||
593 | } | 650 | } |
594 | } | 651 | } |
595 | 652 | ||
@@ -604,113 +661,33 @@ static int ll_require (lua_State *L) { | |||
604 | /* else must load package */ | 661 | /* else must load package */ |
605 | lua_pop(L, 1); /* remove 'getfield' result */ | 662 | lua_pop(L, 1); /* remove 'getfield' result */ |
606 | findloader(L, name); | 663 | findloader(L, name); |
607 | lua_pushstring(L, name); /* pass name as argument to module loader */ | 664 | lua_rotate(L, -2, 1); /* function <-> loader data */ |
608 | lua_insert(L, -2); /* name is 1st argument (before search data) */ | 665 | lua_pushvalue(L, 1); /* name is 1st argument to module loader */ |
666 | lua_pushvalue(L, -3); /* loader data is 2nd argument */ | ||
667 | /* stack: ...; loader data; loader function; mod. name; loader data */ | ||
609 | lua_call(L, 2, 1); /* run loader to load module */ | 668 | lua_call(L, 2, 1); /* run loader to load module */ |
669 | /* stack: ...; loader data; result from loader */ | ||
610 | if (!lua_isnil(L, -1)) /* non-nil return? */ | 670 | if (!lua_isnil(L, -1)) /* non-nil return? */ |
611 | lua_setfield(L, 2, name); /* LOADED[name] = returned value */ | 671 | lua_setfield(L, 2, name); /* LOADED[name] = returned value */ |
672 | else | ||
673 | lua_pop(L, 1); /* pop nil */ | ||
612 | if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ | 674 | if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ |
613 | lua_pushboolean(L, 1); /* use true as result */ | 675 | lua_pushboolean(L, 1); /* use true as result */ |
614 | lua_pushvalue(L, -1); /* extra copy to be returned */ | 676 | lua_copy(L, -1, -2); /* replace loader result */ |
615 | lua_setfield(L, 2, name); /* LOADED[name] = true */ | 677 | lua_setfield(L, 2, name); /* LOADED[name] = true */ |
616 | } | 678 | } |
617 | return 1; | 679 | lua_rotate(L, -2, 1); /* loader data <-> module result */ |
680 | return 2; /* return module result and loader data */ | ||
618 | } | 681 | } |
619 | 682 | ||
620 | /* }====================================================== */ | 683 | /* }====================================================== */ |
621 | 684 | ||
622 | 685 | ||
623 | 686 | ||
624 | /* | ||
625 | ** {====================================================== | ||
626 | ** 'module' function | ||
627 | ** ======================================================= | ||
628 | */ | ||
629 | #if defined(LUA_COMPAT_MODULE) | ||
630 | |||
631 | /* | ||
632 | ** changes the environment variable of calling function | ||
633 | */ | ||
634 | static void set_env (lua_State *L) { | ||
635 | lua_Debug ar; | ||
636 | if (lua_getstack(L, 1, &ar) == 0 || | ||
637 | lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ | ||
638 | lua_iscfunction(L, -1)) | ||
639 | luaL_error(L, "'module' not called from a Lua function"); | ||
640 | lua_pushvalue(L, -2); /* copy new environment table to top */ | ||
641 | lua_setupvalue(L, -2, 1); | ||
642 | lua_pop(L, 1); /* remove function */ | ||
643 | } | ||
644 | |||
645 | |||
646 | static void dooptions (lua_State *L, int n) { | ||
647 | int i; | ||
648 | for (i = 2; i <= n; i++) { | ||
649 | if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ | ||
650 | lua_pushvalue(L, i); /* get option (a function) */ | ||
651 | lua_pushvalue(L, -2); /* module */ | ||
652 | lua_call(L, 1, 0); | ||
653 | } | ||
654 | } | ||
655 | } | ||
656 | |||
657 | |||
658 | static void modinit (lua_State *L, const char *modname) { | ||
659 | const char *dot; | ||
660 | lua_pushvalue(L, -1); | ||
661 | lua_setfield(L, -2, "_M"); /* module._M = module */ | ||
662 | lua_pushstring(L, modname); | ||
663 | lua_setfield(L, -2, "_NAME"); | ||
664 | dot = strrchr(modname, '.'); /* look for last dot in module name */ | ||
665 | if (dot == NULL) dot = modname; | ||
666 | else dot++; | ||
667 | /* set _PACKAGE as package name (full module name minus last part) */ | ||
668 | lua_pushlstring(L, modname, dot - modname); | ||
669 | lua_setfield(L, -2, "_PACKAGE"); | ||
670 | } | ||
671 | |||
672 | |||
673 | static int ll_module (lua_State *L) { | ||
674 | const char *modname = luaL_checkstring(L, 1); | ||
675 | int lastarg = lua_gettop(L); /* last parameter */ | ||
676 | luaL_pushmodule(L, modname, 1); /* get/create module table */ | ||
677 | /* check whether table already has a _NAME field */ | ||
678 | if (lua_getfield(L, -1, "_NAME") != LUA_TNIL) | ||
679 | lua_pop(L, 1); /* table is an initialized module */ | ||
680 | else { /* no; initialize it */ | ||
681 | lua_pop(L, 1); | ||
682 | modinit(L, modname); | ||
683 | } | ||
684 | lua_pushvalue(L, -1); | ||
685 | set_env(L); | ||
686 | dooptions(L, lastarg); | ||
687 | return 1; | ||
688 | } | ||
689 | |||
690 | |||
691 | static int ll_seeall (lua_State *L) { | ||
692 | luaL_checktype(L, 1, LUA_TTABLE); | ||
693 | if (!lua_getmetatable(L, 1)) { | ||
694 | lua_createtable(L, 0, 1); /* create new metatable */ | ||
695 | lua_pushvalue(L, -1); | ||
696 | lua_setmetatable(L, 1); | ||
697 | } | ||
698 | lua_pushglobaltable(L); | ||
699 | lua_setfield(L, -2, "__index"); /* mt.__index = _G */ | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | #endif | ||
704 | /* }====================================================== */ | ||
705 | |||
706 | |||
707 | 687 | ||
708 | static const luaL_Reg pk_funcs[] = { | 688 | static const luaL_Reg pk_funcs[] = { |
709 | {"loadlib", ll_loadlib}, | 689 | {"loadlib", ll_loadlib}, |
710 | {"searchpath", ll_searchpath}, | 690 | {"searchpath", ll_searchpath}, |
711 | #if defined(LUA_COMPAT_MODULE) | ||
712 | {"seeall", ll_seeall}, | ||
713 | #endif | ||
714 | /* placeholders */ | 691 | /* placeholders */ |
715 | {"preload", NULL}, | 692 | {"preload", NULL}, |
716 | {"cpath", NULL}, | 693 | {"cpath", NULL}, |
@@ -722,9 +699,6 @@ static const luaL_Reg pk_funcs[] = { | |||
722 | 699 | ||
723 | 700 | ||
724 | static const luaL_Reg ll_funcs[] = { | 701 | static const luaL_Reg ll_funcs[] = { |
725 | #if defined(LUA_COMPAT_MODULE) | ||
726 | {"module", ll_module}, | ||
727 | #endif | ||
728 | {"require", ll_require}, | 702 | {"require", ll_require}, |
729 | {NULL, NULL} | 703 | {NULL, NULL} |
730 | }; | 704 | }; |
@@ -742,10 +716,6 @@ static void createsearcherstable (lua_State *L) { | |||
742 | lua_pushcclosure(L, searchers[i], 1); | 716 | lua_pushcclosure(L, searchers[i], 1); |
743 | lua_rawseti(L, -2, i+1); | 717 | lua_rawseti(L, -2, i+1); |
744 | } | 718 | } |
745 | #if defined(LUA_COMPAT_LOADERS) | ||
746 | lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ | ||
747 | lua_setfield(L, -3, "loaders"); /* put it in field 'loaders' */ | ||
748 | #endif | ||
749 | lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ | 719 | lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ |
750 | } | 720 | } |
751 | 721 | ||
@@ -755,12 +725,11 @@ static void createsearcherstable (lua_State *L) { | |||
755 | ** setting a finalizer to close all libraries when closing state. | 725 | ** setting a finalizer to close all libraries when closing state. |
756 | */ | 726 | */ |
757 | static void createclibstable (lua_State *L) { | 727 | static void createclibstable (lua_State *L) { |
758 | lua_newtable(L); /* create CLIBS table */ | 728 | luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */ |
759 | lua_createtable(L, 0, 1); /* create metatable for CLIBS */ | 729 | lua_createtable(L, 0, 1); /* create metatable for CLIBS */ |
760 | lua_pushcfunction(L, gctm); | 730 | lua_pushcfunction(L, gctm); |
761 | lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ | 731 | lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ |
762 | lua_setmetatable(L, -2); | 732 | lua_setmetatable(L, -2); |
763 | lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); /* set CLIBS table in registry */ | ||
764 | } | 733 | } |
765 | 734 | ||
766 | 735 | ||
diff --git a/src/lua-5.3/lobject.c b/src/lua/lobject.c index 355bf58..b4efae4 100644 --- a/src/lua-5.3/lobject.c +++ b/src/lua/lobject.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $ | 2 | ** $Id: lobject.c $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -29,36 +29,6 @@ | |||
29 | #include "lvm.h" | 29 | #include "lvm.h" |
30 | 30 | ||
31 | 31 | ||
32 | |||
33 | LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; | ||
34 | |||
35 | |||
36 | /* | ||
37 | ** converts an integer to a "floating point byte", represented as | ||
38 | ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if | ||
39 | ** eeeee != 0 and (xxx) otherwise. | ||
40 | */ | ||
41 | int luaO_int2fb (unsigned int x) { | ||
42 | int e = 0; /* exponent */ | ||
43 | if (x < 8) return x; | ||
44 | while (x >= (8 << 4)) { /* coarse steps */ | ||
45 | x = (x + 0xf) >> 4; /* x = ceil(x / 16) */ | ||
46 | e += 4; | ||
47 | } | ||
48 | while (x >= (8 << 1)) { /* fine steps */ | ||
49 | x = (x + 1) >> 1; /* x = ceil(x / 2) */ | ||
50 | e++; | ||
51 | } | ||
52 | return ((e+1) << 3) | (cast_int(x) - 8); | ||
53 | } | ||
54 | |||
55 | |||
56 | /* converts back */ | ||
57 | int luaO_fb2int (int x) { | ||
58 | return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1); | ||
59 | } | ||
60 | |||
61 | |||
62 | /* | 32 | /* |
63 | ** Computes ceil(log2(x)) | 33 | ** Computes ceil(log2(x)) |
64 | */ | 34 | */ |
@@ -87,7 +57,7 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, | |||
87 | case LUA_OPSUB:return intop(-, v1, v2); | 57 | case LUA_OPSUB:return intop(-, v1, v2); |
88 | case LUA_OPMUL:return intop(*, v1, v2); | 58 | case LUA_OPMUL:return intop(*, v1, v2); |
89 | case LUA_OPMOD: return luaV_mod(L, v1, v2); | 59 | case LUA_OPMOD: return luaV_mod(L, v1, v2); |
90 | case LUA_OPIDIV: return luaV_div(L, v1, v2); | 60 | case LUA_OPIDIV: return luaV_idiv(L, v1, v2); |
91 | case LUA_OPBAND: return intop(&, v1, v2); | 61 | case LUA_OPBAND: return intop(&, v1, v2); |
92 | case LUA_OPBOR: return intop(|, v1, v2); | 62 | case LUA_OPBOR: return intop(|, v1, v2); |
93 | case LUA_OPBXOR: return intop(^, v1, v2); | 63 | case LUA_OPBXOR: return intop(^, v1, v2); |
@@ -110,53 +80,55 @@ static lua_Number numarith (lua_State *L, int op, lua_Number v1, | |||
110 | case LUA_OPPOW: return luai_numpow(L, v1, v2); | 80 | case LUA_OPPOW: return luai_numpow(L, v1, v2); |
111 | case LUA_OPIDIV: return luai_numidiv(L, v1, v2); | 81 | case LUA_OPIDIV: return luai_numidiv(L, v1, v2); |
112 | case LUA_OPUNM: return luai_numunm(L, v1); | 82 | case LUA_OPUNM: return luai_numunm(L, v1); |
113 | case LUA_OPMOD: { | 83 | case LUA_OPMOD: return luaV_modf(L, v1, v2); |
114 | lua_Number m; | ||
115 | luai_nummod(L, v1, v2, m); | ||
116 | return m; | ||
117 | } | ||
118 | default: lua_assert(0); return 0; | 84 | default: lua_assert(0); return 0; |
119 | } | 85 | } |
120 | } | 86 | } |
121 | 87 | ||
122 | 88 | ||
123 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | 89 | int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2, |
124 | TValue *res) { | 90 | TValue *res) { |
125 | switch (op) { | 91 | switch (op) { |
126 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: | 92 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: |
127 | case LUA_OPSHL: case LUA_OPSHR: | 93 | case LUA_OPSHL: case LUA_OPSHR: |
128 | case LUA_OPBNOT: { /* operate only on integers */ | 94 | case LUA_OPBNOT: { /* operate only on integers */ |
129 | lua_Integer i1; lua_Integer i2; | 95 | lua_Integer i1; lua_Integer i2; |
130 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | 96 | if (tointegerns(p1, &i1) && tointegerns(p2, &i2)) { |
131 | setivalue(res, intarith(L, op, i1, i2)); | 97 | setivalue(res, intarith(L, op, i1, i2)); |
132 | return; | 98 | return 1; |
133 | } | 99 | } |
134 | else break; /* go to the end */ | 100 | else return 0; /* fail */ |
135 | } | 101 | } |
136 | case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ | 102 | case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ |
137 | lua_Number n1; lua_Number n2; | 103 | lua_Number n1; lua_Number n2; |
138 | if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | 104 | if (tonumberns(p1, n1) && tonumberns(p2, n2)) { |
139 | setfltvalue(res, numarith(L, op, n1, n2)); | 105 | setfltvalue(res, numarith(L, op, n1, n2)); |
140 | return; | 106 | return 1; |
141 | } | 107 | } |
142 | else break; /* go to the end */ | 108 | else return 0; /* fail */ |
143 | } | 109 | } |
144 | default: { /* other operations */ | 110 | default: { /* other operations */ |
145 | lua_Number n1; lua_Number n2; | 111 | lua_Number n1; lua_Number n2; |
146 | if (ttisinteger(p1) && ttisinteger(p2)) { | 112 | if (ttisinteger(p1) && ttisinteger(p2)) { |
147 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); | 113 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); |
148 | return; | 114 | return 1; |
149 | } | 115 | } |
150 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | 116 | else if (tonumberns(p1, n1) && tonumberns(p2, n2)) { |
151 | setfltvalue(res, numarith(L, op, n1, n2)); | 117 | setfltvalue(res, numarith(L, op, n1, n2)); |
152 | return; | 118 | return 1; |
153 | } | 119 | } |
154 | else break; /* go to the end */ | 120 | else return 0; /* fail */ |
155 | } | 121 | } |
156 | } | 122 | } |
157 | /* could not perform raw operation; try metamethod */ | 123 | } |
158 | lua_assert(L != NULL); /* should not fail when folding (compile time) */ | 124 | |
159 | luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD)); | 125 | |
126 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | ||
127 | StkId res) { | ||
128 | if (!luaO_rawarith(L, op, p1, p2, s2v(res))) { | ||
129 | /* could not perform raw operation; try metamethod */ | ||
130 | luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD)); | ||
131 | } | ||
160 | } | 132 | } |
161 | 133 | ||
162 | 134 | ||
@@ -187,7 +159,7 @@ static int isneg (const char **s) { | |||
187 | #define MAXSIGDIG 30 | 159 | #define MAXSIGDIG 30 |
188 | 160 | ||
189 | /* | 161 | /* |
190 | ** convert an hexadecimal numeric string to a number, following | 162 | ** convert a hexadecimal numeric string to a number, following |
191 | ** C99 specification for 'strtod' | 163 | ** C99 specification for 'strtod' |
192 | */ | 164 | */ |
193 | static lua_Number lua_strx2number (const char *s, char **endptr) { | 165 | static lua_Number lua_strx2number (const char *s, char **endptr) { |
@@ -198,9 +170,9 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { | |||
198 | int e = 0; /* exponent correction */ | 170 | int e = 0; /* exponent correction */ |
199 | int neg; /* 1 if number is negative */ | 171 | int neg; /* 1 if number is negative */ |
200 | int hasdot = 0; /* true after seen a dot */ | 172 | int hasdot = 0; /* true after seen a dot */ |
201 | *endptr = cast(char *, s); /* nothing is valid yet */ | 173 | *endptr = cast_charp(s); /* nothing is valid yet */ |
202 | while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ | 174 | while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ |
203 | neg = isneg(&s); /* check signal */ | 175 | neg = isneg(&s); /* check sign */ |
204 | if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ | 176 | if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ |
205 | return 0.0; /* invalid format (no '0x') */ | 177 | return 0.0; /* invalid format (no '0x') */ |
206 | for (s += 2; ; s++) { /* skip '0x' and read numeral */ | 178 | for (s += 2; ; s++) { /* skip '0x' and read numeral */ |
@@ -220,20 +192,20 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { | |||
220 | } | 192 | } |
221 | if (nosigdig + sigdig == 0) /* no digits? */ | 193 | if (nosigdig + sigdig == 0) /* no digits? */ |
222 | return 0.0; /* invalid format */ | 194 | return 0.0; /* invalid format */ |
223 | *endptr = cast(char *, s); /* valid up to here */ | 195 | *endptr = cast_charp(s); /* valid up to here */ |
224 | e *= 4; /* each digit multiplies/divides value by 2^4 */ | 196 | e *= 4; /* each digit multiplies/divides value by 2^4 */ |
225 | if (*s == 'p' || *s == 'P') { /* exponent part? */ | 197 | if (*s == 'p' || *s == 'P') { /* exponent part? */ |
226 | int exp1 = 0; /* exponent value */ | 198 | int exp1 = 0; /* exponent value */ |
227 | int neg1; /* exponent signal */ | 199 | int neg1; /* exponent sign */ |
228 | s++; /* skip 'p' */ | 200 | s++; /* skip 'p' */ |
229 | neg1 = isneg(&s); /* signal */ | 201 | neg1 = isneg(&s); /* sign */ |
230 | if (!lisdigit(cast_uchar(*s))) | 202 | if (!lisdigit(cast_uchar(*s))) |
231 | return 0.0; /* invalid; must have at least one digit */ | 203 | return 0.0; /* invalid; must have at least one digit */ |
232 | while (lisdigit(cast_uchar(*s))) /* read exponent */ | 204 | while (lisdigit(cast_uchar(*s))) /* read exponent */ |
233 | exp1 = exp1 * 10 + *(s++) - '0'; | 205 | exp1 = exp1 * 10 + *(s++) - '0'; |
234 | if (neg1) exp1 = -exp1; | 206 | if (neg1) exp1 = -exp1; |
235 | e += exp1; | 207 | e += exp1; |
236 | *endptr = cast(char *, s); /* valid up to here */ | 208 | *endptr = cast_charp(s); /* valid up to here */ |
237 | } | 209 | } |
238 | if (neg) r = -r; | 210 | if (neg) r = -r; |
239 | return l_mathop(ldexp)(r, e); | 211 | return l_mathop(ldexp)(r, e); |
@@ -262,7 +234,7 @@ static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { | |||
262 | ** Convert string 's' to a Lua number (put in 'result'). Return NULL | 234 | ** Convert string 's' to a Lua number (put in 'result'). Return NULL |
263 | ** on fail or the address of the ending '\0' on success. | 235 | ** on fail or the address of the ending '\0' on success. |
264 | ** 'pmode' points to (and 'mode' contains) special things in the string: | 236 | ** 'pmode' points to (and 'mode' contains) special things in the string: |
265 | ** - 'x'/'X' means an hexadecimal numeral | 237 | ** - 'x'/'X' means a hexadecimal numeral |
266 | ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) | 238 | ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) |
267 | ** - '.' just optimizes the search for the common case (nothing special) | 239 | ** - '.' just optimizes the search for the common case (nothing special) |
268 | ** This function accepts both the current locale or a dot as the radix | 240 | ** This function accepts both the current locale or a dot as the radix |
@@ -345,17 +317,17 @@ size_t luaO_str2num (const char *s, TValue *o) { | |||
345 | 317 | ||
346 | int luaO_utf8esc (char *buff, unsigned long x) { | 318 | int luaO_utf8esc (char *buff, unsigned long x) { |
347 | int n = 1; /* number of bytes put in buffer (backwards) */ | 319 | int n = 1; /* number of bytes put in buffer (backwards) */ |
348 | lua_assert(x <= 0x10FFFF); | 320 | lua_assert(x <= 0x7FFFFFFFu); |
349 | if (x < 0x80) /* ascii? */ | 321 | if (x < 0x80) /* ascii? */ |
350 | buff[UTF8BUFFSZ - 1] = cast(char, x); | 322 | buff[UTF8BUFFSZ - 1] = cast_char(x); |
351 | else { /* need continuation bytes */ | 323 | else { /* need continuation bytes */ |
352 | unsigned int mfb = 0x3f; /* maximum that fits in first byte */ | 324 | unsigned int mfb = 0x3f; /* maximum that fits in first byte */ |
353 | do { /* add continuation bytes */ | 325 | do { /* add continuation bytes */ |
354 | buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f)); | 326 | buff[UTF8BUFFSZ - (n++)] = cast_char(0x80 | (x & 0x3f)); |
355 | x >>= 6; /* remove added bits */ | 327 | x >>= 6; /* remove added bits */ |
356 | mfb >>= 1; /* now there is one less bit available in first byte */ | 328 | mfb >>= 1; /* now there is one less bit available in first byte */ |
357 | } while (x > mfb); /* still needs continuation byte? */ | 329 | } while (x > mfb); /* still needs continuation byte? */ |
358 | buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */ | 330 | buff[UTF8BUFFSZ - n] = cast_char((~mfb << 1) | x); /* add first byte */ |
359 | } | 331 | } |
360 | return n; | 332 | return n; |
361 | } | 333 | } |
@@ -366,88 +338,178 @@ int luaO_utf8esc (char *buff, unsigned long x) { | |||
366 | 338 | ||
367 | 339 | ||
368 | /* | 340 | /* |
369 | ** Convert a number object to a string | 341 | ** Convert a number object to a string, adding it to a buffer |
370 | */ | 342 | */ |
371 | void luaO_tostring (lua_State *L, StkId obj) { | 343 | static int tostringbuff (TValue *obj, char *buff) { |
372 | char buff[MAXNUMBER2STR]; | 344 | int len; |
373 | size_t len; | ||
374 | lua_assert(ttisnumber(obj)); | 345 | lua_assert(ttisnumber(obj)); |
375 | if (ttisinteger(obj)) | 346 | if (ttisinteger(obj)) |
376 | len = lua_integer2str(buff, sizeof(buff), ivalue(obj)); | 347 | len = lua_integer2str(buff, MAXNUMBER2STR, ivalue(obj)); |
377 | else { | 348 | else { |
378 | len = lua_number2str(buff, sizeof(buff), fltvalue(obj)); | 349 | len = lua_number2str(buff, MAXNUMBER2STR, fltvalue(obj)); |
379 | #if !defined(LUA_COMPAT_FLOATSTRING) | ||
380 | if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ | 350 | if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ |
381 | buff[len++] = lua_getlocaledecpoint(); | 351 | buff[len++] = lua_getlocaledecpoint(); |
382 | buff[len++] = '0'; /* adds '.0' to result */ | 352 | buff[len++] = '0'; /* adds '.0' to result */ |
383 | } | 353 | } |
384 | #endif | ||
385 | } | 354 | } |
386 | setsvalue2s(L, obj, luaS_newlstr(L, buff, len)); | 355 | return len; |
387 | } | 356 | } |
388 | 357 | ||
389 | 358 | ||
390 | static void pushstr (lua_State *L, const char *str, size_t l) { | 359 | /* |
360 | ** Convert a number object to a Lua string, replacing the value at 'obj' | ||
361 | */ | ||
362 | void luaO_tostring (lua_State *L, TValue *obj) { | ||
363 | char buff[MAXNUMBER2STR]; | ||
364 | int len = tostringbuff(obj, buff); | ||
365 | setsvalue(L, obj, luaS_newlstr(L, buff, len)); | ||
366 | } | ||
367 | |||
368 | |||
369 | |||
370 | |||
371 | /* | ||
372 | ** {================================================================== | ||
373 | ** 'luaO_pushvfstring' | ||
374 | ** =================================================================== | ||
375 | */ | ||
376 | |||
377 | /* size for buffer space used by 'luaO_pushvfstring' */ | ||
378 | #define BUFVFS 400 | ||
379 | |||
380 | /* buffer used by 'luaO_pushvfstring' */ | ||
381 | typedef struct BuffFS { | ||
382 | lua_State *L; | ||
383 | int pushed; /* number of string pieces already on the stack */ | ||
384 | int blen; /* length of partial string in 'space' */ | ||
385 | char space[BUFVFS]; /* holds last part of the result */ | ||
386 | } BuffFS; | ||
387 | |||
388 | |||
389 | /* | ||
390 | ** Push given string to the stack, as part of the buffer. If the stack | ||
391 | ** is almost full, join all partial strings in the stack into one. | ||
392 | */ | ||
393 | static void pushstr (BuffFS *buff, const char *str, size_t l) { | ||
394 | lua_State *L = buff->L; | ||
391 | setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); | 395 | setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); |
392 | luaD_inctop(L); | 396 | L->top++; /* may use one extra slot */ |
397 | buff->pushed++; | ||
398 | if (buff->pushed > 1 && L->top + 1 >= L->stack_last) { | ||
399 | luaV_concat(L, buff->pushed); /* join all partial results into one */ | ||
400 | buff->pushed = 1; | ||
401 | } | ||
393 | } | 402 | } |
394 | 403 | ||
395 | 404 | ||
396 | /* | 405 | /* |
397 | ** this function handles only '%d', '%c', '%f', '%p', and '%s' | 406 | ** empty the buffer space into the stack |
407 | */ | ||
408 | static void clearbuff (BuffFS *buff) { | ||
409 | pushstr(buff, buff->space, buff->blen); /* push buffer contents */ | ||
410 | buff->blen = 0; /* space now is empty */ | ||
411 | } | ||
412 | |||
413 | |||
414 | /* | ||
415 | ** Get a space of size 'sz' in the buffer. If buffer has not enough | ||
416 | ** space, empty it. 'sz' must fit in an empty buffer. | ||
417 | */ | ||
418 | static char *getbuff (BuffFS *buff, int sz) { | ||
419 | lua_assert(buff->blen <= BUFVFS); lua_assert(sz <= BUFVFS); | ||
420 | if (sz > BUFVFS - buff->blen) /* not enough space? */ | ||
421 | clearbuff(buff); | ||
422 | return buff->space + buff->blen; | ||
423 | } | ||
424 | |||
425 | |||
426 | #define addsize(b,sz) ((b)->blen += (sz)) | ||
427 | |||
428 | |||
429 | /* | ||
430 | ** Add 'str' to the buffer. If string is larger than the buffer space, | ||
431 | ** push the string directly to the stack. | ||
432 | */ | ||
433 | static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { | ||
434 | if (slen <= BUFVFS) { /* does string fit into buffer? */ | ||
435 | char *bf = getbuff(buff, cast_int(slen)); | ||
436 | memcpy(bf, str, slen); /* add string to buffer */ | ||
437 | addsize(buff, cast_int(slen)); | ||
438 | } | ||
439 | else { /* string larger than buffer */ | ||
440 | clearbuff(buff); /* string comes after buffer's content */ | ||
441 | pushstr(buff, str, slen); /* push string */ | ||
442 | } | ||
443 | } | ||
444 | |||
445 | |||
446 | /* | ||
447 | ** Add a number to the buffer. | ||
448 | */ | ||
449 | static void addnum2buff (BuffFS *buff, TValue *num) { | ||
450 | char *numbuff = getbuff(buff, MAXNUMBER2STR); | ||
451 | int len = tostringbuff(num, numbuff); /* format number into 'numbuff' */ | ||
452 | addsize(buff, len); | ||
453 | } | ||
454 | |||
455 | |||
456 | /* | ||
457 | ** this function handles only '%d', '%c', '%f', '%p', '%s', and '%%' | ||
398 | conventional formats, plus Lua-specific '%I' and '%U' | 458 | conventional formats, plus Lua-specific '%I' and '%U' |
399 | */ | 459 | */ |
400 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | 460 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
401 | int n = 0; | 461 | BuffFS buff; /* holds last part of the result */ |
402 | for (;;) { | 462 | const char *e; /* points to next '%' */ |
403 | const char *e = strchr(fmt, '%'); | 463 | buff.pushed = buff.blen = 0; |
404 | if (e == NULL) break; | 464 | buff.L = L; |
405 | pushstr(L, fmt, e - fmt); | 465 | while ((e = strchr(fmt, '%')) != NULL) { |
406 | switch (*(e+1)) { | 466 | addstr2buff(&buff, fmt, e - fmt); /* add 'fmt' up to '%' */ |
467 | switch (*(e + 1)) { /* conversion specifier */ | ||
407 | case 's': { /* zero-terminated string */ | 468 | case 's': { /* zero-terminated string */ |
408 | const char *s = va_arg(argp, char *); | 469 | const char *s = va_arg(argp, char *); |
409 | if (s == NULL) s = "(null)"; | 470 | if (s == NULL) s = "(null)"; |
410 | pushstr(L, s, strlen(s)); | 471 | addstr2buff(&buff, s, strlen(s)); |
411 | break; | 472 | break; |
412 | } | 473 | } |
413 | case 'c': { /* an 'int' as a character */ | 474 | case 'c': { /* an 'int' as a character */ |
414 | char buff = cast(char, va_arg(argp, int)); | 475 | char c = cast_uchar(va_arg(argp, int)); |
415 | if (lisprint(cast_uchar(buff))) | 476 | addstr2buff(&buff, &c, sizeof(char)); |
416 | pushstr(L, &buff, 1); | ||
417 | else /* non-printable character; print its code */ | ||
418 | luaO_pushfstring(L, "<\\%d>", cast_uchar(buff)); | ||
419 | break; | 477 | break; |
420 | } | 478 | } |
421 | case 'd': { /* an 'int' */ | 479 | case 'd': { /* an 'int' */ |
422 | setivalue(L->top, va_arg(argp, int)); | 480 | TValue num; |
423 | goto top2str; | 481 | setivalue(&num, va_arg(argp, int)); |
482 | addnum2buff(&buff, &num); | ||
483 | break; | ||
424 | } | 484 | } |
425 | case 'I': { /* a 'lua_Integer' */ | 485 | case 'I': { /* a 'lua_Integer' */ |
426 | setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt))); | 486 | TValue num; |
427 | goto top2str; | 487 | setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt))); |
488 | addnum2buff(&buff, &num); | ||
489 | break; | ||
428 | } | 490 | } |
429 | case 'f': { /* a 'lua_Number' */ | 491 | case 'f': { /* a 'lua_Number' */ |
430 | setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); | 492 | TValue num; |
431 | top2str: /* convert the top element to a string */ | 493 | setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber))); |
432 | luaD_inctop(L); | 494 | addnum2buff(&buff, &num); |
433 | luaO_tostring(L, L->top - 1); | ||
434 | break; | 495 | break; |
435 | } | 496 | } |
436 | case 'p': { /* a pointer */ | 497 | case 'p': { /* a pointer */ |
437 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */ | 498 | const int sz = 3 * sizeof(void*) + 8; /* enough space for '%p' */ |
499 | char *bf = getbuff(&buff, sz); | ||
438 | void *p = va_arg(argp, void *); | 500 | void *p = va_arg(argp, void *); |
439 | int l = lua_pointer2str(buff, sizeof(buff), p); | 501 | int len = lua_pointer2str(bf, sz, p); |
440 | pushstr(L, buff, l); | 502 | addsize(&buff, len); |
441 | break; | 503 | break; |
442 | } | 504 | } |
443 | case 'U': { /* an 'int' as a UTF-8 sequence */ | 505 | case 'U': { /* a 'long' as a UTF-8 sequence */ |
444 | char buff[UTF8BUFFSZ]; | 506 | char bf[UTF8BUFFSZ]; |
445 | int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long))); | 507 | int len = luaO_utf8esc(bf, va_arg(argp, long)); |
446 | pushstr(L, buff + UTF8BUFFSZ - l, l); | 508 | addstr2buff(&buff, bf + UTF8BUFFSZ - len, len); |
447 | break; | 509 | break; |
448 | } | 510 | } |
449 | case '%': { | 511 | case '%': { |
450 | pushstr(L, "%", 1); | 512 | addstr2buff(&buff, "%", 1); |
451 | break; | 513 | break; |
452 | } | 514 | } |
453 | default: { | 515 | default: { |
@@ -455,13 +517,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | |||
455 | *(e + 1)); | 517 | *(e + 1)); |
456 | } | 518 | } |
457 | } | 519 | } |
458 | n += 2; | 520 | fmt = e + 2; /* skip '%' and the specifier */ |
459 | fmt = e+2; | ||
460 | } | 521 | } |
461 | luaD_checkstack(L, 1); | 522 | addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ |
462 | pushstr(L, fmt, strlen(fmt)); | 523 | clearbuff(&buff); /* empty buffer into the stack */ |
463 | if (n > 0) luaV_concat(L, n + 1); | 524 | if (buff.pushed > 1) |
464 | return svalue(L->top - 1); | 525 | luaV_concat(L, buff.pushed); /* join all partial results */ |
526 | return svalue(s2v(L->top - 1)); | ||
465 | } | 527 | } |
466 | 528 | ||
467 | 529 | ||
@@ -474,9 +536,8 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { | |||
474 | return msg; | 536 | return msg; |
475 | } | 537 | } |
476 | 538 | ||
539 | /* }================================================================== */ | ||
477 | 540 | ||
478 | /* number of chars of a literal string without the ending \0 */ | ||
479 | #define LL(x) (sizeof(x)/sizeof(char) - 1) | ||
480 | 541 | ||
481 | #define RETS "..." | 542 | #define RETS "..." |
482 | #define PRE "[string \"" | 543 | #define PRE "[string \"" |
@@ -484,36 +545,36 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { | |||
484 | 545 | ||
485 | #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) | 546 | #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) |
486 | 547 | ||
487 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { | 548 | void luaO_chunkid (char *out, const char *source, size_t srclen) { |
488 | size_t l = strlen(source); | 549 | size_t bufflen = LUA_IDSIZE; /* free space in buffer */ |
489 | if (*source == '=') { /* 'literal' source */ | 550 | if (*source == '=') { /* 'literal' source */ |
490 | if (l <= bufflen) /* small enough? */ | 551 | if (srclen <= bufflen) /* small enough? */ |
491 | memcpy(out, source + 1, l * sizeof(char)); | 552 | memcpy(out, source + 1, srclen * sizeof(char)); |
492 | else { /* truncate it */ | 553 | else { /* truncate it */ |
493 | addstr(out, source + 1, bufflen - 1); | 554 | addstr(out, source + 1, bufflen - 1); |
494 | *out = '\0'; | 555 | *out = '\0'; |
495 | } | 556 | } |
496 | } | 557 | } |
497 | else if (*source == '@') { /* file name */ | 558 | else if (*source == '@') { /* file name */ |
498 | if (l <= bufflen) /* small enough? */ | 559 | if (srclen <= bufflen) /* small enough? */ |
499 | memcpy(out, source + 1, l * sizeof(char)); | 560 | memcpy(out, source + 1, srclen * sizeof(char)); |
500 | else { /* add '...' before rest of name */ | 561 | else { /* add '...' before rest of name */ |
501 | addstr(out, RETS, LL(RETS)); | 562 | addstr(out, RETS, LL(RETS)); |
502 | bufflen -= LL(RETS); | 563 | bufflen -= LL(RETS); |
503 | memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); | 564 | memcpy(out, source + 1 + srclen - bufflen, bufflen * sizeof(char)); |
504 | } | 565 | } |
505 | } | 566 | } |
506 | else { /* string; format as [string "source"] */ | 567 | else { /* string; format as [string "source"] */ |
507 | const char *nl = strchr(source, '\n'); /* find first new line (if any) */ | 568 | const char *nl = strchr(source, '\n'); /* find first new line (if any) */ |
508 | addstr(out, PRE, LL(PRE)); /* add prefix */ | 569 | addstr(out, PRE, LL(PRE)); /* add prefix */ |
509 | bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ | 570 | bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ |
510 | if (l < bufflen && nl == NULL) { /* small one-line source? */ | 571 | if (srclen < bufflen && nl == NULL) { /* small one-line source? */ |
511 | addstr(out, source, l); /* keep it */ | 572 | addstr(out, source, srclen); /* keep it */ |
512 | } | 573 | } |
513 | else { | 574 | else { |
514 | if (nl != NULL) l = nl - source; /* stop at first newline */ | 575 | if (nl != NULL) srclen = nl - source; /* stop at first newline */ |
515 | if (l > bufflen) l = bufflen; | 576 | if (srclen > bufflen) srclen = bufflen; |
516 | addstr(out, source, l); | 577 | addstr(out, source, srclen); |
517 | addstr(out, RETS, LL(RETS)); | 578 | addstr(out, RETS, LL(RETS)); |
518 | } | 579 | } |
519 | memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); | 580 | memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); |
diff --git a/src/lua/lobject.h b/src/lua/lobject.h new file mode 100644 index 0000000..04a81d3 --- /dev/null +++ b/src/lua/lobject.h | |||
@@ -0,0 +1,787 @@ | |||
1 | /* | ||
2 | ** $Id: lobject.h $ | ||
3 | ** Type definitions for Lua objects | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #ifndef lobject_h | ||
9 | #define lobject_h | ||
10 | |||
11 | |||
12 | #include <stdarg.h> | ||
13 | |||
14 | |||
15 | #include "llimits.h" | ||
16 | #include "lua.h" | ||
17 | |||
18 | |||
19 | /* | ||
20 | ** Extra types for collectable non-values | ||
21 | */ | ||
22 | #define LUA_TUPVAL LUA_NUMTYPES /* upvalues */ | ||
23 | #define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */ | ||
24 | |||
25 | |||
26 | /* | ||
27 | ** number of all possible types (including LUA_TNONE) | ||
28 | */ | ||
29 | #define LUA_TOTALTYPES (LUA_TPROTO + 2) | ||
30 | |||
31 | |||
32 | /* | ||
33 | ** tags for Tagged Values have the following use of bits: | ||
34 | ** bits 0-3: actual tag (a LUA_T* constant) | ||
35 | ** bits 4-5: variant bits | ||
36 | ** bit 6: whether value is collectable | ||
37 | */ | ||
38 | |||
39 | /* add variant bits to a type */ | ||
40 | #define makevariant(t,v) ((t) | ((v) << 4)) | ||
41 | |||
42 | |||
43 | |||
44 | /* | ||
45 | ** Union of all Lua values | ||
46 | */ | ||
47 | typedef union Value { | ||
48 | struct GCObject *gc; /* collectable objects */ | ||
49 | void *p; /* light userdata */ | ||
50 | lua_CFunction f; /* light C functions */ | ||
51 | lua_Integer i; /* integer numbers */ | ||
52 | lua_Number n; /* float numbers */ | ||
53 | } Value; | ||
54 | |||
55 | |||
56 | /* | ||
57 | ** Tagged Values. This is the basic representation of values in Lua: | ||
58 | ** an actual value plus a tag with its type. | ||
59 | */ | ||
60 | |||
61 | #define TValuefields Value value_; lu_byte tt_ | ||
62 | |||
63 | typedef struct TValue { | ||
64 | TValuefields; | ||
65 | } TValue; | ||
66 | |||
67 | |||
68 | #define val_(o) ((o)->value_) | ||
69 | #define valraw(o) (&val_(o)) | ||
70 | |||
71 | |||
72 | /* raw type tag of a TValue */ | ||
73 | #define rawtt(o) ((o)->tt_) | ||
74 | |||
75 | /* tag with no variants (bits 0-3) */ | ||
76 | #define novariant(t) ((t) & 0x0F) | ||
77 | |||
78 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ | ||
79 | #define withvariant(t) ((t) & 0x3F) | ||
80 | #define ttypetag(o) withvariant(rawtt(o)) | ||
81 | |||
82 | /* type of a TValue */ | ||
83 | #define ttype(o) (novariant(rawtt(o))) | ||
84 | |||
85 | |||
86 | /* Macros to test type */ | ||
87 | #define checktag(o,t) (rawtt(o) == (t)) | ||
88 | #define checktype(o,t) (ttype(o) == (t)) | ||
89 | |||
90 | |||
91 | /* Macros for internal tests */ | ||
92 | |||
93 | /* collectable object has the same tag as the original value */ | ||
94 | #define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt) | ||
95 | |||
96 | /* | ||
97 | ** Any value being manipulated by the program either is non | ||
98 | ** collectable, or the collectable object has the right tag | ||
99 | ** and it is not dead. | ||
100 | */ | ||
101 | #define checkliveness(L,obj) \ | ||
102 | ((void)L, lua_longassert(!iscollectable(obj) || \ | ||
103 | (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))) | ||
104 | |||
105 | |||
106 | /* Macros to set values */ | ||
107 | |||
108 | /* set a value's tag */ | ||
109 | #define settt_(o,t) ((o)->tt_=(t)) | ||
110 | |||
111 | |||
112 | /* main macro to copy values (from 'obj1' to 'obj2') */ | ||
113 | #define setobj(L,obj1,obj2) \ | ||
114 | { TValue *io1=(obj1); const TValue *io2=(obj2); \ | ||
115 | io1->value_ = io2->value_; settt_(io1, io2->tt_); \ | ||
116 | checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); } | ||
117 | |||
118 | /* | ||
119 | ** Different types of assignments, according to source and destination. | ||
120 | ** (They are mostly equal now, but may be different in the future.) | ||
121 | */ | ||
122 | |||
123 | /* from stack to stack */ | ||
124 | #define setobjs2s(L,o1,o2) setobj(L,s2v(o1),s2v(o2)) | ||
125 | /* to stack (not from same stack) */ | ||
126 | #define setobj2s(L,o1,o2) setobj(L,s2v(o1),o2) | ||
127 | /* from table to same table */ | ||
128 | #define setobjt2t setobj | ||
129 | /* to new object */ | ||
130 | #define setobj2n setobj | ||
131 | /* to table */ | ||
132 | #define setobj2t setobj | ||
133 | |||
134 | |||
135 | /* | ||
136 | ** Entries in the Lua stack | ||
137 | */ | ||
138 | typedef union StackValue { | ||
139 | TValue val; | ||
140 | } StackValue; | ||
141 | |||
142 | |||
143 | /* index to stack elements */ | ||
144 | typedef StackValue *StkId; | ||
145 | |||
146 | /* convert a 'StackValue' to a 'TValue' */ | ||
147 | #define s2v(o) (&(o)->val) | ||
148 | |||
149 | |||
150 | |||
151 | /* | ||
152 | ** {================================================================== | ||
153 | ** Nil | ||
154 | ** =================================================================== | ||
155 | */ | ||
156 | |||
157 | /* Standard nil */ | ||
158 | #define LUA_VNIL makevariant(LUA_TNIL, 0) | ||
159 | |||
160 | /* Empty slot (which might be different from a slot containing nil) */ | ||
161 | #define LUA_VEMPTY makevariant(LUA_TNIL, 1) | ||
162 | |||
163 | /* Value returned for a key not found in a table (absent key) */ | ||
164 | #define LUA_VABSTKEY makevariant(LUA_TNIL, 2) | ||
165 | |||
166 | |||
167 | /* macro to test for (any kind of) nil */ | ||
168 | #define ttisnil(v) checktype((v), LUA_TNIL) | ||
169 | |||
170 | |||
171 | /* macro to test for a standard nil */ | ||
172 | #define ttisstrictnil(o) checktag((o), LUA_VNIL) | ||
173 | |||
174 | |||
175 | #define setnilvalue(obj) settt_(obj, LUA_VNIL) | ||
176 | |||
177 | |||
178 | #define isabstkey(v) checktag((v), LUA_VABSTKEY) | ||
179 | |||
180 | |||
181 | /* | ||
182 | ** macro to detect non-standard nils (used only in assertions) | ||
183 | */ | ||
184 | #define isnonstrictnil(v) (ttisnil(v) && !ttisstrictnil(v)) | ||
185 | |||
186 | |||
187 | /* | ||
188 | ** By default, entries with any kind of nil are considered empty. | ||
189 | ** (In any definition, values associated with absent keys must also | ||
190 | ** be accepted as empty.) | ||
191 | */ | ||
192 | #define isempty(v) ttisnil(v) | ||
193 | |||
194 | |||
195 | /* macro defining a value corresponding to an absent key */ | ||
196 | #define ABSTKEYCONSTANT {NULL}, LUA_VABSTKEY | ||
197 | |||
198 | |||
199 | /* mark an entry as empty */ | ||
200 | #define setempty(v) settt_(v, LUA_VEMPTY) | ||
201 | |||
202 | |||
203 | |||
204 | /* }================================================================== */ | ||
205 | |||
206 | |||
207 | /* | ||
208 | ** {================================================================== | ||
209 | ** Booleans | ||
210 | ** =================================================================== | ||
211 | */ | ||
212 | |||
213 | |||
214 | #define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0) | ||
215 | #define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1) | ||
216 | |||
217 | #define ttisboolean(o) checktype((o), LUA_TBOOLEAN) | ||
218 | #define ttisfalse(o) checktag((o), LUA_VFALSE) | ||
219 | #define ttistrue(o) checktag((o), LUA_VTRUE) | ||
220 | |||
221 | |||
222 | #define l_isfalse(o) (ttisfalse(o) || ttisnil(o)) | ||
223 | |||
224 | |||
225 | #define setbfvalue(obj) settt_(obj, LUA_VFALSE) | ||
226 | #define setbtvalue(obj) settt_(obj, LUA_VTRUE) | ||
227 | |||
228 | /* }================================================================== */ | ||
229 | |||
230 | |||
231 | /* | ||
232 | ** {================================================================== | ||
233 | ** Threads | ||
234 | ** =================================================================== | ||
235 | */ | ||
236 | |||
237 | #define LUA_VTHREAD makevariant(LUA_TTHREAD, 0) | ||
238 | |||
239 | #define ttisthread(o) checktag((o), ctb(LUA_VTHREAD)) | ||
240 | |||
241 | #define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) | ||
242 | |||
243 | #define setthvalue(L,obj,x) \ | ||
244 | { TValue *io = (obj); lua_State *x_ = (x); \ | ||
245 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTHREAD)); \ | ||
246 | checkliveness(L,io); } | ||
247 | |||
248 | #define setthvalue2s(L,o,t) setthvalue(L,s2v(o),t) | ||
249 | |||
250 | /* }================================================================== */ | ||
251 | |||
252 | |||
253 | /* | ||
254 | ** {================================================================== | ||
255 | ** Collectable Objects | ||
256 | ** =================================================================== | ||
257 | */ | ||
258 | |||
259 | /* | ||
260 | ** Common Header for all collectable objects (in macro form, to be | ||
261 | ** included in other objects) | ||
262 | */ | ||
263 | #define CommonHeader struct GCObject *next; lu_byte tt; lu_byte marked | ||
264 | |||
265 | |||
266 | /* Common type for all collectable objects */ | ||
267 | typedef struct GCObject { | ||
268 | CommonHeader; | ||
269 | } GCObject; | ||
270 | |||
271 | |||
272 | /* Bit mark for collectable types */ | ||
273 | #define BIT_ISCOLLECTABLE (1 << 6) | ||
274 | |||
275 | #define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE) | ||
276 | |||
277 | /* mark a tag as collectable */ | ||
278 | #define ctb(t) ((t) | BIT_ISCOLLECTABLE) | ||
279 | |||
280 | #define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) | ||
281 | |||
282 | #define gcvalueraw(v) ((v).gc) | ||
283 | |||
284 | #define setgcovalue(L,obj,x) \ | ||
285 | { TValue *io = (obj); GCObject *i_g=(x); \ | ||
286 | val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } | ||
287 | |||
288 | /* }================================================================== */ | ||
289 | |||
290 | |||
291 | /* | ||
292 | ** {================================================================== | ||
293 | ** Numbers | ||
294 | ** =================================================================== | ||
295 | */ | ||
296 | |||
297 | /* Variant tags for numbers */ | ||
298 | #define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */ | ||
299 | #define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */ | ||
300 | |||
301 | #define ttisnumber(o) checktype((o), LUA_TNUMBER) | ||
302 | #define ttisfloat(o) checktag((o), LUA_VNUMFLT) | ||
303 | #define ttisinteger(o) checktag((o), LUA_VNUMINT) | ||
304 | |||
305 | #define nvalue(o) check_exp(ttisnumber(o), \ | ||
306 | (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) | ||
307 | #define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) | ||
308 | #define ivalue(o) check_exp(ttisinteger(o), val_(o).i) | ||
309 | |||
310 | #define fltvalueraw(v) ((v).n) | ||
311 | #define ivalueraw(v) ((v).i) | ||
312 | |||
313 | #define setfltvalue(obj,x) \ | ||
314 | { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_VNUMFLT); } | ||
315 | |||
316 | #define chgfltvalue(obj,x) \ | ||
317 | { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); } | ||
318 | |||
319 | #define setivalue(obj,x) \ | ||
320 | { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_VNUMINT); } | ||
321 | |||
322 | #define chgivalue(obj,x) \ | ||
323 | { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); } | ||
324 | |||
325 | /* }================================================================== */ | ||
326 | |||
327 | |||
328 | /* | ||
329 | ** {================================================================== | ||
330 | ** Strings | ||
331 | ** =================================================================== | ||
332 | */ | ||
333 | |||
334 | /* Variant tags for strings */ | ||
335 | #define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */ | ||
336 | #define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */ | ||
337 | |||
338 | #define ttisstring(o) checktype((o), LUA_TSTRING) | ||
339 | #define ttisshrstring(o) checktag((o), ctb(LUA_VSHRSTR)) | ||
340 | #define ttislngstring(o) checktag((o), ctb(LUA_VLNGSTR)) | ||
341 | |||
342 | #define tsvalueraw(v) (gco2ts((v).gc)) | ||
343 | |||
344 | #define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) | ||
345 | |||
346 | #define setsvalue(L,obj,x) \ | ||
347 | { TValue *io = (obj); TString *x_ = (x); \ | ||
348 | val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ | ||
349 | checkliveness(L,io); } | ||
350 | |||
351 | /* set a string to the stack */ | ||
352 | #define setsvalue2s(L,o,s) setsvalue(L,s2v(o),s) | ||
353 | |||
354 | /* set a string to a new object */ | ||
355 | #define setsvalue2n setsvalue | ||
356 | |||
357 | |||
358 | /* | ||
359 | ** Header for a string value. | ||
360 | */ | ||
361 | typedef struct TString { | ||
362 | CommonHeader; | ||
363 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ | ||
364 | lu_byte shrlen; /* length for short strings */ | ||
365 | unsigned int hash; | ||
366 | union { | ||
367 | size_t lnglen; /* length for long strings */ | ||
368 | struct TString *hnext; /* linked list for hash table */ | ||
369 | } u; | ||
370 | char contents[1]; | ||
371 | } TString; | ||
372 | |||
373 | |||
374 | |||
375 | /* | ||
376 | ** Get the actual string (array of bytes) from a 'TString'. | ||
377 | */ | ||
378 | #define getstr(ts) ((ts)->contents) | ||
379 | |||
380 | |||
381 | /* get the actual string (array of bytes) from a Lua value */ | ||
382 | #define svalue(o) getstr(tsvalue(o)) | ||
383 | |||
384 | /* get string length from 'TString *s' */ | ||
385 | #define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen) | ||
386 | |||
387 | /* get string length from 'TValue *o' */ | ||
388 | #define vslen(o) tsslen(tsvalue(o)) | ||
389 | |||
390 | /* }================================================================== */ | ||
391 | |||
392 | |||
393 | /* | ||
394 | ** {================================================================== | ||
395 | ** Userdata | ||
396 | ** =================================================================== | ||
397 | */ | ||
398 | |||
399 | |||
400 | /* | ||
401 | ** Light userdata should be a variant of userdata, but for compatibility | ||
402 | ** reasons they are also different types. | ||
403 | */ | ||
404 | #define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0) | ||
405 | |||
406 | #define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0) | ||
407 | |||
408 | #define ttislightuserdata(o) checktag((o), LUA_VLIGHTUSERDATA) | ||
409 | #define ttisfulluserdata(o) checktag((o), ctb(LUA_VUSERDATA)) | ||
410 | |||
411 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) | ||
412 | #define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) | ||
413 | |||
414 | #define pvalueraw(v) ((v).p) | ||
415 | |||
416 | #define setpvalue(obj,x) \ | ||
417 | { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_VLIGHTUSERDATA); } | ||
418 | |||
419 | #define setuvalue(L,obj,x) \ | ||
420 | { TValue *io = (obj); Udata *x_ = (x); \ | ||
421 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VUSERDATA)); \ | ||
422 | checkliveness(L,io); } | ||
423 | |||
424 | |||
425 | /* Ensures that addresses after this type are always fully aligned. */ | ||
426 | typedef union UValue { | ||
427 | TValue uv; | ||
428 | LUAI_MAXALIGN; /* ensures maximum alignment for udata bytes */ | ||
429 | } UValue; | ||
430 | |||
431 | |||
432 | /* | ||
433 | ** Header for userdata with user values; | ||
434 | ** memory area follows the end of this structure. | ||
435 | */ | ||
436 | typedef struct Udata { | ||
437 | CommonHeader; | ||
438 | unsigned short nuvalue; /* number of user values */ | ||
439 | size_t len; /* number of bytes */ | ||
440 | struct Table *metatable; | ||
441 | GCObject *gclist; | ||
442 | UValue uv[1]; /* user values */ | ||
443 | } Udata; | ||
444 | |||
445 | |||
446 | /* | ||
447 | ** Header for userdata with no user values. These userdata do not need | ||
448 | ** to be gray during GC, and therefore do not need a 'gclist' field. | ||
449 | ** To simplify, the code always use 'Udata' for both kinds of userdata, | ||
450 | ** making sure it never accesses 'gclist' on userdata with no user values. | ||
451 | ** This structure here is used only to compute the correct size for | ||
452 | ** this representation. (The 'bindata' field in its end ensures correct | ||
453 | ** alignment for binary data following this header.) | ||
454 | */ | ||
455 | typedef struct Udata0 { | ||
456 | CommonHeader; | ||
457 | unsigned short nuvalue; /* number of user values */ | ||
458 | size_t len; /* number of bytes */ | ||
459 | struct Table *metatable; | ||
460 | union {LUAI_MAXALIGN;} bindata; | ||
461 | } Udata0; | ||
462 | |||
463 | |||
464 | /* compute the offset of the memory area of a userdata */ | ||
465 | #define udatamemoffset(nuv) \ | ||
466 | ((nuv) == 0 ? offsetof(Udata0, bindata) \ | ||
467 | : offsetof(Udata, uv) + (sizeof(UValue) * (nuv))) | ||
468 | |||
469 | /* get the address of the memory block inside 'Udata' */ | ||
470 | #define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) | ||
471 | |||
472 | /* compute the size of a userdata */ | ||
473 | #define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb)) | ||
474 | |||
475 | /* }================================================================== */ | ||
476 | |||
477 | |||
478 | /* | ||
479 | ** {================================================================== | ||
480 | ** Prototypes | ||
481 | ** =================================================================== | ||
482 | */ | ||
483 | |||
484 | #define LUA_VPROTO makevariant(LUA_TPROTO, 0) | ||
485 | |||
486 | |||
487 | /* | ||
488 | ** Description of an upvalue for function prototypes | ||
489 | */ | ||
490 | typedef struct Upvaldesc { | ||
491 | TString *name; /* upvalue name (for debug information) */ | ||
492 | lu_byte instack; /* whether it is in stack (register) */ | ||
493 | lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ | ||
494 | lu_byte kind; /* kind of corresponding variable */ | ||
495 | } Upvaldesc; | ||
496 | |||
497 | |||
498 | /* | ||
499 | ** Description of a local variable for function prototypes | ||
500 | ** (used for debug information) | ||
501 | */ | ||
502 | typedef struct LocVar { | ||
503 | TString *varname; | ||
504 | int startpc; /* first point where variable is active */ | ||
505 | int endpc; /* first point where variable is dead */ | ||
506 | } LocVar; | ||
507 | |||
508 | |||
509 | /* | ||
510 | ** Associates the absolute line source for a given instruction ('pc'). | ||
511 | ** The array 'lineinfo' gives, for each instruction, the difference in | ||
512 | ** lines from the previous instruction. When that difference does not | ||
513 | ** fit into a byte, Lua saves the absolute line for that instruction. | ||
514 | ** (Lua also saves the absolute line periodically, to speed up the | ||
515 | ** computation of a line number: we can use binary search in the | ||
516 | ** absolute-line array, but we must traverse the 'lineinfo' array | ||
517 | ** linearly to compute a line.) | ||
518 | */ | ||
519 | typedef struct AbsLineInfo { | ||
520 | int pc; | ||
521 | int line; | ||
522 | } AbsLineInfo; | ||
523 | |||
524 | /* | ||
525 | ** Function Prototypes | ||
526 | */ | ||
527 | typedef struct Proto { | ||
528 | CommonHeader; | ||
529 | lu_byte numparams; /* number of fixed (named) parameters */ | ||
530 | lu_byte is_vararg; | ||
531 | lu_byte maxstacksize; /* number of registers needed by this function */ | ||
532 | int sizeupvalues; /* size of 'upvalues' */ | ||
533 | int sizek; /* size of 'k' */ | ||
534 | int sizecode; | ||
535 | int sizelineinfo; | ||
536 | int sizep; /* size of 'p' */ | ||
537 | int sizelocvars; | ||
538 | int sizeabslineinfo; /* size of 'abslineinfo' */ | ||
539 | int linedefined; /* debug information */ | ||
540 | int lastlinedefined; /* debug information */ | ||
541 | TValue *k; /* constants used by the function */ | ||
542 | Instruction *code; /* opcodes */ | ||
543 | struct Proto **p; /* functions defined inside the function */ | ||
544 | Upvaldesc *upvalues; /* upvalue information */ | ||
545 | ls_byte *lineinfo; /* information about source lines (debug information) */ | ||
546 | AbsLineInfo *abslineinfo; /* idem */ | ||
547 | LocVar *locvars; /* information about local variables (debug information) */ | ||
548 | TString *source; /* used for debug information */ | ||
549 | GCObject *gclist; | ||
550 | } Proto; | ||
551 | |||
552 | /* }================================================================== */ | ||
553 | |||
554 | |||
555 | /* | ||
556 | ** {================================================================== | ||
557 | ** Closures | ||
558 | ** =================================================================== | ||
559 | */ | ||
560 | |||
561 | #define LUA_VUPVAL makevariant(LUA_TUPVAL, 0) | ||
562 | |||
563 | |||
564 | /* Variant tags for functions */ | ||
565 | #define LUA_VLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */ | ||
566 | #define LUA_VLCF makevariant(LUA_TFUNCTION, 1) /* light C function */ | ||
567 | #define LUA_VCCL makevariant(LUA_TFUNCTION, 2) /* C closure */ | ||
568 | |||
569 | #define ttisfunction(o) checktype(o, LUA_TFUNCTION) | ||
570 | #define ttisclosure(o) ((rawtt(o) & 0x1F) == LUA_VLCL) | ||
571 | #define ttisLclosure(o) checktag((o), ctb(LUA_VLCL)) | ||
572 | #define ttislcf(o) checktag((o), LUA_VLCF) | ||
573 | #define ttisCclosure(o) checktag((o), ctb(LUA_VCCL)) | ||
574 | |||
575 | #define isLfunction(o) ttisLclosure(o) | ||
576 | |||
577 | #define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) | ||
578 | #define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) | ||
579 | #define fvalue(o) check_exp(ttislcf(o), val_(o).f) | ||
580 | #define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) | ||
581 | |||
582 | #define fvalueraw(v) ((v).f) | ||
583 | |||
584 | #define setclLvalue(L,obj,x) \ | ||
585 | { TValue *io = (obj); LClosure *x_ = (x); \ | ||
586 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VLCL)); \ | ||
587 | checkliveness(L,io); } | ||
588 | |||
589 | #define setclLvalue2s(L,o,cl) setclLvalue(L,s2v(o),cl) | ||
590 | |||
591 | #define setfvalue(obj,x) \ | ||
592 | { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_VLCF); } | ||
593 | |||
594 | #define setclCvalue(L,obj,x) \ | ||
595 | { TValue *io = (obj); CClosure *x_ = (x); \ | ||
596 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VCCL)); \ | ||
597 | checkliveness(L,io); } | ||
598 | |||
599 | |||
600 | /* | ||
601 | ** Upvalues for Lua closures | ||
602 | */ | ||
603 | typedef struct UpVal { | ||
604 | CommonHeader; | ||
605 | lu_byte tbc; /* true if it represents a to-be-closed variable */ | ||
606 | TValue *v; /* points to stack or to its own value */ | ||
607 | union { | ||
608 | struct { /* (when open) */ | ||
609 | struct UpVal *next; /* linked list */ | ||
610 | struct UpVal **previous; | ||
611 | } open; | ||
612 | TValue value; /* the value (when closed) */ | ||
613 | } u; | ||
614 | } UpVal; | ||
615 | |||
616 | |||
617 | |||
618 | #define ClosureHeader \ | ||
619 | CommonHeader; lu_byte nupvalues; GCObject *gclist | ||
620 | |||
621 | typedef struct CClosure { | ||
622 | ClosureHeader; | ||
623 | lua_CFunction f; | ||
624 | TValue upvalue[1]; /* list of upvalues */ | ||
625 | } CClosure; | ||
626 | |||
627 | |||
628 | typedef struct LClosure { | ||
629 | ClosureHeader; | ||
630 | struct Proto *p; | ||
631 | UpVal *upvals[1]; /* list of upvalues */ | ||
632 | } LClosure; | ||
633 | |||
634 | |||
635 | typedef union Closure { | ||
636 | CClosure c; | ||
637 | LClosure l; | ||
638 | } Closure; | ||
639 | |||
640 | |||
641 | #define getproto(o) (clLvalue(o)->p) | ||
642 | |||
643 | /* }================================================================== */ | ||
644 | |||
645 | |||
646 | /* | ||
647 | ** {================================================================== | ||
648 | ** Tables | ||
649 | ** =================================================================== | ||
650 | */ | ||
651 | |||
652 | #define LUA_VTABLE makevariant(LUA_TTABLE, 0) | ||
653 | |||
654 | #define ttistable(o) checktag((o), ctb(LUA_VTABLE)) | ||
655 | |||
656 | #define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) | ||
657 | |||
658 | #define sethvalue(L,obj,x) \ | ||
659 | { TValue *io = (obj); Table *x_ = (x); \ | ||
660 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTABLE)); \ | ||
661 | checkliveness(L,io); } | ||
662 | |||
663 | #define sethvalue2s(L,o,h) sethvalue(L,s2v(o),h) | ||
664 | |||
665 | |||
666 | /* | ||
667 | ** Nodes for Hash tables: A pack of two TValue's (key-value pairs) | ||
668 | ** plus a 'next' field to link colliding entries. The distribution | ||
669 | ** of the key's fields ('key_tt' and 'key_val') not forming a proper | ||
670 | ** 'TValue' allows for a smaller size for 'Node' both in 4-byte | ||
671 | ** and 8-byte alignments. | ||
672 | */ | ||
673 | typedef union Node { | ||
674 | struct NodeKey { | ||
675 | TValuefields; /* fields for value */ | ||
676 | lu_byte key_tt; /* key type */ | ||
677 | int next; /* for chaining */ | ||
678 | Value key_val; /* key value */ | ||
679 | } u; | ||
680 | TValue i_val; /* direct access to node's value as a proper 'TValue' */ | ||
681 | } Node; | ||
682 | |||
683 | |||
684 | /* copy a value into a key */ | ||
685 | #define setnodekey(L,node,obj) \ | ||
686 | { Node *n_=(node); const TValue *io_=(obj); \ | ||
687 | n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \ | ||
688 | checkliveness(L,io_); } | ||
689 | |||
690 | |||
691 | /* copy a value from a key */ | ||
692 | #define getnodekey(L,obj,node) \ | ||
693 | { TValue *io_=(obj); const Node *n_=(node); \ | ||
694 | io_->value_ = n_->u.key_val; io_->tt_ = n_->u.key_tt; \ | ||
695 | checkliveness(L,io_); } | ||
696 | |||
697 | |||
698 | /* | ||
699 | ** About 'alimit': if 'isrealasize(t)' is true, then 'alimit' is the | ||
700 | ** real size of 'array'. Otherwise, the real size of 'array' is the | ||
701 | ** smallest power of two not smaller than 'alimit' (or zero iff 'alimit' | ||
702 | ** is zero); 'alimit' is then used as a hint for #t. | ||
703 | */ | ||
704 | |||
705 | #define BITRAS (1 << 7) | ||
706 | #define isrealasize(t) (!((t)->marked & BITRAS)) | ||
707 | #define setrealasize(t) ((t)->marked &= cast_byte(~BITRAS)) | ||
708 | #define setnorealasize(t) ((t)->marked |= BITRAS) | ||
709 | |||
710 | |||
711 | typedef struct Table { | ||
712 | CommonHeader; | ||
713 | lu_byte flags; /* 1<<p means tagmethod(p) is not present */ | ||
714 | lu_byte lsizenode; /* log2 of size of 'node' array */ | ||
715 | unsigned int alimit; /* "limit" of 'array' array */ | ||
716 | TValue *array; /* array part */ | ||
717 | Node *node; | ||
718 | Node *lastfree; /* any free position is before this position */ | ||
719 | struct Table *metatable; | ||
720 | GCObject *gclist; | ||
721 | } Table; | ||
722 | |||
723 | |||
724 | /* | ||
725 | ** Macros to manipulate keys inserted in nodes | ||
726 | */ | ||
727 | #define keytt(node) ((node)->u.key_tt) | ||
728 | #define keyval(node) ((node)->u.key_val) | ||
729 | |||
730 | #define keyisnil(node) (keytt(node) == LUA_TNIL) | ||
731 | #define keyisinteger(node) (keytt(node) == LUA_VNUMINT) | ||
732 | #define keyival(node) (keyval(node).i) | ||
733 | #define keyisshrstr(node) (keytt(node) == ctb(LUA_VSHRSTR)) | ||
734 | #define keystrval(node) (gco2ts(keyval(node).gc)) | ||
735 | |||
736 | #define setnilkey(node) (keytt(node) = LUA_TNIL) | ||
737 | |||
738 | #define keyiscollectable(n) (keytt(n) & BIT_ISCOLLECTABLE) | ||
739 | |||
740 | #define gckey(n) (keyval(n).gc) | ||
741 | #define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL) | ||
742 | |||
743 | |||
744 | /* | ||
745 | ** Use a "nil table" to mark dead keys in a table. Those keys serve | ||
746 | ** to keep space for removed entries, which may still be part of | ||
747 | ** chains. Note that the 'keytt' does not have the BIT_ISCOLLECTABLE | ||
748 | ** set, so these values are considered not collectable and are different | ||
749 | ** from any valid value. | ||
750 | */ | ||
751 | #define setdeadkey(n) (keytt(n) = LUA_TTABLE, gckey(n) = NULL) | ||
752 | |||
753 | /* }================================================================== */ | ||
754 | |||
755 | |||
756 | |||
757 | /* | ||
758 | ** 'module' operation for hashing (size is always a power of 2) | ||
759 | */ | ||
760 | #define lmod(s,size) \ | ||
761 | (check_exp((size&(size-1))==0, (cast_int((s) & ((size)-1))))) | ||
762 | |||
763 | |||
764 | #define twoto(x) (1<<(x)) | ||
765 | #define sizenode(t) (twoto((t)->lsizenode)) | ||
766 | |||
767 | |||
768 | /* size of buffer for 'luaO_utf8esc' function */ | ||
769 | #define UTF8BUFFSZ 8 | ||
770 | |||
771 | LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); | ||
772 | LUAI_FUNC int luaO_ceillog2 (unsigned int x); | ||
773 | LUAI_FUNC int luaO_rawarith (lua_State *L, int op, const TValue *p1, | ||
774 | const TValue *p2, TValue *res); | ||
775 | LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, | ||
776 | const TValue *p2, StkId res); | ||
777 | LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); | ||
778 | LUAI_FUNC int luaO_hexavalue (int c); | ||
779 | LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj); | ||
780 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, | ||
781 | va_list argp); | ||
782 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); | ||
783 | LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t srclen); | ||
784 | |||
785 | |||
786 | #endif | ||
787 | |||
diff --git a/src/lua/lopcodes.c b/src/lua/lopcodes.c new file mode 100644 index 0000000..c67aa22 --- /dev/null +++ b/src/lua/lopcodes.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | ** $Id: lopcodes.c $ | ||
3 | ** Opcodes for Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lopcodes_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include "lopcodes.h" | ||
14 | |||
15 | |||
16 | /* ORDER OP */ | ||
17 | |||
18 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | ||
19 | /* MM OT IT T A mode opcode */ | ||
20 | opmode(0, 0, 0, 0, 1, iABC) /* OP_MOVE */ | ||
21 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADI */ | ||
22 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ | ||
23 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ | ||
24 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ | ||
25 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ | ||
26 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LFALSESKIP */ | ||
27 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ | ||
28 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ | ||
29 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ | ||
30 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ | ||
31 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABUP */ | ||
32 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABLE */ | ||
33 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETI */ | ||
34 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETFIELD */ | ||
35 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABUP */ | ||
36 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ | ||
37 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ | ||
38 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ | ||
39 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ | ||
40 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ | ||
41 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ | ||
42 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ | ||
43 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ | ||
44 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ | ||
45 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODK */ | ||
46 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWK */ | ||
47 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVK */ | ||
48 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVK */ | ||
49 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BANDK */ | ||
50 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BORK */ | ||
51 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXORK */ | ||
52 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHRI */ | ||
53 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHLI */ | ||
54 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADD */ | ||
55 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUB */ | ||
56 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MUL */ | ||
57 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MOD */ | ||
58 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POW */ | ||
59 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIV */ | ||
60 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIV */ | ||
61 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BAND */ | ||
62 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BOR */ | ||
63 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXOR */ | ||
64 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHL */ | ||
65 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHR */ | ||
66 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBIN */ | ||
67 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINI*/ | ||
68 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINK*/ | ||
69 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_UNM */ | ||
70 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BNOT */ | ||
71 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NOT */ | ||
72 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LEN */ | ||
73 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_CONCAT */ | ||
74 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ | ||
75 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TBC */ | ||
76 | ,opmode(0, 0, 0, 0, 0, isJ) /* OP_JMP */ | ||
77 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQ */ | ||
78 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LT */ | ||
79 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LE */ | ||
80 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQK */ | ||
81 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQI */ | ||
82 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LTI */ | ||
83 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LEI */ | ||
84 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GTI */ | ||
85 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GEI */ | ||
86 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_TEST */ | ||
87 | ,opmode(0, 0, 0, 1, 1, iABC) /* OP_TESTSET */ | ||
88 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_CALL */ | ||
89 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_TAILCALL */ | ||
90 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_RETURN */ | ||
91 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN0 */ | ||
92 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN1 */ | ||
93 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORLOOP */ | ||
94 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORPREP */ | ||
95 | ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ | ||
96 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ | ||
97 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ | ||
98 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ | ||
99 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ | ||
100 | ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ | ||
101 | ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ | ||
102 | ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ | ||
103 | }; | ||
104 | |||
diff --git a/src/lua/lopcodes.h b/src/lua/lopcodes.h new file mode 100644 index 0000000..122e5d2 --- /dev/null +++ b/src/lua/lopcodes.h | |||
@@ -0,0 +1,392 @@ | |||
1 | /* | ||
2 | ** $Id: lopcodes.h $ | ||
3 | ** Opcodes for Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lopcodes_h | ||
8 | #define lopcodes_h | ||
9 | |||
10 | #include "llimits.h" | ||
11 | |||
12 | |||
13 | /*=========================================================================== | ||
14 | We assume that instructions are unsigned 32-bit integers. | ||
15 | All instructions have an opcode in the first 7 bits. | ||
16 | Instructions can have the following formats: | ||
17 | |||
18 | 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | ||
19 | 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ||
20 | iABC C(8) | B(8) |k| A(8) | Op(7) | | ||
21 | iABx Bx(17) | A(8) | Op(7) | | ||
22 | iAsBx sBx (signed)(17) | A(8) | Op(7) | | ||
23 | iAx Ax(25) | Op(7) | | ||
24 | isJ sJ(25) | Op(7) | | ||
25 | |||
26 | A signed argument is represented in excess K: the represented value is | ||
27 | the written unsigned value minus K, where K is half the maximum for the | ||
28 | corresponding unsigned argument. | ||
29 | ===========================================================================*/ | ||
30 | |||
31 | |||
32 | enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ | ||
33 | |||
34 | |||
35 | /* | ||
36 | ** size and position of opcode arguments. | ||
37 | */ | ||
38 | #define SIZE_C 8 | ||
39 | #define SIZE_B 8 | ||
40 | #define SIZE_Bx (SIZE_C + SIZE_B + 1) | ||
41 | #define SIZE_A 8 | ||
42 | #define SIZE_Ax (SIZE_Bx + SIZE_A) | ||
43 | #define SIZE_sJ (SIZE_Bx + SIZE_A) | ||
44 | |||
45 | #define SIZE_OP 7 | ||
46 | |||
47 | #define POS_OP 0 | ||
48 | |||
49 | #define POS_A (POS_OP + SIZE_OP) | ||
50 | #define POS_k (POS_A + SIZE_A) | ||
51 | #define POS_B (POS_k + 1) | ||
52 | #define POS_C (POS_B + SIZE_B) | ||
53 | |||
54 | #define POS_Bx POS_k | ||
55 | |||
56 | #define POS_Ax POS_A | ||
57 | |||
58 | #define POS_sJ POS_A | ||
59 | |||
60 | |||
61 | /* | ||
62 | ** limits for opcode arguments. | ||
63 | ** we use (signed) 'int' to manipulate most arguments, | ||
64 | ** so they must fit in ints. | ||
65 | */ | ||
66 | |||
67 | /* Check whether type 'int' has at least 'b' bits ('b' < 32) */ | ||
68 | #define L_INTHASBITS(b) ((UINT_MAX >> ((b) - 1)) >= 1) | ||
69 | |||
70 | |||
71 | #if L_INTHASBITS(SIZE_Bx) | ||
72 | #define MAXARG_Bx ((1<<SIZE_Bx)-1) | ||
73 | #else | ||
74 | #define MAXARG_Bx MAX_INT | ||
75 | #endif | ||
76 | |||
77 | #define OFFSET_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */ | ||
78 | |||
79 | |||
80 | #if L_INTHASBITS(SIZE_Ax) | ||
81 | #define MAXARG_Ax ((1<<SIZE_Ax)-1) | ||
82 | #else | ||
83 | #define MAXARG_Ax MAX_INT | ||
84 | #endif | ||
85 | |||
86 | #if L_INTHASBITS(SIZE_sJ) | ||
87 | #define MAXARG_sJ ((1 << SIZE_sJ) - 1) | ||
88 | #else | ||
89 | #define MAXARG_sJ MAX_INT | ||
90 | #endif | ||
91 | |||
92 | #define OFFSET_sJ (MAXARG_sJ >> 1) | ||
93 | |||
94 | |||
95 | #define MAXARG_A ((1<<SIZE_A)-1) | ||
96 | #define MAXARG_B ((1<<SIZE_B)-1) | ||
97 | #define MAXARG_C ((1<<SIZE_C)-1) | ||
98 | #define OFFSET_sC (MAXARG_C >> 1) | ||
99 | |||
100 | #define int2sC(i) ((i) + OFFSET_sC) | ||
101 | #define sC2int(i) ((i) - OFFSET_sC) | ||
102 | |||
103 | |||
104 | /* creates a mask with 'n' 1 bits at position 'p' */ | ||
105 | #define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p)) | ||
106 | |||
107 | /* creates a mask with 'n' 0 bits at position 'p' */ | ||
108 | #define MASK0(n,p) (~MASK1(n,p)) | ||
109 | |||
110 | /* | ||
111 | ** the following macros help to manipulate instructions | ||
112 | */ | ||
113 | |||
114 | #define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) | ||
115 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ | ||
116 | ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP)))) | ||
117 | |||
118 | #define checkopm(i,m) (getOpMode(GET_OPCODE(i)) == m) | ||
119 | |||
120 | |||
121 | #define getarg(i,pos,size) (cast_int(((i)>>(pos)) & MASK1(size,0))) | ||
122 | #define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ | ||
123 | ((cast(Instruction, v)<<pos)&MASK1(size,pos)))) | ||
124 | |||
125 | #define GETARG_A(i) getarg(i, POS_A, SIZE_A) | ||
126 | #define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) | ||
127 | |||
128 | #define GETARG_B(i) check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B)) | ||
129 | #define GETARG_sB(i) sC2int(GETARG_B(i)) | ||
130 | #define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) | ||
131 | |||
132 | #define GETARG_C(i) check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C)) | ||
133 | #define GETARG_sC(i) sC2int(GETARG_C(i)) | ||
134 | #define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) | ||
135 | |||
136 | #define TESTARG_k(i) check_exp(checkopm(i, iABC), (cast_int(((i) & (1u << POS_k))))) | ||
137 | #define GETARG_k(i) check_exp(checkopm(i, iABC), getarg(i, POS_k, 1)) | ||
138 | #define SETARG_k(i,v) setarg(i, v, POS_k, 1) | ||
139 | |||
140 | #define GETARG_Bx(i) check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx)) | ||
141 | #define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx) | ||
142 | |||
143 | #define GETARG_Ax(i) check_exp(checkopm(i, iAx), getarg(i, POS_Ax, SIZE_Ax)) | ||
144 | #define SETARG_Ax(i,v) setarg(i, v, POS_Ax, SIZE_Ax) | ||
145 | |||
146 | #define GETARG_sBx(i) \ | ||
147 | check_exp(checkopm(i, iAsBx), getarg(i, POS_Bx, SIZE_Bx) - OFFSET_sBx) | ||
148 | #define SETARG_sBx(i,b) SETARG_Bx((i),cast_uint((b)+OFFSET_sBx)) | ||
149 | |||
150 | #define GETARG_sJ(i) \ | ||
151 | check_exp(checkopm(i, isJ), getarg(i, POS_sJ, SIZE_sJ) - OFFSET_sJ) | ||
152 | #define SETARG_sJ(i,j) \ | ||
153 | setarg(i, cast_uint((j)+OFFSET_sJ), POS_sJ, SIZE_sJ) | ||
154 | |||
155 | |||
156 | #define CREATE_ABCk(o,a,b,c,k) ((cast(Instruction, o)<<POS_OP) \ | ||
157 | | (cast(Instruction, a)<<POS_A) \ | ||
158 | | (cast(Instruction, b)<<POS_B) \ | ||
159 | | (cast(Instruction, c)<<POS_C) \ | ||
160 | | (cast(Instruction, k)<<POS_k)) | ||
161 | |||
162 | #define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \ | ||
163 | | (cast(Instruction, a)<<POS_A) \ | ||
164 | | (cast(Instruction, bc)<<POS_Bx)) | ||
165 | |||
166 | #define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \ | ||
167 | | (cast(Instruction, a)<<POS_Ax)) | ||
168 | |||
169 | #define CREATE_sJ(o,j,k) ((cast(Instruction, o) << POS_OP) \ | ||
170 | | (cast(Instruction, j) << POS_sJ) \ | ||
171 | | (cast(Instruction, k) << POS_k)) | ||
172 | |||
173 | |||
174 | #if !defined(MAXINDEXRK) /* (for debugging only) */ | ||
175 | #define MAXINDEXRK MAXARG_B | ||
176 | #endif | ||
177 | |||
178 | |||
179 | /* | ||
180 | ** invalid register that fits in 8 bits | ||
181 | */ | ||
182 | #define NO_REG MAXARG_A | ||
183 | |||
184 | |||
185 | /* | ||
186 | ** R[x] - register | ||
187 | ** K[x] - constant (in constant table) | ||
188 | ** RK(x) == if k(i) then K[x] else R[x] | ||
189 | */ | ||
190 | |||
191 | |||
192 | /* | ||
193 | ** grep "ORDER OP" if you change these enums | ||
194 | */ | ||
195 | |||
196 | typedef enum { | ||
197 | /*---------------------------------------------------------------------- | ||
198 | name args description | ||
199 | ------------------------------------------------------------------------*/ | ||
200 | OP_MOVE,/* A B R[A] := R[B] */ | ||
201 | OP_LOADI,/* A sBx R[A] := sBx */ | ||
202 | OP_LOADF,/* A sBx R[A] := (lua_Number)sBx */ | ||
203 | OP_LOADK,/* A Bx R[A] := K[Bx] */ | ||
204 | OP_LOADKX,/* A R[A] := K[extra arg] */ | ||
205 | OP_LOADFALSE,/* A R[A] := false */ | ||
206 | OP_LFALSESKIP,/*A R[A] := false; pc++ */ | ||
207 | OP_LOADTRUE,/* A R[A] := true */ | ||
208 | OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */ | ||
209 | OP_GETUPVAL,/* A B R[A] := UpValue[B] */ | ||
210 | OP_SETUPVAL,/* A B UpValue[B] := R[A] */ | ||
211 | |||
212 | OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:string] */ | ||
213 | OP_GETTABLE,/* A B C R[A] := R[B][R[C]] */ | ||
214 | OP_GETI,/* A B C R[A] := R[B][C] */ | ||
215 | OP_GETFIELD,/* A B C R[A] := R[B][K[C]:string] */ | ||
216 | |||
217 | OP_SETTABUP,/* A B C UpValue[A][K[B]:string] := RK(C) */ | ||
218 | OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */ | ||
219 | OP_SETI,/* A B C R[A][B] := RK(C) */ | ||
220 | OP_SETFIELD,/* A B C R[A][K[B]:string] := RK(C) */ | ||
221 | |||
222 | OP_NEWTABLE,/* A B C k R[A] := {} */ | ||
223 | |||
224 | OP_SELF,/* A B C R[A+1] := R[B]; R[A] := R[B][RK(C):string] */ | ||
225 | |||
226 | OP_ADDI,/* A B sC R[A] := R[B] + sC */ | ||
227 | |||
228 | OP_ADDK,/* A B C R[A] := R[B] + K[C] */ | ||
229 | OP_SUBK,/* A B C R[A] := R[B] - K[C] */ | ||
230 | OP_MULK,/* A B C R[A] := R[B] * K[C] */ | ||
231 | OP_MODK,/* A B C R[A] := R[B] % K[C] */ | ||
232 | OP_POWK,/* A B C R[A] := R[B] ^ K[C] */ | ||
233 | OP_DIVK,/* A B C R[A] := R[B] / K[C] */ | ||
234 | OP_IDIVK,/* A B C R[A] := R[B] // K[C] */ | ||
235 | |||
236 | OP_BANDK,/* A B C R[A] := R[B] & K[C]:integer */ | ||
237 | OP_BORK,/* A B C R[A] := R[B] | K[C]:integer */ | ||
238 | OP_BXORK,/* A B C R[A] := R[B] ~ K[C]:integer */ | ||
239 | |||
240 | OP_SHRI,/* A B sC R[A] := R[B] >> sC */ | ||
241 | OP_SHLI,/* A B sC R[A] := sC << R[B] */ | ||
242 | |||
243 | OP_ADD,/* A B C R[A] := R[B] + R[C] */ | ||
244 | OP_SUB,/* A B C R[A] := R[B] - R[C] */ | ||
245 | OP_MUL,/* A B C R[A] := R[B] * R[C] */ | ||
246 | OP_MOD,/* A B C R[A] := R[B] % R[C] */ | ||
247 | OP_POW,/* A B C R[A] := R[B] ^ R[C] */ | ||
248 | OP_DIV,/* A B C R[A] := R[B] / R[C] */ | ||
249 | OP_IDIV,/* A B C R[A] := R[B] // R[C] */ | ||
250 | |||
251 | OP_BAND,/* A B C R[A] := R[B] & R[C] */ | ||
252 | OP_BOR,/* A B C R[A] := R[B] | R[C] */ | ||
253 | OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */ | ||
254 | OP_SHL,/* A B C R[A] := R[B] << R[C] */ | ||
255 | OP_SHR,/* A B C R[A] := R[B] >> R[C] */ | ||
256 | |||
257 | OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] */ | ||
258 | OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */ | ||
259 | OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */ | ||
260 | |||
261 | OP_UNM,/* A B R[A] := -R[B] */ | ||
262 | OP_BNOT,/* A B R[A] := ~R[B] */ | ||
263 | OP_NOT,/* A B R[A] := not R[B] */ | ||
264 | OP_LEN,/* A B R[A] := length of R[B] */ | ||
265 | |||
266 | OP_CONCAT,/* A B R[A] := R[A].. ... ..R[A + B - 1] */ | ||
267 | |||
268 | OP_CLOSE,/* A close all upvalues >= R[A] */ | ||
269 | OP_TBC,/* A mark variable A "to be closed" */ | ||
270 | OP_JMP,/* sJ pc += sJ */ | ||
271 | OP_EQ,/* A B k if ((R[A] == R[B]) ~= k) then pc++ */ | ||
272 | OP_LT,/* A B k if ((R[A] < R[B]) ~= k) then pc++ */ | ||
273 | OP_LE,/* A B k if ((R[A] <= R[B]) ~= k) then pc++ */ | ||
274 | |||
275 | OP_EQK,/* A B k if ((R[A] == K[B]) ~= k) then pc++ */ | ||
276 | OP_EQI,/* A sB k if ((R[A] == sB) ~= k) then pc++ */ | ||
277 | OP_LTI,/* A sB k if ((R[A] < sB) ~= k) then pc++ */ | ||
278 | OP_LEI,/* A sB k if ((R[A] <= sB) ~= k) then pc++ */ | ||
279 | OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */ | ||
280 | OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */ | ||
281 | |||
282 | OP_TEST,/* A k if (not R[A] == k) then pc++ */ | ||
283 | OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */ | ||
284 | |||
285 | OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */ | ||
286 | OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */ | ||
287 | |||
288 | OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */ | ||
289 | OP_RETURN0,/* return */ | ||
290 | OP_RETURN1,/* A return R[A] */ | ||
291 | |||
292 | OP_FORLOOP,/* A Bx update counters; if loop continues then pc-=Bx; */ | ||
293 | OP_FORPREP,/* A Bx <check values and prepare counters>; | ||
294 | if not to run then pc+=Bx+1; */ | ||
295 | |||
296 | OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */ | ||
297 | OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ | ||
298 | OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ | ||
299 | |||
300 | OP_SETLIST,/* A B C k R[A][(C-1)*FPF+i] := R[A+i], 1 <= i <= B */ | ||
301 | |||
302 | OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ | ||
303 | |||
304 | OP_VARARG,/* A C R[A], R[A+1], ..., R[A+C-2] = vararg */ | ||
305 | |||
306 | OP_VARARGPREP,/*A (adjust vararg parameters) */ | ||
307 | |||
308 | OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ | ||
309 | } OpCode; | ||
310 | |||
311 | |||
312 | #define NUM_OPCODES ((int)(OP_EXTRAARG) + 1) | ||
313 | |||
314 | |||
315 | |||
316 | /*=========================================================================== | ||
317 | Notes: | ||
318 | (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then | ||
319 | 'top' is set to last_result+1, so next open instruction (OP_CALL, | ||
320 | OP_RETURN*, OP_SETLIST) may use 'top'. | ||
321 | |||
322 | (*) In OP_VARARG, if (C == 0) then use actual number of varargs and | ||
323 | set top (like in OP_CALL with C == 0). | ||
324 | |||
325 | (*) In OP_RETURN, if (B == 0) then return up to 'top'. | ||
326 | |||
327 | (*) In OP_LOADKX and OP_NEWTABLE, the next instruction is always | ||
328 | OP_EXTRAARG. | ||
329 | |||
330 | (*) In OP_SETLIST, if (B == 0) then real B = 'top'; if k, then | ||
331 | real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the | ||
332 | bits of C). | ||
333 | |||
334 | (*) In OP_NEWTABLE, B is log2 of the hash size (which is always a | ||
335 | power of 2) plus 1, or zero for size zero. If not k, the array size | ||
336 | is C. Otherwise, the array size is EXTRAARG _ C. | ||
337 | |||
338 | (*) For comparisons, k specifies what condition the test should accept | ||
339 | (true or false). | ||
340 | |||
341 | (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped | ||
342 | (the constant is the first operand). | ||
343 | |||
344 | (*) All 'skips' (pc++) assume that next instruction is a jump. | ||
345 | |||
346 | (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the | ||
347 | function builds upvalues, which may need to be closed. C > 0 means | ||
348 | the function is vararg, so that its 'func' must be corrected before | ||
349 | returning; in this case, (C - 1) is its number of fixed parameters. | ||
350 | |||
351 | (*) In comparisons with an immediate operand, C signals whether the | ||
352 | original operand was a float. (It must be corrected in case of | ||
353 | metamethods.) | ||
354 | |||
355 | ===========================================================================*/ | ||
356 | |||
357 | |||
358 | /* | ||
359 | ** masks for instruction properties. The format is: | ||
360 | ** bits 0-2: op mode | ||
361 | ** bit 3: instruction set register A | ||
362 | ** bit 4: operator is a test (next instruction must be a jump) | ||
363 | ** bit 5: instruction uses 'L->top' set by previous instruction (when B == 0) | ||
364 | ** bit 6: instruction sets 'L->top' for next instruction (when C == 0) | ||
365 | ** bit 7: instruction is an MM instruction (call a metamethod) | ||
366 | */ | ||
367 | |||
368 | LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];) | ||
369 | |||
370 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 7)) | ||
371 | #define testAMode(m) (luaP_opmodes[m] & (1 << 3)) | ||
372 | #define testTMode(m) (luaP_opmodes[m] & (1 << 4)) | ||
373 | #define testITMode(m) (luaP_opmodes[m] & (1 << 5)) | ||
374 | #define testOTMode(m) (luaP_opmodes[m] & (1 << 6)) | ||
375 | #define testMMMode(m) (luaP_opmodes[m] & (1 << 7)) | ||
376 | |||
377 | /* "out top" (set top for next instruction) */ | ||
378 | #define isOT(i) \ | ||
379 | ((testOTMode(GET_OPCODE(i)) && GETARG_C(i) == 0) || \ | ||
380 | GET_OPCODE(i) == OP_TAILCALL) | ||
381 | |||
382 | /* "in top" (uses top from previous instruction) */ | ||
383 | #define isIT(i) (testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0) | ||
384 | |||
385 | #define opmode(mm,ot,it,t,a,m) \ | ||
386 | (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m)) | ||
387 | |||
388 | |||
389 | /* number of list items to accumulate before a SETLIST instruction */ | ||
390 | #define LFIELDS_PER_FLUSH 50 | ||
391 | |||
392 | #endif | ||
diff --git a/src/lua/lopnames.h b/src/lua/lopnames.h new file mode 100644 index 0000000..965cec9 --- /dev/null +++ b/src/lua/lopnames.h | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | ** $Id: lopnames.h $ | ||
3 | ** Opcode names | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #if !defined(lopnames_h) | ||
8 | #define lopnames_h | ||
9 | |||
10 | #include <stddef.h> | ||
11 | |||
12 | |||
13 | /* ORDER OP */ | ||
14 | |||
15 | static const char *const opnames[] = { | ||
16 | "MOVE", | ||
17 | "LOADI", | ||
18 | "LOADF", | ||
19 | "LOADK", | ||
20 | "LOADKX", | ||
21 | "LOADFALSE", | ||
22 | "LFALSESKIP", | ||
23 | "LOADTRUE", | ||
24 | "LOADNIL", | ||
25 | "GETUPVAL", | ||
26 | "SETUPVAL", | ||
27 | "GETTABUP", | ||
28 | "GETTABLE", | ||
29 | "GETI", | ||
30 | "GETFIELD", | ||
31 | "SETTABUP", | ||
32 | "SETTABLE", | ||
33 | "SETI", | ||
34 | "SETFIELD", | ||
35 | "NEWTABLE", | ||
36 | "SELF", | ||
37 | "ADDI", | ||
38 | "ADDK", | ||
39 | "SUBK", | ||
40 | "MULK", | ||
41 | "MODK", | ||
42 | "POWK", | ||
43 | "DIVK", | ||
44 | "IDIVK", | ||
45 | "BANDK", | ||
46 | "BORK", | ||
47 | "BXORK", | ||
48 | "SHRI", | ||
49 | "SHLI", | ||
50 | "ADD", | ||
51 | "SUB", | ||
52 | "MUL", | ||
53 | "MOD", | ||
54 | "POW", | ||
55 | "DIV", | ||
56 | "IDIV", | ||
57 | "BAND", | ||
58 | "BOR", | ||
59 | "BXOR", | ||
60 | "SHL", | ||
61 | "SHR", | ||
62 | "MMBIN", | ||
63 | "MMBINI", | ||
64 | "MMBINK", | ||
65 | "UNM", | ||
66 | "BNOT", | ||
67 | "NOT", | ||
68 | "LEN", | ||
69 | "CONCAT", | ||
70 | "CLOSE", | ||
71 | "TBC", | ||
72 | "JMP", | ||
73 | "EQ", | ||
74 | "LT", | ||
75 | "LE", | ||
76 | "EQK", | ||
77 | "EQI", | ||
78 | "LTI", | ||
79 | "LEI", | ||
80 | "GTI", | ||
81 | "GEI", | ||
82 | "TEST", | ||
83 | "TESTSET", | ||
84 | "CALL", | ||
85 | "TAILCALL", | ||
86 | "RETURN", | ||
87 | "RETURN0", | ||
88 | "RETURN1", | ||
89 | "FORLOOP", | ||
90 | "FORPREP", | ||
91 | "TFORPREP", | ||
92 | "TFORCALL", | ||
93 | "TFORLOOP", | ||
94 | "SETLIST", | ||
95 | "CLOSURE", | ||
96 | "VARARG", | ||
97 | "VARARGPREP", | ||
98 | "EXTRAARG", | ||
99 | NULL | ||
100 | }; | ||
101 | |||
102 | #endif | ||
103 | |||
diff --git a/src/lua-5.3/loslib.c b/src/lua/loslib.c index de590c6..e65e188 100644 --- a/src/lua-5.3/loslib.c +++ b/src/lua/loslib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $ | 2 | ** $Id: loslib.c $ |
3 | ** Standard Operating System library | 3 | ** Standard Operating System library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -59,18 +59,20 @@ | |||
59 | ** =================================================================== | 59 | ** =================================================================== |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #if !defined(l_time_t) /* { */ | ||
63 | /* | 62 | /* |
64 | ** type to represent time_t in Lua | 63 | ** type to represent time_t in Lua |
65 | */ | 64 | */ |
65 | #if !defined(LUA_NUMTIME) /* { */ | ||
66 | |||
66 | #define l_timet lua_Integer | 67 | #define l_timet lua_Integer |
67 | #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) | 68 | #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) |
69 | #define l_gettime(L,arg) luaL_checkinteger(L, arg) | ||
68 | 70 | ||
69 | static time_t l_checktime (lua_State *L, int arg) { | 71 | #else /* }{ */ |
70 | lua_Integer t = luaL_checkinteger(L, arg); | 72 | |
71 | luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); | 73 | #define l_timet lua_Number |
72 | return (time_t)t; | 74 | #define l_pushtime(L,t) lua_pushnumber(L,(lua_Number)(t)) |
73 | } | 75 | #define l_gettime(L,arg) luaL_checknumber(L, arg) |
74 | 76 | ||
75 | #endif /* } */ | 77 | #endif /* } */ |
76 | 78 | ||
@@ -90,7 +92,7 @@ static time_t l_checktime (lua_State *L, int arg) { | |||
90 | 92 | ||
91 | /* ISO C definitions */ | 93 | /* ISO C definitions */ |
92 | #define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) | 94 | #define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) |
93 | #define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) | 95 | #define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) |
94 | 96 | ||
95 | #endif /* } */ | 97 | #endif /* } */ |
96 | 98 | ||
@@ -137,10 +139,11 @@ static time_t l_checktime (lua_State *L, int arg) { | |||
137 | 139 | ||
138 | 140 | ||
139 | 141 | ||
140 | |||
141 | static int os_execute (lua_State *L) { | 142 | static int os_execute (lua_State *L) { |
142 | const char *cmd = luaL_optstring(L, 1, NULL); | 143 | const char *cmd = luaL_optstring(L, 1, NULL); |
143 | int stat = system(cmd); | 144 | int stat; |
145 | errno = 0; | ||
146 | stat = system(cmd); | ||
144 | if (cmd != NULL) | 147 | if (cmd != NULL) |
145 | return luaL_execresult(L, stat); | 148 | return luaL_execresult(L, stat); |
146 | else { | 149 | else { |
@@ -194,11 +197,25 @@ static int os_clock (lua_State *L) { | |||
194 | ** ======================================================= | 197 | ** ======================================================= |
195 | */ | 198 | */ |
196 | 199 | ||
197 | static void setfield (lua_State *L, const char *key, int value) { | 200 | /* |
198 | lua_pushinteger(L, value); | 201 | ** About the overflow check: an overflow cannot occur when time |
202 | ** is represented by a lua_Integer, because either lua_Integer is | ||
203 | ** large enough to represent all int fields or it is not large enough | ||
204 | ** to represent a time that cause a field to overflow. However, if | ||
205 | ** times are represented as doubles and lua_Integer is int, then the | ||
206 | ** time 0x1.e1853b0d184f6p+55 would cause an overflow when adding 1900 | ||
207 | ** to compute the year. | ||
208 | */ | ||
209 | static void setfield (lua_State *L, const char *key, int value, int delta) { | ||
210 | #if (defined(LUA_NUMTIME) && LUA_MAXINTEGER <= INT_MAX) | ||
211 | if (value > LUA_MAXINTEGER - delta) | ||
212 | luaL_error(L, "field '%s' is out-of-bound", key); | ||
213 | #endif | ||
214 | lua_pushinteger(L, (lua_Integer)value + delta); | ||
199 | lua_setfield(L, -2, key); | 215 | lua_setfield(L, -2, key); |
200 | } | 216 | } |
201 | 217 | ||
218 | |||
202 | static void setboolfield (lua_State *L, const char *key, int value) { | 219 | static void setboolfield (lua_State *L, const char *key, int value) { |
203 | if (value < 0) /* undefined? */ | 220 | if (value < 0) /* undefined? */ |
204 | return; /* does not set field */ | 221 | return; /* does not set field */ |
@@ -211,14 +228,14 @@ static void setboolfield (lua_State *L, const char *key, int value) { | |||
211 | ** Set all fields from structure 'tm' in the table on top of the stack | 228 | ** Set all fields from structure 'tm' in the table on top of the stack |
212 | */ | 229 | */ |
213 | static void setallfields (lua_State *L, struct tm *stm) { | 230 | static void setallfields (lua_State *L, struct tm *stm) { |
214 | setfield(L, "sec", stm->tm_sec); | 231 | setfield(L, "year", stm->tm_year, 1900); |
215 | setfield(L, "min", stm->tm_min); | 232 | setfield(L, "month", stm->tm_mon, 1); |
216 | setfield(L, "hour", stm->tm_hour); | 233 | setfield(L, "day", stm->tm_mday, 0); |
217 | setfield(L, "day", stm->tm_mday); | 234 | setfield(L, "hour", stm->tm_hour, 0); |
218 | setfield(L, "month", stm->tm_mon + 1); | 235 | setfield(L, "min", stm->tm_min, 0); |
219 | setfield(L, "year", stm->tm_year + 1900); | 236 | setfield(L, "sec", stm->tm_sec, 0); |
220 | setfield(L, "wday", stm->tm_wday + 1); | 237 | setfield(L, "yday", stm->tm_yday, 1); |
221 | setfield(L, "yday", stm->tm_yday + 1); | 238 | setfield(L, "wday", stm->tm_wday, 1); |
222 | setboolfield(L, "isdst", stm->tm_isdst); | 239 | setboolfield(L, "isdst", stm->tm_isdst); |
223 | } | 240 | } |
224 | 241 | ||
@@ -231,11 +248,6 @@ static int getboolfield (lua_State *L, const char *key) { | |||
231 | } | 248 | } |
232 | 249 | ||
233 | 250 | ||
234 | /* maximum value for date fields (to avoid arithmetic overflows with 'int') */ | ||
235 | #if !defined(L_MAXDATEFIELD) | ||
236 | #define L_MAXDATEFIELD (INT_MAX / 2) | ||
237 | #endif | ||
238 | |||
239 | static int getfield (lua_State *L, const char *key, int d, int delta) { | 251 | static int getfield (lua_State *L, const char *key, int d, int delta) { |
240 | int isnum; | 252 | int isnum; |
241 | int t = lua_getfield(L, -1, key); /* get field and its type */ | 253 | int t = lua_getfield(L, -1, key); /* get field and its type */ |
@@ -248,7 +260,9 @@ static int getfield (lua_State *L, const char *key, int d, int delta) { | |||
248 | res = d; | 260 | res = d; |
249 | } | 261 | } |
250 | else { | 262 | else { |
251 | if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) | 263 | /* unsigned avoids overflow when lua_Integer has 32 bits */ |
264 | if (!(res >= 0 ? (lua_Unsigned)res <= (lua_Unsigned)INT_MAX + delta | ||
265 | : (lua_Integer)INT_MIN + delta <= res)) | ||
252 | return luaL_error(L, "field '%s' is out-of-bound", key); | 266 | return luaL_error(L, "field '%s' is out-of-bound", key); |
253 | res -= delta; | 267 | res -= delta; |
254 | } | 268 | } |
@@ -276,6 +290,13 @@ static const char *checkoption (lua_State *L, const char *conv, | |||
276 | } | 290 | } |
277 | 291 | ||
278 | 292 | ||
293 | static time_t l_checktime (lua_State *L, int arg) { | ||
294 | l_timet t = l_gettime(L, arg); | ||
295 | luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); | ||
296 | return (time_t)t; | ||
297 | } | ||
298 | |||
299 | |||
279 | /* maximum size for an individual 'strftime' item */ | 300 | /* maximum size for an individual 'strftime' item */ |
280 | #define SIZETIMEFMT 250 | 301 | #define SIZETIMEFMT 250 |
281 | 302 | ||
@@ -294,7 +315,7 @@ static int os_date (lua_State *L) { | |||
294 | stm = l_localtime(&t, &tmr); | 315 | stm = l_localtime(&t, &tmr); |
295 | if (stm == NULL) /* invalid date? */ | 316 | if (stm == NULL) /* invalid date? */ |
296 | return luaL_error(L, | 317 | return luaL_error(L, |
297 | "time result cannot be represented in this installation"); | 318 | "date result cannot be represented in this installation"); |
298 | if (strcmp(s, "*t") == 0) { | 319 | if (strcmp(s, "*t") == 0) { |
299 | lua_createtable(L, 0, 9); /* 9 = number of fields */ | 320 | lua_createtable(L, 0, 9); /* 9 = number of fields */ |
300 | setallfields(L, stm); | 321 | setallfields(L, stm); |
@@ -330,12 +351,12 @@ static int os_time (lua_State *L) { | |||
330 | struct tm ts; | 351 | struct tm ts; |
331 | luaL_checktype(L, 1, LUA_TTABLE); | 352 | luaL_checktype(L, 1, LUA_TTABLE); |
332 | lua_settop(L, 1); /* make sure table is at the top */ | 353 | lua_settop(L, 1); /* make sure table is at the top */ |
333 | ts.tm_sec = getfield(L, "sec", 0, 0); | ||
334 | ts.tm_min = getfield(L, "min", 0, 0); | ||
335 | ts.tm_hour = getfield(L, "hour", 12, 0); | ||
336 | ts.tm_mday = getfield(L, "day", -1, 0); | ||
337 | ts.tm_mon = getfield(L, "month", -1, 1); | ||
338 | ts.tm_year = getfield(L, "year", -1, 1900); | 354 | ts.tm_year = getfield(L, "year", -1, 1900); |
355 | ts.tm_mon = getfield(L, "month", -1, 1); | ||
356 | ts.tm_mday = getfield(L, "day", -1, 0); | ||
357 | ts.tm_hour = getfield(L, "hour", 12, 0); | ||
358 | ts.tm_min = getfield(L, "min", 0, 0); | ||
359 | ts.tm_sec = getfield(L, "sec", 0, 0); | ||
339 | ts.tm_isdst = getboolfield(L, "isdst"); | 360 | ts.tm_isdst = getboolfield(L, "isdst"); |
340 | t = mktime(&ts); | 361 | t = mktime(&ts); |
341 | setallfields(L, &ts); /* update fields with normalized values */ | 362 | setallfields(L, &ts); /* update fields with normalized values */ |
diff --git a/src/lua-5.3/lparser.c b/src/lua/lparser.c index cc54de4..bc7d9a4 100644 --- a/src/lua-5.3/lparser.c +++ b/src/lua/lparser.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.155.1.2 2017/04/29 18:11:40 roberto Exp $ | 2 | ** $Id: lparser.c $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -10,6 +10,7 @@ | |||
10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
11 | 11 | ||
12 | 12 | ||
13 | #include <limits.h> | ||
13 | #include <string.h> | 14 | #include <string.h> |
14 | 15 | ||
15 | #include "lua.h" | 16 | #include "lua.h" |
@@ -52,6 +53,7 @@ typedef struct BlockCnt { | |||
52 | lu_byte nactvar; /* # active locals outside the block */ | 53 | lu_byte nactvar; /* # active locals outside the block */ |
53 | lu_byte upval; /* true if some variable in the block is an upvalue */ | 54 | lu_byte upval; /* true if some variable in the block is an upvalue */ |
54 | lu_byte isloop; /* true if 'block' is a loop */ | 55 | lu_byte isloop; /* true if 'block' is a loop */ |
56 | lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ | ||
55 | } BlockCnt; | 57 | } BlockCnt; |
56 | 58 | ||
57 | 59 | ||
@@ -63,13 +65,6 @@ static void statement (LexState *ls); | |||
63 | static void expr (LexState *ls, expdesc *v); | 65 | static void expr (LexState *ls, expdesc *v); |
64 | 66 | ||
65 | 67 | ||
66 | /* semantic error */ | ||
67 | static l_noret semerror (LexState *ls, const char *msg) { | ||
68 | ls->t.token = 0; /* remove "near <token>" from final message */ | ||
69 | luaX_syntaxerror(ls, msg); | ||
70 | } | ||
71 | |||
72 | |||
73 | static l_noret error_expected (LexState *ls, int token) { | 68 | static l_noret error_expected (LexState *ls, int token) { |
74 | luaX_syntaxerror(ls, | 69 | luaX_syntaxerror(ls, |
75 | luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); | 70 | luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); |
@@ -94,6 +89,9 @@ static void checklimit (FuncState *fs, int v, int l, const char *what) { | |||
94 | } | 89 | } |
95 | 90 | ||
96 | 91 | ||
92 | /* | ||
93 | ** Test whether next token is 'c'; if so, skip it. | ||
94 | */ | ||
97 | static int testnext (LexState *ls, int c) { | 95 | static int testnext (LexState *ls, int c) { |
98 | if (ls->t.token == c) { | 96 | if (ls->t.token == c) { |
99 | luaX_next(ls); | 97 | luaX_next(ls); |
@@ -103,12 +101,18 @@ static int testnext (LexState *ls, int c) { | |||
103 | } | 101 | } |
104 | 102 | ||
105 | 103 | ||
104 | /* | ||
105 | ** Check that next token is 'c'. | ||
106 | */ | ||
106 | static void check (LexState *ls, int c) { | 107 | static void check (LexState *ls, int c) { |
107 | if (ls->t.token != c) | 108 | if (ls->t.token != c) |
108 | error_expected(ls, c); | 109 | error_expected(ls, c); |
109 | } | 110 | } |
110 | 111 | ||
111 | 112 | ||
113 | /* | ||
114 | ** Check that next token is 'c' and skip it. | ||
115 | */ | ||
112 | static void checknext (LexState *ls, int c) { | 116 | static void checknext (LexState *ls, int c) { |
113 | check(ls, c); | 117 | check(ls, c); |
114 | luaX_next(ls); | 118 | luaX_next(ls); |
@@ -118,11 +122,15 @@ static void checknext (LexState *ls, int c) { | |||
118 | #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } | 122 | #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } |
119 | 123 | ||
120 | 124 | ||
121 | 125 | /* | |
126 | ** Check that next token is 'what' and skip it. In case of error, | ||
127 | ** raise an error that the expected 'what' should match a 'who' | ||
128 | ** in line 'where' (if that is not the current line). | ||
129 | */ | ||
122 | static void check_match (LexState *ls, int what, int who, int where) { | 130 | static void check_match (LexState *ls, int what, int who, int where) { |
123 | if (!testnext(ls, what)) { | 131 | if (unlikely(!testnext(ls, what))) { |
124 | if (where == ls->linenumber) | 132 | if (where == ls->linenumber) /* all in the same line? */ |
125 | error_expected(ls, what); | 133 | error_expected(ls, what); /* do not need a complex message */ |
126 | else { | 134 | else { |
127 | luaX_syntaxerror(ls, luaO_pushfstring(ls->L, | 135 | luaX_syntaxerror(ls, luaO_pushfstring(ls->L, |
128 | "%s expected (to close %s at line %d)", | 136 | "%s expected (to close %s at line %d)", |
@@ -148,73 +156,189 @@ static void init_exp (expdesc *e, expkind k, int i) { | |||
148 | } | 156 | } |
149 | 157 | ||
150 | 158 | ||
151 | static void codestring (LexState *ls, expdesc *e, TString *s) { | 159 | static void codestring (expdesc *e, TString *s) { |
152 | init_exp(e, VK, luaK_stringK(ls->fs, s)); | 160 | e->f = e->t = NO_JUMP; |
161 | e->k = VKSTR; | ||
162 | e->u.strval = s; | ||
153 | } | 163 | } |
154 | 164 | ||
155 | 165 | ||
156 | static void checkname (LexState *ls, expdesc *e) { | 166 | static void codename (LexState *ls, expdesc *e) { |
157 | codestring(ls, e, str_checkname(ls)); | 167 | codestring(e, str_checkname(ls)); |
158 | } | 168 | } |
159 | 169 | ||
160 | 170 | ||
161 | static int registerlocalvar (LexState *ls, TString *varname) { | 171 | /* |
162 | FuncState *fs = ls->fs; | 172 | ** Register a new local variable in the active 'Proto' (for debug |
173 | ** information). | ||
174 | */ | ||
175 | static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) { | ||
163 | Proto *f = fs->f; | 176 | Proto *f = fs->f; |
164 | int oldsize = f->sizelocvars; | 177 | int oldsize = f->sizelocvars; |
165 | luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, | 178 | luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars, |
166 | LocVar, SHRT_MAX, "local variables"); | 179 | LocVar, SHRT_MAX, "local variables"); |
167 | while (oldsize < f->sizelocvars) | 180 | while (oldsize < f->sizelocvars) |
168 | f->locvars[oldsize++].varname = NULL; | 181 | f->locvars[oldsize++].varname = NULL; |
169 | f->locvars[fs->nlocvars].varname = varname; | 182 | f->locvars[fs->ndebugvars].varname = varname; |
183 | f->locvars[fs->ndebugvars].startpc = fs->pc; | ||
170 | luaC_objbarrier(ls->L, f, varname); | 184 | luaC_objbarrier(ls->L, f, varname); |
171 | return fs->nlocvars++; | 185 | return fs->ndebugvars++; |
172 | } | 186 | } |
173 | 187 | ||
174 | 188 | ||
175 | static void new_localvar (LexState *ls, TString *name) { | 189 | /* |
190 | ** Create a new local variable with the given 'name'. Return its index | ||
191 | ** in the function. | ||
192 | */ | ||
193 | static int new_localvar (LexState *ls, TString *name) { | ||
194 | lua_State *L = ls->L; | ||
176 | FuncState *fs = ls->fs; | 195 | FuncState *fs = ls->fs; |
177 | Dyndata *dyd = ls->dyd; | 196 | Dyndata *dyd = ls->dyd; |
178 | int reg = registerlocalvar(ls, name); | 197 | Vardesc *var; |
179 | checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, | 198 | checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, |
180 | MAXVARS, "local variables"); | 199 | MAXVARS, "local variables"); |
181 | luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, | 200 | luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, |
182 | dyd->actvar.size, Vardesc, MAX_INT, "local variables"); | 201 | dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); |
183 | dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); | 202 | var = &dyd->actvar.arr[dyd->actvar.n++]; |
203 | var->vd.kind = VDKREG; /* default */ | ||
204 | var->vd.name = name; | ||
205 | return dyd->actvar.n - 1 - fs->firstlocal; | ||
184 | } | 206 | } |
185 | 207 | ||
208 | #define new_localvarliteral(ls,v) \ | ||
209 | new_localvar(ls, \ | ||
210 | luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); | ||
211 | |||
186 | 212 | ||
187 | static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { | 213 | |
188 | new_localvar(ls, luaX_newstring(ls, name, sz)); | 214 | /* |
215 | ** Return the "variable description" (Vardesc) of a given variable. | ||
216 | ** (Unless noted otherwise, all variables are referred to by their | ||
217 | ** compiler indices.) | ||
218 | */ | ||
219 | static Vardesc *getlocalvardesc (FuncState *fs, int vidx) { | ||
220 | return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx]; | ||
189 | } | 221 | } |
190 | 222 | ||
191 | #define new_localvarliteral(ls,v) \ | 223 | |
192 | new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) | 224 | /* |
225 | ** Convert 'nvar', a compiler index level, to it corresponding | ||
226 | ** stack index level. For that, search for the highest variable | ||
227 | ** below that level that is in the stack and uses its stack | ||
228 | ** index ('sidx'). | ||
229 | */ | ||
230 | static int stacklevel (FuncState *fs, int nvar) { | ||
231 | while (nvar-- > 0) { | ||
232 | Vardesc *vd = getlocalvardesc(fs, nvar); /* get variable */ | ||
233 | if (vd->vd.kind != RDKCTC) /* is in the stack? */ | ||
234 | return vd->vd.sidx + 1; | ||
235 | } | ||
236 | return 0; /* no variables in the stack */ | ||
237 | } | ||
238 | |||
239 | |||
240 | /* | ||
241 | ** Return the number of variables in the stack for function 'fs' | ||
242 | */ | ||
243 | int luaY_nvarstack (FuncState *fs) { | ||
244 | return stacklevel(fs, fs->nactvar); | ||
245 | } | ||
193 | 246 | ||
194 | 247 | ||
195 | static LocVar *getlocvar (FuncState *fs, int i) { | 248 | /* |
196 | int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; | 249 | ** Get the debug-information entry for current variable 'vidx'. |
197 | lua_assert(idx < fs->nlocvars); | 250 | */ |
198 | return &fs->f->locvars[idx]; | 251 | static LocVar *localdebuginfo (FuncState *fs, int vidx) { |
252 | Vardesc *vd = getlocalvardesc(fs, vidx); | ||
253 | if (vd->vd.kind == RDKCTC) | ||
254 | return NULL; /* no debug info. for constants */ | ||
255 | else { | ||
256 | int idx = vd->vd.pidx; | ||
257 | lua_assert(idx < fs->ndebugvars); | ||
258 | return &fs->f->locvars[idx]; | ||
259 | } | ||
199 | } | 260 | } |
200 | 261 | ||
201 | 262 | ||
263 | /* | ||
264 | ** Create an expression representing variable 'vidx' | ||
265 | */ | ||
266 | static void init_var (FuncState *fs, expdesc *e, int vidx) { | ||
267 | e->f = e->t = NO_JUMP; | ||
268 | e->k = VLOCAL; | ||
269 | e->u.var.vidx = vidx; | ||
270 | e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx; | ||
271 | } | ||
272 | |||
273 | |||
274 | /* | ||
275 | ** Raises an error if variable described by 'e' is read only | ||
276 | */ | ||
277 | static void check_readonly (LexState *ls, expdesc *e) { | ||
278 | FuncState *fs = ls->fs; | ||
279 | TString *varname = NULL; /* to be set if variable is const */ | ||
280 | switch (e->k) { | ||
281 | case VCONST: { | ||
282 | varname = ls->dyd->actvar.arr[e->u.info].vd.name; | ||
283 | break; | ||
284 | } | ||
285 | case VLOCAL: { | ||
286 | Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx); | ||
287 | if (vardesc->vd.kind != VDKREG) /* not a regular variable? */ | ||
288 | varname = vardesc->vd.name; | ||
289 | break; | ||
290 | } | ||
291 | case VUPVAL: { | ||
292 | Upvaldesc *up = &fs->f->upvalues[e->u.info]; | ||
293 | if (up->kind != VDKREG) | ||
294 | varname = up->name; | ||
295 | break; | ||
296 | } | ||
297 | default: | ||
298 | return; /* other cases cannot be read-only */ | ||
299 | } | ||
300 | if (varname) { | ||
301 | const char *msg = luaO_pushfstring(ls->L, | ||
302 | "attempt to assign to const variable '%s'", getstr(varname)); | ||
303 | luaK_semerror(ls, msg); /* error */ | ||
304 | } | ||
305 | } | ||
306 | |||
307 | |||
308 | /* | ||
309 | ** Start the scope for the last 'nvars' created variables. | ||
310 | */ | ||
202 | static void adjustlocalvars (LexState *ls, int nvars) { | 311 | static void adjustlocalvars (LexState *ls, int nvars) { |
203 | FuncState *fs = ls->fs; | 312 | FuncState *fs = ls->fs; |
204 | fs->nactvar = cast_byte(fs->nactvar + nvars); | 313 | int stklevel = luaY_nvarstack(fs); |
205 | for (; nvars; nvars--) { | 314 | int i; |
206 | getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; | 315 | for (i = 0; i < nvars; i++) { |
316 | int vidx = fs->nactvar++; | ||
317 | Vardesc *var = getlocalvardesc(fs, vidx); | ||
318 | var->vd.sidx = stklevel++; | ||
319 | var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); | ||
207 | } | 320 | } |
208 | } | 321 | } |
209 | 322 | ||
210 | 323 | ||
324 | /* | ||
325 | ** Close the scope for all variables up to level 'tolevel'. | ||
326 | ** (debug info.) | ||
327 | */ | ||
211 | static void removevars (FuncState *fs, int tolevel) { | 328 | static void removevars (FuncState *fs, int tolevel) { |
212 | fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); | 329 | fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); |
213 | while (fs->nactvar > tolevel) | 330 | while (fs->nactvar > tolevel) { |
214 | getlocvar(fs, --fs->nactvar)->endpc = fs->pc; | 331 | LocVar *var = localdebuginfo(fs, --fs->nactvar); |
332 | if (var) /* does it have debug information? */ | ||
333 | var->endpc = fs->pc; | ||
334 | } | ||
215 | } | 335 | } |
216 | 336 | ||
217 | 337 | ||
338 | /* | ||
339 | ** Search the upvalues of the function 'fs' for one | ||
340 | ** with the given 'name'. | ||
341 | */ | ||
218 | static int searchupvalue (FuncState *fs, TString *name) { | 342 | static int searchupvalue (FuncState *fs, TString *name) { |
219 | int i; | 343 | int i; |
220 | Upvaldesc *up = fs->f->upvalues; | 344 | Upvaldesc *up = fs->f->upvalues; |
@@ -225,7 +349,7 @@ static int searchupvalue (FuncState *fs, TString *name) { | |||
225 | } | 349 | } |
226 | 350 | ||
227 | 351 | ||
228 | static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | 352 | static Upvaldesc *allocupvalue (FuncState *fs) { |
229 | Proto *f = fs->f; | 353 | Proto *f = fs->f; |
230 | int oldsize = f->sizeupvalues; | 354 | int oldsize = f->sizeupvalues; |
231 | checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); | 355 | checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); |
@@ -233,58 +357,87 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | |||
233 | Upvaldesc, MAXUPVAL, "upvalues"); | 357 | Upvaldesc, MAXUPVAL, "upvalues"); |
234 | while (oldsize < f->sizeupvalues) | 358 | while (oldsize < f->sizeupvalues) |
235 | f->upvalues[oldsize++].name = NULL; | 359 | f->upvalues[oldsize++].name = NULL; |
236 | f->upvalues[fs->nups].instack = (v->k == VLOCAL); | 360 | return &f->upvalues[fs->nups++]; |
237 | f->upvalues[fs->nups].idx = cast_byte(v->u.info); | ||
238 | f->upvalues[fs->nups].name = name; | ||
239 | luaC_objbarrier(fs->ls->L, f, name); | ||
240 | return fs->nups++; | ||
241 | } | 361 | } |
242 | 362 | ||
243 | 363 | ||
244 | static int searchvar (FuncState *fs, TString *n) { | 364 | static int newupvalue (FuncState *fs, TString *name, expdesc *v) { |
365 | Upvaldesc *up = allocupvalue(fs); | ||
366 | FuncState *prev = fs->prev; | ||
367 | if (v->k == VLOCAL) { | ||
368 | up->instack = 1; | ||
369 | up->idx = v->u.var.sidx; | ||
370 | up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind; | ||
371 | lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name)); | ||
372 | } | ||
373 | else { | ||
374 | up->instack = 0; | ||
375 | up->idx = cast_byte(v->u.info); | ||
376 | up->kind = prev->f->upvalues[v->u.info].kind; | ||
377 | lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name)); | ||
378 | } | ||
379 | up->name = name; | ||
380 | luaC_objbarrier(fs->ls->L, fs->f, name); | ||
381 | return fs->nups - 1; | ||
382 | } | ||
383 | |||
384 | |||
385 | /* | ||
386 | ** Look for an active local variable with the name 'n' in the | ||
387 | ** function 'fs'. If found, initialize 'var' with it and return | ||
388 | ** its expression kind; otherwise return -1. | ||
389 | */ | ||
390 | static int searchvar (FuncState *fs, TString *n, expdesc *var) { | ||
245 | int i; | 391 | int i; |
246 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { | 392 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { |
247 | if (eqstr(n, getlocvar(fs, i)->varname)) | 393 | Vardesc *vd = getlocalvardesc(fs, i); |
248 | return i; | 394 | if (eqstr(n, vd->vd.name)) { /* found? */ |
395 | if (vd->vd.kind == RDKCTC) /* compile-time constant? */ | ||
396 | init_exp(var, VCONST, fs->firstlocal + i); | ||
397 | else /* real variable */ | ||
398 | init_var(fs, var, i); | ||
399 | return var->k; | ||
400 | } | ||
249 | } | 401 | } |
250 | return -1; /* not found */ | 402 | return -1; /* not found */ |
251 | } | 403 | } |
252 | 404 | ||
253 | 405 | ||
254 | /* | 406 | /* |
255 | Mark block where variable at given level was defined | 407 | ** Mark block where variable at given level was defined |
256 | (to emit close instructions later). | 408 | ** (to emit close instructions later). |
257 | */ | 409 | */ |
258 | static void markupval (FuncState *fs, int level) { | 410 | static void markupval (FuncState *fs, int level) { |
259 | BlockCnt *bl = fs->bl; | 411 | BlockCnt *bl = fs->bl; |
260 | while (bl->nactvar > level) | 412 | while (bl->nactvar > level) |
261 | bl = bl->previous; | 413 | bl = bl->previous; |
262 | bl->upval = 1; | 414 | bl->upval = 1; |
415 | fs->needclose = 1; | ||
263 | } | 416 | } |
264 | 417 | ||
265 | 418 | ||
266 | /* | 419 | /* |
267 | Find variable with given name 'n'. If it is an upvalue, add this | 420 | ** Find a variable with the given name 'n'. If it is an upvalue, add |
268 | upvalue into all intermediate functions. | 421 | ** this upvalue into all intermediate functions. If it is a global, set |
422 | ** 'var' as 'void' as a flag. | ||
269 | */ | 423 | */ |
270 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | 424 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { |
271 | if (fs == NULL) /* no more levels? */ | 425 | if (fs == NULL) /* no more levels? */ |
272 | init_exp(var, VVOID, 0); /* default is global */ | 426 | init_exp(var, VVOID, 0); /* default is global */ |
273 | else { | 427 | else { |
274 | int v = searchvar(fs, n); /* look up locals at current level */ | 428 | int v = searchvar(fs, n, var); /* look up locals at current level */ |
275 | if (v >= 0) { /* found? */ | 429 | if (v >= 0) { /* found? */ |
276 | init_exp(var, VLOCAL, v); /* variable is local */ | 430 | if (v == VLOCAL && !base) |
277 | if (!base) | 431 | markupval(fs, var->u.var.vidx); /* local will be used as an upval */ |
278 | markupval(fs, v); /* local will be used as an upval */ | ||
279 | } | 432 | } |
280 | else { /* not found as local at current level; try upvalues */ | 433 | else { /* not found as local at current level; try upvalues */ |
281 | int idx = searchupvalue(fs, n); /* try existing upvalues */ | 434 | int idx = searchupvalue(fs, n); /* try existing upvalues */ |
282 | if (idx < 0) { /* not found? */ | 435 | if (idx < 0) { /* not found? */ |
283 | singlevaraux(fs->prev, n, var, 0); /* try upper levels */ | 436 | singlevaraux(fs->prev, n, var, 0); /* try upper levels */ |
284 | if (var->k == VVOID) /* not found? */ | 437 | if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ |
285 | return; /* it is a global */ | 438 | idx = newupvalue(fs, n, var); /* will be a new upvalue */ |
286 | /* else was LOCAL or UPVAL */ | 439 | else /* it is a global or a constant */ |
287 | idx = newupvalue(fs, n, var); /* will be a new upvalue */ | 440 | return; /* don't need to do anything at this level */ |
288 | } | 441 | } |
289 | init_exp(var, VUPVAL, idx); /* new or old upvalue */ | 442 | init_exp(var, VUPVAL, idx); /* new or old upvalue */ |
290 | } | 443 | } |
@@ -292,6 +445,10 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | |||
292 | } | 445 | } |
293 | 446 | ||
294 | 447 | ||
448 | /* | ||
449 | ** Find a variable with the given name 'n', handling global variables | ||
450 | ** too. | ||
451 | */ | ||
295 | static void singlevar (LexState *ls, expdesc *var) { | 452 | static void singlevar (LexState *ls, expdesc *var) { |
296 | TString *varname = str_checkname(ls); | 453 | TString *varname = str_checkname(ls); |
297 | FuncState *fs = ls->fs; | 454 | FuncState *fs = ls->fs; |
@@ -300,88 +457,96 @@ static void singlevar (LexState *ls, expdesc *var) { | |||
300 | expdesc key; | 457 | expdesc key; |
301 | singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ | 458 | singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ |
302 | lua_assert(var->k != VVOID); /* this one must exist */ | 459 | lua_assert(var->k != VVOID); /* this one must exist */ |
303 | codestring(ls, &key, varname); /* key is variable name */ | 460 | codestring(&key, varname); /* key is variable name */ |
304 | luaK_indexed(fs, var, &key); /* env[varname] */ | 461 | luaK_indexed(fs, var, &key); /* env[varname] */ |
305 | } | 462 | } |
306 | } | 463 | } |
307 | 464 | ||
308 | 465 | ||
466 | /* | ||
467 | ** Adjust the number of results from an expression list 'e' with 'nexps' | ||
468 | ** expressions to 'nvars' values. | ||
469 | */ | ||
309 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | 470 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { |
310 | FuncState *fs = ls->fs; | 471 | FuncState *fs = ls->fs; |
311 | int extra = nvars - nexps; | 472 | int needed = nvars - nexps; /* extra values needed */ |
312 | if (hasmultret(e->k)) { | 473 | if (hasmultret(e->k)) { /* last expression has multiple returns? */ |
313 | extra++; /* includes call itself */ | 474 | int extra = needed + 1; /* discount last expression itself */ |
314 | if (extra < 0) extra = 0; | 475 | if (extra < 0) |
476 | extra = 0; | ||
315 | luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ | 477 | luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ |
316 | if (extra > 1) luaK_reserveregs(fs, extra-1); | ||
317 | } | 478 | } |
318 | else { | 479 | else { |
319 | if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ | 480 | if (e->k != VVOID) /* at least one expression? */ |
320 | if (extra > 0) { | 481 | luaK_exp2nextreg(fs, e); /* close last expression */ |
321 | int reg = fs->freereg; | 482 | if (needed > 0) /* missing values? */ |
322 | luaK_reserveregs(fs, extra); | 483 | luaK_nil(fs, fs->freereg, needed); /* complete with nils */ |
323 | luaK_nil(fs, reg, extra); | ||
324 | } | ||
325 | } | 484 | } |
326 | if (nexps > nvars) | 485 | if (needed > 0) |
327 | ls->fs->freereg -= nexps - nvars; /* remove extra values */ | 486 | luaK_reserveregs(fs, needed); /* registers for extra values */ |
487 | else /* adding 'needed' is actually a subtraction */ | ||
488 | fs->freereg += needed; /* remove extra values */ | ||
328 | } | 489 | } |
329 | 490 | ||
330 | 491 | ||
331 | static void enterlevel (LexState *ls) { | 492 | /* |
332 | lua_State *L = ls->L; | 493 | ** Macros to limit the maximum recursion depth while parsing |
333 | ++L->nCcalls; | 494 | */ |
334 | checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); | 495 | #define enterlevel(ls) luaE_enterCcall((ls)->L) |
335 | } | 496 | |
497 | #define leavelevel(ls) luaE_exitCcall((ls)->L) | ||
336 | 498 | ||
337 | 499 | ||
338 | #define leavelevel(ls) ((ls)->L->nCcalls--) | 500 | /* |
501 | ** Generates an error that a goto jumps into the scope of some | ||
502 | ** local variable. | ||
503 | */ | ||
504 | static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { | ||
505 | const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name); | ||
506 | const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'"; | ||
507 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); | ||
508 | luaK_semerror(ls, msg); /* raise the error */ | ||
509 | } | ||
339 | 510 | ||
340 | 511 | ||
341 | static void closegoto (LexState *ls, int g, Labeldesc *label) { | 512 | /* |
513 | ** Solves the goto at index 'g' to given 'label' and removes it | ||
514 | ** from the list of pending goto's. | ||
515 | ** If it jumps into the scope of some variable, raises an error. | ||
516 | */ | ||
517 | static void solvegoto (LexState *ls, int g, Labeldesc *label) { | ||
342 | int i; | 518 | int i; |
343 | FuncState *fs = ls->fs; | 519 | Labellist *gl = &ls->dyd->gt; /* list of goto's */ |
344 | Labellist *gl = &ls->dyd->gt; | 520 | Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */ |
345 | Labeldesc *gt = &gl->arr[g]; | ||
346 | lua_assert(eqstr(gt->name, label->name)); | 521 | lua_assert(eqstr(gt->name, label->name)); |
347 | if (gt->nactvar < label->nactvar) { | 522 | if (unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ |
348 | TString *vname = getlocvar(fs, gt->nactvar)->varname; | 523 | jumpscopeerror(ls, gt); |
349 | const char *msg = luaO_pushfstring(ls->L, | 524 | luaK_patchlist(ls->fs, gt->pc, label->pc); |
350 | "<goto %s> at line %d jumps into the scope of local '%s'", | 525 | for (i = g; i < gl->n - 1; i++) /* remove goto from pending list */ |
351 | getstr(gt->name), gt->line, getstr(vname)); | ||
352 | semerror(ls, msg); | ||
353 | } | ||
354 | luaK_patchlist(fs, gt->pc, label->pc); | ||
355 | /* remove goto from pending list */ | ||
356 | for (i = g; i < gl->n - 1; i++) | ||
357 | gl->arr[i] = gl->arr[i + 1]; | 526 | gl->arr[i] = gl->arr[i + 1]; |
358 | gl->n--; | 527 | gl->n--; |
359 | } | 528 | } |
360 | 529 | ||
361 | 530 | ||
362 | /* | 531 | /* |
363 | ** try to close a goto with existing labels; this solves backward jumps | 532 | ** Search for an active label with the given name. |
364 | */ | 533 | */ |
365 | static int findlabel (LexState *ls, int g) { | 534 | static Labeldesc *findlabel (LexState *ls, TString *name) { |
366 | int i; | 535 | int i; |
367 | BlockCnt *bl = ls->fs->bl; | ||
368 | Dyndata *dyd = ls->dyd; | 536 | Dyndata *dyd = ls->dyd; |
369 | Labeldesc *gt = &dyd->gt.arr[g]; | 537 | /* check labels in current function for a match */ |
370 | /* check labels in current block for a match */ | 538 | for (i = ls->fs->firstlabel; i < dyd->label.n; i++) { |
371 | for (i = bl->firstlabel; i < dyd->label.n; i++) { | ||
372 | Labeldesc *lb = &dyd->label.arr[i]; | 539 | Labeldesc *lb = &dyd->label.arr[i]; |
373 | if (eqstr(lb->name, gt->name)) { /* correct label? */ | 540 | if (eqstr(lb->name, name)) /* correct label? */ |
374 | if (gt->nactvar > lb->nactvar && | 541 | return lb; |
375 | (bl->upval || dyd->label.n > bl->firstlabel)) | ||
376 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); | ||
377 | closegoto(ls, g, lb); /* close it */ | ||
378 | return 1; | ||
379 | } | ||
380 | } | 542 | } |
381 | return 0; /* label not found; cannot close goto */ | 543 | return NULL; /* label not found */ |
382 | } | 544 | } |
383 | 545 | ||
384 | 546 | ||
547 | /* | ||
548 | ** Adds a new label/goto in the corresponding list. | ||
549 | */ | ||
385 | static int newlabelentry (LexState *ls, Labellist *l, TString *name, | 550 | static int newlabelentry (LexState *ls, Labellist *l, TString *name, |
386 | int line, int pc) { | 551 | int line, int pc) { |
387 | int n = l->n; | 552 | int n = l->n; |
@@ -390,48 +555,76 @@ static int newlabelentry (LexState *ls, Labellist *l, TString *name, | |||
390 | l->arr[n].name = name; | 555 | l->arr[n].name = name; |
391 | l->arr[n].line = line; | 556 | l->arr[n].line = line; |
392 | l->arr[n].nactvar = ls->fs->nactvar; | 557 | l->arr[n].nactvar = ls->fs->nactvar; |
558 | l->arr[n].close = 0; | ||
393 | l->arr[n].pc = pc; | 559 | l->arr[n].pc = pc; |
394 | l->n = n + 1; | 560 | l->n = n + 1; |
395 | return n; | 561 | return n; |
396 | } | 562 | } |
397 | 563 | ||
398 | 564 | ||
565 | static int newgotoentry (LexState *ls, TString *name, int line, int pc) { | ||
566 | return newlabelentry(ls, &ls->dyd->gt, name, line, pc); | ||
567 | } | ||
568 | |||
569 | |||
399 | /* | 570 | /* |
400 | ** check whether new label 'lb' matches any pending gotos in current | 571 | ** Solves forward jumps. Check whether new label 'lb' matches any |
401 | ** block; solves forward jumps | 572 | ** pending gotos in current block and solves them. Return true |
573 | ** if any of the goto's need to close upvalues. | ||
402 | */ | 574 | */ |
403 | static void findgotos (LexState *ls, Labeldesc *lb) { | 575 | static int solvegotos (LexState *ls, Labeldesc *lb) { |
404 | Labellist *gl = &ls->dyd->gt; | 576 | Labellist *gl = &ls->dyd->gt; |
405 | int i = ls->fs->bl->firstgoto; | 577 | int i = ls->fs->bl->firstgoto; |
578 | int needsclose = 0; | ||
406 | while (i < gl->n) { | 579 | while (i < gl->n) { |
407 | if (eqstr(gl->arr[i].name, lb->name)) | 580 | if (eqstr(gl->arr[i].name, lb->name)) { |
408 | closegoto(ls, i, lb); | 581 | needsclose |= gl->arr[i].close; |
582 | solvegoto(ls, i, lb); /* will remove 'i' from the list */ | ||
583 | } | ||
409 | else | 584 | else |
410 | i++; | 585 | i++; |
411 | } | 586 | } |
587 | return needsclose; | ||
412 | } | 588 | } |
413 | 589 | ||
414 | 590 | ||
415 | /* | 591 | /* |
416 | ** export pending gotos to outer level, to check them against | 592 | ** Create a new label with the given 'name' at the given 'line'. |
417 | ** outer labels; if the block being exited has upvalues, and | 593 | ** 'last' tells whether label is the last non-op statement in its |
418 | ** the goto exits the scope of any variable (which can be the | 594 | ** block. Solves all pending goto's to this new label and adds |
419 | ** upvalue), close those variables being exited. | 595 | ** a close instruction if necessary. |
596 | ** Returns true iff it added a close instruction. | ||
597 | */ | ||
598 | static int createlabel (LexState *ls, TString *name, int line, | ||
599 | int last) { | ||
600 | FuncState *fs = ls->fs; | ||
601 | Labellist *ll = &ls->dyd->label; | ||
602 | int l = newlabelentry(ls, ll, name, line, luaK_getlabel(fs)); | ||
603 | if (last) { /* label is last no-op statement in the block? */ | ||
604 | /* assume that locals are already out of scope */ | ||
605 | ll->arr[l].nactvar = fs->bl->nactvar; | ||
606 | } | ||
607 | if (solvegotos(ls, &ll->arr[l])) { /* need close? */ | ||
608 | luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0); | ||
609 | return 1; | ||
610 | } | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | |||
615 | /* | ||
616 | ** Adjust pending gotos to outer level of a block. | ||
420 | */ | 617 | */ |
421 | static void movegotosout (FuncState *fs, BlockCnt *bl) { | 618 | static void movegotosout (FuncState *fs, BlockCnt *bl) { |
422 | int i = bl->firstgoto; | 619 | int i; |
423 | Labellist *gl = &fs->ls->dyd->gt; | 620 | Labellist *gl = &fs->ls->dyd->gt; |
424 | /* correct pending gotos to current block and try to close it | 621 | /* correct pending gotos to current block */ |
425 | with visible labels */ | 622 | for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ |
426 | while (i < gl->n) { | ||
427 | Labeldesc *gt = &gl->arr[i]; | 623 | Labeldesc *gt = &gl->arr[i]; |
428 | if (gt->nactvar > bl->nactvar) { | 624 | /* leaving a variable scope? */ |
429 | if (bl->upval) | 625 | if (stacklevel(fs, gt->nactvar) > stacklevel(fs, bl->nactvar)) |
430 | luaK_patchclose(fs, gt->pc, bl->nactvar); | 626 | gt->close |= bl->upval; /* jump may need a close */ |
431 | gt->nactvar = bl->nactvar; | 627 | gt->nactvar = bl->nactvar; /* update goto level */ |
432 | } | ||
433 | if (!findlabel(fs->ls, i)) | ||
434 | i++; /* move to next one */ | ||
435 | } | 628 | } |
436 | } | 629 | } |
437 | 630 | ||
@@ -442,54 +635,50 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { | |||
442 | bl->firstlabel = fs->ls->dyd->label.n; | 635 | bl->firstlabel = fs->ls->dyd->label.n; |
443 | bl->firstgoto = fs->ls->dyd->gt.n; | 636 | bl->firstgoto = fs->ls->dyd->gt.n; |
444 | bl->upval = 0; | 637 | bl->upval = 0; |
638 | bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); | ||
445 | bl->previous = fs->bl; | 639 | bl->previous = fs->bl; |
446 | fs->bl = bl; | 640 | fs->bl = bl; |
447 | lua_assert(fs->freereg == fs->nactvar); | 641 | lua_assert(fs->freereg == luaY_nvarstack(fs)); |
448 | } | 642 | } |
449 | 643 | ||
450 | 644 | ||
451 | /* | 645 | /* |
452 | ** create a label named 'break' to resolve break statements | 646 | ** generates an error for an undefined 'goto'. |
453 | */ | ||
454 | static void breaklabel (LexState *ls) { | ||
455 | TString *n = luaS_new(ls->L, "break"); | ||
456 | int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); | ||
457 | findgotos(ls, &ls->dyd->label.arr[l]); | ||
458 | } | ||
459 | |||
460 | /* | ||
461 | ** generates an error for an undefined 'goto'; choose appropriate | ||
462 | ** message when label name is a reserved word (which can only be 'break') | ||
463 | */ | 647 | */ |
464 | static l_noret undefgoto (LexState *ls, Labeldesc *gt) { | 648 | static l_noret undefgoto (LexState *ls, Labeldesc *gt) { |
465 | const char *msg = isreserved(gt->name) | 649 | const char *msg; |
466 | ? "<%s> at line %d not inside a loop" | 650 | if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) { |
467 | : "no visible label '%s' for <goto> at line %d"; | 651 | msg = "break outside loop at line %d"; |
468 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); | 652 | msg = luaO_pushfstring(ls->L, msg, gt->line); |
469 | semerror(ls, msg); | 653 | } |
654 | else { | ||
655 | msg = "no visible label '%s' for <goto> at line %d"; | ||
656 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); | ||
657 | } | ||
658 | luaK_semerror(ls, msg); | ||
470 | } | 659 | } |
471 | 660 | ||
472 | 661 | ||
473 | static void leaveblock (FuncState *fs) { | 662 | static void leaveblock (FuncState *fs) { |
474 | BlockCnt *bl = fs->bl; | 663 | BlockCnt *bl = fs->bl; |
475 | LexState *ls = fs->ls; | 664 | LexState *ls = fs->ls; |
476 | if (bl->previous && bl->upval) { | 665 | int hasclose = 0; |
477 | /* create a 'jump to here' to close upvalues */ | 666 | int stklevel = stacklevel(fs, bl->nactvar); /* level outside the block */ |
478 | int j = luaK_jump(fs); | 667 | if (bl->isloop) /* fix pending breaks? */ |
479 | luaK_patchclose(fs, j, bl->nactvar); | 668 | hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); |
480 | luaK_patchtohere(fs, j); | 669 | if (!hasclose && bl->previous && bl->upval) |
481 | } | 670 | luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); |
482 | if (bl->isloop) | ||
483 | breaklabel(ls); /* close pending breaks */ | ||
484 | fs->bl = bl->previous; | 671 | fs->bl = bl->previous; |
485 | removevars(fs, bl->nactvar); | 672 | removevars(fs, bl->nactvar); |
486 | lua_assert(bl->nactvar == fs->nactvar); | 673 | lua_assert(bl->nactvar == fs->nactvar); |
487 | fs->freereg = fs->nactvar; /* free registers */ | 674 | fs->freereg = stklevel; /* free registers */ |
488 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ | 675 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ |
489 | if (bl->previous) /* inner block? */ | 676 | if (bl->previous) /* inner block? */ |
490 | movegotosout(fs, bl); /* update pending gotos to outer block */ | 677 | movegotosout(fs, bl); /* update pending gotos to outer block */ |
491 | else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ | 678 | else { |
492 | undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ | 679 | if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ |
680 | undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ | ||
681 | } | ||
493 | } | 682 | } |
494 | 683 | ||
495 | 684 | ||
@@ -515,35 +704,40 @@ static Proto *addprototype (LexState *ls) { | |||
515 | 704 | ||
516 | /* | 705 | /* |
517 | ** codes instruction to create new closure in parent function. | 706 | ** codes instruction to create new closure in parent function. |
518 | ** The OP_CLOSURE instruction must use the last available register, | 707 | ** The OP_CLOSURE instruction uses the last available register, |
519 | ** so that, if it invokes the GC, the GC knows which registers | 708 | ** so that, if it invokes the GC, the GC knows which registers |
520 | ** are in use at that time. | 709 | ** are in use at that time. |
710 | |||
521 | */ | 711 | */ |
522 | static void codeclosure (LexState *ls, expdesc *v) { | 712 | static void codeclosure (LexState *ls, expdesc *v) { |
523 | FuncState *fs = ls->fs->prev; | 713 | FuncState *fs = ls->fs->prev; |
524 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); | 714 | init_exp(v, VRELOC, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); |
525 | luaK_exp2nextreg(fs, v); /* fix it at the last register */ | 715 | luaK_exp2nextreg(fs, v); /* fix it at the last register */ |
526 | } | 716 | } |
527 | 717 | ||
528 | 718 | ||
529 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | 719 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { |
530 | Proto *f; | 720 | Proto *f = fs->f; |
531 | fs->prev = ls->fs; /* linked list of funcstates */ | 721 | fs->prev = ls->fs; /* linked list of funcstates */ |
532 | fs->ls = ls; | 722 | fs->ls = ls; |
533 | ls->fs = fs; | 723 | ls->fs = fs; |
534 | fs->pc = 0; | 724 | fs->pc = 0; |
725 | fs->previousline = f->linedefined; | ||
726 | fs->iwthabs = 0; | ||
535 | fs->lasttarget = 0; | 727 | fs->lasttarget = 0; |
536 | fs->jpc = NO_JUMP; | ||
537 | fs->freereg = 0; | 728 | fs->freereg = 0; |
538 | fs->nk = 0; | 729 | fs->nk = 0; |
730 | fs->nabslineinfo = 0; | ||
539 | fs->np = 0; | 731 | fs->np = 0; |
540 | fs->nups = 0; | 732 | fs->nups = 0; |
541 | fs->nlocvars = 0; | 733 | fs->ndebugvars = 0; |
542 | fs->nactvar = 0; | 734 | fs->nactvar = 0; |
735 | fs->needclose = 0; | ||
543 | fs->firstlocal = ls->dyd->actvar.n; | 736 | fs->firstlocal = ls->dyd->actvar.n; |
737 | fs->firstlabel = ls->dyd->label.n; | ||
544 | fs->bl = NULL; | 738 | fs->bl = NULL; |
545 | f = fs->f; | ||
546 | f->source = ls->source; | 739 | f->source = ls->source; |
740 | luaC_objbarrier(ls->L, f, f->source); | ||
547 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | 741 | f->maxstacksize = 2; /* registers 0/1 are always valid */ |
548 | enterblock(fs, bl, 0); | 742 | enterblock(fs, bl, 0); |
549 | } | 743 | } |
@@ -553,21 +747,18 @@ static void close_func (LexState *ls) { | |||
553 | lua_State *L = ls->L; | 747 | lua_State *L = ls->L; |
554 | FuncState *fs = ls->fs; | 748 | FuncState *fs = ls->fs; |
555 | Proto *f = fs->f; | 749 | Proto *f = fs->f; |
556 | luaK_ret(fs, 0, 0); /* final return */ | 750 | luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ |
557 | leaveblock(fs); | 751 | leaveblock(fs); |
558 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); | ||
559 | f->sizecode = fs->pc; | ||
560 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); | ||
561 | f->sizelineinfo = fs->pc; | ||
562 | luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); | ||
563 | f->sizek = fs->nk; | ||
564 | luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); | ||
565 | f->sizep = fs->np; | ||
566 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | ||
567 | f->sizelocvars = fs->nlocvars; | ||
568 | luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); | ||
569 | f->sizeupvalues = fs->nups; | ||
570 | lua_assert(fs->bl == NULL); | 752 | lua_assert(fs->bl == NULL); |
753 | luaK_finish(fs); | ||
754 | luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); | ||
755 | luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); | ||
756 | luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo, | ||
757 | fs->nabslineinfo, AbsLineInfo); | ||
758 | luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue); | ||
759 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); | ||
760 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); | ||
761 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); | ||
571 | ls->fs = fs->prev; | 762 | ls->fs = fs->prev; |
572 | luaC_checkGC(L); | 763 | luaC_checkGC(L); |
573 | } | 764 | } |
@@ -613,7 +804,7 @@ static void fieldsel (LexState *ls, expdesc *v) { | |||
613 | expdesc key; | 804 | expdesc key; |
614 | luaK_exp2anyregup(fs, v); | 805 | luaK_exp2anyregup(fs, v); |
615 | luaX_next(ls); /* skip the dot or colon */ | 806 | luaX_next(ls); /* skip the dot or colon */ |
616 | checkname(ls, &key); | 807 | codename(ls, &key); |
617 | luaK_indexed(fs, v, &key); | 808 | luaK_indexed(fs, v, &key); |
618 | } | 809 | } |
619 | 810 | ||
@@ -634,48 +825,49 @@ static void yindex (LexState *ls, expdesc *v) { | |||
634 | */ | 825 | */ |
635 | 826 | ||
636 | 827 | ||
637 | struct ConsControl { | 828 | typedef struct ConsControl { |
638 | expdesc v; /* last list item read */ | 829 | expdesc v; /* last list item read */ |
639 | expdesc *t; /* table descriptor */ | 830 | expdesc *t; /* table descriptor */ |
640 | int nh; /* total number of 'record' elements */ | 831 | int nh; /* total number of 'record' elements */ |
641 | int na; /* total number of array elements */ | 832 | int na; /* number of array elements already stored */ |
642 | int tostore; /* number of array elements pending to be stored */ | 833 | int tostore; /* number of array elements pending to be stored */ |
643 | }; | 834 | } ConsControl; |
644 | 835 | ||
645 | 836 | ||
646 | static void recfield (LexState *ls, struct ConsControl *cc) { | 837 | static void recfield (LexState *ls, ConsControl *cc) { |
647 | /* recfield -> (NAME | '['exp1']') = exp1 */ | 838 | /* recfield -> (NAME | '['exp']') = exp */ |
648 | FuncState *fs = ls->fs; | 839 | FuncState *fs = ls->fs; |
649 | int reg = ls->fs->freereg; | 840 | int reg = ls->fs->freereg; |
650 | expdesc key, val; | 841 | expdesc tab, key, val; |
651 | int rkkey; | ||
652 | if (ls->t.token == TK_NAME) { | 842 | if (ls->t.token == TK_NAME) { |
653 | checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); | 843 | checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); |
654 | checkname(ls, &key); | 844 | codename(ls, &key); |
655 | } | 845 | } |
656 | else /* ls->t.token == '[' */ | 846 | else /* ls->t.token == '[' */ |
657 | yindex(ls, &key); | 847 | yindex(ls, &key); |
658 | cc->nh++; | 848 | cc->nh++; |
659 | checknext(ls, '='); | 849 | checknext(ls, '='); |
660 | rkkey = luaK_exp2RK(fs, &key); | 850 | tab = *cc->t; |
851 | luaK_indexed(fs, &tab, &key); | ||
661 | expr(ls, &val); | 852 | expr(ls, &val); |
662 | luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); | 853 | luaK_storevar(fs, &tab, &val); |
663 | fs->freereg = reg; /* free registers */ | 854 | fs->freereg = reg; /* free registers */ |
664 | } | 855 | } |
665 | 856 | ||
666 | 857 | ||
667 | static void closelistfield (FuncState *fs, struct ConsControl *cc) { | 858 | static void closelistfield (FuncState *fs, ConsControl *cc) { |
668 | if (cc->v.k == VVOID) return; /* there is no list item */ | 859 | if (cc->v.k == VVOID) return; /* there is no list item */ |
669 | luaK_exp2nextreg(fs, &cc->v); | 860 | luaK_exp2nextreg(fs, &cc->v); |
670 | cc->v.k = VVOID; | 861 | cc->v.k = VVOID; |
671 | if (cc->tostore == LFIELDS_PER_FLUSH) { | 862 | if (cc->tostore == LFIELDS_PER_FLUSH) { |
672 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ | 863 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ |
864 | cc->na += cc->tostore; | ||
673 | cc->tostore = 0; /* no more items pending */ | 865 | cc->tostore = 0; /* no more items pending */ |
674 | } | 866 | } |
675 | } | 867 | } |
676 | 868 | ||
677 | 869 | ||
678 | static void lastlistfield (FuncState *fs, struct ConsControl *cc) { | 870 | static void lastlistfield (FuncState *fs, ConsControl *cc) { |
679 | if (cc->tostore == 0) return; | 871 | if (cc->tostore == 0) return; |
680 | if (hasmultret(cc->v.k)) { | 872 | if (hasmultret(cc->v.k)) { |
681 | luaK_setmultret(fs, &cc->v); | 873 | luaK_setmultret(fs, &cc->v); |
@@ -687,19 +879,18 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) { | |||
687 | luaK_exp2nextreg(fs, &cc->v); | 879 | luaK_exp2nextreg(fs, &cc->v); |
688 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); | 880 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); |
689 | } | 881 | } |
882 | cc->na += cc->tostore; | ||
690 | } | 883 | } |
691 | 884 | ||
692 | 885 | ||
693 | static void listfield (LexState *ls, struct ConsControl *cc) { | 886 | static void listfield (LexState *ls, ConsControl *cc) { |
694 | /* listfield -> exp */ | 887 | /* listfield -> exp */ |
695 | expr(ls, &cc->v); | 888 | expr(ls, &cc->v); |
696 | checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); | ||
697 | cc->na++; | ||
698 | cc->tostore++; | 889 | cc->tostore++; |
699 | } | 890 | } |
700 | 891 | ||
701 | 892 | ||
702 | static void field (LexState *ls, struct ConsControl *cc) { | 893 | static void field (LexState *ls, ConsControl *cc) { |
703 | /* field -> listfield | recfield */ | 894 | /* field -> listfield | recfield */ |
704 | switch(ls->t.token) { | 895 | switch(ls->t.token) { |
705 | case TK_NAME: { /* may be 'listfield' or 'recfield' */ | 896 | case TK_NAME: { /* may be 'listfield' or 'recfield' */ |
@@ -727,12 +918,13 @@ static void constructor (LexState *ls, expdesc *t) { | |||
727 | FuncState *fs = ls->fs; | 918 | FuncState *fs = ls->fs; |
728 | int line = ls->linenumber; | 919 | int line = ls->linenumber; |
729 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); | 920 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); |
730 | struct ConsControl cc; | 921 | ConsControl cc; |
922 | luaK_code(fs, 0); /* space for extra arg. */ | ||
731 | cc.na = cc.nh = cc.tostore = 0; | 923 | cc.na = cc.nh = cc.tostore = 0; |
732 | cc.t = t; | 924 | cc.t = t; |
733 | init_exp(t, VRELOCABLE, pc); | 925 | init_exp(t, VNONRELOC, fs->freereg); /* table will be at stack top */ |
926 | luaK_reserveregs(fs, 1); | ||
734 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ | 927 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ |
735 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ | ||
736 | checknext(ls, '{'); | 928 | checknext(ls, '{'); |
737 | do { | 929 | do { |
738 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | 930 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); |
@@ -742,20 +934,24 @@ static void constructor (LexState *ls, expdesc *t) { | |||
742 | } while (testnext(ls, ',') || testnext(ls, ';')); | 934 | } while (testnext(ls, ',') || testnext(ls, ';')); |
743 | check_match(ls, '}', '{', line); | 935 | check_match(ls, '}', '{', line); |
744 | lastlistfield(fs, &cc); | 936 | lastlistfield(fs, &cc); |
745 | SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ | 937 | luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh); |
746 | SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ | ||
747 | } | 938 | } |
748 | 939 | ||
749 | /* }====================================================================== */ | 940 | /* }====================================================================== */ |
750 | 941 | ||
751 | 942 | ||
943 | static void setvararg (FuncState *fs, int nparams) { | ||
944 | fs->f->is_vararg = 1; | ||
945 | luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0); | ||
946 | } | ||
947 | |||
752 | 948 | ||
753 | static void parlist (LexState *ls) { | 949 | static void parlist (LexState *ls) { |
754 | /* parlist -> [ param { ',' param } ] */ | 950 | /* parlist -> [ param { ',' param } ] */ |
755 | FuncState *fs = ls->fs; | 951 | FuncState *fs = ls->fs; |
756 | Proto *f = fs->f; | 952 | Proto *f = fs->f; |
757 | int nparams = 0; | 953 | int nparams = 0; |
758 | f->is_vararg = 0; | 954 | int isvararg = 0; |
759 | if (ls->t.token != ')') { /* is 'parlist' not empty? */ | 955 | if (ls->t.token != ')') { /* is 'parlist' not empty? */ |
760 | do { | 956 | do { |
761 | switch (ls->t.token) { | 957 | switch (ls->t.token) { |
@@ -766,16 +962,18 @@ static void parlist (LexState *ls) { | |||
766 | } | 962 | } |
767 | case TK_DOTS: { /* param -> '...' */ | 963 | case TK_DOTS: { /* param -> '...' */ |
768 | luaX_next(ls); | 964 | luaX_next(ls); |
769 | f->is_vararg = 1; /* declared vararg */ | 965 | isvararg = 1; |
770 | break; | 966 | break; |
771 | } | 967 | } |
772 | default: luaX_syntaxerror(ls, "<name> or '...' expected"); | 968 | default: luaX_syntaxerror(ls, "<name> or '...' expected"); |
773 | } | 969 | } |
774 | } while (!f->is_vararg && testnext(ls, ',')); | 970 | } while (!isvararg && testnext(ls, ',')); |
775 | } | 971 | } |
776 | adjustlocalvars(ls, nparams); | 972 | adjustlocalvars(ls, nparams); |
777 | f->numparams = cast_byte(fs->nactvar); | 973 | f->numparams = cast_byte(fs->nactvar); |
778 | luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ | 974 | if (isvararg) |
975 | setvararg(fs, f->numparams); /* declared vararg */ | ||
976 | luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ | ||
779 | } | 977 | } |
780 | 978 | ||
781 | 979 | ||
@@ -825,7 +1023,8 @@ static void funcargs (LexState *ls, expdesc *f, int line) { | |||
825 | args.k = VVOID; | 1023 | args.k = VVOID; |
826 | else { | 1024 | else { |
827 | explist(ls, &args); | 1025 | explist(ls, &args); |
828 | luaK_setmultret(fs, &args); | 1026 | if (hasmultret(args.k)) |
1027 | luaK_setmultret(fs, &args); | ||
829 | } | 1028 | } |
830 | check_match(ls, ')', '(', line); | 1029 | check_match(ls, ')', '(', line); |
831 | break; | 1030 | break; |
@@ -835,7 +1034,7 @@ static void funcargs (LexState *ls, expdesc *f, int line) { | |||
835 | break; | 1034 | break; |
836 | } | 1035 | } |
837 | case TK_STRING: { /* funcargs -> STRING */ | 1036 | case TK_STRING: { /* funcargs -> STRING */ |
838 | codestring(ls, &args, ls->t.seminfo.ts); | 1037 | codestring(&args, ls->t.seminfo.ts); |
839 | luaX_next(ls); /* must use 'seminfo' before 'next' */ | 1038 | luaX_next(ls); /* must use 'seminfo' before 'next' */ |
840 | break; | 1039 | break; |
841 | } | 1040 | } |
@@ -902,7 +1101,7 @@ static void suffixedexp (LexState *ls, expdesc *v) { | |||
902 | fieldsel(ls, v); | 1101 | fieldsel(ls, v); |
903 | break; | 1102 | break; |
904 | } | 1103 | } |
905 | case '[': { /* '[' exp1 ']' */ | 1104 | case '[': { /* '[' exp ']' */ |
906 | expdesc key; | 1105 | expdesc key; |
907 | luaK_exp2anyregup(fs, v); | 1106 | luaK_exp2anyregup(fs, v); |
908 | yindex(ls, &key); | 1107 | yindex(ls, &key); |
@@ -912,7 +1111,7 @@ static void suffixedexp (LexState *ls, expdesc *v) { | |||
912 | case ':': { /* ':' NAME funcargs */ | 1111 | case ':': { /* ':' NAME funcargs */ |
913 | expdesc key; | 1112 | expdesc key; |
914 | luaX_next(ls); | 1113 | luaX_next(ls); |
915 | checkname(ls, &key); | 1114 | codename(ls, &key); |
916 | luaK_self(fs, v, &key); | 1115 | luaK_self(fs, v, &key); |
917 | funcargs(ls, v, line); | 1116 | funcargs(ls, v, line); |
918 | break; | 1117 | break; |
@@ -943,7 +1142,7 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
943 | break; | 1142 | break; |
944 | } | 1143 | } |
945 | case TK_STRING: { | 1144 | case TK_STRING: { |
946 | codestring(ls, v, ls->t.seminfo.ts); | 1145 | codestring(v, ls->t.seminfo.ts); |
947 | break; | 1146 | break; |
948 | } | 1147 | } |
949 | case TK_NIL: { | 1148 | case TK_NIL: { |
@@ -962,7 +1161,7 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
962 | FuncState *fs = ls->fs; | 1161 | FuncState *fs = ls->fs; |
963 | check_condition(ls, fs->f->is_vararg, | 1162 | check_condition(ls, fs->f->is_vararg, |
964 | "cannot use '...' outside a vararg function"); | 1163 | "cannot use '...' outside a vararg function"); |
965 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); | 1164 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); |
966 | break; | 1165 | break; |
967 | } | 1166 | } |
968 | case '{': { /* constructor */ | 1167 | case '{': { /* constructor */ |
@@ -1022,6 +1221,9 @@ static BinOpr getbinopr (int op) { | |||
1022 | } | 1221 | } |
1023 | 1222 | ||
1024 | 1223 | ||
1224 | /* | ||
1225 | ** Priority table for binary operators. | ||
1226 | */ | ||
1025 | static const struct { | 1227 | static const struct { |
1026 | lu_byte left; /* left priority for each binary operator */ | 1228 | lu_byte left; /* left priority for each binary operator */ |
1027 | lu_byte right; /* right priority */ | 1229 | lu_byte right; /* right priority */ |
@@ -1050,9 +1252,9 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | |||
1050 | UnOpr uop; | 1252 | UnOpr uop; |
1051 | enterlevel(ls); | 1253 | enterlevel(ls); |
1052 | uop = getunopr(ls->t.token); | 1254 | uop = getunopr(ls->t.token); |
1053 | if (uop != OPR_NOUNOPR) { | 1255 | if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */ |
1054 | int line = ls->linenumber; | 1256 | int line = ls->linenumber; |
1055 | luaX_next(ls); | 1257 | luaX_next(ls); /* skip operator */ |
1056 | subexpr(ls, v, UNARY_PRIORITY); | 1258 | subexpr(ls, v, UNARY_PRIORITY); |
1057 | luaK_prefix(ls->fs, uop, v, line); | 1259 | luaK_prefix(ls->fs, uop, v, line); |
1058 | } | 1260 | } |
@@ -1063,7 +1265,7 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | |||
1063 | expdesc v2; | 1265 | expdesc v2; |
1064 | BinOpr nextop; | 1266 | BinOpr nextop; |
1065 | int line = ls->linenumber; | 1267 | int line = ls->linenumber; |
1066 | luaX_next(ls); | 1268 | luaX_next(ls); /* skip operator */ |
1067 | luaK_infix(ls->fs, op, v); | 1269 | luaK_infix(ls->fs, op, v); |
1068 | /* read sub-expression with higher priority */ | 1270 | /* read sub-expression with higher priority */ |
1069 | nextop = subexpr(ls, &v2, priority[op].right); | 1271 | nextop = subexpr(ls, &v2, priority[op].right); |
@@ -1121,43 +1323,60 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | |||
1121 | int extra = fs->freereg; /* eventual position to save local variable */ | 1323 | int extra = fs->freereg; /* eventual position to save local variable */ |
1122 | int conflict = 0; | 1324 | int conflict = 0; |
1123 | for (; lh; lh = lh->prev) { /* check all previous assignments */ | 1325 | for (; lh; lh = lh->prev) { /* check all previous assignments */ |
1124 | if (lh->v.k == VINDEXED) { /* assigning to a table? */ | 1326 | if (vkisindexed(lh->v.k)) { /* assignment to table field? */ |
1125 | /* table is the upvalue/local being assigned now? */ | 1327 | if (lh->v.k == VINDEXUP) { /* is table an upvalue? */ |
1126 | if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { | 1328 | if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) { |
1127 | conflict = 1; | 1329 | conflict = 1; /* table is the upvalue being assigned now */ |
1128 | lh->v.u.ind.vt = VLOCAL; | 1330 | lh->v.k = VINDEXSTR; |
1129 | lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ | 1331 | lh->v.u.ind.t = extra; /* assignment will use safe copy */ |
1332 | } | ||
1130 | } | 1333 | } |
1131 | /* index is the local being assigned? (index cannot be upvalue) */ | 1334 | else { /* table is a register */ |
1132 | if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { | 1335 | if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.sidx) { |
1133 | conflict = 1; | 1336 | conflict = 1; /* table is the local being assigned now */ |
1134 | lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ | 1337 | lh->v.u.ind.t = extra; /* assignment will use safe copy */ |
1338 | } | ||
1339 | /* is index the local being assigned? */ | ||
1340 | if (lh->v.k == VINDEXED && v->k == VLOCAL && | ||
1341 | lh->v.u.ind.idx == v->u.var.sidx) { | ||
1342 | conflict = 1; | ||
1343 | lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ | ||
1344 | } | ||
1135 | } | 1345 | } |
1136 | } | 1346 | } |
1137 | } | 1347 | } |
1138 | if (conflict) { | 1348 | if (conflict) { |
1139 | /* copy upvalue/local value to a temporary (in position 'extra') */ | 1349 | /* copy upvalue/local value to a temporary (in position 'extra') */ |
1140 | OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; | 1350 | if (v->k == VLOCAL) |
1141 | luaK_codeABC(fs, op, extra, v->u.info, 0); | 1351 | luaK_codeABC(fs, OP_MOVE, extra, v->u.var.sidx, 0); |
1352 | else | ||
1353 | luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0); | ||
1142 | luaK_reserveregs(fs, 1); | 1354 | luaK_reserveregs(fs, 1); |
1143 | } | 1355 | } |
1144 | } | 1356 | } |
1145 | 1357 | ||
1146 | 1358 | /* | |
1147 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | 1359 | ** Parse and compile a multiple assignment. The first "variable" |
1360 | ** (a 'suffixedexp') was already read by the caller. | ||
1361 | ** | ||
1362 | ** assignment -> suffixedexp restassign | ||
1363 | ** restassign -> ',' suffixedexp restassign | '=' explist | ||
1364 | */ | ||
1365 | static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) { | ||
1148 | expdesc e; | 1366 | expdesc e; |
1149 | check_condition(ls, vkisvar(lh->v.k), "syntax error"); | 1367 | check_condition(ls, vkisvar(lh->v.k), "syntax error"); |
1150 | if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ | 1368 | check_readonly(ls, &lh->v); |
1369 | if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */ | ||
1151 | struct LHS_assign nv; | 1370 | struct LHS_assign nv; |
1152 | nv.prev = lh; | 1371 | nv.prev = lh; |
1153 | suffixedexp(ls, &nv.v); | 1372 | suffixedexp(ls, &nv.v); |
1154 | if (nv.v.k != VINDEXED) | 1373 | if (!vkisindexed(nv.v.k)) |
1155 | check_conflict(ls, lh, &nv.v); | 1374 | check_conflict(ls, lh, &nv.v); |
1156 | checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, | 1375 | enterlevel(ls); /* control recursion depth */ |
1157 | "C levels"); | 1376 | restassign(ls, &nv, nvars+1); |
1158 | assignment(ls, &nv, nvars+1); | 1377 | leavelevel(ls); |
1159 | } | 1378 | } |
1160 | else { /* assignment -> '=' explist */ | 1379 | else { /* restassign -> '=' explist */ |
1161 | int nexps; | 1380 | int nexps; |
1162 | checknext(ls, '='); | 1381 | checknext(ls, '='); |
1163 | nexps = explist(ls, &e); | 1382 | nexps = explist(ls, &e); |
@@ -1184,57 +1403,55 @@ static int cond (LexState *ls) { | |||
1184 | } | 1403 | } |
1185 | 1404 | ||
1186 | 1405 | ||
1187 | static void gotostat (LexState *ls, int pc) { | 1406 | static void gotostat (LexState *ls) { |
1407 | FuncState *fs = ls->fs; | ||
1188 | int line = ls->linenumber; | 1408 | int line = ls->linenumber; |
1189 | TString *label; | 1409 | TString *name = str_checkname(ls); /* label's name */ |
1190 | int g; | 1410 | Labeldesc *lb = findlabel(ls, name); |
1191 | if (testnext(ls, TK_GOTO)) | 1411 | if (lb == NULL) /* no label? */ |
1192 | label = str_checkname(ls); | 1412 | /* forward jump; will be resolved when the label is declared */ |
1193 | else { | 1413 | newgotoentry(ls, name, line, luaK_jump(fs)); |
1194 | luaX_next(ls); /* skip break */ | 1414 | else { /* found a label */ |
1195 | label = luaS_new(ls->L, "break"); | 1415 | /* backward jump; will be resolved here */ |
1416 | int lblevel = stacklevel(fs, lb->nactvar); /* label level */ | ||
1417 | if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */ | ||
1418 | luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0); | ||
1419 | /* create jump and link it to the label */ | ||
1420 | luaK_patchlist(fs, luaK_jump(fs), lb->pc); | ||
1196 | } | 1421 | } |
1197 | g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); | ||
1198 | findlabel(ls, g); /* close it if label already defined */ | ||
1199 | } | 1422 | } |
1200 | 1423 | ||
1201 | 1424 | ||
1202 | /* check for repeated labels on the same block */ | 1425 | /* |
1203 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { | 1426 | ** Break statement. Semantically equivalent to "goto break". |
1204 | int i; | 1427 | */ |
1205 | for (i = fs->bl->firstlabel; i < ll->n; i++) { | 1428 | static void breakstat (LexState *ls) { |
1206 | if (eqstr(label, ll->arr[i].name)) { | 1429 | int line = ls->linenumber; |
1207 | const char *msg = luaO_pushfstring(fs->ls->L, | 1430 | luaX_next(ls); /* skip break */ |
1208 | "label '%s' already defined on line %d", | 1431 | newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, luaK_jump(ls->fs)); |
1209 | getstr(label), ll->arr[i].line); | ||
1210 | semerror(fs->ls, msg); | ||
1211 | } | ||
1212 | } | ||
1213 | } | 1432 | } |
1214 | 1433 | ||
1215 | 1434 | ||
1216 | /* skip no-op statements */ | 1435 | /* |
1217 | static void skipnoopstat (LexState *ls) { | 1436 | ** Check whether there is already a label with the given 'name'. |
1218 | while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) | 1437 | */ |
1219 | statement(ls); | 1438 | static void checkrepeated (LexState *ls, TString *name) { |
1439 | Labeldesc *lb = findlabel(ls, name); | ||
1440 | if (unlikely(lb != NULL)) { /* already defined? */ | ||
1441 | const char *msg = "label '%s' already defined on line %d"; | ||
1442 | msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line); | ||
1443 | luaK_semerror(ls, msg); /* error */ | ||
1444 | } | ||
1220 | } | 1445 | } |
1221 | 1446 | ||
1222 | 1447 | ||
1223 | static void labelstat (LexState *ls, TString *label, int line) { | 1448 | static void labelstat (LexState *ls, TString *name, int line) { |
1224 | /* label -> '::' NAME '::' */ | 1449 | /* label -> '::' NAME '::' */ |
1225 | FuncState *fs = ls->fs; | ||
1226 | Labellist *ll = &ls->dyd->label; | ||
1227 | int l; /* index of new label being created */ | ||
1228 | checkrepeated(fs, ll, label); /* check for repeated labels */ | ||
1229 | checknext(ls, TK_DBCOLON); /* skip double colon */ | 1450 | checknext(ls, TK_DBCOLON); /* skip double colon */ |
1230 | /* create new entry for this label */ | 1451 | while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) |
1231 | l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs)); | 1452 | statement(ls); /* skip other no-op statements */ |
1232 | skipnoopstat(ls); /* skip other no-op statements */ | 1453 | checkrepeated(ls, name); /* check for repeated labels */ |
1233 | if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ | 1454 | createlabel(ls, name, line, block_follow(ls, 0)); |
1234 | /* assume that locals are already out of scope */ | ||
1235 | ll->arr[l].nactvar = fs->bl->nactvar; | ||
1236 | } | ||
1237 | findgotos(ls, &ll->arr[l]); | ||
1238 | } | 1455 | } |
1239 | 1456 | ||
1240 | 1457 | ||
@@ -1269,58 +1486,83 @@ static void repeatstat (LexState *ls, int line) { | |||
1269 | statlist(ls); | 1486 | statlist(ls); |
1270 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 1487 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
1271 | condexit = cond(ls); /* read condition (inside scope block) */ | 1488 | condexit = cond(ls); /* read condition (inside scope block) */ |
1272 | if (bl2.upval) /* upvalues? */ | ||
1273 | luaK_patchclose(fs, condexit, bl2.nactvar); | ||
1274 | leaveblock(fs); /* finish scope */ | 1489 | leaveblock(fs); /* finish scope */ |
1490 | if (bl2.upval) { /* upvalues? */ | ||
1491 | int exit = luaK_jump(fs); /* normal exit must jump over fix */ | ||
1492 | luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ | ||
1493 | luaK_codeABC(fs, OP_CLOSE, stacklevel(fs, bl2.nactvar), 0, 0); | ||
1494 | condexit = luaK_jump(fs); /* repeat after closing upvalues */ | ||
1495 | luaK_patchtohere(fs, exit); /* normal exit comes to here */ | ||
1496 | } | ||
1275 | luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ | 1497 | luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ |
1276 | leaveblock(fs); /* finish loop */ | 1498 | leaveblock(fs); /* finish loop */ |
1277 | } | 1499 | } |
1278 | 1500 | ||
1279 | 1501 | ||
1280 | static int exp1 (LexState *ls) { | 1502 | /* |
1503 | ** Read an expression and generate code to put its results in next | ||
1504 | ** stack slot. | ||
1505 | ** | ||
1506 | */ | ||
1507 | static void exp1 (LexState *ls) { | ||
1281 | expdesc e; | 1508 | expdesc e; |
1282 | int reg; | ||
1283 | expr(ls, &e); | 1509 | expr(ls, &e); |
1284 | luaK_exp2nextreg(ls->fs, &e); | 1510 | luaK_exp2nextreg(ls->fs, &e); |
1285 | lua_assert(e.k == VNONRELOC); | 1511 | lua_assert(e.k == VNONRELOC); |
1286 | reg = e.u.info; | ||
1287 | return reg; | ||
1288 | } | 1512 | } |
1289 | 1513 | ||
1290 | 1514 | ||
1291 | static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { | 1515 | /* |
1516 | ** Fix for instruction at position 'pc' to jump to 'dest'. | ||
1517 | ** (Jump addresses are relative in Lua). 'back' true means | ||
1518 | ** a back jump. | ||
1519 | */ | ||
1520 | static void fixforjump (FuncState *fs, int pc, int dest, int back) { | ||
1521 | Instruction *jmp = &fs->f->code[pc]; | ||
1522 | int offset = dest - (pc + 1); | ||
1523 | if (back) | ||
1524 | offset = -offset; | ||
1525 | if (unlikely(offset > MAXARG_Bx)) | ||
1526 | luaX_syntaxerror(fs->ls, "control structure too long"); | ||
1527 | SETARG_Bx(*jmp, offset); | ||
1528 | } | ||
1529 | |||
1530 | |||
1531 | /* | ||
1532 | ** Generate code for a 'for' loop. | ||
1533 | */ | ||
1534 | static void forbody (LexState *ls, int base, int line, int nvars, int isgen) { | ||
1292 | /* forbody -> DO block */ | 1535 | /* forbody -> DO block */ |
1536 | static const OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP}; | ||
1537 | static const OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP}; | ||
1293 | BlockCnt bl; | 1538 | BlockCnt bl; |
1294 | FuncState *fs = ls->fs; | 1539 | FuncState *fs = ls->fs; |
1295 | int prep, endfor; | 1540 | int prep, endfor; |
1296 | adjustlocalvars(ls, 3); /* control variables */ | ||
1297 | checknext(ls, TK_DO); | 1541 | checknext(ls, TK_DO); |
1298 | prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); | 1542 | prep = luaK_codeABx(fs, forprep[isgen], base, 0); |
1299 | enterblock(fs, &bl, 0); /* scope for declared variables */ | 1543 | enterblock(fs, &bl, 0); /* scope for declared variables */ |
1300 | adjustlocalvars(ls, nvars); | 1544 | adjustlocalvars(ls, nvars); |
1301 | luaK_reserveregs(fs, nvars); | 1545 | luaK_reserveregs(fs, nvars); |
1302 | block(ls); | 1546 | block(ls); |
1303 | leaveblock(fs); /* end of scope for declared variables */ | 1547 | leaveblock(fs); /* end of scope for declared variables */ |
1304 | luaK_patchtohere(fs, prep); | 1548 | fixforjump(fs, prep, luaK_getlabel(fs), 0); |
1305 | if (isnum) /* numeric for? */ | 1549 | if (isgen) { /* generic for? */ |
1306 | endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); | ||
1307 | else { /* generic for */ | ||
1308 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); | 1550 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); |
1309 | luaK_fixline(fs, line); | 1551 | luaK_fixline(fs, line); |
1310 | endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); | ||
1311 | } | 1552 | } |
1312 | luaK_patchlist(fs, endfor, prep + 1); | 1553 | endfor = luaK_codeABx(fs, forloop[isgen], base, 0); |
1554 | fixforjump(fs, endfor, prep + 1, 1); | ||
1313 | luaK_fixline(fs, line); | 1555 | luaK_fixline(fs, line); |
1314 | } | 1556 | } |
1315 | 1557 | ||
1316 | 1558 | ||
1317 | static void fornum (LexState *ls, TString *varname, int line) { | 1559 | static void fornum (LexState *ls, TString *varname, int line) { |
1318 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | 1560 | /* fornum -> NAME = exp,exp[,exp] forbody */ |
1319 | FuncState *fs = ls->fs; | 1561 | FuncState *fs = ls->fs; |
1320 | int base = fs->freereg; | 1562 | int base = fs->freereg; |
1321 | new_localvarliteral(ls, "(for index)"); | 1563 | new_localvarliteral(ls, "(for state)"); |
1322 | new_localvarliteral(ls, "(for limit)"); | 1564 | new_localvarliteral(ls, "(for state)"); |
1323 | new_localvarliteral(ls, "(for step)"); | 1565 | new_localvarliteral(ls, "(for state)"); |
1324 | new_localvar(ls, varname); | 1566 | new_localvar(ls, varname); |
1325 | checknext(ls, '='); | 1567 | checknext(ls, '='); |
1326 | exp1(ls); /* initial value */ | 1568 | exp1(ls); /* initial value */ |
@@ -1329,10 +1571,11 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1329 | if (testnext(ls, ',')) | 1571 | if (testnext(ls, ',')) |
1330 | exp1(ls); /* optional step */ | 1572 | exp1(ls); /* optional step */ |
1331 | else { /* default step = 1 */ | 1573 | else { /* default step = 1 */ |
1332 | luaK_codek(fs, fs->freereg, luaK_intK(fs, 1)); | 1574 | luaK_int(fs, fs->freereg, 1); |
1333 | luaK_reserveregs(fs, 1); | 1575 | luaK_reserveregs(fs, 1); |
1334 | } | 1576 | } |
1335 | forbody(ls, base, line, 1, 1); | 1577 | adjustlocalvars(ls, 3); /* control variables */ |
1578 | forbody(ls, base, line, 1, 0); | ||
1336 | } | 1579 | } |
1337 | 1580 | ||
1338 | 1581 | ||
@@ -1340,13 +1583,14 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1340 | /* forlist -> NAME {,NAME} IN explist forbody */ | 1583 | /* forlist -> NAME {,NAME} IN explist forbody */ |
1341 | FuncState *fs = ls->fs; | 1584 | FuncState *fs = ls->fs; |
1342 | expdesc e; | 1585 | expdesc e; |
1343 | int nvars = 4; /* gen, state, control, plus at least one declared var */ | 1586 | int nvars = 5; /* gen, state, control, toclose, 'indexname' */ |
1344 | int line; | 1587 | int line; |
1345 | int base = fs->freereg; | 1588 | int base = fs->freereg; |
1346 | /* create control variables */ | 1589 | /* create control variables */ |
1347 | new_localvarliteral(ls, "(for generator)"); | ||
1348 | new_localvarliteral(ls, "(for state)"); | 1590 | new_localvarliteral(ls, "(for state)"); |
1349 | new_localvarliteral(ls, "(for control)"); | 1591 | new_localvarliteral(ls, "(for state)"); |
1592 | new_localvarliteral(ls, "(for state)"); | ||
1593 | new_localvarliteral(ls, "(for state)"); | ||
1350 | /* create declared variables */ | 1594 | /* create declared variables */ |
1351 | new_localvar(ls, indexname); | 1595 | new_localvar(ls, indexname); |
1352 | while (testnext(ls, ',')) { | 1596 | while (testnext(ls, ',')) { |
@@ -1355,9 +1599,11 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1355 | } | 1599 | } |
1356 | checknext(ls, TK_IN); | 1600 | checknext(ls, TK_IN); |
1357 | line = ls->linenumber; | 1601 | line = ls->linenumber; |
1358 | adjust_assign(ls, 3, explist(ls, &e), &e); | 1602 | adjust_assign(ls, 4, explist(ls, &e), &e); |
1603 | adjustlocalvars(ls, 4); /* control variables */ | ||
1604 | markupval(fs, fs->nactvar); /* last control var. must be closed */ | ||
1359 | luaK_checkstack(fs, 3); /* extra space to call generator */ | 1605 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
1360 | forbody(ls, base, line, nvars - 3, 0); | 1606 | forbody(ls, base, line, nvars - 4, 1); |
1361 | } | 1607 | } |
1362 | 1608 | ||
1363 | 1609 | ||
@@ -1379,28 +1625,68 @@ static void forstat (LexState *ls, int line) { | |||
1379 | } | 1625 | } |
1380 | 1626 | ||
1381 | 1627 | ||
1628 | /* | ||
1629 | ** Check whether next instruction is a single jump (a 'break', a 'goto' | ||
1630 | ** to a forward label, or a 'goto' to a backward label with no variable | ||
1631 | ** to close). If so, set the name of the 'label' it is jumping to | ||
1632 | ** ("break" for a 'break') or to where it is jumping to ('target') and | ||
1633 | ** return true. If not a single jump, leave input unchanged, to be | ||
1634 | ** handled as a regular statement. | ||
1635 | */ | ||
1636 | static int issinglejump (LexState *ls, TString **label, int *target) { | ||
1637 | if (testnext(ls, TK_BREAK)) { /* a break? */ | ||
1638 | *label = luaS_newliteral(ls->L, "break"); | ||
1639 | return 1; | ||
1640 | } | ||
1641 | else if (ls->t.token != TK_GOTO || luaX_lookahead(ls) != TK_NAME) | ||
1642 | return 0; /* not a valid goto */ | ||
1643 | else { | ||
1644 | TString *lname = ls->lookahead.seminfo.ts; /* label's id */ | ||
1645 | Labeldesc *lb = findlabel(ls, lname); | ||
1646 | if (lb) { /* a backward jump? */ | ||
1647 | /* does it need to close variables? */ | ||
1648 | if (luaY_nvarstack(ls->fs) > stacklevel(ls->fs, lb->nactvar)) | ||
1649 | return 0; /* not a single jump; cannot optimize */ | ||
1650 | *target = lb->pc; | ||
1651 | } | ||
1652 | else /* jump forward */ | ||
1653 | *label = lname; | ||
1654 | luaX_next(ls); /* skip goto */ | ||
1655 | luaX_next(ls); /* skip name */ | ||
1656 | return 1; | ||
1657 | } | ||
1658 | } | ||
1659 | |||
1660 | |||
1382 | static void test_then_block (LexState *ls, int *escapelist) { | 1661 | static void test_then_block (LexState *ls, int *escapelist) { |
1383 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ | 1662 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ |
1384 | BlockCnt bl; | 1663 | BlockCnt bl; |
1664 | int line; | ||
1385 | FuncState *fs = ls->fs; | 1665 | FuncState *fs = ls->fs; |
1666 | TString *jlb = NULL; | ||
1667 | int target = NO_JUMP; | ||
1386 | expdesc v; | 1668 | expdesc v; |
1387 | int jf; /* instruction to skip 'then' code (if condition is false) */ | 1669 | int jf; /* instruction to skip 'then' code (if condition is false) */ |
1388 | luaX_next(ls); /* skip IF or ELSEIF */ | 1670 | luaX_next(ls); /* skip IF or ELSEIF */ |
1389 | expr(ls, &v); /* read condition */ | 1671 | expr(ls, &v); /* read condition */ |
1390 | checknext(ls, TK_THEN); | 1672 | checknext(ls, TK_THEN); |
1391 | if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { | 1673 | line = ls->linenumber; |
1674 | if (issinglejump(ls, &jlb, &target)) { /* 'if x then goto' ? */ | ||
1392 | luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ | 1675 | luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ |
1393 | enterblock(fs, &bl, 0); /* must enter block before 'goto' */ | 1676 | enterblock(fs, &bl, 0); /* must enter block before 'goto' */ |
1394 | gotostat(ls, v.t); /* handle goto/break */ | 1677 | if (jlb != NULL) /* forward jump? */ |
1395 | while (testnext(ls, ';')) {} /* skip colons */ | 1678 | newgotoentry(ls, jlb, line, v.t); /* will be resolved later */ |
1396 | if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ | 1679 | else /* backward jump */ |
1680 | luaK_patchlist(fs, v.t, target); /* jump directly to 'target' */ | ||
1681 | while (testnext(ls, ';')) {} /* skip semicolons */ | ||
1682 | if (block_follow(ls, 0)) { /* jump is the entire block? */ | ||
1397 | leaveblock(fs); | 1683 | leaveblock(fs); |
1398 | return; /* and that is it */ | 1684 | return; /* and that is it */ |
1399 | } | 1685 | } |
1400 | else /* must skip over 'then' part if condition is false */ | 1686 | else /* must skip over 'then' part if condition is false */ |
1401 | jf = luaK_jump(fs); | 1687 | jf = luaK_jump(fs); |
1402 | } | 1688 | } |
1403 | else { /* regular case (not goto/break) */ | 1689 | else { /* regular case (not a jump) */ |
1404 | luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ | 1690 | luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ |
1405 | enterblock(fs, &bl, 0); | 1691 | enterblock(fs, &bl, 0); |
1406 | jf = v.f; | 1692 | jf = v.f; |
@@ -1431,21 +1717,60 @@ static void ifstat (LexState *ls, int line) { | |||
1431 | static void localfunc (LexState *ls) { | 1717 | static void localfunc (LexState *ls) { |
1432 | expdesc b; | 1718 | expdesc b; |
1433 | FuncState *fs = ls->fs; | 1719 | FuncState *fs = ls->fs; |
1720 | int fvar = fs->nactvar; /* function's variable index */ | ||
1434 | new_localvar(ls, str_checkname(ls)); /* new local variable */ | 1721 | new_localvar(ls, str_checkname(ls)); /* new local variable */ |
1435 | adjustlocalvars(ls, 1); /* enter its scope */ | 1722 | adjustlocalvars(ls, 1); /* enter its scope */ |
1436 | body(ls, &b, 0, ls->linenumber); /* function created in next register */ | 1723 | body(ls, &b, 0, ls->linenumber); /* function created in next register */ |
1437 | /* debug information will only see the variable after this point! */ | 1724 | /* debug information will only see the variable after this point! */ |
1438 | getlocvar(fs, b.u.info)->startpc = fs->pc; | 1725 | localdebuginfo(fs, fvar)->startpc = fs->pc; |
1726 | } | ||
1727 | |||
1728 | |||
1729 | static int getlocalattribute (LexState *ls) { | ||
1730 | /* ATTRIB -> ['<' Name '>'] */ | ||
1731 | if (testnext(ls, '<')) { | ||
1732 | const char *attr = getstr(str_checkname(ls)); | ||
1733 | checknext(ls, '>'); | ||
1734 | if (strcmp(attr, "const") == 0) | ||
1735 | return RDKCONST; /* read-only variable */ | ||
1736 | else if (strcmp(attr, "close") == 0) | ||
1737 | return RDKTOCLOSE; /* to-be-closed variable */ | ||
1738 | else | ||
1739 | luaK_semerror(ls, | ||
1740 | luaO_pushfstring(ls->L, "unknown attribute '%s'", attr)); | ||
1741 | } | ||
1742 | return VDKREG; /* regular variable */ | ||
1743 | } | ||
1744 | |||
1745 | |||
1746 | static void checktoclose (LexState *ls, int level) { | ||
1747 | if (level != -1) { /* is there a to-be-closed variable? */ | ||
1748 | FuncState *fs = ls->fs; | ||
1749 | markupval(fs, level + 1); | ||
1750 | fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ | ||
1751 | luaK_codeABC(fs, OP_TBC, stacklevel(fs, level), 0, 0); | ||
1752 | } | ||
1439 | } | 1753 | } |
1440 | 1754 | ||
1441 | 1755 | ||
1442 | static void localstat (LexState *ls) { | 1756 | static void localstat (LexState *ls) { |
1443 | /* stat -> LOCAL NAME {',' NAME} ['=' explist] */ | 1757 | /* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */ |
1758 | FuncState *fs = ls->fs; | ||
1759 | int toclose = -1; /* index of to-be-closed variable (if any) */ | ||
1760 | Vardesc *var; /* last variable */ | ||
1761 | int vidx, kind; /* index and kind of last variable */ | ||
1444 | int nvars = 0; | 1762 | int nvars = 0; |
1445 | int nexps; | 1763 | int nexps; |
1446 | expdesc e; | 1764 | expdesc e; |
1447 | do { | 1765 | do { |
1448 | new_localvar(ls, str_checkname(ls)); | 1766 | vidx = new_localvar(ls, str_checkname(ls)); |
1767 | kind = getlocalattribute(ls); | ||
1768 | getlocalvardesc(fs, vidx)->vd.kind = kind; | ||
1769 | if (kind == RDKTOCLOSE) { /* to-be-closed? */ | ||
1770 | if (toclose != -1) /* one already present? */ | ||
1771 | luaK_semerror(ls, "multiple to-be-closed variables in local list"); | ||
1772 | toclose = fs->nactvar + nvars; | ||
1773 | } | ||
1449 | nvars++; | 1774 | nvars++; |
1450 | } while (testnext(ls, ',')); | 1775 | } while (testnext(ls, ',')); |
1451 | if (testnext(ls, '=')) | 1776 | if (testnext(ls, '=')) |
@@ -1454,8 +1779,19 @@ static void localstat (LexState *ls) { | |||
1454 | e.k = VVOID; | 1779 | e.k = VVOID; |
1455 | nexps = 0; | 1780 | nexps = 0; |
1456 | } | 1781 | } |
1457 | adjust_assign(ls, nvars, nexps, &e); | 1782 | var = getlocalvardesc(fs, vidx); /* get last variable */ |
1458 | adjustlocalvars(ls, nvars); | 1783 | if (nvars == nexps && /* no adjustments? */ |
1784 | var->vd.kind == RDKCONST && /* last variable is const? */ | ||
1785 | luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ | ||
1786 | var->vd.kind = RDKCTC; /* variable is a compile-time constant */ | ||
1787 | adjustlocalvars(ls, nvars - 1); /* exclude last variable */ | ||
1788 | fs->nactvar++; /* but count it */ | ||
1789 | } | ||
1790 | else { | ||
1791 | adjust_assign(ls, nvars, nexps, &e); | ||
1792 | adjustlocalvars(ls, nvars); | ||
1793 | } | ||
1794 | checktoclose(ls, toclose); | ||
1459 | } | 1795 | } |
1460 | 1796 | ||
1461 | 1797 | ||
@@ -1492,11 +1828,13 @@ static void exprstat (LexState *ls) { | |||
1492 | suffixedexp(ls, &v.v); | 1828 | suffixedexp(ls, &v.v); |
1493 | if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ | 1829 | if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ |
1494 | v.prev = NULL; | 1830 | v.prev = NULL; |
1495 | assignment(ls, &v, 1); | 1831 | restassign(ls, &v, 1); |
1496 | } | 1832 | } |
1497 | else { /* stat -> func */ | 1833 | else { /* stat -> func */ |
1834 | Instruction *inst; | ||
1498 | check_condition(ls, v.v.k == VCALL, "syntax error"); | 1835 | check_condition(ls, v.v.k == VCALL, "syntax error"); |
1499 | SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */ | 1836 | inst = &getinstruction(fs, &v.v); |
1837 | SETARG_C(*inst, 1); /* call statement uses no results */ | ||
1500 | } | 1838 | } |
1501 | } | 1839 | } |
1502 | 1840 | ||
@@ -1505,26 +1843,25 @@ static void retstat (LexState *ls) { | |||
1505 | /* stat -> RETURN [explist] [';'] */ | 1843 | /* stat -> RETURN [explist] [';'] */ |
1506 | FuncState *fs = ls->fs; | 1844 | FuncState *fs = ls->fs; |
1507 | expdesc e; | 1845 | expdesc e; |
1508 | int first, nret; /* registers with returned values */ | 1846 | int nret; /* number of values being returned */ |
1847 | int first = luaY_nvarstack(fs); /* first slot to be returned */ | ||
1509 | if (block_follow(ls, 1) || ls->t.token == ';') | 1848 | if (block_follow(ls, 1) || ls->t.token == ';') |
1510 | first = nret = 0; /* return no values */ | 1849 | nret = 0; /* return no values */ |
1511 | else { | 1850 | else { |
1512 | nret = explist(ls, &e); /* optional return values */ | 1851 | nret = explist(ls, &e); /* optional return values */ |
1513 | if (hasmultret(e.k)) { | 1852 | if (hasmultret(e.k)) { |
1514 | luaK_setmultret(fs, &e); | 1853 | luaK_setmultret(fs, &e); |
1515 | if (e.k == VCALL && nret == 1) { /* tail call? */ | 1854 | if (e.k == VCALL && nret == 1 && !fs->bl->insidetbc) { /* tail call? */ |
1516 | SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); | 1855 | SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); |
1517 | lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar); | 1856 | lua_assert(GETARG_A(getinstruction(fs,&e)) == luaY_nvarstack(fs)); |
1518 | } | 1857 | } |
1519 | first = fs->nactvar; | ||
1520 | nret = LUA_MULTRET; /* return all values */ | 1858 | nret = LUA_MULTRET; /* return all values */ |
1521 | } | 1859 | } |
1522 | else { | 1860 | else { |
1523 | if (nret == 1) /* only one single value? */ | 1861 | if (nret == 1) /* only one single value? */ |
1524 | first = luaK_exp2anyreg(fs, &e); | 1862 | first = luaK_exp2anyreg(fs, &e); /* can use original slot */ |
1525 | else { | 1863 | else { /* values must go to the top of the stack */ |
1526 | luaK_exp2nextreg(fs, &e); /* values must go to the stack */ | 1864 | luaK_exp2nextreg(fs, &e); |
1527 | first = fs->nactvar; /* return all active values */ | ||
1528 | lua_assert(nret == fs->freereg - first); | 1865 | lua_assert(nret == fs->freereg - first); |
1529 | } | 1866 | } |
1530 | } | 1867 | } |
@@ -1586,9 +1923,13 @@ static void statement (LexState *ls) { | |||
1586 | retstat(ls); | 1923 | retstat(ls); |
1587 | break; | 1924 | break; |
1588 | } | 1925 | } |
1589 | case TK_BREAK: /* stat -> breakstat */ | 1926 | case TK_BREAK: { /* stat -> breakstat */ |
1927 | breakstat(ls); | ||
1928 | break; | ||
1929 | } | ||
1590 | case TK_GOTO: { /* stat -> 'goto' NAME */ | 1930 | case TK_GOTO: { /* stat -> 'goto' NAME */ |
1591 | gotostat(ls, luaK_jump(ls->fs)); | 1931 | luaX_next(ls); /* skip 'goto' */ |
1932 | gotostat(ls); | ||
1592 | break; | 1933 | break; |
1593 | } | 1934 | } |
1594 | default: { /* stat -> func | assignment */ | 1935 | default: { /* stat -> func | assignment */ |
@@ -1597,8 +1938,8 @@ static void statement (LexState *ls) { | |||
1597 | } | 1938 | } |
1598 | } | 1939 | } |
1599 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | 1940 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && |
1600 | ls->fs->freereg >= ls->fs->nactvar); | 1941 | ls->fs->freereg >= luaY_nvarstack(ls->fs)); |
1601 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | 1942 | ls->fs->freereg = luaY_nvarstack(ls->fs); /* free registers */ |
1602 | leavelevel(ls); | 1943 | leavelevel(ls); |
1603 | } | 1944 | } |
1604 | 1945 | ||
@@ -1611,11 +1952,15 @@ static void statement (LexState *ls) { | |||
1611 | */ | 1952 | */ |
1612 | static void mainfunc (LexState *ls, FuncState *fs) { | 1953 | static void mainfunc (LexState *ls, FuncState *fs) { |
1613 | BlockCnt bl; | 1954 | BlockCnt bl; |
1614 | expdesc v; | 1955 | Upvaldesc *env; |
1615 | open_func(ls, fs, &bl); | 1956 | open_func(ls, fs, &bl); |
1616 | fs->f->is_vararg = 1; /* main function is always declared vararg */ | 1957 | setvararg(fs, 0); /* main function is always declared vararg */ |
1617 | init_exp(&v, VLOCAL, 0); /* create and... */ | 1958 | env = allocupvalue(fs); /* ...set environment upvalue */ |
1618 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ | 1959 | env->instack = 1; |
1960 | env->idx = 0; | ||
1961 | env->kind = VDKREG; | ||
1962 | env->name = ls->envn; | ||
1963 | luaC_objbarrier(ls->L, fs->f, env->name); | ||
1619 | luaX_next(ls); /* read first token */ | 1964 | luaX_next(ls); /* read first token */ |
1620 | statlist(ls); /* parse main body */ | 1965 | statlist(ls); /* parse main body */ |
1621 | check(ls, TK_EOS); | 1966 | check(ls, TK_EOS); |
@@ -1628,14 +1973,15 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |||
1628 | LexState lexstate; | 1973 | LexState lexstate; |
1629 | FuncState funcstate; | 1974 | FuncState funcstate; |
1630 | LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ | 1975 | LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ |
1631 | setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ | 1976 | setclLvalue2s(L, L->top, cl); /* anchor it (to avoid being collected) */ |
1632 | luaD_inctop(L); | 1977 | luaD_inctop(L); |
1633 | lexstate.h = luaH_new(L); /* create table for scanner */ | 1978 | lexstate.h = luaH_new(L); /* create table for scanner */ |
1634 | sethvalue(L, L->top, lexstate.h); /* anchor it */ | 1979 | sethvalue2s(L, L->top, lexstate.h); /* anchor it */ |
1635 | luaD_inctop(L); | 1980 | luaD_inctop(L); |
1636 | funcstate.f = cl->p = luaF_newproto(L); | 1981 | funcstate.f = cl->p = luaF_newproto(L); |
1982 | luaC_objbarrier(L, cl, cl->p); | ||
1637 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ | 1983 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ |
1638 | lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ | 1984 | luaC_objbarrier(L, funcstate.f, funcstate.f->source); |
1639 | lexstate.buff = buff; | 1985 | lexstate.buff = buff; |
1640 | lexstate.dyd = dyd; | 1986 | lexstate.dyd = dyd; |
1641 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; | 1987 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; |
diff --git a/src/lua-5.3/lparser.h b/src/lua/lparser.h index f45b23c..618cb01 100644 --- a/src/lua-5.3/lparser.h +++ b/src/lua/lparser.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lparser.h $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -30,56 +30,88 @@ typedef enum { | |||
30 | VFALSE, /* constant false */ | 30 | VFALSE, /* constant false */ |
31 | VK, /* constant in 'k'; info = index of constant in 'k' */ | 31 | VK, /* constant in 'k'; info = index of constant in 'k' */ |
32 | VKFLT, /* floating constant; nval = numerical float value */ | 32 | VKFLT, /* floating constant; nval = numerical float value */ |
33 | VKINT, /* integer constant; nval = numerical integer value */ | 33 | VKINT, /* integer constant; ival = numerical integer value */ |
34 | VKSTR, /* string constant; strval = TString address; | ||
35 | (string is fixed by the lexer) */ | ||
34 | VNONRELOC, /* expression has its value in a fixed register; | 36 | VNONRELOC, /* expression has its value in a fixed register; |
35 | info = result register */ | 37 | info = result register */ |
36 | VLOCAL, /* local variable; info = local register */ | 38 | VLOCAL, /* local variable; var.sidx = stack index (local register); |
39 | var.vidx = relative index in 'actvar.arr' */ | ||
37 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ | 40 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ |
41 | VCONST, /* compile-time constant; info = absolute index in 'actvar.arr' */ | ||
38 | VINDEXED, /* indexed variable; | 42 | VINDEXED, /* indexed variable; |
39 | ind.vt = whether 't' is register or upvalue; | 43 | ind.t = table register; |
40 | ind.t = table register or upvalue; | 44 | ind.idx = key's R index */ |
41 | ind.idx = key's R/K index */ | 45 | VINDEXUP, /* indexed upvalue; |
46 | ind.t = table upvalue; | ||
47 | ind.idx = key's K index */ | ||
48 | VINDEXI, /* indexed variable with constant integer; | ||
49 | ind.t = table register; | ||
50 | ind.idx = key's value */ | ||
51 | VINDEXSTR, /* indexed variable with literal string; | ||
52 | ind.t = table register; | ||
53 | ind.idx = key's K index */ | ||
42 | VJMP, /* expression is a test/comparison; | 54 | VJMP, /* expression is a test/comparison; |
43 | info = pc of corresponding jump instruction */ | 55 | info = pc of corresponding jump instruction */ |
44 | VRELOCABLE, /* expression can put result in any register; | 56 | VRELOC, /* expression can put result in any register; |
45 | info = instruction pc */ | 57 | info = instruction pc */ |
46 | VCALL, /* expression is a function call; info = instruction pc */ | 58 | VCALL, /* expression is a function call; info = instruction pc */ |
47 | VVARARG /* vararg expression; info = instruction pc */ | 59 | VVARARG /* vararg expression; info = instruction pc */ |
48 | } expkind; | 60 | } expkind; |
49 | 61 | ||
50 | 62 | ||
51 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) | 63 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) |
52 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) | 64 | #define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) |
65 | |||
53 | 66 | ||
54 | typedef struct expdesc { | 67 | typedef struct expdesc { |
55 | expkind k; | 68 | expkind k; |
56 | union { | 69 | union { |
57 | lua_Integer ival; /* for VKINT */ | 70 | lua_Integer ival; /* for VKINT */ |
58 | lua_Number nval; /* for VKFLT */ | 71 | lua_Number nval; /* for VKFLT */ |
72 | TString *strval; /* for VKSTR */ | ||
59 | int info; /* for generic use */ | 73 | int info; /* for generic use */ |
60 | struct { /* for indexed variables (VINDEXED) */ | 74 | struct { /* for indexed variables */ |
61 | short idx; /* index (R/K) */ | 75 | short idx; /* index (R or "long" K) */ |
62 | lu_byte t; /* table (register or upvalue) */ | 76 | lu_byte t; /* table (register or upvalue) */ |
63 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ | ||
64 | } ind; | 77 | } ind; |
78 | struct { /* for local variables */ | ||
79 | lu_byte sidx; /* index in the stack */ | ||
80 | unsigned short vidx; /* compiler index (in 'actvar.arr') */ | ||
81 | } var; | ||
65 | } u; | 82 | } u; |
66 | int t; /* patch list of 'exit when true' */ | 83 | int t; /* patch list of 'exit when true' */ |
67 | int f; /* patch list of 'exit when false' */ | 84 | int f; /* patch list of 'exit when false' */ |
68 | } expdesc; | 85 | } expdesc; |
69 | 86 | ||
70 | 87 | ||
71 | /* description of active local variable */ | 88 | /* kinds of variables */ |
72 | typedef struct Vardesc { | 89 | #define VDKREG 0 /* regular */ |
73 | short idx; /* variable index in stack */ | 90 | #define RDKCONST 1 /* constant */ |
91 | #define RDKTOCLOSE 2 /* to-be-closed */ | ||
92 | #define RDKCTC 3 /* compile-time constant */ | ||
93 | |||
94 | /* description of an active local variable */ | ||
95 | typedef union Vardesc { | ||
96 | struct { | ||
97 | TValuefields; /* constant value (if it is a compile-time constant) */ | ||
98 | lu_byte kind; | ||
99 | lu_byte sidx; /* index of the variable in the stack */ | ||
100 | short pidx; /* index of the variable in the Proto's 'locvars' array */ | ||
101 | TString *name; /* variable name */ | ||
102 | } vd; | ||
103 | TValue k; /* constant value (if any) */ | ||
74 | } Vardesc; | 104 | } Vardesc; |
75 | 105 | ||
76 | 106 | ||
107 | |||
77 | /* description of pending goto statements and label statements */ | 108 | /* description of pending goto statements and label statements */ |
78 | typedef struct Labeldesc { | 109 | typedef struct Labeldesc { |
79 | TString *name; /* label identifier */ | 110 | TString *name; /* label identifier */ |
80 | int pc; /* position in code */ | 111 | int pc; /* position in code */ |
81 | int line; /* line where it appeared */ | 112 | int line; /* line where it appeared */ |
82 | lu_byte nactvar; /* local level where it appears in current block */ | 113 | lu_byte nactvar; /* number of active variables in that position */ |
114 | lu_byte close; /* goto that escapes upvalues */ | ||
83 | } Labeldesc; | 115 | } Labeldesc; |
84 | 116 | ||
85 | 117 | ||
@@ -93,7 +125,7 @@ typedef struct Labellist { | |||
93 | 125 | ||
94 | /* dynamic structures used by the parser */ | 126 | /* dynamic structures used by the parser */ |
95 | typedef struct Dyndata { | 127 | typedef struct Dyndata { |
96 | struct { /* list of active local variables */ | 128 | struct { /* list of all active local variables */ |
97 | Vardesc *arr; | 129 | Vardesc *arr; |
98 | int n; | 130 | int n; |
99 | int size; | 131 | int size; |
@@ -115,17 +147,22 @@ typedef struct FuncState { | |||
115 | struct BlockCnt *bl; /* chain of current blocks */ | 147 | struct BlockCnt *bl; /* chain of current blocks */ |
116 | int pc; /* next position to code (equivalent to 'ncode') */ | 148 | int pc; /* next position to code (equivalent to 'ncode') */ |
117 | int lasttarget; /* 'label' of last 'jump label' */ | 149 | int lasttarget; /* 'label' of last 'jump label' */ |
118 | int jpc; /* list of pending jumps to 'pc' */ | 150 | int previousline; /* last line that was saved in 'lineinfo' */ |
119 | int nk; /* number of elements in 'k' */ | 151 | int nk; /* number of elements in 'k' */ |
120 | int np; /* number of elements in 'p' */ | 152 | int np; /* number of elements in 'p' */ |
153 | int nabslineinfo; /* number of elements in 'abslineinfo' */ | ||
121 | int firstlocal; /* index of first local var (in Dyndata array) */ | 154 | int firstlocal; /* index of first local var (in Dyndata array) */ |
122 | short nlocvars; /* number of elements in 'f->locvars' */ | 155 | int firstlabel; /* index of first label (in 'dyd->label->arr') */ |
156 | short ndebugvars; /* number of elements in 'f->locvars' */ | ||
123 | lu_byte nactvar; /* number of active local variables */ | 157 | lu_byte nactvar; /* number of active local variables */ |
124 | lu_byte nups; /* number of upvalues */ | 158 | lu_byte nups; /* number of upvalues */ |
125 | lu_byte freereg; /* first free register */ | 159 | lu_byte freereg; /* first free register */ |
160 | lu_byte iwthabs; /* instructions issued since last absolute line info */ | ||
161 | lu_byte needclose; /* function needs to close upvalues when returning */ | ||
126 | } FuncState; | 162 | } FuncState; |
127 | 163 | ||
128 | 164 | ||
165 | LUAI_FUNC int luaY_nvarstack (FuncState *fs); | ||
129 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | 166 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, |
130 | Dyndata *dyd, const char *name, int firstchar); | 167 | Dyndata *dyd, const char *name, int firstchar); |
131 | 168 | ||
diff --git a/src/lua-5.3/lprefix.h b/src/lua/lprefix.h index 9a749a3..484f2ad 100644 --- a/src/lua-5.3/lprefix.h +++ b/src/lua/lprefix.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lprefix.h $ |
3 | ** Definitions for Lua code that must come before any other header file | 3 | ** Definitions for Lua code that must come before any other header file |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -33,7 +33,7 @@ | |||
33 | /* | 33 | /* |
34 | ** Windows stuff | 34 | ** Windows stuff |
35 | */ | 35 | */ |
36 | #if defined(_WIN32) /* { */ | 36 | #if defined(_WIN32) /* { */ |
37 | 37 | ||
38 | #if !defined(_CRT_SECURE_NO_WARNINGS) | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) |
39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ | 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ |
diff --git a/src/lua-5.3/lstate.c b/src/lua/lstate.c index c1a7664..4434211 100644 --- a/src/lua-5.3/lstate.c +++ b/src/lua/lstate.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $ | 2 | ** $Id: lstate.c $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -28,25 +28,6 @@ | |||
28 | #include "ltm.h" | 28 | #include "ltm.h" |
29 | 29 | ||
30 | 30 | ||
31 | #if !defined(LUAI_GCPAUSE) | ||
32 | #define LUAI_GCPAUSE 200 /* 200% */ | ||
33 | #endif | ||
34 | |||
35 | #if !defined(LUAI_GCMUL) | ||
36 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ | ||
37 | #endif | ||
38 | |||
39 | |||
40 | /* | ||
41 | ** a macro to help the creation of a unique random seed when a state is | ||
42 | ** created; the seed is used to randomize hashes. | ||
43 | */ | ||
44 | #if !defined(luai_makeseed) | ||
45 | #include <time.h> | ||
46 | #define luai_makeseed() cast(unsigned int, time(NULL)) | ||
47 | #endif | ||
48 | |||
49 | |||
50 | 31 | ||
51 | /* | 32 | /* |
52 | ** thread state + extra space | 33 | ** thread state + extra space |
@@ -71,25 +52,35 @@ typedef struct LG { | |||
71 | 52 | ||
72 | 53 | ||
73 | /* | 54 | /* |
74 | ** Compute an initial seed as random as possible. Rely on Address Space | 55 | ** A macro to create a "random" seed when a state is created; |
75 | ** Layout Randomization (if present) to increase randomness.. | 56 | ** the seed is used to randomize string hashes. |
57 | */ | ||
58 | #if !defined(luai_makeseed) | ||
59 | |||
60 | #include <time.h> | ||
61 | |||
62 | /* | ||
63 | ** Compute an initial seed with some level of randomness. | ||
64 | ** Rely on Address Space Layout Randomization (if present) and | ||
65 | ** current time. | ||
76 | */ | 66 | */ |
77 | #define addbuff(b,p,e) \ | 67 | #define addbuff(b,p,e) \ |
78 | { size_t t = cast(size_t, e); \ | 68 | { size_t t = cast_sizet(e); \ |
79 | memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } | 69 | memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } |
80 | 70 | ||
81 | static unsigned int makeseed (lua_State *L) { | 71 | static unsigned int luai_makeseed (lua_State *L) { |
82 | char buff[4 * sizeof(size_t)]; | 72 | char buff[3 * sizeof(size_t)]; |
83 | unsigned int h = luai_makeseed(); | 73 | unsigned int h = cast_uint(time(NULL)); |
84 | int p = 0; | 74 | int p = 0; |
85 | addbuff(buff, p, L); /* heap variable */ | 75 | addbuff(buff, p, L); /* heap variable */ |
86 | addbuff(buff, p, &h); /* local variable */ | 76 | addbuff(buff, p, &h); /* local variable */ |
87 | addbuff(buff, p, luaO_nilobject); /* global variable */ | ||
88 | addbuff(buff, p, &lua_newstate); /* public function */ | 77 | addbuff(buff, p, &lua_newstate); /* public function */ |
89 | lua_assert(p == sizeof(buff)); | 78 | lua_assert(p == sizeof(buff)); |
90 | return luaS_hash(buff, p, h); | 79 | return luaS_hash(buff, p, h, 1); |
91 | } | 80 | } |
92 | 81 | ||
82 | #endif | ||
83 | |||
93 | 84 | ||
94 | /* | 85 | /* |
95 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) | 86 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) |
@@ -105,12 +96,73 @@ void luaE_setdebt (global_State *g, l_mem debt) { | |||
105 | } | 96 | } |
106 | 97 | ||
107 | 98 | ||
99 | LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { | ||
100 | global_State *g = G(L); | ||
101 | int ccalls; | ||
102 | luaE_freeCI(L); /* release unused CIs */ | ||
103 | ccalls = getCcalls(L); | ||
104 | if (limit >= 40000) | ||
105 | return 0; /* out of bounds */ | ||
106 | limit += CSTACKERR; | ||
107 | if (L != g-> mainthread) | ||
108 | return 0; /* only main thread can change the C stack */ | ||
109 | else if (ccalls <= CSTACKERR) | ||
110 | return 0; /* handling overflow */ | ||
111 | else { | ||
112 | int diff = limit - g->Cstacklimit; | ||
113 | if (ccalls + diff <= CSTACKERR) | ||
114 | return 0; /* new limit would cause an overflow */ | ||
115 | g->Cstacklimit = limit; /* set new limit */ | ||
116 | L->nCcalls += diff; /* correct 'nCcalls' */ | ||
117 | return limit - diff - CSTACKERR; /* success; return previous limit */ | ||
118 | } | ||
119 | } | ||
120 | |||
121 | |||
122 | /* | ||
123 | ** Decrement count of "C calls" and check for overflows. In case of | ||
124 | ** a stack overflow, check appropriate error ("regular" overflow or | ||
125 | ** overflow while handling stack overflow). If 'nCcalls' is smaller | ||
126 | ** than CSTACKERR but larger than CSTACKMARK, it means it has just | ||
127 | ** entered the "overflow zone", so the function raises an overflow | ||
128 | ** error. If 'nCcalls' is smaller than CSTACKMARK (which means it is | ||
129 | ** already handling an overflow) but larger than CSTACKERRMARK, does | ||
130 | ** not report an error (to allow message handling to work). Otherwise, | ||
131 | ** report a stack overflow while handling a stack overflow (probably | ||
132 | ** caused by a repeating error in the message handling function). | ||
133 | */ | ||
134 | |||
135 | void luaE_enterCcall (lua_State *L) { | ||
136 | int ncalls = getCcalls(L); | ||
137 | L->nCcalls--; | ||
138 | if (ncalls <= CSTACKERR) { /* possible overflow? */ | ||
139 | luaE_freeCI(L); /* release unused CIs */ | ||
140 | ncalls = getCcalls(L); /* update call count */ | ||
141 | if (ncalls <= CSTACKERR) { /* still overflow? */ | ||
142 | if (ncalls <= CSTACKERRMARK) /* below error-handling zone? */ | ||
143 | luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ | ||
144 | else if (ncalls >= CSTACKMARK) { | ||
145 | /* not in error-handling zone; raise the error now */ | ||
146 | L->nCcalls = (CSTACKMARK - 1); /* enter error-handling zone */ | ||
147 | luaG_runerror(L, "C stack overflow"); | ||
148 | } | ||
149 | /* else stack is in the error-handling zone; | ||
150 | allow message handler to work */ | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
155 | |||
108 | CallInfo *luaE_extendCI (lua_State *L) { | 156 | CallInfo *luaE_extendCI (lua_State *L) { |
109 | CallInfo *ci = luaM_new(L, CallInfo); | 157 | CallInfo *ci; |
158 | lua_assert(L->ci->next == NULL); | ||
159 | luaE_enterCcall(L); | ||
160 | ci = luaM_new(L, CallInfo); | ||
110 | lua_assert(L->ci->next == NULL); | 161 | lua_assert(L->ci->next == NULL); |
111 | L->ci->next = ci; | 162 | L->ci->next = ci; |
112 | ci->previous = L->ci; | 163 | ci->previous = L->ci; |
113 | ci->next = NULL; | 164 | ci->next = NULL; |
165 | ci->u.l.trap = 0; | ||
114 | L->nci++; | 166 | L->nci++; |
115 | return ci; | 167 | return ci; |
116 | } | 168 | } |
@@ -123,46 +175,60 @@ void luaE_freeCI (lua_State *L) { | |||
123 | CallInfo *ci = L->ci; | 175 | CallInfo *ci = L->ci; |
124 | CallInfo *next = ci->next; | 176 | CallInfo *next = ci->next; |
125 | ci->next = NULL; | 177 | ci->next = NULL; |
178 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ | ||
126 | while ((ci = next) != NULL) { | 179 | while ((ci = next) != NULL) { |
127 | next = ci->next; | 180 | next = ci->next; |
128 | luaM_free(L, ci); | 181 | luaM_free(L, ci); |
129 | L->nci--; | 182 | L->nci--; |
130 | } | 183 | } |
184 | L->nCcalls -= L->nci; /* adjust result */ | ||
131 | } | 185 | } |
132 | 186 | ||
133 | 187 | ||
134 | /* | 188 | /* |
135 | ** free half of the CallInfo structures not in use by a thread | 189 | ** free half of the CallInfo structures not in use by a thread, |
190 | ** keeping the first one. | ||
136 | */ | 191 | */ |
137 | void luaE_shrinkCI (lua_State *L) { | 192 | void luaE_shrinkCI (lua_State *L) { |
138 | CallInfo *ci = L->ci; | 193 | CallInfo *ci = L->ci->next; /* first free CallInfo */ |
139 | CallInfo *next2; /* next's next */ | 194 | CallInfo *next; |
140 | /* while there are two nexts */ | 195 | if (ci == NULL) |
141 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { | 196 | return; /* no extra elements */ |
142 | luaM_free(L, ci->next); /* free next */ | 197 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ |
198 | while ((next = ci->next) != NULL) { /* two extra elements? */ | ||
199 | CallInfo *next2 = next->next; /* next's next */ | ||
200 | ci->next = next2; /* remove next from the list */ | ||
143 | L->nci--; | 201 | L->nci--; |
144 | ci->next = next2; /* remove 'next' from the list */ | 202 | luaM_free(L, next); /* free next */ |
145 | next2->previous = ci; | 203 | if (next2 == NULL) |
146 | ci = next2; /* keep next's next */ | 204 | break; /* no more elements */ |
205 | else { | ||
206 | next2->previous = ci; | ||
207 | ci = next2; /* continue */ | ||
208 | } | ||
147 | } | 209 | } |
210 | L->nCcalls -= L->nci; /* adjust result */ | ||
148 | } | 211 | } |
149 | 212 | ||
150 | 213 | ||
151 | static void stack_init (lua_State *L1, lua_State *L) { | 214 | static void stack_init (lua_State *L1, lua_State *L) { |
152 | int i; CallInfo *ci; | 215 | int i; CallInfo *ci; |
153 | /* initialize stack array */ | 216 | /* initialize stack array */ |
154 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); | 217 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); |
155 | L1->stacksize = BASIC_STACK_SIZE; | 218 | L1->stacksize = BASIC_STACK_SIZE; |
156 | for (i = 0; i < BASIC_STACK_SIZE; i++) | 219 | for (i = 0; i < BASIC_STACK_SIZE; i++) |
157 | setnilvalue(L1->stack + i); /* erase new stack */ | 220 | setnilvalue(s2v(L1->stack + i)); /* erase new stack */ |
158 | L1->top = L1->stack; | 221 | L1->top = L1->stack; |
159 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; | 222 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; |
160 | /* initialize first ci */ | 223 | /* initialize first ci */ |
161 | ci = &L1->base_ci; | 224 | ci = &L1->base_ci; |
162 | ci->next = ci->previous = NULL; | 225 | ci->next = ci->previous = NULL; |
163 | ci->callstatus = 0; | 226 | ci->callstatus = CIST_C; |
164 | ci->func = L1->top; | 227 | ci->func = L1->top; |
165 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ | 228 | ci->u.c.k = NULL; |
229 | ci->nresults = 0; | ||
230 | setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */ | ||
231 | L1->top++; | ||
166 | ci->top = L1->top + LUA_MINSTACK; | 232 | ci->top = L1->top + LUA_MINSTACK; |
167 | L1->ci = ci; | 233 | L1->ci = ci; |
168 | } | 234 | } |
@@ -198,7 +264,8 @@ static void init_registry (lua_State *L, global_State *g) { | |||
198 | 264 | ||
199 | /* | 265 | /* |
200 | ** open parts of the state that may cause memory-allocation errors. | 266 | ** open parts of the state that may cause memory-allocation errors. |
201 | ** ('g->version' != NULL flags that the state was completely build) | 267 | ** ('g->nilvalue' being a nil value flags that the state was completely |
268 | ** build.) | ||
202 | */ | 269 | */ |
203 | static void f_luaopen (lua_State *L, void *ud) { | 270 | static void f_luaopen (lua_State *L, void *ud) { |
204 | global_State *g = G(L); | 271 | global_State *g = G(L); |
@@ -209,7 +276,7 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
209 | luaT_init(L); | 276 | luaT_init(L); |
210 | luaX_init(L); | 277 | luaX_init(L); |
211 | g->gcrunning = 1; /* allow gc */ | 278 | g->gcrunning = 1; /* allow gc */ |
212 | g->version = lua_version(NULL); | 279 | setnilvalue(&g->nilvalue); |
213 | luai_userstateopen(L); | 280 | luai_userstateopen(L); |
214 | } | 281 | } |
215 | 282 | ||
@@ -226,14 +293,12 @@ static void preinit_thread (lua_State *L, global_State *g) { | |||
226 | L->stacksize = 0; | 293 | L->stacksize = 0; |
227 | L->twups = L; /* thread has no upvalues */ | 294 | L->twups = L; /* thread has no upvalues */ |
228 | L->errorJmp = NULL; | 295 | L->errorJmp = NULL; |
229 | L->nCcalls = 0; | ||
230 | L->hook = NULL; | 296 | L->hook = NULL; |
231 | L->hookmask = 0; | 297 | L->hookmask = 0; |
232 | L->basehookcount = 0; | 298 | L->basehookcount = 0; |
233 | L->allowhook = 1; | 299 | L->allowhook = 1; |
234 | resethookcount(L); | 300 | resethookcount(L); |
235 | L->openupval = NULL; | 301 | L->openupval = NULL; |
236 | L->nny = 1; | ||
237 | L->status = LUA_OK; | 302 | L->status = LUA_OK; |
238 | L->errfunc = 0; | 303 | L->errfunc = 0; |
239 | } | 304 | } |
@@ -241,9 +306,9 @@ static void preinit_thread (lua_State *L, global_State *g) { | |||
241 | 306 | ||
242 | static void close_state (lua_State *L) { | 307 | static void close_state (lua_State *L) { |
243 | global_State *g = G(L); | 308 | global_State *g = G(L); |
244 | luaF_close(L, L->stack); /* close all upvalues for this thread */ | 309 | luaF_close(L, L->stack, CLOSEPROTECT); /* close all upvalues */ |
245 | luaC_freeallobjects(L); /* collect all objects */ | 310 | luaC_freeallobjects(L); /* collect all objects */ |
246 | if (g->version) /* closing a fully built state? */ | 311 | if (ttisnil(&g->nilvalue)) /* closing a fully built state? */ |
247 | luai_userstateclose(L); | 312 | luai_userstateclose(L); |
248 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); | 313 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); |
249 | freestack(L); | 314 | freestack(L); |
@@ -260,14 +325,15 @@ LUA_API lua_State *lua_newthread (lua_State *L) { | |||
260 | /* create new thread */ | 325 | /* create new thread */ |
261 | L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; | 326 | L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; |
262 | L1->marked = luaC_white(g); | 327 | L1->marked = luaC_white(g); |
263 | L1->tt = LUA_TTHREAD; | 328 | L1->tt = LUA_VTHREAD; |
264 | /* link it on list 'allgc' */ | 329 | /* link it on list 'allgc' */ |
265 | L1->next = g->allgc; | 330 | L1->next = g->allgc; |
266 | g->allgc = obj2gco(L1); | 331 | g->allgc = obj2gco(L1); |
267 | /* anchor it on L stack */ | 332 | /* anchor it on L stack */ |
268 | setthvalue(L, L->top, L1); | 333 | setthvalue2s(L, L->top, L1); |
269 | api_incr_top(L); | 334 | api_incr_top(L); |
270 | preinit_thread(L1, g); | 335 | preinit_thread(L1, g); |
336 | L1->nCcalls = getCcalls(L); | ||
271 | L1->hookmask = L->hookmask; | 337 | L1->hookmask = L->hookmask; |
272 | L1->basehookcount = L->basehookcount; | 338 | L1->basehookcount = L->basehookcount; |
273 | L1->hook = L->hook; | 339 | L1->hook = L->hook; |
@@ -284,7 +350,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) { | |||
284 | 350 | ||
285 | void luaE_freethread (lua_State *L, lua_State *L1) { | 351 | void luaE_freethread (lua_State *L, lua_State *L1) { |
286 | LX *l = fromstate(L1); | 352 | LX *l = fromstate(L1); |
287 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ | 353 | luaF_close(L1, L1->stack, NOCLOSINGMETH); /* close all upvalues */ |
288 | lua_assert(L1->openupval == NULL); | 354 | lua_assert(L1->openupval == NULL); |
289 | luai_userstatefree(L, L1); | 355 | luai_userstatefree(L, L1); |
290 | freestack(L1); | 356 | freestack(L1); |
@@ -292,6 +358,28 @@ void luaE_freethread (lua_State *L, lua_State *L1) { | |||
292 | } | 358 | } |
293 | 359 | ||
294 | 360 | ||
361 | int lua_resetthread (lua_State *L) { | ||
362 | CallInfo *ci; | ||
363 | int status; | ||
364 | lua_lock(L); | ||
365 | L->ci = ci = &L->base_ci; /* unwind CallInfo list */ | ||
366 | setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */ | ||
367 | ci->func = L->stack; | ||
368 | ci->callstatus = CIST_C; | ||
369 | status = luaF_close(L, L->stack, CLOSEPROTECT); | ||
370 | if (status != CLOSEPROTECT) /* real errors? */ | ||
371 | luaD_seterrorobj(L, status, L->stack + 1); | ||
372 | else { | ||
373 | status = LUA_OK; | ||
374 | L->top = L->stack + 1; | ||
375 | } | ||
376 | ci->top = L->top + LUA_MINSTACK; | ||
377 | L->status = status; | ||
378 | lua_unlock(L); | ||
379 | return status; | ||
380 | } | ||
381 | |||
382 | |||
295 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | 383 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { |
296 | int i; | 384 | int i; |
297 | lua_State *L; | 385 | lua_State *L; |
@@ -300,34 +388,43 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
300 | if (l == NULL) return NULL; | 388 | if (l == NULL) return NULL; |
301 | L = &l->l.l; | 389 | L = &l->l.l; |
302 | g = &l->g; | 390 | g = &l->g; |
303 | L->next = NULL; | 391 | L->tt = LUA_VTHREAD; |
304 | L->tt = LUA_TTHREAD; | ||
305 | g->currentwhite = bitmask(WHITE0BIT); | 392 | g->currentwhite = bitmask(WHITE0BIT); |
306 | L->marked = luaC_white(g); | 393 | L->marked = luaC_white(g); |
307 | preinit_thread(L, g); | 394 | preinit_thread(L, g); |
395 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ | ||
396 | L->next = NULL; | ||
397 | g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; | ||
308 | g->frealloc = f; | 398 | g->frealloc = f; |
309 | g->ud = ud; | 399 | g->ud = ud; |
400 | g->warnf = NULL; | ||
401 | g->ud_warn = NULL; | ||
310 | g->mainthread = L; | 402 | g->mainthread = L; |
311 | g->seed = makeseed(L); | 403 | g->seed = luai_makeseed(L); |
312 | g->gcrunning = 0; /* no GC while building state */ | 404 | g->gcrunning = 0; /* no GC while building state */ |
313 | g->GCestimate = 0; | ||
314 | g->strt.size = g->strt.nuse = 0; | 405 | g->strt.size = g->strt.nuse = 0; |
315 | g->strt.hash = NULL; | 406 | g->strt.hash = NULL; |
316 | setnilvalue(&g->l_registry); | 407 | setnilvalue(&g->l_registry); |
317 | g->panic = NULL; | 408 | g->panic = NULL; |
318 | g->version = NULL; | ||
319 | g->gcstate = GCSpause; | 409 | g->gcstate = GCSpause; |
320 | g->gckind = KGC_NORMAL; | 410 | g->gckind = KGC_INC; |
321 | g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL; | 411 | g->gcemergency = 0; |
412 | g->finobj = g->tobefnz = g->fixedgc = NULL; | ||
413 | g->survival = g->old = g->reallyold = NULL; | ||
414 | g->finobjsur = g->finobjold = g->finobjrold = NULL; | ||
322 | g->sweepgc = NULL; | 415 | g->sweepgc = NULL; |
323 | g->gray = g->grayagain = NULL; | 416 | g->gray = g->grayagain = NULL; |
324 | g->weak = g->ephemeron = g->allweak = NULL; | 417 | g->weak = g->ephemeron = g->allweak = NULL; |
325 | g->twups = NULL; | 418 | g->twups = NULL; |
326 | g->totalbytes = sizeof(LG); | 419 | g->totalbytes = sizeof(LG); |
327 | g->GCdebt = 0; | 420 | g->GCdebt = 0; |
328 | g->gcfinnum = 0; | 421 | g->lastatomic = 0; |
329 | g->gcpause = LUAI_GCPAUSE; | 422 | setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ |
330 | g->gcstepmul = LUAI_GCMUL; | 423 | setgcparam(g->gcpause, LUAI_GCPAUSE); |
424 | setgcparam(g->gcstepmul, LUAI_GCMUL); | ||
425 | g->gcstepsize = LUAI_GCSTEPSIZE; | ||
426 | setgcparam(g->genmajormul, LUAI_GENMAJORMUL); | ||
427 | g->genminormul = LUAI_GENMINORMUL; | ||
331 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; | 428 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; |
332 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { | 429 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { |
333 | /* memory allocation error: free partial state */ | 430 | /* memory allocation error: free partial state */ |
@@ -345,3 +442,26 @@ LUA_API void lua_close (lua_State *L) { | |||
345 | } | 442 | } |
346 | 443 | ||
347 | 444 | ||
445 | void luaE_warning (lua_State *L, const char *msg, int tocont) { | ||
446 | lua_WarnFunction wf = G(L)->warnf; | ||
447 | if (wf != NULL) | ||
448 | wf(G(L)->ud_warn, msg, tocont); | ||
449 | } | ||
450 | |||
451 | |||
452 | /* | ||
453 | ** Generate a warning from an error message | ||
454 | */ | ||
455 | void luaE_warnerror (lua_State *L, const char *where) { | ||
456 | TValue *errobj = s2v(L->top - 1); /* error object */ | ||
457 | const char *msg = (ttisstring(errobj)) | ||
458 | ? svalue(errobj) | ||
459 | : "error object is not a string"; | ||
460 | /* produce warning "error in %s (%s)" (where, msg) */ | ||
461 | luaE_warning(L, "error in ", 1); | ||
462 | luaE_warning(L, where, 1); | ||
463 | luaE_warning(L, " (", 1); | ||
464 | luaE_warning(L, msg, 1); | ||
465 | luaE_warning(L, ")", 0); | ||
466 | } | ||
467 | |||
diff --git a/src/lua-5.3/lstate.h b/src/lua/lstate.h index 56b3741..2e8bd6c 100644 --- a/src/lua-5.3/lstate.h +++ b/src/lua/lstate.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $ | 2 | ** $Id: lstate.h $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | 16 | ||
17 | /* | 17 | /* |
18 | |||
19 | ** Some notes about garbage-collected objects: All objects in Lua must | 18 | ** Some notes about garbage-collected objects: All objects in Lua must |
20 | ** be kept somehow accessible until being freed, so all objects always | 19 | ** be kept somehow accessible until being freed, so all objects always |
21 | ** belong to one (and only one) of these lists, using field 'next' of | 20 | ** belong to one (and only one) of these lists, using field 'next' of |
@@ -27,6 +26,22 @@ | |||
27 | ** 'fixedgc': all objects that are not to be collected (currently | 26 | ** 'fixedgc': all objects that are not to be collected (currently |
28 | ** only small strings, such as reserved words). | 27 | ** only small strings, such as reserved words). |
29 | ** | 28 | ** |
29 | ** For the generational collector, some of these lists have marks for | ||
30 | ** generations. Each mark points to the first element in the list for | ||
31 | ** that particular generation; that generation goes until the next mark. | ||
32 | ** | ||
33 | ** 'allgc' -> 'survival': new objects; | ||
34 | ** 'survival' -> 'old': objects that survived one collection; | ||
35 | ** 'old' -> 'reallyold': objects that became old in last collection; | ||
36 | ** 'reallyold' -> NULL: objects old for more than one cycle. | ||
37 | ** | ||
38 | ** 'finobj' -> 'finobjsur': new objects marked for finalization; | ||
39 | ** 'finobjsur' -> 'finobjold': survived """"; | ||
40 | ** 'finobjold' -> 'finobjrold': just old """"; | ||
41 | ** 'finobjrold' -> NULL: really old """". | ||
42 | */ | ||
43 | |||
44 | /* | ||
30 | ** Moreover, there is another set of lists that control gray objects. | 45 | ** Moreover, there is another set of lists that control gray objects. |
31 | ** These lists are linked by fields 'gclist'. (All objects that | 46 | ** These lists are linked by fields 'gclist'. (All objects that |
32 | ** can become gray have such a field. The field is not the same | 47 | ** can become gray have such a field. The field is not the same |
@@ -43,9 +58,77 @@ | |||
43 | ** 'weak': tables with weak values to be cleared; | 58 | ** 'weak': tables with weak values to be cleared; |
44 | ** 'ephemeron': ephemeron tables with white->white entries; | 59 | ** 'ephemeron': ephemeron tables with white->white entries; |
45 | ** 'allweak': tables with weak keys and/or weak values to be cleared. | 60 | ** 'allweak': tables with weak keys and/or weak values to be cleared. |
46 | ** The last three lists are used only during the atomic phase. | 61 | */ |
62 | |||
63 | |||
47 | 64 | ||
65 | /* | ||
66 | ** About 'nCcalls': each thread in Lua (a lua_State) keeps a count of | ||
67 | ** how many "C calls" it still can do in the C stack, to avoid C-stack | ||
68 | ** overflow. This count is very rough approximation; it considers only | ||
69 | ** recursive functions inside the interpreter, as non-recursive calls | ||
70 | ** can be considered using a fixed (although unknown) amount of stack | ||
71 | ** space. | ||
72 | ** | ||
73 | ** The count has two parts: the lower part is the count itself; the | ||
74 | ** higher part counts the number of non-yieldable calls in the stack. | ||
75 | ** (They are together so that we can change both with one instruction.) | ||
76 | ** | ||
77 | ** Because calls to external C functions can use an unknown amount | ||
78 | ** of space (e.g., functions using an auxiliary buffer), calls | ||
79 | ** to these functions add more than one to the count (see CSTACKCF). | ||
80 | ** | ||
81 | ** The proper count excludes the number of CallInfo structures allocated | ||
82 | ** by Lua, as a kind of "potential" calls. So, when Lua calls a function | ||
83 | ** (and "consumes" one CallInfo), it needs neither to decrement nor to | ||
84 | ** check 'nCcalls', as its use of C stack is already accounted for. | ||
85 | */ | ||
86 | |||
87 | /* number of "C stack slots" used by an external C function */ | ||
88 | #define CSTACKCF 10 | ||
89 | |||
90 | |||
91 | /* | ||
92 | ** The C-stack size is sliced in the following zones: | ||
93 | ** - larger than CSTACKERR: normal stack; | ||
94 | ** - [CSTACKMARK, CSTACKERR]: buffer zone to signal a stack overflow; | ||
95 | ** - [CSTACKCF, CSTACKERRMARK]: error-handling zone; | ||
96 | ** - below CSTACKERRMARK: buffer zone to signal overflow during overflow; | ||
97 | ** (Because the counter can be decremented CSTACKCF at once, we need | ||
98 | ** the so called "buffer zones", with at least that size, to properly | ||
99 | ** detect a change from one zone to the next.) | ||
48 | */ | 100 | */ |
101 | #define CSTACKERR (8 * CSTACKCF) | ||
102 | #define CSTACKMARK (CSTACKERR - (CSTACKCF + 2)) | ||
103 | #define CSTACKERRMARK (CSTACKCF + 2) | ||
104 | |||
105 | |||
106 | /* initial limit for the C-stack of threads */ | ||
107 | #define CSTACKTHREAD (2 * CSTACKERR) | ||
108 | |||
109 | |||
110 | /* true if this thread does not have non-yieldable calls in the stack */ | ||
111 | #define yieldable(L) (((L)->nCcalls & 0xffff0000) == 0) | ||
112 | |||
113 | /* real number of C calls */ | ||
114 | #define getCcalls(L) ((L)->nCcalls & 0xffff) | ||
115 | |||
116 | |||
117 | /* Increment the number of non-yieldable calls */ | ||
118 | #define incnny(L) ((L)->nCcalls += 0x10000) | ||
119 | |||
120 | /* Decrement the number of non-yieldable calls */ | ||
121 | #define decnny(L) ((L)->nCcalls -= 0x10000) | ||
122 | |||
123 | /* Increment the number of non-yieldable calls and decrement nCcalls */ | ||
124 | #define incXCcalls(L) ((L)->nCcalls += 0x10000 - CSTACKCF) | ||
125 | |||
126 | /* Decrement the number of non-yieldable calls and increment nCcalls */ | ||
127 | #define decXCcalls(L) ((L)->nCcalls -= 0x10000 - CSTACKCF) | ||
128 | |||
129 | |||
130 | |||
131 | |||
49 | 132 | ||
50 | 133 | ||
51 | struct lua_longjmp; /* defined in ldo.c */ | 134 | struct lua_longjmp; /* defined in ldo.c */ |
@@ -69,8 +152,8 @@ struct lua_longjmp; /* defined in ldo.c */ | |||
69 | 152 | ||
70 | 153 | ||
71 | /* kinds of Garbage Collection */ | 154 | /* kinds of Garbage Collection */ |
72 | #define KGC_NORMAL 0 | 155 | #define KGC_INC 0 /* incremental gc */ |
73 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ | 156 | #define KGC_GEN 1 /* generational gc */ |
74 | 157 | ||
75 | 158 | ||
76 | typedef struct stringtable { | 159 | typedef struct stringtable { |
@@ -82,12 +165,6 @@ typedef struct stringtable { | |||
82 | 165 | ||
83 | /* | 166 | /* |
84 | ** Information about a call. | 167 | ** Information about a call. |
85 | ** When a thread yields, 'func' is adjusted to pretend that the | ||
86 | ** top function has only the yielded values in its stack; in that | ||
87 | ** case, the actual 'func' value is saved in field 'extra'. | ||
88 | ** When a function calls another with a continuation, 'extra' keeps | ||
89 | ** the function index so that, in case of errors, the continuation | ||
90 | ** function can be called with the correct top. | ||
91 | */ | 168 | */ |
92 | typedef struct CallInfo { | 169 | typedef struct CallInfo { |
93 | StkId func; /* function index in the stack */ | 170 | StkId func; /* function index in the stack */ |
@@ -95,8 +172,9 @@ typedef struct CallInfo { | |||
95 | struct CallInfo *previous, *next; /* dynamic call link */ | 172 | struct CallInfo *previous, *next; /* dynamic call link */ |
96 | union { | 173 | union { |
97 | struct { /* only for Lua functions */ | 174 | struct { /* only for Lua functions */ |
98 | StkId base; /* base for this function */ | ||
99 | const Instruction *savedpc; | 175 | const Instruction *savedpc; |
176 | volatile l_signalT trap; | ||
177 | int nextraargs; /* # of extra arguments in vararg functions */ | ||
100 | } l; | 178 | } l; |
101 | struct { /* only for C functions */ | 179 | struct { /* only for C functions */ |
102 | lua_KFunction k; /* continuation in case of yields */ | 180 | lua_KFunction k; /* continuation in case of yields */ |
@@ -104,7 +182,14 @@ typedef struct CallInfo { | |||
104 | lua_KContext ctx; /* context info. in case of yields */ | 182 | lua_KContext ctx; /* context info. in case of yields */ |
105 | } c; | 183 | } c; |
106 | } u; | 184 | } u; |
107 | ptrdiff_t extra; | 185 | union { |
186 | int funcidx; /* called-function index */ | ||
187 | int nyield; /* number of values yielded */ | ||
188 | struct { /* info about transferred values (for call/return hooks) */ | ||
189 | unsigned short ftransfer; /* offset of first value transferred */ | ||
190 | unsigned short ntransfer; /* number of values transferred */ | ||
191 | } transferinfo; | ||
192 | } u2; | ||
108 | short nresults; /* expected number of results from this function */ | 193 | short nresults; /* expected number of results from this function */ |
109 | unsigned short callstatus; | 194 | unsigned short callstatus; |
110 | } CallInfo; | 195 | } CallInfo; |
@@ -114,17 +199,22 @@ typedef struct CallInfo { | |||
114 | ** Bits in CallInfo status | 199 | ** Bits in CallInfo status |
115 | */ | 200 | */ |
116 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ | 201 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ |
117 | #define CIST_LUA (1<<1) /* call is running a Lua function */ | 202 | #define CIST_C (1<<1) /* call is running a C function */ |
118 | #define CIST_HOOKED (1<<2) /* call is running a debug hook */ | 203 | #define CIST_HOOKED (1<<2) /* call is running a debug hook */ |
119 | #define CIST_FRESH (1<<3) /* call is running on a fresh invocation | 204 | #define CIST_YPCALL (1<<3) /* call is a yieldable protected call */ |
120 | of luaV_execute */ | 205 | #define CIST_TAIL (1<<4) /* call was tail called */ |
121 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ | 206 | #define CIST_HOOKYIELD (1<<5) /* last hook called yielded */ |
122 | #define CIST_TAIL (1<<5) /* call was tail called */ | 207 | #define CIST_FIN (1<<6) /* call is running a finalizer */ |
123 | #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ | 208 | #define CIST_TRAN (1<<7) /* 'ci' has transfer information */ |
124 | #define CIST_LEQ (1<<7) /* using __lt for __le */ | 209 | #if defined(LUA_COMPAT_LT_LE) |
125 | #define CIST_FIN (1<<8) /* call is running a finalizer */ | 210 | #define CIST_LEQ (1<<8) /* using __lt for __le */ |
211 | #endif | ||
212 | |||
213 | /* active function is a Lua function */ | ||
214 | #define isLua(ci) (!((ci)->callstatus & CIST_C)) | ||
126 | 215 | ||
127 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) | 216 | /* call is running Lua code (not a hook) */ |
217 | #define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED))) | ||
128 | 218 | ||
129 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ | 219 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ |
130 | #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) | 220 | #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) |
@@ -139,15 +229,22 @@ typedef struct global_State { | |||
139 | void *ud; /* auxiliary data to 'frealloc' */ | 229 | void *ud; /* auxiliary data to 'frealloc' */ |
140 | l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ | 230 | l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ |
141 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ | 231 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ |
142 | lu_mem GCmemtrav; /* memory traversed by the GC */ | ||
143 | lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ | 232 | lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ |
233 | lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */ | ||
144 | stringtable strt; /* hash table for strings */ | 234 | stringtable strt; /* hash table for strings */ |
145 | TValue l_registry; | 235 | TValue l_registry; |
236 | TValue nilvalue; /* a nil value */ | ||
146 | unsigned int seed; /* randomized seed for hashes */ | 237 | unsigned int seed; /* randomized seed for hashes */ |
147 | lu_byte currentwhite; | 238 | lu_byte currentwhite; |
148 | lu_byte gcstate; /* state of garbage collector */ | 239 | lu_byte gcstate; /* state of garbage collector */ |
149 | lu_byte gckind; /* kind of GC running */ | 240 | lu_byte gckind; /* kind of GC running */ |
241 | lu_byte genminormul; /* control for minor generational collections */ | ||
242 | lu_byte genmajormul; /* control for major generational collections */ | ||
150 | lu_byte gcrunning; /* true if GC is running */ | 243 | lu_byte gcrunning; /* true if GC is running */ |
244 | lu_byte gcemergency; /* true if this is an emergency collection */ | ||
245 | lu_byte gcpause; /* size of pause between successive GCs */ | ||
246 | lu_byte gcstepmul; /* GC "speed" */ | ||
247 | lu_byte gcstepsize; /* (log2 of) GC granularity */ | ||
151 | GCObject *allgc; /* list of all collectable objects */ | 248 | GCObject *allgc; /* list of all collectable objects */ |
152 | GCObject **sweepgc; /* current position of sweep in list */ | 249 | GCObject **sweepgc; /* current position of sweep in list */ |
153 | GCObject *finobj; /* list of collectable objects with finalizers */ | 250 | GCObject *finobj; /* list of collectable objects with finalizers */ |
@@ -158,17 +255,23 @@ typedef struct global_State { | |||
158 | GCObject *allweak; /* list of all-weak tables */ | 255 | GCObject *allweak; /* list of all-weak tables */ |
159 | GCObject *tobefnz; /* list of userdata to be GC */ | 256 | GCObject *tobefnz; /* list of userdata to be GC */ |
160 | GCObject *fixedgc; /* list of objects not to be collected */ | 257 | GCObject *fixedgc; /* list of objects not to be collected */ |
258 | /* fields for generational collector */ | ||
259 | GCObject *survival; /* start of objects that survived one GC cycle */ | ||
260 | GCObject *old; /* start of old objects */ | ||
261 | GCObject *reallyold; /* old objects with more than one cycle */ | ||
262 | GCObject *finobjsur; /* list of survival objects with finalizers */ | ||
263 | GCObject *finobjold; /* list of old objects with finalizers */ | ||
264 | GCObject *finobjrold; /* list of really old objects with finalizers */ | ||
161 | struct lua_State *twups; /* list of threads with open upvalues */ | 265 | struct lua_State *twups; /* list of threads with open upvalues */ |
162 | unsigned int gcfinnum; /* number of finalizers to call in each GC step */ | ||
163 | int gcpause; /* size of pause between successive GCs */ | ||
164 | int gcstepmul; /* GC 'granularity' */ | ||
165 | lua_CFunction panic; /* to be called in unprotected errors */ | 266 | lua_CFunction panic; /* to be called in unprotected errors */ |
166 | struct lua_State *mainthread; | 267 | struct lua_State *mainthread; |
167 | const lua_Number *version; /* pointer to version number */ | 268 | TString *memerrmsg; /* message for memory-allocation errors */ |
168 | TString *memerrmsg; /* memory-error message */ | ||
169 | TString *tmname[TM_N]; /* array with tag-method names */ | 269 | TString *tmname[TM_N]; /* array with tag-method names */ |
170 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ | 270 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ |
171 | TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ | 271 | TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ |
272 | lua_WarnFunction warnf; /* warning function */ | ||
273 | void *ud_warn; /* auxiliary data to 'warnf' */ | ||
274 | unsigned int Cstacklimit; /* current limit for the C stack */ | ||
172 | } global_State; | 275 | } global_State; |
173 | 276 | ||
174 | 277 | ||
@@ -177,8 +280,9 @@ typedef struct global_State { | |||
177 | */ | 280 | */ |
178 | struct lua_State { | 281 | struct lua_State { |
179 | CommonHeader; | 282 | CommonHeader; |
180 | unsigned short nci; /* number of items in 'ci' list */ | ||
181 | lu_byte status; | 283 | lu_byte status; |
284 | lu_byte allowhook; | ||
285 | unsigned short nci; /* number of items in 'ci' list */ | ||
182 | StkId top; /* first free slot in the stack */ | 286 | StkId top; /* first free slot in the stack */ |
183 | global_State *l_G; | 287 | global_State *l_G; |
184 | CallInfo *ci; /* call info for current function */ | 288 | CallInfo *ci; /* call info for current function */ |
@@ -192,13 +296,11 @@ struct lua_State { | |||
192 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | 296 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ |
193 | volatile lua_Hook hook; | 297 | volatile lua_Hook hook; |
194 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 298 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
299 | l_uint32 nCcalls; /* number of allowed nested C calls - 'nci' */ | ||
195 | int stacksize; | 300 | int stacksize; |
196 | int basehookcount; | 301 | int basehookcount; |
197 | int hookcount; | 302 | int hookcount; |
198 | unsigned short nny; /* number of non-yieldable calls in stack */ | 303 | volatile l_signalT hookmask; |
199 | unsigned short nCcalls; /* number of nested C calls */ | ||
200 | l_signalT hookmask; | ||
201 | lu_byte allowhook; | ||
202 | }; | 304 | }; |
203 | 305 | ||
204 | 306 | ||
@@ -216,6 +318,7 @@ union GCUnion { | |||
216 | struct Table h; | 318 | struct Table h; |
217 | struct Proto p; | 319 | struct Proto p; |
218 | struct lua_State th; /* thread */ | 320 | struct lua_State th; /* thread */ |
321 | struct UpVal upv; | ||
219 | }; | 322 | }; |
220 | 323 | ||
221 | 324 | ||
@@ -224,19 +327,22 @@ union GCUnion { | |||
224 | /* macros to convert a GCObject into a specific value */ | 327 | /* macros to convert a GCObject into a specific value */ |
225 | #define gco2ts(o) \ | 328 | #define gco2ts(o) \ |
226 | check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) | 329 | check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) |
227 | #define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) | 330 | #define gco2u(o) check_exp((o)->tt == LUA_VUSERDATA, &((cast_u(o))->u)) |
228 | #define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) | 331 | #define gco2lcl(o) check_exp((o)->tt == LUA_VLCL, &((cast_u(o))->cl.l)) |
229 | #define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c)) | 332 | #define gco2ccl(o) check_exp((o)->tt == LUA_VCCL, &((cast_u(o))->cl.c)) |
230 | #define gco2cl(o) \ | 333 | #define gco2cl(o) \ |
231 | check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) | 334 | check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) |
232 | #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) | 335 | #define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h)) |
233 | #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) | 336 | #define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p)) |
234 | #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) | 337 | #define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th)) |
338 | #define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv)) | ||
235 | 339 | ||
236 | 340 | ||
237 | /* macro to convert a Lua object into a GCObject */ | 341 | /* |
238 | #define obj2gco(v) \ | 342 | ** macro to convert a Lua object into a GCObject |
239 | check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc))) | 343 | ** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.) |
344 | */ | ||
345 | #define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc)) | ||
240 | 346 | ||
241 | 347 | ||
242 | /* actual number of total bytes allocated */ | 348 | /* actual number of total bytes allocated */ |
@@ -247,7 +353,12 @@ LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | |||
247 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | 353 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
248 | LUAI_FUNC void luaE_freeCI (lua_State *L); | 354 | LUAI_FUNC void luaE_freeCI (lua_State *L); |
249 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | 355 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); |
356 | LUAI_FUNC void luaE_enterCcall (lua_State *L); | ||
357 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); | ||
358 | LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); | ||
359 | |||
250 | 360 | ||
361 | #define luaE_exitCcall(L) ((L)->nCcalls++) | ||
251 | 362 | ||
252 | #endif | 363 | #endif |
253 | 364 | ||
diff --git a/src/lua-5.3/lstring.c b/src/lua/lstring.c index 6257f21..6f15747 100644 --- a/src/lua-5.3/lstring.c +++ b/src/lua/lstring.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lstring.c $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -22,11 +22,8 @@ | |||
22 | #include "lstring.h" | 22 | #include "lstring.h" |
23 | 23 | ||
24 | 24 | ||
25 | #define MEMERRMSG "not enough memory" | ||
26 | |||
27 | |||
28 | /* | 25 | /* |
29 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to | 26 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a long string to |
30 | ** compute its hash | 27 | ** compute its hash |
31 | */ | 28 | */ |
32 | #if !defined(LUAI_HASHLIMIT) | 29 | #if !defined(LUAI_HASHLIMIT) |
@@ -34,21 +31,28 @@ | |||
34 | #endif | 31 | #endif |
35 | 32 | ||
36 | 33 | ||
34 | |||
35 | /* | ||
36 | ** Maximum size for string table. | ||
37 | */ | ||
38 | #define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) | ||
39 | |||
40 | |||
37 | /* | 41 | /* |
38 | ** equality for long strings | 42 | ** equality for long strings |
39 | */ | 43 | */ |
40 | int luaS_eqlngstr (TString *a, TString *b) { | 44 | int luaS_eqlngstr (TString *a, TString *b) { |
41 | size_t len = a->u.lnglen; | 45 | size_t len = a->u.lnglen; |
42 | lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); | 46 | lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); |
43 | return (a == b) || /* same instance or... */ | 47 | return (a == b) || /* same instance or... */ |
44 | ((len == b->u.lnglen) && /* equal length and ... */ | 48 | ((len == b->u.lnglen) && /* equal length and ... */ |
45 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ | 49 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ |
46 | } | 50 | } |
47 | 51 | ||
48 | 52 | ||
49 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { | 53 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed, |
50 | unsigned int h = seed ^ cast(unsigned int, l); | 54 | size_t step) { |
51 | size_t step = (l >> LUAI_HASHLIMIT) + 1; | 55 | unsigned int h = seed ^ cast_uint(l); |
52 | for (; l >= step; l -= step) | 56 | for (; l >= step; l -= step) |
53 | h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); | 57 | h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); |
54 | return h; | 58 | return h; |
@@ -56,43 +60,58 @@ unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { | |||
56 | 60 | ||
57 | 61 | ||
58 | unsigned int luaS_hashlongstr (TString *ts) { | 62 | unsigned int luaS_hashlongstr (TString *ts) { |
59 | lua_assert(ts->tt == LUA_TLNGSTR); | 63 | lua_assert(ts->tt == LUA_VLNGSTR); |
60 | if (ts->extra == 0) { /* no hash? */ | 64 | if (ts->extra == 0) { /* no hash? */ |
61 | ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash); | 65 | size_t len = ts->u.lnglen; |
66 | size_t step = (len >> LUAI_HASHLIMIT) + 1; | ||
67 | ts->hash = luaS_hash(getstr(ts), len, ts->hash, step); | ||
62 | ts->extra = 1; /* now it has its hash */ | 68 | ts->extra = 1; /* now it has its hash */ |
63 | } | 69 | } |
64 | return ts->hash; | 70 | return ts->hash; |
65 | } | 71 | } |
66 | 72 | ||
67 | 73 | ||
68 | /* | 74 | static void tablerehash (TString **vect, int osize, int nsize) { |
69 | ** resizes the string table | ||
70 | */ | ||
71 | void luaS_resize (lua_State *L, int newsize) { | ||
72 | int i; | 75 | int i; |
73 | stringtable *tb = &G(L)->strt; | 76 | for (i = osize; i < nsize; i++) /* clear new elements */ |
74 | if (newsize > tb->size) { /* grow table if needed */ | 77 | vect[i] = NULL; |
75 | luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); | 78 | for (i = 0; i < osize; i++) { /* rehash old part of the array */ |
76 | for (i = tb->size; i < newsize; i++) | 79 | TString *p = vect[i]; |
77 | tb->hash[i] = NULL; | 80 | vect[i] = NULL; |
78 | } | 81 | while (p) { /* for each string in the list */ |
79 | for (i = 0; i < tb->size; i++) { /* rehash */ | ||
80 | TString *p = tb->hash[i]; | ||
81 | tb->hash[i] = NULL; | ||
82 | while (p) { /* for each node in the list */ | ||
83 | TString *hnext = p->u.hnext; /* save next */ | 82 | TString *hnext = p->u.hnext; /* save next */ |
84 | unsigned int h = lmod(p->hash, newsize); /* new position */ | 83 | unsigned int h = lmod(p->hash, nsize); /* new position */ |
85 | p->u.hnext = tb->hash[h]; /* chain it */ | 84 | p->u.hnext = vect[h]; /* chain it into array */ |
86 | tb->hash[h] = p; | 85 | vect[h] = p; |
87 | p = hnext; | 86 | p = hnext; |
88 | } | 87 | } |
89 | } | 88 | } |
90 | if (newsize < tb->size) { /* shrink table if needed */ | 89 | } |
91 | /* vanishing slice should be empty */ | 90 | |
92 | lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); | 91 | |
93 | luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); | 92 | /* |
93 | ** Resize the string table. If allocation fails, keep the current size. | ||
94 | ** (This can degrade performance, but any non-zero size should work | ||
95 | ** correctly.) | ||
96 | */ | ||
97 | void luaS_resize (lua_State *L, int nsize) { | ||
98 | stringtable *tb = &G(L)->strt; | ||
99 | int osize = tb->size; | ||
100 | TString **newvect; | ||
101 | if (nsize < osize) /* shrinking table? */ | ||
102 | tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */ | ||
103 | newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*); | ||
104 | if (unlikely(newvect == NULL)) { /* reallocation failed? */ | ||
105 | if (nsize < osize) /* was it shrinking table? */ | ||
106 | tablerehash(tb->hash, nsize, osize); /* restore to original size */ | ||
107 | /* leave table as it was */ | ||
108 | } | ||
109 | else { /* allocation succeeded */ | ||
110 | tb->hash = newvect; | ||
111 | tb->size = nsize; | ||
112 | if (nsize > osize) | ||
113 | tablerehash(newvect, osize, nsize); /* rehash for new size */ | ||
94 | } | 114 | } |
95 | tb->size = newsize; | ||
96 | } | 115 | } |
97 | 116 | ||
98 | 117 | ||
@@ -104,8 +123,8 @@ void luaS_clearcache (global_State *g) { | |||
104 | int i, j; | 123 | int i, j; |
105 | for (i = 0; i < STRCACHE_N; i++) | 124 | for (i = 0; i < STRCACHE_N; i++) |
106 | for (j = 0; j < STRCACHE_M; j++) { | 125 | for (j = 0; j < STRCACHE_M; j++) { |
107 | if (iswhite(g->strcache[i][j])) /* will entry be collected? */ | 126 | if (iswhite(g->strcache[i][j])) /* will entry be collected? */ |
108 | g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ | 127 | g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ |
109 | } | 128 | } |
110 | } | 129 | } |
111 | 130 | ||
@@ -116,7 +135,10 @@ void luaS_clearcache (global_State *g) { | |||
116 | void luaS_init (lua_State *L) { | 135 | void luaS_init (lua_State *L) { |
117 | global_State *g = G(L); | 136 | global_State *g = G(L); |
118 | int i, j; | 137 | int i, j; |
119 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ | 138 | stringtable *tb = &G(L)->strt; |
139 | tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*); | ||
140 | tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */ | ||
141 | tb->size = MINSTRTABSIZE; | ||
120 | /* pre-create memory-error message */ | 142 | /* pre-create memory-error message */ |
121 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); | 143 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); |
122 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ | 144 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ |
@@ -145,7 +167,7 @@ static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { | |||
145 | 167 | ||
146 | 168 | ||
147 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { | 169 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { |
148 | TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed); | 170 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); |
149 | ts->u.lnglen = l; | 171 | ts->u.lnglen = l; |
150 | return ts; | 172 | return ts; |
151 | } | 173 | } |
@@ -161,34 +183,46 @@ void luaS_remove (lua_State *L, TString *ts) { | |||
161 | } | 183 | } |
162 | 184 | ||
163 | 185 | ||
186 | static void growstrtab (lua_State *L, stringtable *tb) { | ||
187 | if (unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ | ||
188 | luaC_fullgc(L, 1); /* try to free some... */ | ||
189 | if (tb->nuse == MAX_INT) /* still too many? */ | ||
190 | luaM_error(L); /* cannot even create a message... */ | ||
191 | } | ||
192 | if (tb->size <= MAXSTRTB / 2) /* can grow string table? */ | ||
193 | luaS_resize(L, tb->size * 2); | ||
194 | } | ||
195 | |||
196 | |||
164 | /* | 197 | /* |
165 | ** checks whether short string exists and reuses it or creates a new one | 198 | ** Checks whether short string exists and reuses it or creates a new one. |
166 | */ | 199 | */ |
167 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { | 200 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { |
168 | TString *ts; | 201 | TString *ts; |
169 | global_State *g = G(L); | 202 | global_State *g = G(L); |
170 | unsigned int h = luaS_hash(str, l, g->seed); | 203 | stringtable *tb = &g->strt; |
171 | TString **list = &g->strt.hash[lmod(h, g->strt.size)]; | 204 | unsigned int h = luaS_hash(str, l, g->seed, 1); |
205 | TString **list = &tb->hash[lmod(h, tb->size)]; | ||
172 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ | 206 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ |
173 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { | 207 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { |
174 | if (l == ts->shrlen && | 208 | if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { |
175 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | ||
176 | /* found! */ | 209 | /* found! */ |
177 | if (isdead(g, ts)) /* dead (but not collected yet)? */ | 210 | if (isdead(g, ts)) /* dead (but not collected yet)? */ |
178 | changewhite(ts); /* resurrect it */ | 211 | changewhite(ts); /* resurrect it */ |
179 | return ts; | 212 | return ts; |
180 | } | 213 | } |
181 | } | 214 | } |
182 | if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) { | 215 | /* else must create a new string */ |
183 | luaS_resize(L, g->strt.size * 2); | 216 | if (tb->nuse >= tb->size) { /* need to grow string table? */ |
184 | list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ | 217 | growstrtab(L, tb); |
218 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ | ||
185 | } | 219 | } |
186 | ts = createstrobj(L, l, LUA_TSHRSTR, h); | 220 | ts = createstrobj(L, l, LUA_VSHRSTR, h); |
187 | memcpy(getstr(ts), str, l * sizeof(char)); | 221 | memcpy(getstr(ts), str, l * sizeof(char)); |
188 | ts->shrlen = cast_byte(l); | 222 | ts->shrlen = cast_byte(l); |
189 | ts->u.hnext = *list; | 223 | ts->u.hnext = *list; |
190 | *list = ts; | 224 | *list = ts; |
191 | g->strt.nuse++; | 225 | tb->nuse++; |
192 | return ts; | 226 | return ts; |
193 | } | 227 | } |
194 | 228 | ||
@@ -201,7 +235,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
201 | return internshrstr(L, str, l); | 235 | return internshrstr(L, str, l); |
202 | else { | 236 | else { |
203 | TString *ts; | 237 | TString *ts; |
204 | if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char)) | 238 | if (unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) |
205 | luaM_toobig(L); | 239 | luaM_toobig(L); |
206 | ts = luaS_createlngstrobj(L, l); | 240 | ts = luaS_createlngstrobj(L, l); |
207 | memcpy(getstr(ts), str, l * sizeof(char)); | 241 | memcpy(getstr(ts), str, l * sizeof(char)); |
@@ -233,16 +267,19 @@ TString *luaS_new (lua_State *L, const char *str) { | |||
233 | } | 267 | } |
234 | 268 | ||
235 | 269 | ||
236 | Udata *luaS_newudata (lua_State *L, size_t s) { | 270 | Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) { |
237 | Udata *u; | 271 | Udata *u; |
272 | int i; | ||
238 | GCObject *o; | 273 | GCObject *o; |
239 | if (s > MAX_SIZE - sizeof(Udata)) | 274 | if (unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) |
240 | luaM_toobig(L); | 275 | luaM_toobig(L); |
241 | o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s)); | 276 | o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s)); |
242 | u = gco2u(o); | 277 | u = gco2u(o); |
243 | u->len = s; | 278 | u->len = s; |
279 | u->nuvalue = nuvalue; | ||
244 | u->metatable = NULL; | 280 | u->metatable = NULL; |
245 | setuservalue(L, u, luaO_nilobject); | 281 | for (i = 0; i < nuvalue; i++) |
282 | setnilvalue(&u->uv[i].uv); | ||
246 | return u; | 283 | return u; |
247 | } | 284 | } |
248 | 285 | ||
diff --git a/src/lua-5.3/lstring.h b/src/lua/lstring.h index d612abd..a413a9d 100644 --- a/src/lua-5.3/lstring.h +++ b/src/lua/lstring.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lstring.h $ |
3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -12,10 +12,18 @@ | |||
12 | #include "lstate.h" | 12 | #include "lstate.h" |
13 | 13 | ||
14 | 14 | ||
15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) | 15 | /* |
16 | ** Memory-allocation error message must be preallocated (it cannot | ||
17 | ** be created after memory is exhausted) | ||
18 | */ | ||
19 | #define MEMERRMSG "not enough memory" | ||
20 | |||
16 | 21 | ||
17 | #define sizeludata(l) (sizeof(union UUdata) + (l)) | 22 | /* |
18 | #define sizeudata(u) sizeludata((u)->len) | 23 | ** Size of a TString: Size of the header plus space for the string |
24 | ** itself (including final '\0'). | ||
25 | */ | ||
26 | #define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) | ||
19 | 27 | ||
20 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ | 28 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
21 | (sizeof(s)/sizeof(char))-1)) | 29 | (sizeof(s)/sizeof(char))-1)) |
@@ -24,23 +32,24 @@ | |||
24 | /* | 32 | /* |
25 | ** test whether a string is a reserved word | 33 | ** test whether a string is a reserved word |
26 | */ | 34 | */ |
27 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) | 35 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) |
28 | 36 | ||
29 | 37 | ||
30 | /* | 38 | /* |
31 | ** equality for short strings, which are always internalized | 39 | ** equality for short strings, which are always internalized |
32 | */ | 40 | */ |
33 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) | 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) |
34 | 42 | ||
35 | 43 | ||
36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, |
45 | unsigned int seed, size_t step); | ||
37 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); | 46 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); |
38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); | 47 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); |
39 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 48 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
40 | LUAI_FUNC void luaS_clearcache (global_State *g); | 49 | LUAI_FUNC void luaS_clearcache (global_State *g); |
41 | LUAI_FUNC void luaS_init (lua_State *L); | 50 | LUAI_FUNC void luaS_init (lua_State *L); |
42 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); | 51 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); |
43 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); | 52 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); |
44 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | 53 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); |
45 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); | 54 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); |
46 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); | 55 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); |
diff --git a/src/lua-5.3/lstrlib.c b/src/lua/lstrlib.c index b4bed7e..2ba8bde 100644 --- a/src/lua-5.3/lstrlib.c +++ b/src/lua/lstrlib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstrlib.c,v 1.254.1.1 2017/04/19 17:29:57 roberto Exp $ | 2 | ** $Id: lstrlib.c $ |
3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,6 +14,7 @@ | |||
14 | #include <float.h> | 14 | #include <float.h> |
15 | #include <limits.h> | 15 | #include <limits.h> |
16 | #include <locale.h> | 16 | #include <locale.h> |
17 | #include <math.h> | ||
17 | #include <stddef.h> | 18 | #include <stddef.h> |
18 | #include <stdio.h> | 19 | #include <stdio.h> |
19 | #include <stdlib.h> | 20 | #include <stdlib.h> |
@@ -59,23 +60,50 @@ static int str_len (lua_State *L) { | |||
59 | } | 60 | } |
60 | 61 | ||
61 | 62 | ||
62 | /* translate a relative string position: negative means back from end */ | 63 | /* |
63 | static lua_Integer posrelat (lua_Integer pos, size_t len) { | 64 | ** translate a relative initial string position |
64 | if (pos >= 0) return pos; | 65 | ** (negative means back from end): clip result to [1, inf). |
65 | else if (0u - (size_t)pos > len) return 0; | 66 | ** The length of any string in Lua must fit in a lua_Integer, |
66 | else return (lua_Integer)len + pos + 1; | 67 | ** so there are no overflows in the casts. |
68 | ** The inverted comparison avoids a possible overflow | ||
69 | ** computing '-pos'. | ||
70 | */ | ||
71 | static size_t posrelatI (lua_Integer pos, size_t len) { | ||
72 | if (pos > 0) | ||
73 | return (size_t)pos; | ||
74 | else if (pos == 0) | ||
75 | return 1; | ||
76 | else if (pos < -(lua_Integer)len) /* inverted comparison */ | ||
77 | return 1; /* clip to 1 */ | ||
78 | else return len + (size_t)pos + 1; | ||
79 | } | ||
80 | |||
81 | |||
82 | /* | ||
83 | ** Gets an optional ending string position from argument 'arg', | ||
84 | ** with default value 'def'. | ||
85 | ** Negative means back from end: clip result to [0, len] | ||
86 | */ | ||
87 | static size_t getendpos (lua_State *L, int arg, lua_Integer def, | ||
88 | size_t len) { | ||
89 | lua_Integer pos = luaL_optinteger(L, arg, def); | ||
90 | if (pos > (lua_Integer)len) | ||
91 | return len; | ||
92 | else if (pos >= 0) | ||
93 | return (size_t)pos; | ||
94 | else if (pos < -(lua_Integer)len) | ||
95 | return 0; | ||
96 | else return len + (size_t)pos + 1; | ||
67 | } | 97 | } |
68 | 98 | ||
69 | 99 | ||
70 | static int str_sub (lua_State *L) { | 100 | static int str_sub (lua_State *L) { |
71 | size_t l; | 101 | size_t l; |
72 | const char *s = luaL_checklstring(L, 1, &l); | 102 | const char *s = luaL_checklstring(L, 1, &l); |
73 | lua_Integer start = posrelat(luaL_checkinteger(L, 2), l); | 103 | size_t start = posrelatI(luaL_checkinteger(L, 2), l); |
74 | lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l); | 104 | size_t end = getendpos(L, 3, -1, l); |
75 | if (start < 1) start = 1; | ||
76 | if (end > (lua_Integer)l) end = l; | ||
77 | if (start <= end) | 105 | if (start <= end) |
78 | lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1); | 106 | lua_pushlstring(L, s + start - 1, (end - start) + 1); |
79 | else lua_pushliteral(L, ""); | 107 | else lua_pushliteral(L, ""); |
80 | return 1; | 108 | return 1; |
81 | } | 109 | } |
@@ -148,13 +176,12 @@ static int str_rep (lua_State *L) { | |||
148 | static int str_byte (lua_State *L) { | 176 | static int str_byte (lua_State *L) { |
149 | size_t l; | 177 | size_t l; |
150 | const char *s = luaL_checklstring(L, 1, &l); | 178 | const char *s = luaL_checklstring(L, 1, &l); |
151 | lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l); | 179 | lua_Integer pi = luaL_optinteger(L, 2, 1); |
152 | lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l); | 180 | size_t posi = posrelatI(pi, l); |
181 | size_t pose = getendpos(L, 3, pi, l); | ||
153 | int n, i; | 182 | int n, i; |
154 | if (posi < 1) posi = 1; | ||
155 | if (pose > (lua_Integer)l) pose = l; | ||
156 | if (posi > pose) return 0; /* empty interval; return no values */ | 183 | if (posi > pose) return 0; /* empty interval; return no values */ |
157 | if (pose - posi >= INT_MAX) /* arithmetic overflow? */ | 184 | if (pose - posi >= (size_t)INT_MAX) /* arithmetic overflow? */ |
158 | return luaL_error(L, "string slice too long"); | 185 | return luaL_error(L, "string slice too long"); |
159 | n = (int)(pose - posi) + 1; | 186 | n = (int)(pose - posi) + 1; |
160 | luaL_checkstack(L, n, "string slice too long"); | 187 | luaL_checkstack(L, n, "string slice too long"); |
@@ -170,8 +197,8 @@ static int str_char (lua_State *L) { | |||
170 | luaL_Buffer b; | 197 | luaL_Buffer b; |
171 | char *p = luaL_buffinitsize(L, &b, n); | 198 | char *p = luaL_buffinitsize(L, &b, n); |
172 | for (i=1; i<=n; i++) { | 199 | for (i=1; i<=n; i++) { |
173 | lua_Integer c = luaL_checkinteger(L, i); | 200 | lua_Unsigned c = (lua_Unsigned)luaL_checkinteger(L, i); |
174 | luaL_argcheck(L, uchar(c) == c, i, "value out of range"); | 201 | luaL_argcheck(L, c <= (lua_Unsigned)UCHAR_MAX, i, "value out of range"); |
175 | p[i - 1] = uchar(c); | 202 | p[i - 1] = uchar(c); |
176 | } | 203 | } |
177 | luaL_pushresultsize(&b, n); | 204 | luaL_pushresultsize(&b, n); |
@@ -179,22 +206,38 @@ static int str_char (lua_State *L) { | |||
179 | } | 206 | } |
180 | 207 | ||
181 | 208 | ||
182 | static int writer (lua_State *L, const void *b, size_t size, void *B) { | 209 | /* |
183 | (void)L; | 210 | ** Buffer to store the result of 'string.dump'. It must be initialized |
184 | luaL_addlstring((luaL_Buffer *) B, (const char *)b, size); | 211 | ** after the call to 'lua_dump', to ensure that the function is on the |
212 | ** top of the stack when 'lua_dump' is called. ('luaL_buffinit' might | ||
213 | ** push stuff.) | ||
214 | */ | ||
215 | struct str_Writer { | ||
216 | int init; /* true iff buffer has been initialized */ | ||
217 | luaL_Buffer B; | ||
218 | }; | ||
219 | |||
220 | |||
221 | static int writer (lua_State *L, const void *b, size_t size, void *ud) { | ||
222 | struct str_Writer *state = (struct str_Writer *)ud; | ||
223 | if (!state->init) { | ||
224 | state->init = 1; | ||
225 | luaL_buffinit(L, &state->B); | ||
226 | } | ||
227 | luaL_addlstring(&state->B, (const char *)b, size); | ||
185 | return 0; | 228 | return 0; |
186 | } | 229 | } |
187 | 230 | ||
188 | 231 | ||
189 | static int str_dump (lua_State *L) { | 232 | static int str_dump (lua_State *L) { |
190 | luaL_Buffer b; | 233 | struct str_Writer state; |
191 | int strip = lua_toboolean(L, 2); | 234 | int strip = lua_toboolean(L, 2); |
192 | luaL_checktype(L, 1, LUA_TFUNCTION); | 235 | luaL_checktype(L, 1, LUA_TFUNCTION); |
193 | lua_settop(L, 1); | 236 | lua_settop(L, 1); /* ensure function is on the top of the stack */ |
194 | luaL_buffinit(L,&b); | 237 | state.init = 0; |
195 | if (lua_dump(L, writer, &b, strip) != 0) | 238 | if (lua_dump(L, writer, &state, strip) != 0) |
196 | return luaL_error(L, "unable to dump given function"); | 239 | return luaL_error(L, "unable to dump given function"); |
197 | luaL_pushresult(&b); | 240 | luaL_pushresult(&state.B); |
198 | return 1; | 241 | return 1; |
199 | } | 242 | } |
200 | 243 | ||
@@ -202,6 +245,105 @@ static int str_dump (lua_State *L) { | |||
202 | 245 | ||
203 | /* | 246 | /* |
204 | ** {====================================================== | 247 | ** {====================================================== |
248 | ** METAMETHODS | ||
249 | ** ======================================================= | ||
250 | */ | ||
251 | |||
252 | #if defined(LUA_NOCVTS2N) /* { */ | ||
253 | |||
254 | /* no coercion from strings to numbers */ | ||
255 | |||
256 | static const luaL_Reg stringmetamethods[] = { | ||
257 | {"__index", NULL}, /* placeholder */ | ||
258 | {NULL, NULL} | ||
259 | }; | ||
260 | |||
261 | #else /* }{ */ | ||
262 | |||
263 | static int tonum (lua_State *L, int arg) { | ||
264 | if (lua_type(L, arg) == LUA_TNUMBER) { /* already a number? */ | ||
265 | lua_pushvalue(L, arg); | ||
266 | return 1; | ||
267 | } | ||
268 | else { /* check whether it is a numerical string */ | ||
269 | size_t len; | ||
270 | const char *s = lua_tolstring(L, arg, &len); | ||
271 | return (s != NULL && lua_stringtonumber(L, s) == len + 1); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | |||
276 | static void trymt (lua_State *L, const char *mtname) { | ||
277 | lua_settop(L, 2); /* back to the original arguments */ | ||
278 | if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname)) | ||
279 | luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, | ||
280 | luaL_typename(L, -2), luaL_typename(L, -1)); | ||
281 | lua_insert(L, -3); /* put metamethod before arguments */ | ||
282 | lua_call(L, 2, 1); /* call metamethod */ | ||
283 | } | ||
284 | |||
285 | |||
286 | static int arith (lua_State *L, int op, const char *mtname) { | ||
287 | if (tonum(L, 1) && tonum(L, 2)) | ||
288 | lua_arith(L, op); /* result will be on the top */ | ||
289 | else | ||
290 | trymt(L, mtname); | ||
291 | return 1; | ||
292 | } | ||
293 | |||
294 | |||
295 | static int arith_add (lua_State *L) { | ||
296 | return arith(L, LUA_OPADD, "__add"); | ||
297 | } | ||
298 | |||
299 | static int arith_sub (lua_State *L) { | ||
300 | return arith(L, LUA_OPSUB, "__sub"); | ||
301 | } | ||
302 | |||
303 | static int arith_mul (lua_State *L) { | ||
304 | return arith(L, LUA_OPMUL, "__mul"); | ||
305 | } | ||
306 | |||
307 | static int arith_mod (lua_State *L) { | ||
308 | return arith(L, LUA_OPMOD, "__mod"); | ||
309 | } | ||
310 | |||
311 | static int arith_pow (lua_State *L) { | ||
312 | return arith(L, LUA_OPPOW, "__pow"); | ||
313 | } | ||
314 | |||
315 | static int arith_div (lua_State *L) { | ||
316 | return arith(L, LUA_OPDIV, "__div"); | ||
317 | } | ||
318 | |||
319 | static int arith_idiv (lua_State *L) { | ||
320 | return arith(L, LUA_OPIDIV, "__idiv"); | ||
321 | } | ||
322 | |||
323 | static int arith_unm (lua_State *L) { | ||
324 | return arith(L, LUA_OPUNM, "__unm"); | ||
325 | } | ||
326 | |||
327 | |||
328 | static const luaL_Reg stringmetamethods[] = { | ||
329 | {"__add", arith_add}, | ||
330 | {"__sub", arith_sub}, | ||
331 | {"__mul", arith_mul}, | ||
332 | {"__mod", arith_mod}, | ||
333 | {"__pow", arith_pow}, | ||
334 | {"__div", arith_div}, | ||
335 | {"__idiv", arith_idiv}, | ||
336 | {"__unm", arith_unm}, | ||
337 | {"__index", NULL}, /* placeholder */ | ||
338 | {NULL, NULL} | ||
339 | }; | ||
340 | |||
341 | #endif /* } */ | ||
342 | |||
343 | /* }====================================================== */ | ||
344 | |||
345 | /* | ||
346 | ** {====================================================== | ||
205 | ** PATTERN MATCHING | 347 | ** PATTERN MATCHING |
206 | ** ======================================================= | 348 | ** ======================================================= |
207 | */ | 349 | */ |
@@ -547,25 +689,46 @@ static const char *lmemfind (const char *s1, size_t l1, | |||
547 | } | 689 | } |
548 | 690 | ||
549 | 691 | ||
550 | static void push_onecapture (MatchState *ms, int i, const char *s, | 692 | /* |
551 | const char *e) { | 693 | ** get information about the i-th capture. If there are no captures |
694 | ** and 'i==0', return information about the whole match, which | ||
695 | ** is the range 's'..'e'. If the capture is a string, return | ||
696 | ** its length and put its address in '*cap'. If it is an integer | ||
697 | ** (a position), push it on the stack and return CAP_POSITION. | ||
698 | */ | ||
699 | static size_t get_onecapture (MatchState *ms, int i, const char *s, | ||
700 | const char *e, const char **cap) { | ||
552 | if (i >= ms->level) { | 701 | if (i >= ms->level) { |
553 | if (i == 0) /* ms->level == 0, too */ | 702 | if (i != 0) |
554 | lua_pushlstring(ms->L, s, e - s); /* add whole match */ | ||
555 | else | ||
556 | luaL_error(ms->L, "invalid capture index %%%d", i + 1); | 703 | luaL_error(ms->L, "invalid capture index %%%d", i + 1); |
704 | *cap = s; | ||
705 | return e - s; | ||
557 | } | 706 | } |
558 | else { | 707 | else { |
559 | ptrdiff_t l = ms->capture[i].len; | 708 | ptrdiff_t capl = ms->capture[i].len; |
560 | if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); | 709 | *cap = ms->capture[i].init; |
561 | if (l == CAP_POSITION) | 710 | if (capl == CAP_UNFINISHED) |
711 | luaL_error(ms->L, "unfinished capture"); | ||
712 | else if (capl == CAP_POSITION) | ||
562 | lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); | 713 | lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); |
563 | else | 714 | return capl; |
564 | lua_pushlstring(ms->L, ms->capture[i].init, l); | ||
565 | } | 715 | } |
566 | } | 716 | } |
567 | 717 | ||
568 | 718 | ||
719 | /* | ||
720 | ** Push the i-th capture on the stack. | ||
721 | */ | ||
722 | static void push_onecapture (MatchState *ms, int i, const char *s, | ||
723 | const char *e) { | ||
724 | const char *cap; | ||
725 | ptrdiff_t l = get_onecapture(ms, i, s, e, &cap); | ||
726 | if (l != CAP_POSITION) | ||
727 | lua_pushlstring(ms->L, cap, l); | ||
728 | /* else position was already pushed */ | ||
729 | } | ||
730 | |||
731 | |||
569 | static int push_captures (MatchState *ms, const char *s, const char *e) { | 732 | static int push_captures (MatchState *ms, const char *s, const char *e) { |
570 | int i; | 733 | int i; |
571 | int nlevels = (ms->level == 0 && s) ? 1 : ms->level; | 734 | int nlevels = (ms->level == 0 && s) ? 1 : ms->level; |
@@ -608,16 +771,15 @@ static int str_find_aux (lua_State *L, int find) { | |||
608 | size_t ls, lp; | 771 | size_t ls, lp; |
609 | const char *s = luaL_checklstring(L, 1, &ls); | 772 | const char *s = luaL_checklstring(L, 1, &ls); |
610 | const char *p = luaL_checklstring(L, 2, &lp); | 773 | const char *p = luaL_checklstring(L, 2, &lp); |
611 | lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls); | 774 | size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; |
612 | if (init < 1) init = 1; | 775 | if (init > ls) { /* start after string's end? */ |
613 | else if (init > (lua_Integer)ls + 1) { /* start after string's end? */ | 776 | luaL_pushfail(L); /* cannot find anything */ |
614 | lua_pushnil(L); /* cannot find anything */ | ||
615 | return 1; | 777 | return 1; |
616 | } | 778 | } |
617 | /* explicit request or no special characters? */ | 779 | /* explicit request or no special characters? */ |
618 | if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { | 780 | if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { |
619 | /* do a plain search */ | 781 | /* do a plain search */ |
620 | const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp); | 782 | const char *s2 = lmemfind(s + init, ls - init, p, lp); |
621 | if (s2) { | 783 | if (s2) { |
622 | lua_pushinteger(L, (s2 - s) + 1); | 784 | lua_pushinteger(L, (s2 - s) + 1); |
623 | lua_pushinteger(L, (s2 - s) + lp); | 785 | lua_pushinteger(L, (s2 - s) + lp); |
@@ -626,7 +788,7 @@ static int str_find_aux (lua_State *L, int find) { | |||
626 | } | 788 | } |
627 | else { | 789 | else { |
628 | MatchState ms; | 790 | MatchState ms; |
629 | const char *s1 = s + init - 1; | 791 | const char *s1 = s + init; |
630 | int anchor = (*p == '^'); | 792 | int anchor = (*p == '^'); |
631 | if (anchor) { | 793 | if (anchor) { |
632 | p++; lp--; /* skip anchor character */ | 794 | p++; lp--; /* skip anchor character */ |
@@ -646,7 +808,7 @@ static int str_find_aux (lua_State *L, int find) { | |||
646 | } | 808 | } |
647 | } while (s1++ < ms.src_end && !anchor); | 809 | } while (s1++ < ms.src_end && !anchor); |
648 | } | 810 | } |
649 | lua_pushnil(L); /* not found */ | 811 | luaL_pushfail(L); /* not found */ |
650 | return 1; | 812 | return 1; |
651 | } | 813 | } |
652 | 814 | ||
@@ -690,11 +852,14 @@ static int gmatch (lua_State *L) { | |||
690 | size_t ls, lp; | 852 | size_t ls, lp; |
691 | const char *s = luaL_checklstring(L, 1, &ls); | 853 | const char *s = luaL_checklstring(L, 1, &ls); |
692 | const char *p = luaL_checklstring(L, 2, &lp); | 854 | const char *p = luaL_checklstring(L, 2, &lp); |
855 | size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; | ||
693 | GMatchState *gm; | 856 | GMatchState *gm; |
694 | lua_settop(L, 2); /* keep them on closure to avoid being collected */ | 857 | lua_settop(L, 2); /* keep strings on closure to avoid being collected */ |
695 | gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState)); | 858 | gm = (GMatchState *)lua_newuserdatauv(L, sizeof(GMatchState), 0); |
859 | if (init > ls) /* start after string's end? */ | ||
860 | init = ls + 1; /* avoid overflows in 's + init' */ | ||
696 | prepstate(&gm->ms, L, s, ls, p, lp); | 861 | prepstate(&gm->ms, L, s, ls, p, lp); |
697 | gm->src = s; gm->p = p; gm->lastmatch = NULL; | 862 | gm->src = s + init; gm->p = p; gm->lastmatch = NULL; |
698 | lua_pushcclosure(L, gmatch_aux, 3); | 863 | lua_pushcclosure(L, gmatch_aux, 3); |
699 | return 1; | 864 | return 1; |
700 | } | 865 | } |
@@ -702,60 +867,72 @@ static int gmatch (lua_State *L) { | |||
702 | 867 | ||
703 | static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, | 868 | static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, |
704 | const char *e) { | 869 | const char *e) { |
705 | size_t l, i; | 870 | size_t l; |
706 | lua_State *L = ms->L; | 871 | lua_State *L = ms->L; |
707 | const char *news = lua_tolstring(L, 3, &l); | 872 | const char *news = lua_tolstring(L, 3, &l); |
708 | for (i = 0; i < l; i++) { | 873 | const char *p; |
709 | if (news[i] != L_ESC) | 874 | while ((p = (char *)memchr(news, L_ESC, l)) != NULL) { |
710 | luaL_addchar(b, news[i]); | 875 | luaL_addlstring(b, news, p - news); |
711 | else { | 876 | p++; /* skip ESC */ |
712 | i++; /* skip ESC */ | 877 | if (*p == L_ESC) /* '%%' */ |
713 | if (!isdigit(uchar(news[i]))) { | 878 | luaL_addchar(b, *p); |
714 | if (news[i] != L_ESC) | 879 | else if (*p == '0') /* '%0' */ |
715 | luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); | 880 | luaL_addlstring(b, s, e - s); |
716 | luaL_addchar(b, news[i]); | 881 | else if (isdigit(uchar(*p))) { /* '%n' */ |
717 | } | 882 | const char *cap; |
718 | else if (news[i] == '0') | 883 | ptrdiff_t resl = get_onecapture(ms, *p - '1', s, e, &cap); |
719 | luaL_addlstring(b, s, e - s); | 884 | if (resl == CAP_POSITION) |
720 | else { | 885 | luaL_addvalue(b); /* add position to accumulated result */ |
721 | push_onecapture(ms, news[i] - '1', s, e); | 886 | else |
722 | luaL_tolstring(L, -1, NULL); /* if number, convert it to string */ | 887 | luaL_addlstring(b, cap, resl); |
723 | lua_remove(L, -2); /* remove original value */ | ||
724 | luaL_addvalue(b); /* add capture to accumulated result */ | ||
725 | } | ||
726 | } | 888 | } |
889 | else | ||
890 | luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); | ||
891 | l -= p + 1 - news; | ||
892 | news = p + 1; | ||
727 | } | 893 | } |
894 | luaL_addlstring(b, news, l); | ||
728 | } | 895 | } |
729 | 896 | ||
730 | 897 | ||
731 | static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, | 898 | /* |
732 | const char *e, int tr) { | 899 | ** Add the replacement value to the string buffer 'b'. |
900 | ** Return true if the original string was changed. (Function calls and | ||
901 | ** table indexing resulting in nil or false do not change the subject.) | ||
902 | */ | ||
903 | static int add_value (MatchState *ms, luaL_Buffer *b, const char *s, | ||
904 | const char *e, int tr) { | ||
733 | lua_State *L = ms->L; | 905 | lua_State *L = ms->L; |
734 | switch (tr) { | 906 | switch (tr) { |
735 | case LUA_TFUNCTION: { | 907 | case LUA_TFUNCTION: { /* call the function */ |
736 | int n; | 908 | int n; |
737 | lua_pushvalue(L, 3); | 909 | lua_pushvalue(L, 3); /* push the function */ |
738 | n = push_captures(ms, s, e); | 910 | n = push_captures(ms, s, e); /* all captures as arguments */ |
739 | lua_call(L, n, 1); | 911 | lua_call(L, n, 1); /* call it */ |
740 | break; | 912 | break; |
741 | } | 913 | } |
742 | case LUA_TTABLE: { | 914 | case LUA_TTABLE: { /* index the table */ |
743 | push_onecapture(ms, 0, s, e); | 915 | push_onecapture(ms, 0, s, e); /* first capture is the index */ |
744 | lua_gettable(L, 3); | 916 | lua_gettable(L, 3); |
745 | break; | 917 | break; |
746 | } | 918 | } |
747 | default: { /* LUA_TNUMBER or LUA_TSTRING */ | 919 | default: { /* LUA_TNUMBER or LUA_TSTRING */ |
748 | add_s(ms, b, s, e); | 920 | add_s(ms, b, s, e); /* add value to the buffer */ |
749 | return; | 921 | return 1; /* something changed */ |
750 | } | 922 | } |
751 | } | 923 | } |
752 | if (!lua_toboolean(L, -1)) { /* nil or false? */ | 924 | if (!lua_toboolean(L, -1)) { /* nil or false? */ |
753 | lua_pop(L, 1); | 925 | lua_pop(L, 1); /* remove value */ |
754 | lua_pushlstring(L, s, e - s); /* keep original text */ | 926 | luaL_addlstring(b, s, e - s); /* keep original text */ |
927 | return 0; /* no changes */ | ||
755 | } | 928 | } |
756 | else if (!lua_isstring(L, -1)) | 929 | else if (!lua_isstring(L, -1)) |
757 | luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); | 930 | return luaL_error(L, "invalid replacement value (a %s)", |
758 | luaL_addvalue(b); /* add result to accumulator */ | 931 | luaL_typename(L, -1)); |
932 | else { | ||
933 | luaL_addvalue(b); /* add result to accumulator */ | ||
934 | return 1; /* something changed */ | ||
935 | } | ||
759 | } | 936 | } |
760 | 937 | ||
761 | 938 | ||
@@ -768,11 +945,12 @@ static int str_gsub (lua_State *L) { | |||
768 | lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ | 945 | lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ |
769 | int anchor = (*p == '^'); | 946 | int anchor = (*p == '^'); |
770 | lua_Integer n = 0; /* replacement count */ | 947 | lua_Integer n = 0; /* replacement count */ |
948 | int changed = 0; /* change flag */ | ||
771 | MatchState ms; | 949 | MatchState ms; |
772 | luaL_Buffer b; | 950 | luaL_Buffer b; |
773 | luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || | 951 | luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || |
774 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, | 952 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, |
775 | "string/function/table expected"); | 953 | "string/function/table"); |
776 | luaL_buffinit(L, &b); | 954 | luaL_buffinit(L, &b); |
777 | if (anchor) { | 955 | if (anchor) { |
778 | p++; lp--; /* skip anchor character */ | 956 | p++; lp--; /* skip anchor character */ |
@@ -783,7 +961,7 @@ static int str_gsub (lua_State *L) { | |||
783 | reprepstate(&ms); /* (re)prepare state for new match */ | 961 | reprepstate(&ms); /* (re)prepare state for new match */ |
784 | if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ | 962 | if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ |
785 | n++; | 963 | n++; |
786 | add_value(&ms, &b, src, e, tr); /* add replacement to buffer */ | 964 | changed = add_value(&ms, &b, src, e, tr) | changed; |
787 | src = lastmatch = e; | 965 | src = lastmatch = e; |
788 | } | 966 | } |
789 | else if (src < ms.src_end) /* otherwise, skip one character */ | 967 | else if (src < ms.src_end) /* otherwise, skip one character */ |
@@ -791,8 +969,12 @@ static int str_gsub (lua_State *L) { | |||
791 | else break; /* end of subject */ | 969 | else break; /* end of subject */ |
792 | if (anchor) break; | 970 | if (anchor) break; |
793 | } | 971 | } |
794 | luaL_addlstring(&b, src, ms.src_end-src); | 972 | if (!changed) /* no changes? */ |
795 | luaL_pushresult(&b); | 973 | lua_pushvalue(L, 1); /* return original string */ |
974 | else { /* something changed */ | ||
975 | luaL_addlstring(&b, src, ms.src_end-src); | ||
976 | luaL_pushresult(&b); /* create and return new string */ | ||
977 | } | ||
796 | lua_pushinteger(L, n); /* number of substitutions */ | 978 | lua_pushinteger(L, n); /* number of substitutions */ |
797 | return 2; | 979 | return 2; |
798 | } | 980 | } |
@@ -813,8 +995,6 @@ static int str_gsub (lua_State *L) { | |||
813 | ** Hexadecimal floating-point formatter | 995 | ** Hexadecimal floating-point formatter |
814 | */ | 996 | */ |
815 | 997 | ||
816 | #include <math.h> | ||
817 | |||
818 | #define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) | 998 | #define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) |
819 | 999 | ||
820 | 1000 | ||
@@ -824,7 +1004,7 @@ static int str_gsub (lua_State *L) { | |||
824 | ** to nibble boundaries by making what is left after that first digit a | 1004 | ** to nibble boundaries by making what is left after that first digit a |
825 | ** multiple of 4. | 1005 | ** multiple of 4. |
826 | */ | 1006 | */ |
827 | #define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1) | 1007 | #define L_NBFD ((l_floatatt(MANT_DIG) - 1)%4 + 1) |
828 | 1008 | ||
829 | 1009 | ||
830 | /* | 1010 | /* |
@@ -851,7 +1031,7 @@ static int num2straux (char *buff, int sz, lua_Number x) { | |||
851 | lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ | 1031 | lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ |
852 | int n = 0; /* character count */ | 1032 | int n = 0; /* character count */ |
853 | if (m < 0) { /* is number negative? */ | 1033 | if (m < 0) { /* is number negative? */ |
854 | buff[n++] = '-'; /* add signal */ | 1034 | buff[n++] = '-'; /* add sign */ |
855 | m = -m; /* make it positive */ | 1035 | m = -m; /* make it positive */ |
856 | } | 1036 | } |
857 | buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ | 1037 | buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ |
@@ -887,17 +1067,30 @@ static int lua_number2strx (lua_State *L, char *buff, int sz, | |||
887 | 1067 | ||
888 | 1068 | ||
889 | /* | 1069 | /* |
890 | ** Maximum size of each formatted item. This maximum size is produced | 1070 | ** Maximum size for items formatted with '%f'. This size is produced |
891 | ** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', | 1071 | ** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', |
892 | ** and '\0') + number of decimal digits to represent maxfloat (which | 1072 | ** and '\0') + number of decimal digits to represent maxfloat (which |
893 | ** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra | 1073 | ** is maximum exponent + 1). (99+3+1, adding some extra, 110) |
894 | ** expenses", such as locale-dependent stuff) | ||
895 | */ | 1074 | */ |
896 | #define MAX_ITEM (120 + l_mathlim(MAX_10_EXP)) | 1075 | #define MAX_ITEMF (110 + l_floatatt(MAX_10_EXP)) |
1076 | |||
1077 | |||
1078 | /* | ||
1079 | ** All formats except '%f' do not need that large limit. The other | ||
1080 | ** float formats use exponents, so that they fit in the 99 limit for | ||
1081 | ** significant digits; 's' for large strings and 'q' add items directly | ||
1082 | ** to the buffer; all integer formats also fit in the 99 limit. The | ||
1083 | ** worst case are floats: they may need 99 significant digits, plus | ||
1084 | ** '0x', '-', '.', 'e+XXXX', and '\0'. Adding some extra, 120. | ||
1085 | */ | ||
1086 | #define MAX_ITEM 120 | ||
897 | 1087 | ||
898 | 1088 | ||
899 | /* valid flags in a format specification */ | 1089 | /* valid flags in a format specification */ |
900 | #define FLAGS "-+ #0" | 1090 | #if !defined(L_FMTFLAGS) |
1091 | #define L_FMTFLAGS "-+ #0" | ||
1092 | #endif | ||
1093 | |||
901 | 1094 | ||
902 | /* | 1095 | /* |
903 | ** maximum size of each format specification (such as "%-099.99d") | 1096 | ** maximum size of each format specification (such as "%-099.99d") |
@@ -929,14 +1122,32 @@ static void addquoted (luaL_Buffer *b, const char *s, size_t len) { | |||
929 | 1122 | ||
930 | 1123 | ||
931 | /* | 1124 | /* |
932 | ** Ensures the 'buff' string uses a dot as the radix character. | 1125 | ** Serialize a floating-point number in such a way that it can be |
1126 | ** scanned back by Lua. Use hexadecimal format for "common" numbers | ||
1127 | ** (to preserve precision); inf, -inf, and NaN are handled separately. | ||
1128 | ** (NaN cannot be expressed as a numeral, so we write '(0/0)' for it.) | ||
933 | */ | 1129 | */ |
934 | static void checkdp (char *buff, int nb) { | 1130 | static int quotefloat (lua_State *L, char *buff, lua_Number n) { |
935 | if (memchr(buff, '.', nb) == NULL) { /* no dot? */ | 1131 | const char *s; /* for the fixed representations */ |
936 | char point = lua_getlocaledecpoint(); /* try locale point */ | 1132 | if (n == (lua_Number)HUGE_VAL) /* inf? */ |
937 | char *ppoint = (char *)memchr(buff, point, nb); | 1133 | s = "1e9999"; |
938 | if (ppoint) *ppoint = '.'; /* change it to a dot */ | 1134 | else if (n == -(lua_Number)HUGE_VAL) /* -inf? */ |
1135 | s = "-1e9999"; | ||
1136 | else if (n != n) /* NaN? */ | ||
1137 | s = "(0/0)"; | ||
1138 | else { /* format number as hexadecimal */ | ||
1139 | int nb = lua_number2strx(L, buff, MAX_ITEM, | ||
1140 | "%" LUA_NUMBER_FRMLEN "a", n); | ||
1141 | /* ensures that 'buff' string uses a dot as the radix character */ | ||
1142 | if (memchr(buff, '.', nb) == NULL) { /* no dot? */ | ||
1143 | char point = lua_getlocaledecpoint(); /* try locale point */ | ||
1144 | char *ppoint = (char *)memchr(buff, point, nb); | ||
1145 | if (ppoint) *ppoint = '.'; /* change it to a dot */ | ||
1146 | } | ||
1147 | return nb; | ||
939 | } | 1148 | } |
1149 | /* for the fixed representations */ | ||
1150 | return l_sprintf(buff, MAX_ITEM, "%s", s); | ||
940 | } | 1151 | } |
941 | 1152 | ||
942 | 1153 | ||
@@ -951,15 +1162,12 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { | |||
951 | case LUA_TNUMBER: { | 1162 | case LUA_TNUMBER: { |
952 | char *buff = luaL_prepbuffsize(b, MAX_ITEM); | 1163 | char *buff = luaL_prepbuffsize(b, MAX_ITEM); |
953 | int nb; | 1164 | int nb; |
954 | if (!lua_isinteger(L, arg)) { /* float? */ | 1165 | if (!lua_isinteger(L, arg)) /* float? */ |
955 | lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */ | 1166 | nb = quotefloat(L, buff, lua_tonumber(L, arg)); |
956 | nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n); | ||
957 | checkdp(buff, nb); /* ensure it uses a dot */ | ||
958 | } | ||
959 | else { /* integers */ | 1167 | else { /* integers */ |
960 | lua_Integer n = lua_tointeger(L, arg); | 1168 | lua_Integer n = lua_tointeger(L, arg); |
961 | const char *format = (n == LUA_MININTEGER) /* corner case? */ | 1169 | const char *format = (n == LUA_MININTEGER) /* corner case? */ |
962 | ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */ | 1170 | ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hex */ |
963 | : LUA_INTEGER_FMT; /* else use default format */ | 1171 | : LUA_INTEGER_FMT; /* else use default format */ |
964 | nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); | 1172 | nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); |
965 | } | 1173 | } |
@@ -980,8 +1188,8 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { | |||
980 | 1188 | ||
981 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { | 1189 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { |
982 | const char *p = strfrmt; | 1190 | const char *p = strfrmt; |
983 | while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ | 1191 | while (*p != '\0' && strchr(L_FMTFLAGS, *p) != NULL) p++; /* skip flags */ |
984 | if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) | 1192 | if ((size_t)(p - strfrmt) >= sizeof(L_FMTFLAGS)/sizeof(char)) |
985 | luaL_error(L, "invalid format (repeated flags)"); | 1193 | luaL_error(L, "invalid format (repeated flags)"); |
986 | if (isdigit(uchar(*p))) p++; /* skip width */ | 1194 | if (isdigit(uchar(*p))) p++; /* skip width */ |
987 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | 1195 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ |
@@ -1028,36 +1236,51 @@ static int str_format (lua_State *L) { | |||
1028 | luaL_addchar(&b, *strfrmt++); /* %% */ | 1236 | luaL_addchar(&b, *strfrmt++); /* %% */ |
1029 | else { /* format item */ | 1237 | else { /* format item */ |
1030 | char form[MAX_FORMAT]; /* to store the format ('%...') */ | 1238 | char form[MAX_FORMAT]; /* to store the format ('%...') */ |
1031 | char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ | 1239 | int maxitem = MAX_ITEM; |
1240 | char *buff = luaL_prepbuffsize(&b, maxitem); /* to put formatted item */ | ||
1032 | int nb = 0; /* number of bytes in added item */ | 1241 | int nb = 0; /* number of bytes in added item */ |
1033 | if (++arg > top) | 1242 | if (++arg > top) |
1034 | luaL_argerror(L, arg, "no value"); | 1243 | return luaL_argerror(L, arg, "no value"); |
1035 | strfrmt = scanformat(L, strfrmt, form); | 1244 | strfrmt = scanformat(L, strfrmt, form); |
1036 | switch (*strfrmt++) { | 1245 | switch (*strfrmt++) { |
1037 | case 'c': { | 1246 | case 'c': { |
1038 | nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); | 1247 | nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); |
1039 | break; | 1248 | break; |
1040 | } | 1249 | } |
1041 | case 'd': case 'i': | 1250 | case 'd': case 'i': |
1042 | case 'o': case 'u': case 'x': case 'X': { | 1251 | case 'o': case 'u': case 'x': case 'X': { |
1043 | lua_Integer n = luaL_checkinteger(L, arg); | 1252 | lua_Integer n = luaL_checkinteger(L, arg); |
1044 | addlenmod(form, LUA_INTEGER_FRMLEN); | 1253 | addlenmod(form, LUA_INTEGER_FRMLEN); |
1045 | nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n); | 1254 | nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); |
1046 | break; | 1255 | break; |
1047 | } | 1256 | } |
1048 | case 'a': case 'A': | 1257 | case 'a': case 'A': |
1049 | addlenmod(form, LUA_NUMBER_FRMLEN); | 1258 | addlenmod(form, LUA_NUMBER_FRMLEN); |
1050 | nb = lua_number2strx(L, buff, MAX_ITEM, form, | 1259 | nb = lua_number2strx(L, buff, maxitem, form, |
1051 | luaL_checknumber(L, arg)); | 1260 | luaL_checknumber(L, arg)); |
1052 | break; | 1261 | break; |
1053 | case 'e': case 'E': case 'f': | 1262 | case 'f': |
1054 | case 'g': case 'G': { | 1263 | maxitem = MAX_ITEMF; /* extra space for '%f' */ |
1264 | buff = luaL_prepbuffsize(&b, maxitem); | ||
1265 | /* FALLTHROUGH */ | ||
1266 | case 'e': case 'E': case 'g': case 'G': { | ||
1055 | lua_Number n = luaL_checknumber(L, arg); | 1267 | lua_Number n = luaL_checknumber(L, arg); |
1056 | addlenmod(form, LUA_NUMBER_FRMLEN); | 1268 | addlenmod(form, LUA_NUMBER_FRMLEN); |
1057 | nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); | 1269 | nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); |
1270 | break; | ||
1271 | } | ||
1272 | case 'p': { | ||
1273 | const void *p = lua_topointer(L, arg); | ||
1274 | if (p == NULL) { /* avoid calling 'printf' with argument NULL */ | ||
1275 | p = "(null)"; /* result */ | ||
1276 | form[strlen(form) - 1] = 's'; /* format it as a string */ | ||
1277 | } | ||
1278 | nb = l_sprintf(buff, maxitem, form, p); | ||
1058 | break; | 1279 | break; |
1059 | } | 1280 | } |
1060 | case 'q': { | 1281 | case 'q': { |
1282 | if (form[2] != '\0') /* modifiers? */ | ||
1283 | return luaL_error(L, "specifier '%%q' cannot have modifiers"); | ||
1061 | addliteral(L, &b, arg); | 1284 | addliteral(L, &b, arg); |
1062 | break; | 1285 | break; |
1063 | } | 1286 | } |
@@ -1073,18 +1296,17 @@ static int str_format (lua_State *L) { | |||
1073 | luaL_addvalue(&b); /* keep entire string */ | 1296 | luaL_addvalue(&b); /* keep entire string */ |
1074 | } | 1297 | } |
1075 | else { /* format the string into 'buff' */ | 1298 | else { /* format the string into 'buff' */ |
1076 | nb = l_sprintf(buff, MAX_ITEM, form, s); | 1299 | nb = l_sprintf(buff, maxitem, form, s); |
1077 | lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ | 1300 | lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ |
1078 | } | 1301 | } |
1079 | } | 1302 | } |
1080 | break; | 1303 | break; |
1081 | } | 1304 | } |
1082 | default: { /* also treat cases 'pnLlh' */ | 1305 | default: { /* also treat cases 'pnLlh' */ |
1083 | return luaL_error(L, "invalid option '%%%c' to 'format'", | 1306 | return luaL_error(L, "invalid conversion '%s' to 'format'", form); |
1084 | *(strfrmt - 1)); | ||
1085 | } | 1307 | } |
1086 | } | 1308 | } |
1087 | lua_assert(nb < MAX_ITEM); | 1309 | lua_assert(nb < maxitem); |
1088 | luaL_addsize(&b, nb); | 1310 | luaL_addsize(&b, nb); |
1089 | } | 1311 | } |
1090 | } | 1312 | } |
@@ -1422,17 +1644,12 @@ static int str_packsize (lua_State *L) { | |||
1422 | while (*fmt != '\0') { | 1644 | while (*fmt != '\0') { |
1423 | int size, ntoalign; | 1645 | int size, ntoalign; |
1424 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); | 1646 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); |
1647 | luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, | ||
1648 | "variable-length format"); | ||
1425 | size += ntoalign; /* total space used by option */ | 1649 | size += ntoalign; /* total space used by option */ |
1426 | luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, | 1650 | luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, |
1427 | "format result too large"); | 1651 | "format result too large"); |
1428 | totalsize += size; | 1652 | totalsize += size; |
1429 | switch (opt) { | ||
1430 | case Kstring: /* strings with length count */ | ||
1431 | case Kzstr: /* zero-terminated string */ | ||
1432 | luaL_argerror(L, 1, "variable-length format"); | ||
1433 | /* call never return, but to avoid warnings: *//* FALLTHROUGH */ | ||
1434 | default: break; | ||
1435 | } | ||
1436 | } | 1653 | } |
1437 | lua_pushinteger(L, (lua_Integer)totalsize); | 1654 | lua_pushinteger(L, (lua_Integer)totalsize); |
1438 | return 1; | 1655 | return 1; |
@@ -1478,15 +1695,15 @@ static int str_unpack (lua_State *L) { | |||
1478 | const char *fmt = luaL_checkstring(L, 1); | 1695 | const char *fmt = luaL_checkstring(L, 1); |
1479 | size_t ld; | 1696 | size_t ld; |
1480 | const char *data = luaL_checklstring(L, 2, &ld); | 1697 | const char *data = luaL_checklstring(L, 2, &ld); |
1481 | size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; | 1698 | size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1; |
1482 | int n = 0; /* number of results */ | 1699 | int n = 0; /* number of results */ |
1483 | luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); | 1700 | luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); |
1484 | initheader(L, &h); | 1701 | initheader(L, &h); |
1485 | while (*fmt != '\0') { | 1702 | while (*fmt != '\0') { |
1486 | int size, ntoalign; | 1703 | int size, ntoalign; |
1487 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); | 1704 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); |
1488 | if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) | 1705 | luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, |
1489 | luaL_argerror(L, 2, "data string too short"); | 1706 | "data string too short"); |
1490 | pos += ntoalign; /* skip alignment */ | 1707 | pos += ntoalign; /* skip alignment */ |
1491 | /* stack space for item + next position */ | 1708 | /* stack space for item + next position */ |
1492 | luaL_checkstack(L, 2, "too many results"); | 1709 | luaL_checkstack(L, 2, "too many results"); |
@@ -1515,13 +1732,15 @@ static int str_unpack (lua_State *L) { | |||
1515 | } | 1732 | } |
1516 | case Kstring: { | 1733 | case Kstring: { |
1517 | size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); | 1734 | size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); |
1518 | luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); | 1735 | luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); |
1519 | lua_pushlstring(L, data + pos + size, len); | 1736 | lua_pushlstring(L, data + pos + size, len); |
1520 | pos += len; /* skip string */ | 1737 | pos += len; /* skip string */ |
1521 | break; | 1738 | break; |
1522 | } | 1739 | } |
1523 | case Kzstr: { | 1740 | case Kzstr: { |
1524 | size_t len = (int)strlen(data + pos); | 1741 | size_t len = (int)strlen(data + pos); |
1742 | luaL_argcheck(L, pos + len < ld, 2, | ||
1743 | "unfinished string for format 'z'"); | ||
1525 | lua_pushlstring(L, data + pos, len); | 1744 | lua_pushlstring(L, data + pos, len); |
1526 | pos += len + 1; /* skip string plus final '\0' */ | 1745 | pos += len + 1; /* skip string plus final '\0' */ |
1527 | break; | 1746 | break; |
@@ -1562,7 +1781,9 @@ static const luaL_Reg strlib[] = { | |||
1562 | 1781 | ||
1563 | 1782 | ||
1564 | static void createmetatable (lua_State *L) { | 1783 | static void createmetatable (lua_State *L) { |
1565 | lua_createtable(L, 0, 1); /* table to be metatable for strings */ | 1784 | /* table to be metatable for strings */ |
1785 | luaL_newlibtable(L, stringmetamethods); | ||
1786 | luaL_setfuncs(L, stringmetamethods, 0); | ||
1566 | lua_pushliteral(L, ""); /* dummy string */ | 1787 | lua_pushliteral(L, ""); /* dummy string */ |
1567 | lua_pushvalue(L, -2); /* copy table */ | 1788 | lua_pushvalue(L, -2); /* copy table */ |
1568 | lua_setmetatable(L, -2); /* set table as metatable for strings */ | 1789 | lua_setmetatable(L, -2); /* set table as metatable for strings */ |
diff --git a/src/lua/ltable.c b/src/lua/ltable.c new file mode 100644 index 0000000..d7eb69a --- /dev/null +++ b/src/lua/ltable.c | |||
@@ -0,0 +1,924 @@ | |||
1 | /* | ||
2 | ** $Id: ltable.c $ | ||
3 | ** Lua tables (hash) | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define ltable_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | /* | ||
14 | ** Implementation of tables (aka arrays, objects, or hash tables). | ||
15 | ** Tables keep its elements in two parts: an array part and a hash part. | ||
16 | ** Non-negative integer keys are all candidates to be kept in the array | ||
17 | ** part. The actual size of the array is the largest 'n' such that | ||
18 | ** more than half the slots between 1 and n are in use. | ||
19 | ** Hash uses a mix of chained scatter table with Brent's variation. | ||
20 | ** A main invariant of these tables is that, if an element is not | ||
21 | ** in its main position (i.e. the 'original' position that its hash gives | ||
22 | ** to it), then the colliding element is in its own main position. | ||
23 | ** Hence even when the load factor reaches 100%, performance remains good. | ||
24 | */ | ||
25 | |||
26 | #include <math.h> | ||
27 | #include <limits.h> | ||
28 | |||
29 | #include "lua.h" | ||
30 | |||
31 | #include "ldebug.h" | ||
32 | #include "ldo.h" | ||
33 | #include "lgc.h" | ||
34 | #include "lmem.h" | ||
35 | #include "lobject.h" | ||
36 | #include "lstate.h" | ||
37 | #include "lstring.h" | ||
38 | #include "ltable.h" | ||
39 | #include "lvm.h" | ||
40 | |||
41 | |||
42 | /* | ||
43 | ** MAXABITS is the largest integer such that MAXASIZE fits in an | ||
44 | ** unsigned int. | ||
45 | */ | ||
46 | #define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) | ||
47 | |||
48 | |||
49 | /* | ||
50 | ** MAXASIZE is the maximum size of the array part. It is the minimum | ||
51 | ** between 2^MAXABITS and the maximum size that, measured in bytes, | ||
52 | ** fits in a 'size_t'. | ||
53 | */ | ||
54 | #define MAXASIZE luaM_limitN(1u << MAXABITS, TValue) | ||
55 | |||
56 | /* | ||
57 | ** MAXHBITS is the largest integer such that 2^MAXHBITS fits in a | ||
58 | ** signed int. | ||
59 | */ | ||
60 | #define MAXHBITS (MAXABITS - 1) | ||
61 | |||
62 | |||
63 | /* | ||
64 | ** MAXHSIZE is the maximum size of the hash part. It is the minimum | ||
65 | ** between 2^MAXHBITS and the maximum size such that, measured in bytes, | ||
66 | ** it fits in a 'size_t'. | ||
67 | */ | ||
68 | #define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node) | ||
69 | |||
70 | |||
71 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) | ||
72 | |||
73 | #define hashstr(t,str) hashpow2(t, (str)->hash) | ||
74 | #define hashboolean(t,p) hashpow2(t, p) | ||
75 | #define hashint(t,i) hashpow2(t, i) | ||
76 | |||
77 | |||
78 | /* | ||
79 | ** for some types, it is better to avoid modulus by power of 2, as | ||
80 | ** they tend to have many 2 factors. | ||
81 | */ | ||
82 | #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) | ||
83 | |||
84 | |||
85 | #define hashpointer(t,p) hashmod(t, point2uint(p)) | ||
86 | |||
87 | |||
88 | #define dummynode (&dummynode_) | ||
89 | |||
90 | static const Node dummynode_ = { | ||
91 | {{NULL}, LUA_VEMPTY, /* value's value and type */ | ||
92 | LUA_VNIL, 0, {NULL}} /* key type, next, and key value */ | ||
93 | }; | ||
94 | |||
95 | |||
96 | static const TValue absentkey = {ABSTKEYCONSTANT}; | ||
97 | |||
98 | |||
99 | |||
100 | /* | ||
101 | ** Hash for floating-point numbers. | ||
102 | ** The main computation should be just | ||
103 | ** n = frexp(n, &i); return (n * INT_MAX) + i | ||
104 | ** but there are some numerical subtleties. | ||
105 | ** In a two-complement representation, INT_MAX does not has an exact | ||
106 | ** representation as a float, but INT_MIN does; because the absolute | ||
107 | ** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the | ||
108 | ** absolute value of the product 'frexp * -INT_MIN' is smaller or equal | ||
109 | ** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when | ||
110 | ** adding 'i'; the use of '~u' (instead of '-u') avoids problems with | ||
111 | ** INT_MIN. | ||
112 | */ | ||
113 | #if !defined(l_hashfloat) | ||
114 | static int l_hashfloat (lua_Number n) { | ||
115 | int i; | ||
116 | lua_Integer ni; | ||
117 | n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN); | ||
118 | if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */ | ||
119 | lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL)); | ||
120 | return 0; | ||
121 | } | ||
122 | else { /* normal case */ | ||
123 | unsigned int u = cast_uint(i) + cast_uint(ni); | ||
124 | return cast_int(u <= cast_uint(INT_MAX) ? u : ~u); | ||
125 | } | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | |||
130 | /* | ||
131 | ** returns the 'main' position of an element in a table (that is, | ||
132 | ** the index of its hash value). The key comes broken (tag in 'ktt' | ||
133 | ** and value in 'vkl') so that we can call it on keys inserted into | ||
134 | ** nodes. | ||
135 | */ | ||
136 | static Node *mainposition (const Table *t, int ktt, const Value *kvl) { | ||
137 | switch (withvariant(ktt)) { | ||
138 | case LUA_VNUMINT: | ||
139 | return hashint(t, ivalueraw(*kvl)); | ||
140 | case LUA_VNUMFLT: | ||
141 | return hashmod(t, l_hashfloat(fltvalueraw(*kvl))); | ||
142 | case LUA_VSHRSTR: | ||
143 | return hashstr(t, tsvalueraw(*kvl)); | ||
144 | case LUA_VLNGSTR: | ||
145 | return hashpow2(t, luaS_hashlongstr(tsvalueraw(*kvl))); | ||
146 | case LUA_VFALSE: | ||
147 | return hashboolean(t, 0); | ||
148 | case LUA_VTRUE: | ||
149 | return hashboolean(t, 1); | ||
150 | case LUA_VLIGHTUSERDATA: | ||
151 | return hashpointer(t, pvalueraw(*kvl)); | ||
152 | case LUA_VLCF: | ||
153 | return hashpointer(t, fvalueraw(*kvl)); | ||
154 | default: | ||
155 | return hashpointer(t, gcvalueraw(*kvl)); | ||
156 | } | ||
157 | } | ||
158 | |||
159 | |||
160 | /* | ||
161 | ** Returns the main position of an element given as a 'TValue' | ||
162 | */ | ||
163 | static Node *mainpositionTV (const Table *t, const TValue *key) { | ||
164 | return mainposition(t, rawtt(key), valraw(key)); | ||
165 | } | ||
166 | |||
167 | |||
168 | /* | ||
169 | ** Check whether key 'k1' is equal to the key in node 'n2'. | ||
170 | ** This equality is raw, so there are no metamethods. Floats | ||
171 | ** with integer values have been normalized, so integers cannot | ||
172 | ** be equal to floats. It is assumed that 'eqshrstr' is simply | ||
173 | ** pointer equality, so that short strings are handled in the | ||
174 | ** default case. | ||
175 | */ | ||
176 | static int equalkey (const TValue *k1, const Node *n2) { | ||
177 | if (rawtt(k1) != keytt(n2)) /* not the same variants? */ | ||
178 | return 0; /* cannot be same key */ | ||
179 | switch (ttypetag(k1)) { | ||
180 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: | ||
181 | return 1; | ||
182 | case LUA_VNUMINT: | ||
183 | return (ivalue(k1) == keyival(n2)); | ||
184 | case LUA_VNUMFLT: | ||
185 | return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2))); | ||
186 | case LUA_VLIGHTUSERDATA: | ||
187 | return pvalue(k1) == pvalueraw(keyval(n2)); | ||
188 | case LUA_VLCF: | ||
189 | return fvalue(k1) == fvalueraw(keyval(n2)); | ||
190 | case LUA_VLNGSTR: | ||
191 | return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); | ||
192 | default: | ||
193 | return gcvalue(k1) == gcvalueraw(keyval(n2)); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | |||
198 | /* | ||
199 | ** True if value of 'alimit' is equal to the real size of the array | ||
200 | ** part of table 't'. (Otherwise, the array part must be larger than | ||
201 | ** 'alimit'.) | ||
202 | */ | ||
203 | #define limitequalsasize(t) (isrealasize(t) || ispow2((t)->alimit)) | ||
204 | |||
205 | |||
206 | /* | ||
207 | ** Returns the real size of the 'array' array | ||
208 | */ | ||
209 | LUAI_FUNC unsigned int luaH_realasize (const Table *t) { | ||
210 | if (limitequalsasize(t)) | ||
211 | return t->alimit; /* this is the size */ | ||
212 | else { | ||
213 | unsigned int size = t->alimit; | ||
214 | /* compute the smallest power of 2 not smaller than 'n' */ | ||
215 | size |= (size >> 1); | ||
216 | size |= (size >> 2); | ||
217 | size |= (size >> 4); | ||
218 | size |= (size >> 8); | ||
219 | size |= (size >> 16); | ||
220 | #if (UINT_MAX >> 30) > 3 | ||
221 | size |= (size >> 32); /* unsigned int has more than 32 bits */ | ||
222 | #endif | ||
223 | size++; | ||
224 | lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size); | ||
225 | return size; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | |||
230 | /* | ||
231 | ** Check whether real size of the array is a power of 2. | ||
232 | ** (If it is not, 'alimit' cannot be changed to any other value | ||
233 | ** without changing the real size.) | ||
234 | */ | ||
235 | static int ispow2realasize (const Table *t) { | ||
236 | return (!isrealasize(t) || ispow2(t->alimit)); | ||
237 | } | ||
238 | |||
239 | |||
240 | static unsigned int setlimittosize (Table *t) { | ||
241 | t->alimit = luaH_realasize(t); | ||
242 | setrealasize(t); | ||
243 | return t->alimit; | ||
244 | } | ||
245 | |||
246 | |||
247 | #define limitasasize(t) check_exp(isrealasize(t), t->alimit) | ||
248 | |||
249 | |||
250 | |||
251 | /* | ||
252 | ** "Generic" get version. (Not that generic: not valid for integers, | ||
253 | ** which may be in array part, nor for floats with integral values.) | ||
254 | */ | ||
255 | static const TValue *getgeneric (Table *t, const TValue *key) { | ||
256 | Node *n = mainpositionTV(t, key); | ||
257 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
258 | if (equalkey(key, n)) | ||
259 | return gval(n); /* that's it */ | ||
260 | else { | ||
261 | int nx = gnext(n); | ||
262 | if (nx == 0) | ||
263 | return &absentkey; /* not found */ | ||
264 | n += nx; | ||
265 | } | ||
266 | } | ||
267 | } | ||
268 | |||
269 | |||
270 | /* | ||
271 | ** returns the index for 'k' if 'k' is an appropriate key to live in | ||
272 | ** the array part of a table, 0 otherwise. | ||
273 | */ | ||
274 | static unsigned int arrayindex (lua_Integer k) { | ||
275 | if (l_castS2U(k) - 1u < MAXASIZE) /* 'k' in [1, MAXASIZE]? */ | ||
276 | return cast_uint(k); /* 'key' is an appropriate array index */ | ||
277 | else | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | |||
282 | /* | ||
283 | ** returns the index of a 'key' for table traversals. First goes all | ||
284 | ** elements in the array part, then elements in the hash part. The | ||
285 | ** beginning of a traversal is signaled by 0. | ||
286 | */ | ||
287 | static unsigned int findindex (lua_State *L, Table *t, TValue *key, | ||
288 | unsigned int asize) { | ||
289 | unsigned int i; | ||
290 | if (ttisnil(key)) return 0; /* first iteration */ | ||
291 | i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0; | ||
292 | if (i - 1u < asize) /* is 'key' inside array part? */ | ||
293 | return i; /* yes; that's the index */ | ||
294 | else { | ||
295 | const TValue *n = getgeneric(t, key); | ||
296 | if (unlikely(isabstkey(n))) | ||
297 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ | ||
298 | i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ | ||
299 | /* hash elements are numbered after array ones */ | ||
300 | return (i + 1) + asize; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | |||
305 | int luaH_next (lua_State *L, Table *t, StkId key) { | ||
306 | unsigned int asize = luaH_realasize(t); | ||
307 | unsigned int i = findindex(L, t, s2v(key), asize); /* find original key */ | ||
308 | for (; i < asize; i++) { /* try first array part */ | ||
309 | if (!isempty(&t->array[i])) { /* a non-empty entry? */ | ||
310 | setivalue(s2v(key), i + 1); | ||
311 | setobj2s(L, key + 1, &t->array[i]); | ||
312 | return 1; | ||
313 | } | ||
314 | } | ||
315 | for (i -= asize; cast_int(i) < sizenode(t); i++) { /* hash part */ | ||
316 | if (!isempty(gval(gnode(t, i)))) { /* a non-empty entry? */ | ||
317 | Node *n = gnode(t, i); | ||
318 | getnodekey(L, s2v(key), n); | ||
319 | setobj2s(L, key + 1, gval(n)); | ||
320 | return 1; | ||
321 | } | ||
322 | } | ||
323 | return 0; /* no more elements */ | ||
324 | } | ||
325 | |||
326 | |||
327 | static void freehash (lua_State *L, Table *t) { | ||
328 | if (!isdummy(t)) | ||
329 | luaM_freearray(L, t->node, cast_sizet(sizenode(t))); | ||
330 | } | ||
331 | |||
332 | |||
333 | /* | ||
334 | ** {============================================================= | ||
335 | ** Rehash | ||
336 | ** ============================================================== | ||
337 | */ | ||
338 | |||
339 | /* | ||
340 | ** Compute the optimal size for the array part of table 't'. 'nums' is a | ||
341 | ** "count array" where 'nums[i]' is the number of integers in the table | ||
342 | ** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of | ||
343 | ** integer keys in the table and leaves with the number of keys that | ||
344 | ** will go to the array part; return the optimal size. (The condition | ||
345 | ** 'twotoi > 0' in the for loop stops the loop if 'twotoi' overflows.) | ||
346 | */ | ||
347 | static unsigned int computesizes (unsigned int nums[], unsigned int *pna) { | ||
348 | int i; | ||
349 | unsigned int twotoi; /* 2^i (candidate for optimal size) */ | ||
350 | unsigned int a = 0; /* number of elements smaller than 2^i */ | ||
351 | unsigned int na = 0; /* number of elements to go to array part */ | ||
352 | unsigned int optimal = 0; /* optimal size for array part */ | ||
353 | /* loop while keys can fill more than half of total size */ | ||
354 | for (i = 0, twotoi = 1; | ||
355 | twotoi > 0 && *pna > twotoi / 2; | ||
356 | i++, twotoi *= 2) { | ||
357 | a += nums[i]; | ||
358 | if (a > twotoi/2) { /* more than half elements present? */ | ||
359 | optimal = twotoi; /* optimal size (till now) */ | ||
360 | na = a; /* all elements up to 'optimal' will go to array part */ | ||
361 | } | ||
362 | } | ||
363 | lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal); | ||
364 | *pna = na; | ||
365 | return optimal; | ||
366 | } | ||
367 | |||
368 | |||
369 | static int countint (lua_Integer key, unsigned int *nums) { | ||
370 | unsigned int k = arrayindex(key); | ||
371 | if (k != 0) { /* is 'key' an appropriate array index? */ | ||
372 | nums[luaO_ceillog2(k)]++; /* count as such */ | ||
373 | return 1; | ||
374 | } | ||
375 | else | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | |||
380 | /* | ||
381 | ** Count keys in array part of table 't': Fill 'nums[i]' with | ||
382 | ** number of keys that will go into corresponding slice and return | ||
383 | ** total number of non-nil keys. | ||
384 | */ | ||
385 | static unsigned int numusearray (const Table *t, unsigned int *nums) { | ||
386 | int lg; | ||
387 | unsigned int ttlg; /* 2^lg */ | ||
388 | unsigned int ause = 0; /* summation of 'nums' */ | ||
389 | unsigned int i = 1; /* count to traverse all array keys */ | ||
390 | unsigned int asize = limitasasize(t); /* real array size */ | ||
391 | /* traverse each slice */ | ||
392 | for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { | ||
393 | unsigned int lc = 0; /* counter */ | ||
394 | unsigned int lim = ttlg; | ||
395 | if (lim > asize) { | ||
396 | lim = asize; /* adjust upper limit */ | ||
397 | if (i > lim) | ||
398 | break; /* no more elements to count */ | ||
399 | } | ||
400 | /* count elements in range (2^(lg - 1), 2^lg] */ | ||
401 | for (; i <= lim; i++) { | ||
402 | if (!isempty(&t->array[i-1])) | ||
403 | lc++; | ||
404 | } | ||
405 | nums[lg] += lc; | ||
406 | ause += lc; | ||
407 | } | ||
408 | return ause; | ||
409 | } | ||
410 | |||
411 | |||
412 | static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) { | ||
413 | int totaluse = 0; /* total number of elements */ | ||
414 | int ause = 0; /* elements added to 'nums' (can go to array part) */ | ||
415 | int i = sizenode(t); | ||
416 | while (i--) { | ||
417 | Node *n = &t->node[i]; | ||
418 | if (!isempty(gval(n))) { | ||
419 | if (keyisinteger(n)) | ||
420 | ause += countint(keyival(n), nums); | ||
421 | totaluse++; | ||
422 | } | ||
423 | } | ||
424 | *pna += ause; | ||
425 | return totaluse; | ||
426 | } | ||
427 | |||
428 | |||
429 | /* | ||
430 | ** Creates an array for the hash part of a table with the given | ||
431 | ** size, or reuses the dummy node if size is zero. | ||
432 | ** The computation for size overflow is in two steps: the first | ||
433 | ** comparison ensures that the shift in the second one does not | ||
434 | ** overflow. | ||
435 | */ | ||
436 | static void setnodevector (lua_State *L, Table *t, unsigned int size) { | ||
437 | if (size == 0) { /* no elements to hash part? */ | ||
438 | t->node = cast(Node *, dummynode); /* use common 'dummynode' */ | ||
439 | t->lsizenode = 0; | ||
440 | t->lastfree = NULL; /* signal that it is using dummy node */ | ||
441 | } | ||
442 | else { | ||
443 | int i; | ||
444 | int lsize = luaO_ceillog2(size); | ||
445 | if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE) | ||
446 | luaG_runerror(L, "table overflow"); | ||
447 | size = twoto(lsize); | ||
448 | t->node = luaM_newvector(L, size, Node); | ||
449 | for (i = 0; i < (int)size; i++) { | ||
450 | Node *n = gnode(t, i); | ||
451 | gnext(n) = 0; | ||
452 | setnilkey(n); | ||
453 | setempty(gval(n)); | ||
454 | } | ||
455 | t->lsizenode = cast_byte(lsize); | ||
456 | t->lastfree = gnode(t, size); /* all positions are free */ | ||
457 | } | ||
458 | } | ||
459 | |||
460 | |||
461 | /* | ||
462 | ** (Re)insert all elements from the hash part of 'ot' into table 't'. | ||
463 | */ | ||
464 | static void reinsert (lua_State *L, Table *ot, Table *t) { | ||
465 | int j; | ||
466 | int size = sizenode(ot); | ||
467 | for (j = 0; j < size; j++) { | ||
468 | Node *old = gnode(ot, j); | ||
469 | if (!isempty(gval(old))) { | ||
470 | /* doesn't need barrier/invalidate cache, as entry was | ||
471 | already present in the table */ | ||
472 | TValue k; | ||
473 | getnodekey(L, &k, old); | ||
474 | setobjt2t(L, luaH_set(L, t, &k), gval(old)); | ||
475 | } | ||
476 | } | ||
477 | } | ||
478 | |||
479 | |||
480 | /* | ||
481 | ** Exchange the hash part of 't1' and 't2'. | ||
482 | */ | ||
483 | static void exchangehashpart (Table *t1, Table *t2) { | ||
484 | lu_byte lsizenode = t1->lsizenode; | ||
485 | Node *node = t1->node; | ||
486 | Node *lastfree = t1->lastfree; | ||
487 | t1->lsizenode = t2->lsizenode; | ||
488 | t1->node = t2->node; | ||
489 | t1->lastfree = t2->lastfree; | ||
490 | t2->lsizenode = lsizenode; | ||
491 | t2->node = node; | ||
492 | t2->lastfree = lastfree; | ||
493 | } | ||
494 | |||
495 | |||
496 | /* | ||
497 | ** Resize table 't' for the new given sizes. Both allocations (for | ||
498 | ** the hash part and for the array part) can fail, which creates some | ||
499 | ** subtleties. If the first allocation, for the hash part, fails, an | ||
500 | ** error is raised and that is it. Otherwise, it copies the elements from | ||
501 | ** the shrinking part of the array (if it is shrinking) into the new | ||
502 | ** hash. Then it reallocates the array part. If that fails, the table | ||
503 | ** is in its original state; the function frees the new hash part and then | ||
504 | ** raises the allocation error. Otherwise, it sets the new hash part | ||
505 | ** into the table, initializes the new part of the array (if any) with | ||
506 | ** nils and reinserts the elements of the old hash back into the new | ||
507 | ** parts of the table. | ||
508 | */ | ||
509 | void luaH_resize (lua_State *L, Table *t, unsigned int newasize, | ||
510 | unsigned int nhsize) { | ||
511 | unsigned int i; | ||
512 | Table newt; /* to keep the new hash part */ | ||
513 | unsigned int oldasize = setlimittosize(t); | ||
514 | TValue *newarray; | ||
515 | /* create new hash part with appropriate size into 'newt' */ | ||
516 | setnodevector(L, &newt, nhsize); | ||
517 | if (newasize < oldasize) { /* will array shrink? */ | ||
518 | t->alimit = newasize; /* pretend array has new size... */ | ||
519 | exchangehashpart(t, &newt); /* and new hash */ | ||
520 | /* re-insert into the new hash the elements from vanishing slice */ | ||
521 | for (i = newasize; i < oldasize; i++) { | ||
522 | if (!isempty(&t->array[i])) | ||
523 | luaH_setint(L, t, i + 1, &t->array[i]); | ||
524 | } | ||
525 | t->alimit = oldasize; /* restore current size... */ | ||
526 | exchangehashpart(t, &newt); /* and hash (in case of errors) */ | ||
527 | } | ||
528 | /* allocate new array */ | ||
529 | newarray = luaM_reallocvector(L, t->array, oldasize, newasize, TValue); | ||
530 | if (unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ | ||
531 | freehash(L, &newt); /* release new hash part */ | ||
532 | luaM_error(L); /* raise error (with array unchanged) */ | ||
533 | } | ||
534 | /* allocation ok; initialize new part of the array */ | ||
535 | exchangehashpart(t, &newt); /* 't' has the new hash ('newt' has the old) */ | ||
536 | t->array = newarray; /* set new array part */ | ||
537 | t->alimit = newasize; | ||
538 | for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ | ||
539 | setempty(&t->array[i]); | ||
540 | /* re-insert elements from old hash part into new parts */ | ||
541 | reinsert(L, &newt, t); /* 'newt' now has the old hash */ | ||
542 | freehash(L, &newt); /* free old hash part */ | ||
543 | } | ||
544 | |||
545 | |||
546 | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { | ||
547 | int nsize = allocsizenode(t); | ||
548 | luaH_resize(L, t, nasize, nsize); | ||
549 | } | ||
550 | |||
551 | /* | ||
552 | ** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i | ||
553 | */ | ||
554 | static void rehash (lua_State *L, Table *t, const TValue *ek) { | ||
555 | unsigned int asize; /* optimal size for array part */ | ||
556 | unsigned int na; /* number of keys in the array part */ | ||
557 | unsigned int nums[MAXABITS + 1]; | ||
558 | int i; | ||
559 | int totaluse; | ||
560 | for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */ | ||
561 | setlimittosize(t); | ||
562 | na = numusearray(t, nums); /* count keys in array part */ | ||
563 | totaluse = na; /* all those keys are integer keys */ | ||
564 | totaluse += numusehash(t, nums, &na); /* count keys in hash part */ | ||
565 | /* count extra key */ | ||
566 | if (ttisinteger(ek)) | ||
567 | na += countint(ivalue(ek), nums); | ||
568 | totaluse++; | ||
569 | /* compute new size for array part */ | ||
570 | asize = computesizes(nums, &na); | ||
571 | /* resize the table to new computed sizes */ | ||
572 | luaH_resize(L, t, asize, totaluse - na); | ||
573 | } | ||
574 | |||
575 | |||
576 | |||
577 | /* | ||
578 | ** }============================================================= | ||
579 | */ | ||
580 | |||
581 | |||
582 | Table *luaH_new (lua_State *L) { | ||
583 | GCObject *o = luaC_newobj(L, LUA_VTABLE, sizeof(Table)); | ||
584 | Table *t = gco2t(o); | ||
585 | t->metatable = NULL; | ||
586 | t->flags = cast_byte(~0); | ||
587 | t->array = NULL; | ||
588 | t->alimit = 0; | ||
589 | setnodevector(L, t, 0); | ||
590 | return t; | ||
591 | } | ||
592 | |||
593 | |||
594 | void luaH_free (lua_State *L, Table *t) { | ||
595 | freehash(L, t); | ||
596 | luaM_freearray(L, t->array, luaH_realasize(t)); | ||
597 | luaM_free(L, t); | ||
598 | } | ||
599 | |||
600 | |||
601 | static Node *getfreepos (Table *t) { | ||
602 | if (!isdummy(t)) { | ||
603 | while (t->lastfree > t->node) { | ||
604 | t->lastfree--; | ||
605 | if (keyisnil(t->lastfree)) | ||
606 | return t->lastfree; | ||
607 | } | ||
608 | } | ||
609 | return NULL; /* could not find a free place */ | ||
610 | } | ||
611 | |||
612 | |||
613 | |||
614 | /* | ||
615 | ** inserts a new key into a hash table; first, check whether key's main | ||
616 | ** position is free. If not, check whether colliding node is in its main | ||
617 | ** position or not: if it is not, move colliding node to an empty place and | ||
618 | ** put new key in its main position; otherwise (colliding node is in its main | ||
619 | ** position), new key goes to an empty position. | ||
620 | */ | ||
621 | TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | ||
622 | Node *mp; | ||
623 | TValue aux; | ||
624 | if (unlikely(ttisnil(key))) | ||
625 | luaG_runerror(L, "table index is nil"); | ||
626 | else if (ttisfloat(key)) { | ||
627 | lua_Number f = fltvalue(key); | ||
628 | lua_Integer k; | ||
629 | if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */ | ||
630 | setivalue(&aux, k); | ||
631 | key = &aux; /* insert it as an integer */ | ||
632 | } | ||
633 | else if (unlikely(luai_numisnan(f))) | ||
634 | luaG_runerror(L, "table index is NaN"); | ||
635 | } | ||
636 | mp = mainpositionTV(t, key); | ||
637 | if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */ | ||
638 | Node *othern; | ||
639 | Node *f = getfreepos(t); /* get a free place */ | ||
640 | if (f == NULL) { /* cannot find a free place? */ | ||
641 | rehash(L, t, key); /* grow table */ | ||
642 | /* whatever called 'newkey' takes care of TM cache */ | ||
643 | return luaH_set(L, t, key); /* insert key into grown table */ | ||
644 | } | ||
645 | lua_assert(!isdummy(t)); | ||
646 | othern = mainposition(t, keytt(mp), &keyval(mp)); | ||
647 | if (othern != mp) { /* is colliding node out of its main position? */ | ||
648 | /* yes; move colliding node into free position */ | ||
649 | while (othern + gnext(othern) != mp) /* find previous */ | ||
650 | othern += gnext(othern); | ||
651 | gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */ | ||
652 | *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | ||
653 | if (gnext(mp) != 0) { | ||
654 | gnext(f) += cast_int(mp - f); /* correct 'next' */ | ||
655 | gnext(mp) = 0; /* now 'mp' is free */ | ||
656 | } | ||
657 | setempty(gval(mp)); | ||
658 | } | ||
659 | else { /* colliding node is in its own main position */ | ||
660 | /* new node will go into free position */ | ||
661 | if (gnext(mp) != 0) | ||
662 | gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */ | ||
663 | else lua_assert(gnext(f) == 0); | ||
664 | gnext(mp) = cast_int(f - mp); | ||
665 | mp = f; | ||
666 | } | ||
667 | } | ||
668 | setnodekey(L, mp, key); | ||
669 | luaC_barrierback(L, obj2gco(t), key); | ||
670 | lua_assert(isempty(gval(mp))); | ||
671 | return gval(mp); | ||
672 | } | ||
673 | |||
674 | |||
675 | /* | ||
676 | ** Search function for integers. If integer is inside 'alimit', get it | ||
677 | ** directly from the array part. Otherwise, if 'alimit' is not equal to | ||
678 | ** the real size of the array, key still can be in the array part. In | ||
679 | ** this case, try to avoid a call to 'luaH_realasize' when key is just | ||
680 | ** one more than the limit (so that it can be incremented without | ||
681 | ** changing the real size of the array). | ||
682 | */ | ||
683 | const TValue *luaH_getint (Table *t, lua_Integer key) { | ||
684 | if (l_castS2U(key) - 1u < t->alimit) /* 'key' in [1, t->alimit]? */ | ||
685 | return &t->array[key - 1]; | ||
686 | else if (!limitequalsasize(t) && /* key still may be in the array part? */ | ||
687 | (l_castS2U(key) == t->alimit + 1 || | ||
688 | l_castS2U(key) - 1u < luaH_realasize(t))) { | ||
689 | t->alimit = cast_uint(key); /* probably '#t' is here now */ | ||
690 | return &t->array[key - 1]; | ||
691 | } | ||
692 | else { | ||
693 | Node *n = hashint(t, key); | ||
694 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
695 | if (keyisinteger(n) && keyival(n) == key) | ||
696 | return gval(n); /* that's it */ | ||
697 | else { | ||
698 | int nx = gnext(n); | ||
699 | if (nx == 0) break; | ||
700 | n += nx; | ||
701 | } | ||
702 | } | ||
703 | return &absentkey; | ||
704 | } | ||
705 | } | ||
706 | |||
707 | |||
708 | /* | ||
709 | ** search function for short strings | ||
710 | */ | ||
711 | const TValue *luaH_getshortstr (Table *t, TString *key) { | ||
712 | Node *n = hashstr(t, key); | ||
713 | lua_assert(key->tt == LUA_VSHRSTR); | ||
714 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
715 | if (keyisshrstr(n) && eqshrstr(keystrval(n), key)) | ||
716 | return gval(n); /* that's it */ | ||
717 | else { | ||
718 | int nx = gnext(n); | ||
719 | if (nx == 0) | ||
720 | return &absentkey; /* not found */ | ||
721 | n += nx; | ||
722 | } | ||
723 | } | ||
724 | } | ||
725 | |||
726 | |||
727 | const TValue *luaH_getstr (Table *t, TString *key) { | ||
728 | if (key->tt == LUA_VSHRSTR) | ||
729 | return luaH_getshortstr(t, key); | ||
730 | else { /* for long strings, use generic case */ | ||
731 | TValue ko; | ||
732 | setsvalue(cast(lua_State *, NULL), &ko, key); | ||
733 | return getgeneric(t, &ko); | ||
734 | } | ||
735 | } | ||
736 | |||
737 | |||
738 | /* | ||
739 | ** main search function | ||
740 | */ | ||
741 | const TValue *luaH_get (Table *t, const TValue *key) { | ||
742 | switch (ttypetag(key)) { | ||
743 | case LUA_VSHRSTR: return luaH_getshortstr(t, tsvalue(key)); | ||
744 | case LUA_VNUMINT: return luaH_getint(t, ivalue(key)); | ||
745 | case LUA_VNIL: return &absentkey; | ||
746 | case LUA_VNUMFLT: { | ||
747 | lua_Integer k; | ||
748 | if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ | ||
749 | return luaH_getint(t, k); /* use specialized version */ | ||
750 | /* else... */ | ||
751 | } /* FALLTHROUGH */ | ||
752 | default: | ||
753 | return getgeneric(t, key); | ||
754 | } | ||
755 | } | ||
756 | |||
757 | |||
758 | /* | ||
759 | ** beware: when using this function you probably need to check a GC | ||
760 | ** barrier and invalidate the TM cache. | ||
761 | */ | ||
762 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { | ||
763 | const TValue *p = luaH_get(t, key); | ||
764 | if (!isabstkey(p)) | ||
765 | return cast(TValue *, p); | ||
766 | else return luaH_newkey(L, t, key); | ||
767 | } | ||
768 | |||
769 | |||
770 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | ||
771 | const TValue *p = luaH_getint(t, key); | ||
772 | TValue *cell; | ||
773 | if (!isabstkey(p)) | ||
774 | cell = cast(TValue *, p); | ||
775 | else { | ||
776 | TValue k; | ||
777 | setivalue(&k, key); | ||
778 | cell = luaH_newkey(L, t, &k); | ||
779 | } | ||
780 | setobj2t(L, cell, value); | ||
781 | } | ||
782 | |||
783 | |||
784 | /* | ||
785 | ** Try to find a boundary in the hash part of table 't'. From the | ||
786 | ** caller, we know that 'j' is zero or present and that 'j + 1' is | ||
787 | ** present. We want to find a larger key that is absent from the | ||
788 | ** table, so that we can do a binary search between the two keys to | ||
789 | ** find a boundary. We keep doubling 'j' until we get an absent index. | ||
790 | ** If the doubling would overflow, we try LUA_MAXINTEGER. If it is | ||
791 | ** absent, we are ready for the binary search. ('j', being max integer, | ||
792 | ** is larger or equal to 'i', but it cannot be equal because it is | ||
793 | ** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a | ||
794 | ** boundary. ('j + 1' cannot be a present integer key because it is | ||
795 | ** not a valid integer in Lua.) | ||
796 | */ | ||
797 | static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { | ||
798 | lua_Unsigned i; | ||
799 | if (j == 0) j++; /* the caller ensures 'j + 1' is present */ | ||
800 | do { | ||
801 | i = j; /* 'i' is a present index */ | ||
802 | if (j <= l_castS2U(LUA_MAXINTEGER) / 2) | ||
803 | j *= 2; | ||
804 | else { | ||
805 | j = LUA_MAXINTEGER; | ||
806 | if (isempty(luaH_getint(t, j))) /* t[j] not present? */ | ||
807 | break; /* 'j' now is an absent index */ | ||
808 | else /* weird case */ | ||
809 | return j; /* well, max integer is a boundary... */ | ||
810 | } | ||
811 | } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */ | ||
812 | /* i < j && t[i] present && t[j] absent */ | ||
813 | while (j - i > 1u) { /* do a binary search between them */ | ||
814 | lua_Unsigned m = (i + j) / 2; | ||
815 | if (isempty(luaH_getint(t, m))) j = m; | ||
816 | else i = m; | ||
817 | } | ||
818 | return i; | ||
819 | } | ||
820 | |||
821 | |||
822 | static unsigned int binsearch (const TValue *array, unsigned int i, | ||
823 | unsigned int j) { | ||
824 | while (j - i > 1u) { /* binary search */ | ||
825 | unsigned int m = (i + j) / 2; | ||
826 | if (isempty(&array[m - 1])) j = m; | ||
827 | else i = m; | ||
828 | } | ||
829 | return i; | ||
830 | } | ||
831 | |||
832 | |||
833 | /* | ||
834 | ** Try to find a boundary in table 't'. (A 'boundary' is an integer index | ||
835 | ** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent | ||
836 | ** and 'maxinteger' if t[maxinteger] is present.) | ||
837 | ** (In the next explanation, we use Lua indices, that is, with base 1. | ||
838 | ** The code itself uses base 0 when indexing the array part of the table.) | ||
839 | ** The code starts with 'limit = t->alimit', a position in the array | ||
840 | ** part that may be a boundary. | ||
841 | ** | ||
842 | ** (1) If 't[limit]' is empty, there must be a boundary before it. | ||
843 | ** As a common case (e.g., after 't[#t]=nil'), check whether 'limit-1' | ||
844 | ** is present. If so, it is a boundary. Otherwise, do a binary search | ||
845 | ** between 0 and limit to find a boundary. In both cases, try to | ||
846 | ** use this boundary as the new 'alimit', as a hint for the next call. | ||
847 | ** | ||
848 | ** (2) If 't[limit]' is not empty and the array has more elements | ||
849 | ** after 'limit', try to find a boundary there. Again, try first | ||
850 | ** the special case (which should be quite frequent) where 'limit+1' | ||
851 | ** is empty, so that 'limit' is a boundary. Otherwise, check the | ||
852 | ** last element of the array part. If it is empty, there must be a | ||
853 | ** boundary between the old limit (present) and the last element | ||
854 | ** (absent), which is found with a binary search. (This boundary always | ||
855 | ** can be a new limit.) | ||
856 | ** | ||
857 | ** (3) The last case is when there are no elements in the array part | ||
858 | ** (limit == 0) or its last element (the new limit) is present. | ||
859 | ** In this case, must check the hash part. If there is no hash part | ||
860 | ** or 'limit+1' is absent, 'limit' is a boundary. Otherwise, call | ||
861 | ** 'hash_search' to find a boundary in the hash part of the table. | ||
862 | ** (In those cases, the boundary is not inside the array part, and | ||
863 | ** therefore cannot be used as a new limit.) | ||
864 | */ | ||
865 | lua_Unsigned luaH_getn (Table *t) { | ||
866 | unsigned int limit = t->alimit; | ||
867 | if (limit > 0 && isempty(&t->array[limit - 1])) { /* (1)? */ | ||
868 | /* there must be a boundary before 'limit' */ | ||
869 | if (limit >= 2 && !isempty(&t->array[limit - 2])) { | ||
870 | /* 'limit - 1' is a boundary; can it be a new limit? */ | ||
871 | if (ispow2realasize(t) && !ispow2(limit - 1)) { | ||
872 | t->alimit = limit - 1; | ||
873 | setnorealasize(t); /* now 'alimit' is not the real size */ | ||
874 | } | ||
875 | return limit - 1; | ||
876 | } | ||
877 | else { /* must search for a boundary in [0, limit] */ | ||
878 | unsigned int boundary = binsearch(t->array, 0, limit); | ||
879 | /* can this boundary represent the real size of the array? */ | ||
880 | if (ispow2realasize(t) && boundary > luaH_realasize(t) / 2) { | ||
881 | t->alimit = boundary; /* use it as the new limit */ | ||
882 | setnorealasize(t); | ||
883 | } | ||
884 | return boundary; | ||
885 | } | ||
886 | } | ||
887 | /* 'limit' is zero or present in table */ | ||
888 | if (!limitequalsasize(t)) { /* (2)? */ | ||
889 | /* 'limit' > 0 and array has more elements after 'limit' */ | ||
890 | if (isempty(&t->array[limit])) /* 'limit + 1' is empty? */ | ||
891 | return limit; /* this is the boundary */ | ||
892 | /* else, try last element in the array */ | ||
893 | limit = luaH_realasize(t); | ||
894 | if (isempty(&t->array[limit - 1])) { /* empty? */ | ||
895 | /* there must be a boundary in the array after old limit, | ||
896 | and it must be a valid new limit */ | ||
897 | unsigned int boundary = binsearch(t->array, t->alimit, limit); | ||
898 | t->alimit = boundary; | ||
899 | return boundary; | ||
900 | } | ||
901 | /* else, new limit is present in the table; check the hash part */ | ||
902 | } | ||
903 | /* (3) 'limit' is the last element and either is zero or present in table */ | ||
904 | lua_assert(limit == luaH_realasize(t) && | ||
905 | (limit == 0 || !isempty(&t->array[limit - 1]))); | ||
906 | if (isdummy(t) || isempty(luaH_getint(t, cast(lua_Integer, limit + 1)))) | ||
907 | return limit; /* 'limit + 1' is absent */ | ||
908 | else /* 'limit + 1' is also present */ | ||
909 | return hash_search(t, limit); | ||
910 | } | ||
911 | |||
912 | |||
913 | |||
914 | #if defined(LUA_DEBUG) | ||
915 | |||
916 | /* export these functions for the test library */ | ||
917 | |||
918 | Node *luaH_mainposition (const Table *t, const TValue *key) { | ||
919 | return mainpositionTV(t, key); | ||
920 | } | ||
921 | |||
922 | int luaH_isdummy (const Table *t) { return isdummy(t); } | ||
923 | |||
924 | #endif | ||
diff --git a/src/lua-5.3/ltable.h b/src/lua/ltable.h index 92db0ac..ebd7f8e 100644 --- a/src/lua-5.3/ltable.h +++ b/src/lua/ltable.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $ | 2 | ** $Id: ltable.h $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -12,18 +12,9 @@ | |||
12 | 12 | ||
13 | #define gnode(t,i) (&(t)->node[i]) | 13 | #define gnode(t,i) (&(t)->node[i]) |
14 | #define gval(n) (&(n)->i_val) | 14 | #define gval(n) (&(n)->i_val) |
15 | #define gnext(n) ((n)->i_key.nk.next) | 15 | #define gnext(n) ((n)->u.next) |
16 | 16 | ||
17 | 17 | ||
18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ | ||
19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) | ||
20 | |||
21 | /* | ||
22 | ** writable version of 'gkey'; allows updates to individual fields, | ||
23 | ** but not to the whole (which has incompatible type) | ||
24 | */ | ||
25 | #define wgkey(n) (&(n)->i_key.nk) | ||
26 | |||
27 | #define invalidateTMcache(t) ((t)->flags = 0) | 18 | #define invalidateTMcache(t) ((t)->flags = 0) |
28 | 19 | ||
29 | 20 | ||
@@ -35,9 +26,8 @@ | |||
35 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) | 26 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) |
36 | 27 | ||
37 | 28 | ||
38 | /* returns the key, given the value of a table entry */ | 29 | /* returns the Node, given the value of a table entry */ |
39 | #define keyfromval(v) \ | 30 | #define nodefromval(v) cast(Node *, (v)) |
40 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) | ||
41 | 31 | ||
42 | 32 | ||
43 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); | 33 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); |
@@ -55,6 +45,7 @@ LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); | |||
55 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); | 45 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); |
56 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); | 46 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); |
57 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); | 47 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); |
48 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); | ||
58 | 49 | ||
59 | 50 | ||
60 | #if defined(LUA_DEBUG) | 51 | #if defined(LUA_DEBUG) |
diff --git a/src/lua-5.3/ltablib.c b/src/lua/ltablib.c index c534957..d344a47 100644 --- a/src/lua-5.3/ltablib.c +++ b/src/lua/ltablib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: ltablib.c $ |
3 | ** Library for Table Manipulation | 3 | ** Library for Table Manipulation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -58,24 +58,6 @@ static void checktab (lua_State *L, int arg, int what) { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | 60 | ||
61 | #if defined(LUA_COMPAT_MAXN) | ||
62 | static int maxn (lua_State *L) { | ||
63 | lua_Number max = 0; | ||
64 | luaL_checktype(L, 1, LUA_TTABLE); | ||
65 | lua_pushnil(L); /* first key */ | ||
66 | while (lua_next(L, 1)) { | ||
67 | lua_pop(L, 1); /* remove value */ | ||
68 | if (lua_type(L, -1) == LUA_TNUMBER) { | ||
69 | lua_Number v = lua_tonumber(L, -1); | ||
70 | if (v > max) max = v; | ||
71 | } | ||
72 | } | ||
73 | lua_pushnumber(L, max); | ||
74 | return 1; | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | |||
79 | static int tinsert (lua_State *L) { | 61 | static int tinsert (lua_State *L) { |
80 | lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ | 62 | lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ |
81 | lua_Integer pos; /* where to insert new element */ | 63 | lua_Integer pos; /* where to insert new element */ |
@@ -87,7 +69,9 @@ static int tinsert (lua_State *L) { | |||
87 | case 3: { | 69 | case 3: { |
88 | lua_Integer i; | 70 | lua_Integer i; |
89 | pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ | 71 | pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ |
90 | luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); | 72 | /* check whether 'pos' is in [1, e] */ |
73 | luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2, | ||
74 | "position out of bounds"); | ||
91 | for (i = e; i > pos; i--) { /* move up elements */ | 75 | for (i = e; i > pos; i--) { /* move up elements */ |
92 | lua_geti(L, 1, i - 1); | 76 | lua_geti(L, 1, i - 1); |
93 | lua_seti(L, 1, i); /* t[i] = t[i - 1] */ | 77 | lua_seti(L, 1, i); /* t[i] = t[i - 1] */ |
@@ -107,14 +91,16 @@ static int tremove (lua_State *L) { | |||
107 | lua_Integer size = aux_getn(L, 1, TAB_RW); | 91 | lua_Integer size = aux_getn(L, 1, TAB_RW); |
108 | lua_Integer pos = luaL_optinteger(L, 2, size); | 92 | lua_Integer pos = luaL_optinteger(L, 2, size); |
109 | if (pos != size) /* validate 'pos' if given */ | 93 | if (pos != size) /* validate 'pos' if given */ |
110 | luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); | 94 | /* check whether 'pos' is in [1, size + 1] */ |
95 | luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 1, | ||
96 | "position out of bounds"); | ||
111 | lua_geti(L, 1, pos); /* result = t[pos] */ | 97 | lua_geti(L, 1, pos); /* result = t[pos] */ |
112 | for ( ; pos < size; pos++) { | 98 | for ( ; pos < size; pos++) { |
113 | lua_geti(L, 1, pos + 1); | 99 | lua_geti(L, 1, pos + 1); |
114 | lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ | 100 | lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ |
115 | } | 101 | } |
116 | lua_pushnil(L); | 102 | lua_pushnil(L); |
117 | lua_seti(L, 1, pos); /* t[pos] = nil */ | 103 | lua_seti(L, 1, pos); /* remove entry t[pos] */ |
118 | return 1; | 104 | return 1; |
119 | } | 105 | } |
120 | 106 | ||
@@ -191,7 +177,7 @@ static int tconcat (lua_State *L) { | |||
191 | ** ======================================================= | 177 | ** ======================================================= |
192 | */ | 178 | */ |
193 | 179 | ||
194 | static int pack (lua_State *L) { | 180 | static int tpack (lua_State *L) { |
195 | int i; | 181 | int i; |
196 | int n = lua_gettop(L); /* number of elements to pack */ | 182 | int n = lua_gettop(L); /* number of elements to pack */ |
197 | lua_createtable(L, n, 1); /* create result table */ | 183 | lua_createtable(L, n, 1); /* create result table */ |
@@ -204,7 +190,7 @@ static int pack (lua_State *L) { | |||
204 | } | 190 | } |
205 | 191 | ||
206 | 192 | ||
207 | static int unpack (lua_State *L) { | 193 | static int tunpack (lua_State *L) { |
208 | lua_Unsigned n; | 194 | lua_Unsigned n; |
209 | lua_Integer i = luaL_optinteger(L, 2, 1); | 195 | lua_Integer i = luaL_optinteger(L, 2, 1); |
210 | lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); | 196 | lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); |
@@ -313,14 +299,14 @@ static IdxT partition (lua_State *L, IdxT lo, IdxT up) { | |||
313 | /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ | 299 | /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ |
314 | for (;;) { | 300 | for (;;) { |
315 | /* next loop: repeat ++i while a[i] < P */ | 301 | /* next loop: repeat ++i while a[i] < P */ |
316 | while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { | 302 | while ((void)lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { |
317 | if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ | 303 | if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ |
318 | luaL_error(L, "invalid order function for sorting"); | 304 | luaL_error(L, "invalid order function for sorting"); |
319 | lua_pop(L, 1); /* remove a[i] */ | 305 | lua_pop(L, 1); /* remove a[i] */ |
320 | } | 306 | } |
321 | /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ | 307 | /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ |
322 | /* next loop: repeat --j while P < a[j] */ | 308 | /* next loop: repeat --j while P < a[j] */ |
323 | while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { | 309 | while ((void)lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { |
324 | if (j < i) /* j < i but a[j] > P ?? */ | 310 | if (j < i) /* j < i but a[j] > P ?? */ |
325 | luaL_error(L, "invalid order function for sorting"); | 311 | luaL_error(L, "invalid order function for sorting"); |
326 | lua_pop(L, 1); /* remove a[j] */ | 312 | lua_pop(L, 1); /* remove a[j] */ |
@@ -352,7 +338,7 @@ static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { | |||
352 | 338 | ||
353 | 339 | ||
354 | /* | 340 | /* |
355 | ** QuickSort algorithm (recursive function) | 341 | ** Quicksort algorithm (recursive function) |
356 | */ | 342 | */ |
357 | static void auxsort (lua_State *L, IdxT lo, IdxT up, | 343 | static void auxsort (lua_State *L, IdxT lo, IdxT up, |
358 | unsigned int rnd) { | 344 | unsigned int rnd) { |
@@ -425,12 +411,9 @@ static int sort (lua_State *L) { | |||
425 | 411 | ||
426 | static const luaL_Reg tab_funcs[] = { | 412 | static const luaL_Reg tab_funcs[] = { |
427 | {"concat", tconcat}, | 413 | {"concat", tconcat}, |
428 | #if defined(LUA_COMPAT_MAXN) | ||
429 | {"maxn", maxn}, | ||
430 | #endif | ||
431 | {"insert", tinsert}, | 414 | {"insert", tinsert}, |
432 | {"pack", pack}, | 415 | {"pack", tpack}, |
433 | {"unpack", unpack}, | 416 | {"unpack", tunpack}, |
434 | {"remove", tremove}, | 417 | {"remove", tremove}, |
435 | {"move", tmove}, | 418 | {"move", tmove}, |
436 | {"sort", sort}, | 419 | {"sort", sort}, |
@@ -440,11 +423,6 @@ static const luaL_Reg tab_funcs[] = { | |||
440 | 423 | ||
441 | LUAMOD_API int luaopen_table (lua_State *L) { | 424 | LUAMOD_API int luaopen_table (lua_State *L) { |
442 | luaL_newlib(L, tab_funcs); | 425 | luaL_newlib(L, tab_funcs); |
443 | #if defined(LUA_COMPAT_UNPACK) | ||
444 | /* _G.unpack = table.unpack */ | ||
445 | lua_getfield(L, -1, "unpack"); | ||
446 | lua_setglobal(L, "unpack"); | ||
447 | #endif | ||
448 | return 1; | 426 | return 1; |
449 | } | 427 | } |
450 | 428 | ||
diff --git a/src/lua/ltm.c b/src/lua/ltm.c new file mode 100644 index 0000000..ae60983 --- /dev/null +++ b/src/lua/ltm.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | ** $Id: ltm.c $ | ||
3 | ** Tag methods | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define ltm_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <string.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lgc.h" | ||
20 | #include "lobject.h" | ||
21 | #include "lstate.h" | ||
22 | #include "lstring.h" | ||
23 | #include "ltable.h" | ||
24 | #include "ltm.h" | ||
25 | #include "lvm.h" | ||
26 | |||
27 | |||
28 | static const char udatatypename[] = "userdata"; | ||
29 | |||
30 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTYPES] = { | ||
31 | "no value", | ||
32 | "nil", "boolean", udatatypename, "number", | ||
33 | "string", "table", "function", udatatypename, "thread", | ||
34 | "upvalue", "proto" /* these last cases are used for tests only */ | ||
35 | }; | ||
36 | |||
37 | |||
38 | void luaT_init (lua_State *L) { | ||
39 | static const char *const luaT_eventname[] = { /* ORDER TM */ | ||
40 | "__index", "__newindex", | ||
41 | "__gc", "__mode", "__len", "__eq", | ||
42 | "__add", "__sub", "__mul", "__mod", "__pow", | ||
43 | "__div", "__idiv", | ||
44 | "__band", "__bor", "__bxor", "__shl", "__shr", | ||
45 | "__unm", "__bnot", "__lt", "__le", | ||
46 | "__concat", "__call", "__close" | ||
47 | }; | ||
48 | int i; | ||
49 | for (i=0; i<TM_N; i++) { | ||
50 | G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); | ||
51 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ | ||
52 | } | ||
53 | } | ||
54 | |||
55 | |||
56 | /* | ||
57 | ** function to be used with macro "fasttm": optimized for absence of | ||
58 | ** tag methods | ||
59 | */ | ||
60 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { | ||
61 | const TValue *tm = luaH_getshortstr(events, ename); | ||
62 | lua_assert(event <= TM_EQ); | ||
63 | if (notm(tm)) { /* no tag method? */ | ||
64 | events->flags |= cast_byte(1u<<event); /* cache this fact */ | ||
65 | return NULL; | ||
66 | } | ||
67 | else return tm; | ||
68 | } | ||
69 | |||
70 | |||
71 | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { | ||
72 | Table *mt; | ||
73 | switch (ttype(o)) { | ||
74 | case LUA_TTABLE: | ||
75 | mt = hvalue(o)->metatable; | ||
76 | break; | ||
77 | case LUA_TUSERDATA: | ||
78 | mt = uvalue(o)->metatable; | ||
79 | break; | ||
80 | default: | ||
81 | mt = G(L)->mt[ttype(o)]; | ||
82 | } | ||
83 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); | ||
84 | } | ||
85 | |||
86 | |||
87 | /* | ||
88 | ** Return the name of the type of an object. For tables and userdata | ||
89 | ** with metatable, use their '__name' metafield, if present. | ||
90 | */ | ||
91 | const char *luaT_objtypename (lua_State *L, const TValue *o) { | ||
92 | Table *mt; | ||
93 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || | ||
94 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { | ||
95 | const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); | ||
96 | if (ttisstring(name)) /* is '__name' a string? */ | ||
97 | return getstr(tsvalue(name)); /* use it as type name */ | ||
98 | } | ||
99 | return ttypename(ttype(o)); /* else use standard type name */ | ||
100 | } | ||
101 | |||
102 | |||
103 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, | ||
104 | const TValue *p2, const TValue *p3) { | ||
105 | StkId func = L->top; | ||
106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ | ||
107 | setobj2s(L, func + 1, p1); /* 1st argument */ | ||
108 | setobj2s(L, func + 2, p2); /* 2nd argument */ | ||
109 | setobj2s(L, func + 3, p3); /* 3rd argument */ | ||
110 | L->top = func + 4; | ||
111 | /* metamethod may yield only when called from Lua code */ | ||
112 | if (isLuacode(L->ci)) | ||
113 | luaD_call(L, func, 0); | ||
114 | else | ||
115 | luaD_callnoyield(L, func, 0); | ||
116 | } | ||
117 | |||
118 | |||
119 | void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, | ||
120 | const TValue *p2, StkId res) { | ||
121 | ptrdiff_t result = savestack(L, res); | ||
122 | StkId func = L->top; | ||
123 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ | ||
124 | setobj2s(L, func + 1, p1); /* 1st argument */ | ||
125 | setobj2s(L, func + 2, p2); /* 2nd argument */ | ||
126 | L->top += 3; | ||
127 | /* metamethod may yield only when called from Lua code */ | ||
128 | if (isLuacode(L->ci)) | ||
129 | luaD_call(L, func, 1); | ||
130 | else | ||
131 | luaD_callnoyield(L, func, 1); | ||
132 | res = restorestack(L, result); | ||
133 | setobjs2s(L, res, --L->top); /* move result to its place */ | ||
134 | } | ||
135 | |||
136 | |||
137 | static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
138 | StkId res, TMS event) { | ||
139 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | ||
140 | if (notm(tm)) | ||
141 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | ||
142 | if (notm(tm)) return 0; | ||
143 | luaT_callTMres(L, tm, p1, p2, res); | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | |||
148 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
149 | StkId res, TMS event) { | ||
150 | if (!callbinTM(L, p1, p2, res, event)) { | ||
151 | switch (event) { | ||
152 | case TM_BAND: case TM_BOR: case TM_BXOR: | ||
153 | case TM_SHL: case TM_SHR: case TM_BNOT: { | ||
154 | if (ttisnumber(p1) && ttisnumber(p2)) | ||
155 | luaG_tointerror(L, p1, p2); | ||
156 | else | ||
157 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); | ||
158 | } | ||
159 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ | ||
160 | default: | ||
161 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | |||
167 | void luaT_tryconcatTM (lua_State *L) { | ||
168 | StkId top = L->top; | ||
169 | if (!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, TM_CONCAT)) | ||
170 | luaG_concaterror(L, s2v(top - 2), s2v(top - 1)); | ||
171 | } | ||
172 | |||
173 | |||
174 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
175 | int flip, StkId res, TMS event) { | ||
176 | if (flip) | ||
177 | luaT_trybinTM(L, p2, p1, res, event); | ||
178 | else | ||
179 | luaT_trybinTM(L, p1, p2, res, event); | ||
180 | } | ||
181 | |||
182 | |||
183 | void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, | ||
184 | int flip, StkId res, TMS event) { | ||
185 | TValue aux; | ||
186 | setivalue(&aux, i2); | ||
187 | luaT_trybinassocTM(L, p1, &aux, flip, res, event); | ||
188 | } | ||
189 | |||
190 | |||
191 | /* | ||
192 | ** Calls an order tag method. | ||
193 | ** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old | ||
194 | ** behavior: if there is no '__le', try '__lt', based on l <= r iff | ||
195 | ** !(r < l) (assuming a total order). If the metamethod yields during | ||
196 | ** this substitution, the continuation has to know about it (to negate | ||
197 | ** the result of r<l); bit CIST_LEQ in the call status keeps that | ||
198 | ** information. | ||
199 | */ | ||
200 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
201 | TMS event) { | ||
202 | if (callbinTM(L, p1, p2, L->top, event)) /* try original event */ | ||
203 | return !l_isfalse(s2v(L->top)); | ||
204 | #if defined(LUA_COMPAT_LT_LE) | ||
205 | else if (event == TM_LE) { | ||
206 | /* try '!(p2 < p1)' for '(p1 <= p2)' */ | ||
207 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ | ||
208 | if (callbinTM(L, p2, p1, L->top, TM_LT)) { | ||
209 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ | ||
210 | return l_isfalse(s2v(L->top)); | ||
211 | } | ||
212 | /* else error will remove this 'ci'; no need to clear mark */ | ||
213 | } | ||
214 | #endif | ||
215 | luaG_ordererror(L, p1, p2); /* no metamethod found */ | ||
216 | return 0; /* to avoid warnings */ | ||
217 | } | ||
218 | |||
219 | |||
220 | int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | ||
221 | int flip, int isfloat, TMS event) { | ||
222 | TValue aux; const TValue *p2; | ||
223 | if (isfloat) { | ||
224 | setfltvalue(&aux, cast_num(v2)); | ||
225 | } | ||
226 | else | ||
227 | setivalue(&aux, v2); | ||
228 | if (flip) { /* arguments were exchanged? */ | ||
229 | p2 = p1; p1 = &aux; /* correct them */ | ||
230 | } | ||
231 | else | ||
232 | p2 = &aux; | ||
233 | return luaT_callorderTM(L, p1, p2, event); | ||
234 | } | ||
235 | |||
236 | |||
237 | void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, | ||
238 | const Proto *p) { | ||
239 | int i; | ||
240 | int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */ | ||
241 | int nextra = actual - nfixparams; /* number of extra arguments */ | ||
242 | ci->u.l.nextraargs = nextra; | ||
243 | checkstackGC(L, p->maxstacksize + 1); | ||
244 | /* copy function to the top of the stack */ | ||
245 | setobjs2s(L, L->top++, ci->func); | ||
246 | /* move fixed parameters to the top of the stack */ | ||
247 | for (i = 1; i <= nfixparams; i++) { | ||
248 | setobjs2s(L, L->top++, ci->func + i); | ||
249 | setnilvalue(s2v(ci->func + i)); /* erase original parameter (for GC) */ | ||
250 | } | ||
251 | ci->func += actual + 1; | ||
252 | ci->top += actual + 1; | ||
253 | lua_assert(L->top <= ci->top && ci->top <= L->stack_last); | ||
254 | } | ||
255 | |||
256 | |||
257 | void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { | ||
258 | int i; | ||
259 | int nextra = ci->u.l.nextraargs; | ||
260 | if (wanted < 0) { | ||
261 | wanted = nextra; /* get all extra arguments available */ | ||
262 | checkstackp(L, nextra, where); /* ensure stack space */ | ||
263 | L->top = where + nextra; /* next instruction will need top */ | ||
264 | } | ||
265 | for (i = 0; i < wanted && i < nextra; i++) | ||
266 | setobjs2s(L, where + i, ci->func - nextra + i); | ||
267 | for (; i < wanted; i++) /* complete required results with nil */ | ||
268 | setnilvalue(s2v(where + i)); | ||
269 | } | ||
270 | |||
diff --git a/src/lua-5.3/ltm.h b/src/lua/ltm.h index 8170688..99b545e 100644 --- a/src/lua-5.3/ltm.h +++ b/src/lua/ltm.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: ltm.h $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -40,10 +40,17 @@ typedef enum { | |||
40 | TM_LE, | 40 | TM_LE, |
41 | TM_CONCAT, | 41 | TM_CONCAT, |
42 | TM_CALL, | 42 | TM_CALL, |
43 | TM_CLOSE, | ||
43 | TM_N /* number of elements in the enum */ | 44 | TM_N /* number of elements in the enum */ |
44 | } TMS; | 45 | } TMS; |
45 | 46 | ||
46 | 47 | ||
48 | /* | ||
49 | ** Test whether there is no tagmethod. | ||
50 | ** (Because tagmethods use raw accesses, the result may be an "empty" nil.) | ||
51 | */ | ||
52 | #define notm(tm) ttisnil(tm) | ||
53 | |||
47 | 54 | ||
48 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ | 55 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ |
49 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) | 56 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) |
@@ -52,7 +59,7 @@ typedef enum { | |||
52 | 59 | ||
53 | #define ttypename(x) luaT_typenames_[(x) + 1] | 60 | #define ttypename(x) luaT_typenames_[(x) + 1] |
54 | 61 | ||
55 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; | 62 | LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];) |
56 | 63 | ||
57 | 64 | ||
58 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); | 65 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); |
@@ -63,14 +70,25 @@ LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, | |||
63 | LUAI_FUNC void luaT_init (lua_State *L); | 70 | LUAI_FUNC void luaT_init (lua_State *L); |
64 | 71 | ||
65 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, | 72 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, |
66 | const TValue *p2, TValue *p3, int hasres); | 73 | const TValue *p2, const TValue *p3); |
67 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | 74 | LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, |
68 | StkId res, TMS event); | 75 | const TValue *p1, const TValue *p2, StkId p3); |
69 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | 76 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, |
70 | StkId res, TMS event); | 77 | StkId res, TMS event); |
78 | LUAI_FUNC void luaT_tryconcatTM (lua_State *L); | ||
79 | LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, | ||
80 | const TValue *p2, int inv, StkId res, TMS event); | ||
81 | LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, | ||
82 | int inv, StkId res, TMS event); | ||
71 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, | 83 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, |
72 | const TValue *p2, TMS event); | 84 | const TValue *p2, TMS event); |
85 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | ||
86 | int inv, int isfloat, TMS event); | ||
73 | 87 | ||
88 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, | ||
89 | struct CallInfo *ci, const Proto *p); | ||
90 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, | ||
91 | StkId where, int wanted); | ||
74 | 92 | ||
75 | 93 | ||
76 | #endif | 94 | #endif |
diff --git a/src/lua-5.3/lua.h b/src/lua/lua.h index c236e36..b348c14 100644 --- a/src/lua-5.3/lua.h +++ b/src/lua/lua.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $ | 2 | ** $Id: lua.h $ |
3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
@@ -17,13 +17,15 @@ | |||
17 | 17 | ||
18 | 18 | ||
19 | #define LUA_VERSION_MAJOR "5" | 19 | #define LUA_VERSION_MAJOR "5" |
20 | #define LUA_VERSION_MINOR "3" | 20 | #define LUA_VERSION_MINOR "4" |
21 | #define LUA_VERSION_NUM 503 | 21 | #define LUA_VERSION_RELEASE "0" |
22 | #define LUA_VERSION_RELEASE "5" | 22 | |
23 | #define LUA_VERSION_NUM 504 | ||
24 | #define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0) | ||
23 | 25 | ||
24 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR | 26 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR |
25 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE | 27 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE |
26 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2018 Lua.org, PUC-Rio" | 28 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2020 Lua.org, PUC-Rio" |
27 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" | 29 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" |
28 | 30 | ||
29 | 31 | ||
@@ -49,8 +51,7 @@ | |||
49 | #define LUA_ERRRUN 2 | 51 | #define LUA_ERRRUN 2 |
50 | #define LUA_ERRSYNTAX 3 | 52 | #define LUA_ERRSYNTAX 3 |
51 | #define LUA_ERRMEM 4 | 53 | #define LUA_ERRMEM 4 |
52 | #define LUA_ERRGCMM 5 | 54 | #define LUA_ERRERR 5 |
53 | #define LUA_ERRERR 6 | ||
54 | 55 | ||
55 | 56 | ||
56 | typedef struct lua_State lua_State; | 57 | typedef struct lua_State lua_State; |
@@ -71,7 +72,7 @@ typedef struct lua_State lua_State; | |||
71 | #define LUA_TUSERDATA 7 | 72 | #define LUA_TUSERDATA 7 |
72 | #define LUA_TTHREAD 8 | 73 | #define LUA_TTHREAD 8 |
73 | 74 | ||
74 | #define LUA_NUMTAGS 9 | 75 | #define LUA_NUMTYPES 9 |
75 | 76 | ||
76 | 77 | ||
77 | 78 | ||
@@ -124,6 +125,13 @@ typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); | |||
124 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); | 125 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); |
125 | 126 | ||
126 | 127 | ||
128 | /* | ||
129 | ** Type for warning functions | ||
130 | */ | ||
131 | typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); | ||
132 | |||
133 | |||
134 | |||
127 | 135 | ||
128 | /* | 136 | /* |
129 | ** generic extra include file | 137 | ** generic extra include file |
@@ -145,11 +153,12 @@ extern const char lua_ident[]; | |||
145 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); | 153 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); |
146 | LUA_API void (lua_close) (lua_State *L); | 154 | LUA_API void (lua_close) (lua_State *L); |
147 | LUA_API lua_State *(lua_newthread) (lua_State *L); | 155 | LUA_API lua_State *(lua_newthread) (lua_State *L); |
156 | LUA_API int (lua_resetthread) (lua_State *L); | ||
148 | 157 | ||
149 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); | 158 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); |
150 | 159 | ||
151 | 160 | ||
152 | LUA_API const lua_Number *(lua_version) (lua_State *L); | 161 | LUA_API lua_Number (lua_version) (lua_State *L); |
153 | 162 | ||
154 | 163 | ||
155 | /* | 164 | /* |
@@ -182,7 +191,7 @@ LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); | |||
182 | LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); | 191 | LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); |
183 | LUA_API int (lua_toboolean) (lua_State *L, int idx); | 192 | LUA_API int (lua_toboolean) (lua_State *L, int idx); |
184 | LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); | 193 | LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); |
185 | LUA_API size_t (lua_rawlen) (lua_State *L, int idx); | 194 | LUA_API lua_Unsigned (lua_rawlen) (lua_State *L, int idx); |
186 | LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); | 195 | LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); |
187 | LUA_API void *(lua_touserdata) (lua_State *L, int idx); | 196 | LUA_API void *(lua_touserdata) (lua_State *L, int idx); |
188 | LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); | 197 | LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); |
@@ -247,9 +256,9 @@ LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); | |||
247 | LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); | 256 | LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); |
248 | 257 | ||
249 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); | 258 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); |
250 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); | 259 | LUA_API void *(lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue); |
251 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); | 260 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); |
252 | LUA_API int (lua_getuservalue) (lua_State *L, int idx); | 261 | LUA_API int (lua_getiuservalue) (lua_State *L, int idx, int n); |
253 | 262 | ||
254 | 263 | ||
255 | /* | 264 | /* |
@@ -263,7 +272,7 @@ LUA_API void (lua_rawset) (lua_State *L, int idx); | |||
263 | LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); | 272 | LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); |
264 | LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); | 273 | LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); |
265 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); | 274 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); |
266 | LUA_API void (lua_setuservalue) (lua_State *L, int idx); | 275 | LUA_API int (lua_setiuservalue) (lua_State *L, int idx, int n); |
267 | 276 | ||
268 | 277 | ||
269 | /* | 278 | /* |
@@ -288,7 +297,8 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); | |||
288 | */ | 297 | */ |
289 | LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, | 298 | LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, |
290 | lua_KFunction k); | 299 | lua_KFunction k); |
291 | LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); | 300 | LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg, |
301 | int *nres); | ||
292 | LUA_API int (lua_status) (lua_State *L); | 302 | LUA_API int (lua_status) (lua_State *L); |
293 | LUA_API int (lua_isyieldable) (lua_State *L); | 303 | LUA_API int (lua_isyieldable) (lua_State *L); |
294 | 304 | ||
@@ -296,6 +306,13 @@ LUA_API int (lua_isyieldable) (lua_State *L); | |||
296 | 306 | ||
297 | 307 | ||
298 | /* | 308 | /* |
309 | ** Warning-related functions | ||
310 | */ | ||
311 | LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud); | ||
312 | LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); | ||
313 | |||
314 | |||
315 | /* | ||
299 | ** garbage-collection function and options | 316 | ** garbage-collection function and options |
300 | */ | 317 | */ |
301 | 318 | ||
@@ -308,8 +325,10 @@ LUA_API int (lua_isyieldable) (lua_State *L); | |||
308 | #define LUA_GCSETPAUSE 6 | 325 | #define LUA_GCSETPAUSE 6 |
309 | #define LUA_GCSETSTEPMUL 7 | 326 | #define LUA_GCSETSTEPMUL 7 |
310 | #define LUA_GCISRUNNING 9 | 327 | #define LUA_GCISRUNNING 9 |
328 | #define LUA_GCGEN 10 | ||
329 | #define LUA_GCINC 11 | ||
311 | 330 | ||
312 | LUA_API int (lua_gc) (lua_State *L, int what, int data); | 331 | LUA_API int (lua_gc) (lua_State *L, int what, ...); |
313 | 332 | ||
314 | 333 | ||
315 | /* | 334 | /* |
@@ -328,6 +347,7 @@ LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); | |||
328 | LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); | 347 | LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); |
329 | LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); | 348 | LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); |
330 | 349 | ||
350 | LUA_API void (lua_toclose) (lua_State *L, int idx); | ||
331 | 351 | ||
332 | 352 | ||
333 | /* | 353 | /* |
@@ -377,7 +397,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); | |||
377 | 397 | ||
378 | /* | 398 | /* |
379 | ** {============================================================== | 399 | ** {============================================================== |
380 | ** compatibility macros for unsigned conversions | 400 | ** compatibility macros |
381 | ** =============================================================== | 401 | ** =============================================================== |
382 | */ | 402 | */ |
383 | #if defined(LUA_COMPAT_APIINTCASTS) | 403 | #if defined(LUA_COMPAT_APIINTCASTS) |
@@ -387,6 +407,13 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); | |||
387 | #define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) | 407 | #define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) |
388 | 408 | ||
389 | #endif | 409 | #endif |
410 | |||
411 | #define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) | ||
412 | #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) | ||
413 | #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) | ||
414 | |||
415 | #define LUA_NUMTAGS LUA_NUMTYPES | ||
416 | |||
390 | /* }============================================================== */ | 417 | /* }============================================================== */ |
391 | 418 | ||
392 | /* | 419 | /* |
@@ -437,6 +464,7 @@ LUA_API lua_Hook (lua_gethook) (lua_State *L); | |||
437 | LUA_API int (lua_gethookmask) (lua_State *L); | 464 | LUA_API int (lua_gethookmask) (lua_State *L); |
438 | LUA_API int (lua_gethookcount) (lua_State *L); | 465 | LUA_API int (lua_gethookcount) (lua_State *L); |
439 | 466 | ||
467 | LUA_API int (lua_setcstacklimit) (lua_State *L, unsigned int limit); | ||
440 | 468 | ||
441 | struct lua_Debug { | 469 | struct lua_Debug { |
442 | int event; | 470 | int event; |
@@ -444,6 +472,7 @@ struct lua_Debug { | |||
444 | const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ | 472 | const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ |
445 | const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ | 473 | const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ |
446 | const char *source; /* (S) */ | 474 | const char *source; /* (S) */ |
475 | size_t srclen; /* (S) */ | ||
447 | int currentline; /* (l) */ | 476 | int currentline; /* (l) */ |
448 | int linedefined; /* (S) */ | 477 | int linedefined; /* (S) */ |
449 | int lastlinedefined; /* (S) */ | 478 | int lastlinedefined; /* (S) */ |
@@ -451,6 +480,8 @@ struct lua_Debug { | |||
451 | unsigned char nparams;/* (u) number of parameters */ | 480 | unsigned char nparams;/* (u) number of parameters */ |
452 | char isvararg; /* (u) */ | 481 | char isvararg; /* (u) */ |
453 | char istailcall; /* (t) */ | 482 | char istailcall; /* (t) */ |
483 | unsigned short ftransfer; /* (r) index of first value transferred */ | ||
484 | unsigned short ntransfer; /* (r) number of transferred values */ | ||
454 | char short_src[LUA_IDSIZE]; /* (S) */ | 485 | char short_src[LUA_IDSIZE]; /* (S) */ |
455 | /* private part */ | 486 | /* private part */ |
456 | struct CallInfo *i_ci; /* active function */ | 487 | struct CallInfo *i_ci; /* active function */ |
@@ -460,7 +491,7 @@ struct lua_Debug { | |||
460 | 491 | ||
461 | 492 | ||
462 | /****************************************************************************** | 493 | /****************************************************************************** |
463 | * Copyright (C) 1994-2018 Lua.org, PUC-Rio. | 494 | * Copyright (C) 1994-2020 Lua.org, PUC-Rio. |
464 | * | 495 | * |
465 | * Permission is hereby granted, free of charge, to any person obtaining | 496 | * Permission is hereby granted, free of charge, to any person obtaining |
466 | * a copy of this software and associated documentation files (the | 497 | * a copy of this software and associated documentation files (the |
diff --git a/src/lua-5.3/luaconf.h b/src/lua/luaconf.h index 9eeeea6..bdf927e 100644 --- a/src/lua-5.3/luaconf.h +++ b/src/lua/luaconf.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $ | 2 | ** $Id: luaconf.h $ |
3 | ** Configuration file for Lua | 3 | ** Configuration file for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,6 +14,16 @@ | |||
14 | 14 | ||
15 | /* | 15 | /* |
16 | ** =================================================================== | 16 | ** =================================================================== |
17 | ** General Configuration File for Lua | ||
18 | ** | ||
19 | ** Some definitions here can be changed externally, through the | ||
20 | ** compiler (e.g., with '-D' options). Those are protected by | ||
21 | ** '#if !defined' guards. However, several other definitions should | ||
22 | ** be changed directly here, either because they affect the Lua | ||
23 | ** ABI (by making the changes here, you ensure that all software | ||
24 | ** connected to Lua, such as C libraries, will be compiled with the | ||
25 | ** same configuration); or because they are seldom changed. | ||
26 | ** | ||
17 | ** Search for "@@" to find all configurable definitions. | 27 | ** Search for "@@" to find all configurable definitions. |
18 | ** =================================================================== | 28 | ** =================================================================== |
19 | */ | 29 | */ |
@@ -22,18 +32,23 @@ | |||
22 | /* | 32 | /* |
23 | ** {==================================================================== | 33 | ** {==================================================================== |
24 | ** System Configuration: macros to adapt (if needed) Lua to some | 34 | ** System Configuration: macros to adapt (if needed) Lua to some |
25 | ** particular platform, for instance compiling it with 32-bit numbers or | 35 | ** particular platform, for instance restricting it to C89. |
26 | ** restricting it to C89. | ||
27 | ** ===================================================================== | 36 | ** ===================================================================== |
28 | */ | 37 | */ |
29 | 38 | ||
30 | /* | 39 | /* |
31 | @@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You | 40 | @@ LUAI_MAXCSTACK defines the maximum depth for nested calls and |
32 | ** can also define LUA_32BITS in the make file, but changing here you | 41 | ** also limits the maximum depth of other recursive algorithms in |
33 | ** ensure that all software connected to Lua will be compiled with the | 42 | ** the implementation, such as syntactic analysis. A value too |
34 | ** same configuration. | 43 | ** large may allow the interpreter to crash (C-stack overflow). |
44 | ** The default value seems ok for regular machines, but may be | ||
45 | ** too high for restricted hardware. | ||
46 | ** The test file 'cstack.lua' may help finding a good limit. | ||
47 | ** (It will crash with a limit too high.) | ||
35 | */ | 48 | */ |
36 | /* #define LUA_32BITS */ | 49 | #if !defined(LUAI_MAXCSTACK) |
50 | #define LUAI_MAXCSTACK 2000 | ||
51 | #endif | ||
37 | 52 | ||
38 | 53 | ||
39 | /* | 54 | /* |
@@ -61,45 +76,51 @@ | |||
61 | #if defined(LUA_USE_LINUX) | 76 | #if defined(LUA_USE_LINUX) |
62 | #define LUA_USE_POSIX | 77 | #define LUA_USE_POSIX |
63 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ | 78 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ |
64 | #define LUA_USE_READLINE /* needs some extra libraries */ | ||
65 | #endif | 79 | #endif |
66 | 80 | ||
67 | 81 | ||
68 | #if defined(LUA_USE_MACOSX) | 82 | #if defined(LUA_USE_MACOSX) |
69 | #define LUA_USE_POSIX | 83 | #define LUA_USE_POSIX |
70 | #define LUA_USE_DLOPEN /* MacOS does not need -ldl */ | 84 | #define LUA_USE_DLOPEN /* MacOS does not need -ldl */ |
71 | #define LUA_USE_READLINE /* needs an extra library: -lreadline */ | ||
72 | #endif | 85 | #endif |
73 | 86 | ||
74 | 87 | ||
75 | /* | 88 | /* |
76 | @@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for | 89 | @@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits. |
77 | ** C89 ('long' and 'double'); Windows always has '__int64', so it does | ||
78 | ** not need to use this case. | ||
79 | */ | 90 | */ |
80 | #if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) | 91 | #define LUAI_IS32INT ((UINT_MAX >> 30) >= 3) |
81 | #define LUA_C89_NUMBERS | 92 | |
82 | #endif | 93 | /* }================================================================== */ |
83 | 94 | ||
84 | 95 | ||
85 | 96 | ||
86 | /* | 97 | /* |
87 | @@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'. | 98 | ** {================================================================== |
99 | ** Configuration for Number types. | ||
100 | ** =================================================================== | ||
88 | */ | 101 | */ |
89 | /* avoid undefined shifts */ | 102 | |
90 | #if ((INT_MAX >> 15) >> 15) >= 1 | 103 | /* |
91 | #define LUAI_BITSINT 32 | 104 | @@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. |
92 | #else | 105 | */ |
93 | /* 'int' always must have at least 16 bits */ | 106 | /* #define LUA_32BITS */ |
94 | #define LUAI_BITSINT 16 | 107 | |
108 | |||
109 | /* | ||
110 | @@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for | ||
111 | ** C89 ('long' and 'double'); Windows always has '__int64', so it does | ||
112 | ** not need to use this case. | ||
113 | */ | ||
114 | #if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) | ||
115 | #define LUA_C89_NUMBERS | ||
95 | #endif | 116 | #endif |
96 | 117 | ||
97 | 118 | ||
98 | /* | 119 | /* |
99 | @@ LUA_INT_TYPE defines the type for Lua integers. | 120 | @@ LUA_INT_TYPE defines the type for Lua integers. |
100 | @@ LUA_FLOAT_TYPE defines the type for Lua floats. | 121 | @@ LUA_FLOAT_TYPE defines the type for Lua floats. |
101 | ** Lua should work fine with any mix of these options (if supported | 122 | ** Lua should work fine with any mix of these options supported |
102 | ** by your C compiler). The usual configurations are 64-bit integers | 123 | ** by your C compiler. The usual configurations are 64-bit integers |
103 | ** and 'double' (the default), 32-bit integers and 'float' (for | 124 | ** and 'double' (the default), 32-bit integers and 'float' (for |
104 | ** restricted platforms), and 'long'/'double' (for C compilers not | 125 | ** restricted platforms), and 'long'/'double' (for C compilers not |
105 | ** compliant with C99, which may not have support for 'long long'). | 126 | ** compliant with C99, which may not have support for 'long long'). |
@@ -119,7 +140,7 @@ | |||
119 | /* | 140 | /* |
120 | ** 32-bit integers and 'float' | 141 | ** 32-bit integers and 'float' |
121 | */ | 142 | */ |
122 | #if LUAI_BITSINT >= 32 /* use 'int' if big enough */ | 143 | #if LUAI_IS32INT /* use 'int' if big enough */ |
123 | #define LUA_INT_TYPE LUA_INT_INT | 144 | #define LUA_INT_TYPE LUA_INT_INT |
124 | #else /* otherwise use 'long' */ | 145 | #else /* otherwise use 'long' */ |
125 | #define LUA_INT_TYPE LUA_INT_LONG | 146 | #define LUA_INT_TYPE LUA_INT_LONG |
@@ -151,7 +172,6 @@ | |||
151 | 172 | ||
152 | 173 | ||
153 | 174 | ||
154 | |||
155 | /* | 175 | /* |
156 | ** {================================================================== | 176 | ** {================================================================== |
157 | ** Configuration for Paths. | 177 | ** Configuration for Paths. |
@@ -179,6 +199,7 @@ | |||
179 | ** hierarchy or if you want to install your libraries in | 199 | ** hierarchy or if you want to install your libraries in |
180 | ** non-conventional directories. | 200 | ** non-conventional directories. |
181 | */ | 201 | */ |
202 | |||
182 | #define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR | 203 | #define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR |
183 | #if defined(_WIN32) /* { */ | 204 | #if defined(_WIN32) /* { */ |
184 | /* | 205 | /* |
@@ -188,27 +209,40 @@ | |||
188 | #define LUA_LDIR "!\\lua\\" | 209 | #define LUA_LDIR "!\\lua\\" |
189 | #define LUA_CDIR "!\\" | 210 | #define LUA_CDIR "!\\" |
190 | #define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" | 211 | #define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" |
212 | |||
213 | #if !defined(LUA_PATH_DEFAULT) | ||
191 | #define LUA_PATH_DEFAULT \ | 214 | #define LUA_PATH_DEFAULT \ |
192 | LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ | 215 | LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ |
193 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ | 216 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ |
194 | LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ | 217 | LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ |
195 | ".\\?.lua;" ".\\?\\init.lua" | 218 | ".\\?.lua;" ".\\?\\init.lua" |
219 | #endif | ||
220 | |||
221 | #if !defined(LUA_CPATH_DEFAULT) | ||
196 | #define LUA_CPATH_DEFAULT \ | 222 | #define LUA_CPATH_DEFAULT \ |
197 | LUA_CDIR"?.dll;" \ | 223 | LUA_CDIR"?.dll;" \ |
198 | LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ | 224 | LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ |
199 | LUA_CDIR"loadall.dll;" ".\\?.dll" | 225 | LUA_CDIR"loadall.dll;" ".\\?.dll" |
226 | #endif | ||
200 | 227 | ||
201 | #else /* }{ */ | 228 | #else /* }{ */ |
202 | 229 | ||
203 | #define LUA_ROOT "/usr/local/" | 230 | #define LUA_ROOT "/usr/local/" |
204 | #define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" | 231 | #define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" |
205 | #define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" | 232 | #define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" |
233 | |||
234 | #if !defined(LUA_PATH_DEFAULT) | ||
206 | #define LUA_PATH_DEFAULT \ | 235 | #define LUA_PATH_DEFAULT \ |
207 | LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ | 236 | LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ |
208 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ | 237 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ |
209 | "./?.lua;" "./?/init.lua" | 238 | "./?.lua;" "./?/init.lua" |
239 | #endif | ||
240 | |||
241 | #if !defined(LUA_CPATH_DEFAULT) | ||
210 | #define LUA_CPATH_DEFAULT \ | 242 | #define LUA_CPATH_DEFAULT \ |
211 | LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" | 243 | LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" |
244 | #endif | ||
245 | |||
212 | #endif /* } */ | 246 | #endif /* } */ |
213 | 247 | ||
214 | 248 | ||
@@ -217,12 +251,16 @@ | |||
217 | ** CHANGE it if your machine does not use "/" as the directory separator | 251 | ** CHANGE it if your machine does not use "/" as the directory separator |
218 | ** and is not Windows. (On Windows Lua automatically uses "\".) | 252 | ** and is not Windows. (On Windows Lua automatically uses "\".) |
219 | */ | 253 | */ |
254 | #if !defined(LUA_DIRSEP) | ||
255 | |||
220 | #if defined(_WIN32) | 256 | #if defined(_WIN32) |
221 | #define LUA_DIRSEP "\\" | 257 | #define LUA_DIRSEP "\\" |
222 | #else | 258 | #else |
223 | #define LUA_DIRSEP "/" | 259 | #define LUA_DIRSEP "/" |
224 | #endif | 260 | #endif |
225 | 261 | ||
262 | #endif | ||
263 | |||
226 | /* }================================================================== */ | 264 | /* }================================================================== */ |
227 | 265 | ||
228 | 266 | ||
@@ -256,16 +294,18 @@ | |||
256 | #endif /* } */ | 294 | #endif /* } */ |
257 | 295 | ||
258 | 296 | ||
259 | /* more often than not the libs go together with the core */ | 297 | /* |
298 | ** More often than not the libs go together with the core. | ||
299 | */ | ||
260 | #define LUALIB_API LUA_API | 300 | #define LUALIB_API LUA_API |
261 | #define LUAMOD_API LUALIB_API | 301 | #define LUAMOD_API LUA_API |
262 | 302 | ||
263 | 303 | ||
264 | /* | 304 | /* |
265 | @@ LUAI_FUNC is a mark for all extern functions that are not to be | 305 | @@ LUAI_FUNC is a mark for all extern functions that are not to be |
266 | ** exported to outside modules. | 306 | ** exported to outside modules. |
267 | @@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables | 307 | @@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables, |
268 | ** that are not to be exported to outside modules (LUAI_DDEF for | 308 | ** none of which to be exported to outside modules (LUAI_DDEF for |
269 | ** definitions and LUAI_DDEC for declarations). | 309 | ** definitions and LUAI_DDEC for declarations). |
270 | ** CHANGE them if you need to mark them in some special way. Elf/gcc | 310 | ** CHANGE them if you need to mark them in some special way. Elf/gcc |
271 | ** (versions 3.2 and later) mark them as "hidden" to optimize access | 311 | ** (versions 3.2 and later) mark them as "hidden" to optimize access |
@@ -277,12 +317,12 @@ | |||
277 | */ | 317 | */ |
278 | #if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ | 318 | #if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ |
279 | defined(__ELF__) /* { */ | 319 | defined(__ELF__) /* { */ |
280 | #define LUAI_FUNC __attribute__((visibility("hidden"))) extern | 320 | #define LUAI_FUNC __attribute__((visibility("internal"))) extern |
281 | #else /* }{ */ | 321 | #else /* }{ */ |
282 | #define LUAI_FUNC extern | 322 | #define LUAI_FUNC extern |
283 | #endif /* } */ | 323 | #endif /* } */ |
284 | 324 | ||
285 | #define LUAI_DDEC LUAI_FUNC | 325 | #define LUAI_DDEC(dec) LUAI_FUNC dec |
286 | #define LUAI_DDEF /* empty */ | 326 | #define LUAI_DDEF /* empty */ |
287 | 327 | ||
288 | /* }================================================================== */ | 328 | /* }================================================================== */ |
@@ -295,88 +335,43 @@ | |||
295 | */ | 335 | */ |
296 | 336 | ||
297 | /* | 337 | /* |
298 | @@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2. | 338 | @@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. |
299 | @@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1. | ||
300 | ** You can define it to get all options, or change specific options | 339 | ** You can define it to get all options, or change specific options |
301 | ** to fit your specific needs. | 340 | ** to fit your specific needs. |
302 | */ | 341 | */ |
303 | #if defined(LUA_COMPAT_5_2) /* { */ | 342 | #if defined(LUA_COMPAT_5_3) /* { */ |
304 | 343 | ||
305 | /* | 344 | /* |
306 | @@ LUA_COMPAT_MATHLIB controls the presence of several deprecated | 345 | @@ LUA_COMPAT_MATHLIB controls the presence of several deprecated |
307 | ** functions in the mathematical library. | 346 | ** functions in the mathematical library. |
347 | ** (These functions were already officially removed in 5.3; | ||
348 | ** nevertheless they are still available here.) | ||
308 | */ | 349 | */ |
309 | #define LUA_COMPAT_MATHLIB | 350 | #define LUA_COMPAT_MATHLIB |
310 | 351 | ||
311 | /* | 352 | /* |
312 | @@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'. | ||
313 | */ | ||
314 | #define LUA_COMPAT_BITLIB | ||
315 | |||
316 | /* | ||
317 | @@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod. | ||
318 | */ | ||
319 | #define LUA_COMPAT_IPAIRS | ||
320 | |||
321 | /* | ||
322 | @@ LUA_COMPAT_APIINTCASTS controls the presence of macros for | 353 | @@ LUA_COMPAT_APIINTCASTS controls the presence of macros for |
323 | ** manipulating other integer types (lua_pushunsigned, lua_tounsigned, | 354 | ** manipulating other integer types (lua_pushunsigned, lua_tounsigned, |
324 | ** luaL_checkint, luaL_checklong, etc.) | 355 | ** luaL_checkint, luaL_checklong, etc.) |
356 | ** (These macros were also officially removed in 5.3, but they are still | ||
357 | ** available here.) | ||
325 | */ | 358 | */ |
326 | #define LUA_COMPAT_APIINTCASTS | 359 | #define LUA_COMPAT_APIINTCASTS |
327 | 360 | ||
328 | #endif /* } */ | ||
329 | |||
330 | |||
331 | #if defined(LUA_COMPAT_5_1) /* { */ | ||
332 | |||
333 | /* Incompatibilities from 5.2 -> 5.3 */ | ||
334 | #define LUA_COMPAT_MATHLIB | ||
335 | #define LUA_COMPAT_APIINTCASTS | ||
336 | 361 | ||
337 | /* | 362 | /* |
338 | @@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. | 363 | @@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod |
339 | ** You can replace it with 'table.unpack'. | 364 | ** using '__lt'. |
340 | */ | 365 | */ |
341 | #define LUA_COMPAT_UNPACK | 366 | #define LUA_COMPAT_LT_LE |
342 | 367 | ||
343 | /* | ||
344 | @@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. | ||
345 | ** You can replace it with 'package.searchers'. | ||
346 | */ | ||
347 | #define LUA_COMPAT_LOADERS | ||
348 | |||
349 | /* | ||
350 | @@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. | ||
351 | ** You can call your C function directly (with light C functions). | ||
352 | */ | ||
353 | #define lua_cpcall(L,f,u) \ | ||
354 | (lua_pushcfunction(L, (f)), \ | ||
355 | lua_pushlightuserdata(L,(u)), \ | ||
356 | lua_pcall(L,1,0,0)) | ||
357 | |||
358 | |||
359 | /* | ||
360 | @@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. | ||
361 | ** You can rewrite 'log10(x)' as 'log(x, 10)'. | ||
362 | */ | ||
363 | #define LUA_COMPAT_LOG10 | ||
364 | |||
365 | /* | ||
366 | @@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base | ||
367 | ** library. You can rewrite 'loadstring(s)' as 'load(s)'. | ||
368 | */ | ||
369 | #define LUA_COMPAT_LOADSTRING | ||
370 | |||
371 | /* | ||
372 | @@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. | ||
373 | */ | ||
374 | #define LUA_COMPAT_MAXN | ||
375 | 368 | ||
376 | /* | 369 | /* |
377 | @@ The following macros supply trivial compatibility for some | 370 | @@ The following macros supply trivial compatibility for some |
378 | ** changes in the API. The macros themselves document how to | 371 | ** changes in the API. The macros themselves document how to |
379 | ** change your code to avoid using them. | 372 | ** change your code to avoid using them. |
373 | ** (Once more, these macros were officially removed in 5.3, but they are | ||
374 | ** still available here.) | ||
380 | */ | 375 | */ |
381 | #define lua_strlen(L,i) lua_rawlen(L, (i)) | 376 | #define lua_strlen(L,i) lua_rawlen(L, (i)) |
382 | 377 | ||
@@ -385,23 +380,8 @@ | |||
385 | #define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) | 380 | #define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) |
386 | #define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) | 381 | #define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) |
387 | 382 | ||
388 | /* | ||
389 | @@ LUA_COMPAT_MODULE controls compatibility with previous | ||
390 | ** module functions 'module' (Lua) and 'luaL_register' (C). | ||
391 | */ | ||
392 | #define LUA_COMPAT_MODULE | ||
393 | |||
394 | #endif /* } */ | 383 | #endif /* } */ |
395 | 384 | ||
396 | |||
397 | /* | ||
398 | @@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a | ||
399 | @@ a float mark ('.0'). | ||
400 | ** This macro is not on by default even in compatibility mode, | ||
401 | ** because this is not really an incompatibility. | ||
402 | */ | ||
403 | /* #define LUA_COMPAT_FLOATSTRING */ | ||
404 | |||
405 | /* }================================================================== */ | 385 | /* }================================================================== */ |
406 | 386 | ||
407 | 387 | ||
@@ -418,14 +398,14 @@ | |||
418 | @@ LUA_NUMBER is the floating-point type used by Lua. | 398 | @@ LUA_NUMBER is the floating-point type used by Lua. |
419 | @@ LUAI_UACNUMBER is the result of a 'default argument promotion' | 399 | @@ LUAI_UACNUMBER is the result of a 'default argument promotion' |
420 | @@ over a floating number. | 400 | @@ over a floating number. |
421 | @@ l_mathlim(x) corrects limit name 'x' to the proper float type | 401 | @@ l_floatatt(x) corrects float attribute 'x' to the proper float type |
422 | ** by prefixing it with one of FLT/DBL/LDBL. | 402 | ** by prefixing it with one of FLT/DBL/LDBL. |
423 | @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. | 403 | @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. |
424 | @@ LUA_NUMBER_FMT is the format for writing floats. | 404 | @@ LUA_NUMBER_FMT is the format for writing floats. |
425 | @@ lua_number2str converts a float to a string. | 405 | @@ lua_number2str converts a float to a string. |
426 | @@ l_mathop allows the addition of an 'l' or 'f' to all math operations. | 406 | @@ l_mathop allows the addition of an 'l' or 'f' to all math operations. |
427 | @@ l_floor takes the floor of a float. | 407 | @@ l_floor takes the floor of a float. |
428 | @@ lua_str2number converts a decimal numeric string to a number. | 408 | @@ lua_str2number converts a decimal numeral to a number. |
429 | */ | 409 | */ |
430 | 410 | ||
431 | 411 | ||
@@ -437,12 +417,13 @@ | |||
437 | l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) | 417 | l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) |
438 | 418 | ||
439 | /* | 419 | /* |
440 | @@ lua_numbertointeger converts a float number to an integer, or | 420 | @@ lua_numbertointeger converts a float number with an integral value |
441 | ** returns 0 if float is not within the range of a lua_Integer. | 421 | ** to an integer, or returns 0 if float is not within the range of |
442 | ** (The range comparisons are tricky because of rounding. The tests | 422 | ** a lua_Integer. (The range comparisons are tricky because of |
443 | ** here assume a two-complement representation, where MININTEGER always | 423 | ** rounding. The tests here assume a two-complement representation, |
444 | ** has an exact representation as a float; MAXINTEGER may not have one, | 424 | ** where MININTEGER always has an exact representation as a float; |
445 | ** and therefore its conversion to float may have an ill-defined value.) | 425 | ** MAXINTEGER may not have one, and therefore its conversion to float |
426 | ** may have an ill-defined value.) | ||
446 | */ | 427 | */ |
447 | #define lua_numbertointeger(n,p) \ | 428 | #define lua_numbertointeger(n,p) \ |
448 | ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ | 429 | ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ |
@@ -456,7 +437,7 @@ | |||
456 | 437 | ||
457 | #define LUA_NUMBER float | 438 | #define LUA_NUMBER float |
458 | 439 | ||
459 | #define l_mathlim(n) (FLT_##n) | 440 | #define l_floatatt(n) (FLT_##n) |
460 | 441 | ||
461 | #define LUAI_UACNUMBER double | 442 | #define LUAI_UACNUMBER double |
462 | 443 | ||
@@ -472,7 +453,7 @@ | |||
472 | 453 | ||
473 | #define LUA_NUMBER long double | 454 | #define LUA_NUMBER long double |
474 | 455 | ||
475 | #define l_mathlim(n) (LDBL_##n) | 456 | #define l_floatatt(n) (LDBL_##n) |
476 | 457 | ||
477 | #define LUAI_UACNUMBER long double | 458 | #define LUAI_UACNUMBER long double |
478 | 459 | ||
@@ -487,7 +468,7 @@ | |||
487 | 468 | ||
488 | #define LUA_NUMBER double | 469 | #define LUA_NUMBER double |
489 | 470 | ||
490 | #define l_mathlim(n) (DBL_##n) | 471 | #define l_floatatt(n) (DBL_##n) |
491 | 472 | ||
492 | #define LUAI_UACNUMBER double | 473 | #define LUAI_UACNUMBER double |
493 | 474 | ||
@@ -512,11 +493,13 @@ | |||
512 | @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. | 493 | @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. |
513 | ** | 494 | ** |
514 | @@ LUAI_UACINT is the result of a 'default argument promotion' | 495 | @@ LUAI_UACINT is the result of a 'default argument promotion' |
515 | @@ over a lUA_INTEGER. | 496 | @@ over a LUA_INTEGER. |
516 | @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. | 497 | @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. |
517 | @@ LUA_INTEGER_FMT is the format for writing integers. | 498 | @@ LUA_INTEGER_FMT is the format for writing integers. |
518 | @@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. | 499 | @@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. |
519 | @@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. | 500 | @@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. |
501 | @@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. | ||
502 | @@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED. | ||
520 | @@ lua_integer2str converts an integer to a string. | 503 | @@ lua_integer2str converts an integer to a string. |
521 | */ | 504 | */ |
522 | 505 | ||
@@ -537,6 +520,9 @@ | |||
537 | #define LUA_UNSIGNED unsigned LUAI_UACINT | 520 | #define LUA_UNSIGNED unsigned LUAI_UACINT |
538 | 521 | ||
539 | 522 | ||
523 | #define LUA_UNSIGNEDBITS (sizeof(LUA_UNSIGNED) * CHAR_BIT) | ||
524 | |||
525 | |||
540 | /* now the variable definitions */ | 526 | /* now the variable definitions */ |
541 | 527 | ||
542 | #if LUA_INT_TYPE == LUA_INT_INT /* { int */ | 528 | #if LUA_INT_TYPE == LUA_INT_INT /* { int */ |
@@ -547,6 +533,8 @@ | |||
547 | #define LUA_MAXINTEGER INT_MAX | 533 | #define LUA_MAXINTEGER INT_MAX |
548 | #define LUA_MININTEGER INT_MIN | 534 | #define LUA_MININTEGER INT_MIN |
549 | 535 | ||
536 | #define LUA_MAXUNSIGNED UINT_MAX | ||
537 | |||
550 | #elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ | 538 | #elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ |
551 | 539 | ||
552 | #define LUA_INTEGER long | 540 | #define LUA_INTEGER long |
@@ -555,6 +543,8 @@ | |||
555 | #define LUA_MAXINTEGER LONG_MAX | 543 | #define LUA_MAXINTEGER LONG_MAX |
556 | #define LUA_MININTEGER LONG_MIN | 544 | #define LUA_MININTEGER LONG_MIN |
557 | 545 | ||
546 | #define LUA_MAXUNSIGNED ULONG_MAX | ||
547 | |||
558 | #elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ | 548 | #elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ |
559 | 549 | ||
560 | /* use presence of macro LLONG_MAX as proxy for C99 compliance */ | 550 | /* use presence of macro LLONG_MAX as proxy for C99 compliance */ |
@@ -567,6 +557,8 @@ | |||
567 | #define LUA_MAXINTEGER LLONG_MAX | 557 | #define LUA_MAXINTEGER LLONG_MAX |
568 | #define LUA_MININTEGER LLONG_MIN | 558 | #define LUA_MININTEGER LLONG_MIN |
569 | 559 | ||
560 | #define LUA_MAXUNSIGNED ULLONG_MAX | ||
561 | |||
570 | #elif defined(LUA_USE_WINDOWS) /* }{ */ | 562 | #elif defined(LUA_USE_WINDOWS) /* }{ */ |
571 | /* in Windows, can use specific Windows types */ | 563 | /* in Windows, can use specific Windows types */ |
572 | 564 | ||
@@ -576,6 +568,8 @@ | |||
576 | #define LUA_MAXINTEGER _I64_MAX | 568 | #define LUA_MAXINTEGER _I64_MAX |
577 | #define LUA_MININTEGER _I64_MIN | 569 | #define LUA_MININTEGER _I64_MIN |
578 | 570 | ||
571 | #define LUA_MAXUNSIGNED _UI64_MAX | ||
572 | |||
579 | #else /* }{ */ | 573 | #else /* }{ */ |
580 | 574 | ||
581 | #error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ | 575 | #error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ |
@@ -610,7 +604,7 @@ | |||
610 | 604 | ||
611 | 605 | ||
612 | /* | 606 | /* |
613 | @@ lua_strx2number converts an hexadecimal numeric string to a number. | 607 | @@ lua_strx2number converts a hexadecimal numeral to a number. |
614 | ** In C99, 'strtod' does that conversion. Otherwise, you can | 608 | ** In C99, 'strtod' does that conversion. Otherwise, you can |
615 | ** leave 'lua_strx2number' undefined and Lua will provide its own | 609 | ** leave 'lua_strx2number' undefined and Lua will provide its own |
616 | ** implementation. | 610 | ** implementation. |
@@ -628,7 +622,7 @@ | |||
628 | 622 | ||
629 | 623 | ||
630 | /* | 624 | /* |
631 | @@ lua_number2strx converts a float to an hexadecimal numeric string. | 625 | @@ lua_number2strx converts a float to a hexadecimal numeral. |
632 | ** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. | 626 | ** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. |
633 | ** Otherwise, you can leave 'lua_number2strx' undefined and Lua will | 627 | ** Otherwise, you can leave 'lua_number2strx' undefined and Lua will |
634 | ** provide its own implementation. | 628 | ** provide its own implementation. |
@@ -674,7 +668,7 @@ | |||
674 | /* | 668 | /* |
675 | @@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). | 669 | @@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). |
676 | ** Change that if you do not want to use C locales. (Code using this | 670 | ** Change that if you do not want to use C locales. (Code using this |
677 | ** macro must include header 'locale.h'.) | 671 | ** macro must include the header 'locale.h'.) |
678 | */ | 672 | */ |
679 | #if !defined(lua_getlocaledecpoint) | 673 | #if !defined(lua_getlocaledecpoint) |
680 | #define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) | 674 | #define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) |
@@ -715,7 +709,7 @@ | |||
715 | ** {================================================================== | 709 | ** {================================================================== |
716 | ** Macros that affect the API and must be stable (that is, must be the | 710 | ** Macros that affect the API and must be stable (that is, must be the |
717 | ** same when you compile Lua and when you compile code that links to | 711 | ** same when you compile Lua and when you compile code that links to |
718 | ** Lua). You probably do not want/need to change them. | 712 | ** Lua). |
719 | ** ===================================================================== | 713 | ** ===================================================================== |
720 | */ | 714 | */ |
721 | 715 | ||
@@ -724,8 +718,9 @@ | |||
724 | ** CHANGE it if you need a different limit. This limit is arbitrary; | 718 | ** CHANGE it if you need a different limit. This limit is arbitrary; |
725 | ** its only purpose is to stop Lua from consuming unlimited stack | 719 | ** its only purpose is to stop Lua from consuming unlimited stack |
726 | ** space (and to reserve some numbers for pseudo-indices). | 720 | ** space (and to reserve some numbers for pseudo-indices). |
721 | ** (It must fit into max(size_t)/32.) | ||
727 | */ | 722 | */ |
728 | #if LUAI_BITSINT >= 32 | 723 | #if LUAI_IS32INT |
729 | #define LUAI_MAXSTACK 1000000 | 724 | #define LUAI_MAXSTACK 1000000 |
730 | #else | 725 | #else |
731 | #define LUAI_MAXSTACK 15000 | 726 | #define LUAI_MAXSTACK 15000 |
@@ -750,27 +745,18 @@ | |||
750 | 745 | ||
751 | /* | 746 | /* |
752 | @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. | 747 | @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. |
753 | ** CHANGE it if it uses too much C-stack space. (For long double, | ||
754 | ** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a | ||
755 | ** smaller buffer would force a memory allocation for each call to | ||
756 | ** 'string.format'.) | ||
757 | */ | 748 | */ |
758 | #if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE | 749 | #define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number))) |
759 | #define LUAL_BUFFERSIZE 8192 | ||
760 | #else | ||
761 | #define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) | ||
762 | #endif | ||
763 | |||
764 | /* }================================================================== */ | ||
765 | 750 | ||
766 | 751 | ||
767 | /* | 752 | /* |
768 | @@ LUA_QL describes how error messages quote program elements. | 753 | @@ LUAI_MAXALIGN defines fields that, when used in a union, ensure |
769 | ** Lua does not use these macros anymore; they are here for | 754 | ** maximum alignment for the other items in that union. |
770 | ** compatibility only. | ||
771 | */ | 755 | */ |
772 | #define LUA_QL(x) "'" x "'" | 756 | #define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l |
773 | #define LUA_QS LUA_QL("%s") | 757 | |
758 | /* }================================================================== */ | ||
759 | |||
774 | 760 | ||
775 | 761 | ||
776 | 762 | ||
diff --git a/src/lua-5.3/lualib.h b/src/lua/lualib.h index f5304aa..eb08b53 100644 --- a/src/lua-5.3/lualib.h +++ b/src/lua/lualib.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lualib.h $ |
3 | ** Lua standard libraries | 3 | ** Lua standard libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -35,9 +35,6 @@ LUAMOD_API int (luaopen_string) (lua_State *L); | |||
35 | #define LUA_UTF8LIBNAME "utf8" | 35 | #define LUA_UTF8LIBNAME "utf8" |
36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); | 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); |
37 | 37 | ||
38 | #define LUA_BITLIBNAME "bit32" | ||
39 | LUAMOD_API int (luaopen_bit32) (lua_State *L); | ||
40 | |||
41 | #define LUA_MATHLIBNAME "math" | 38 | #define LUA_MATHLIBNAME "math" |
42 | LUAMOD_API int (luaopen_math) (lua_State *L); | 39 | LUAMOD_API int (luaopen_math) (lua_State *L); |
43 | 40 | ||
diff --git a/src/lua/lundump.c b/src/lua/lundump.c new file mode 100644 index 0000000..4243678 --- /dev/null +++ b/src/lua/lundump.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | ** $Id: lundump.c $ | ||
3 | ** load precompiled Lua chunks | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lundump_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | |||
13 | #include <limits.h> | ||
14 | #include <string.h> | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "ldebug.h" | ||
19 | #include "ldo.h" | ||
20 | #include "lfunc.h" | ||
21 | #include "lmem.h" | ||
22 | #include "lobject.h" | ||
23 | #include "lstring.h" | ||
24 | #include "lundump.h" | ||
25 | #include "lzio.h" | ||
26 | |||
27 | |||
28 | #if !defined(luai_verifycode) | ||
29 | #define luai_verifycode(L,f) /* empty */ | ||
30 | #endif | ||
31 | |||
32 | |||
33 | typedef struct { | ||
34 | lua_State *L; | ||
35 | ZIO *Z; | ||
36 | const char *name; | ||
37 | } LoadState; | ||
38 | |||
39 | |||
40 | static l_noret error (LoadState *S, const char *why) { | ||
41 | luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); | ||
42 | luaD_throw(S->L, LUA_ERRSYNTAX); | ||
43 | } | ||
44 | |||
45 | |||
46 | /* | ||
47 | ** All high-level loads go through loadVector; you can change it to | ||
48 | ** adapt to the endianness of the input | ||
49 | */ | ||
50 | #define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) | ||
51 | |||
52 | static void loadBlock (LoadState *S, void *b, size_t size) { | ||
53 | if (luaZ_read(S->Z, b, size) != 0) | ||
54 | error(S, "truncated chunk"); | ||
55 | } | ||
56 | |||
57 | |||
58 | #define loadVar(S,x) loadVector(S,&x,1) | ||
59 | |||
60 | |||
61 | static lu_byte loadByte (LoadState *S) { | ||
62 | int b = zgetc(S->Z); | ||
63 | if (b == EOZ) | ||
64 | error(S, "truncated chunk"); | ||
65 | return cast_byte(b); | ||
66 | } | ||
67 | |||
68 | |||
69 | static size_t loadUnsigned (LoadState *S, size_t limit) { | ||
70 | size_t x = 0; | ||
71 | int b; | ||
72 | limit >>= 7; | ||
73 | do { | ||
74 | b = loadByte(S); | ||
75 | if (x >= limit) | ||
76 | error(S, "integer overflow"); | ||
77 | x = (x << 7) | (b & 0x7f); | ||
78 | } while ((b & 0x80) == 0); | ||
79 | return x; | ||
80 | } | ||
81 | |||
82 | |||
83 | static size_t loadSize (LoadState *S) { | ||
84 | return loadUnsigned(S, ~(size_t)0); | ||
85 | } | ||
86 | |||
87 | |||
88 | static int loadInt (LoadState *S) { | ||
89 | return cast_int(loadUnsigned(S, INT_MAX)); | ||
90 | } | ||
91 | |||
92 | |||
93 | static lua_Number loadNumber (LoadState *S) { | ||
94 | lua_Number x; | ||
95 | loadVar(S, x); | ||
96 | return x; | ||
97 | } | ||
98 | |||
99 | |||
100 | static lua_Integer loadInteger (LoadState *S) { | ||
101 | lua_Integer x; | ||
102 | loadVar(S, x); | ||
103 | return x; | ||
104 | } | ||
105 | |||
106 | |||
107 | /* | ||
108 | ** Load a nullable string into prototype 'p'. | ||
109 | */ | ||
110 | static TString *loadStringN (LoadState *S, Proto *p) { | ||
111 | lua_State *L = S->L; | ||
112 | TString *ts; | ||
113 | size_t size = loadSize(S); | ||
114 | if (size == 0) /* no string? */ | ||
115 | return NULL; | ||
116 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ | ||
117 | char buff[LUAI_MAXSHORTLEN]; | ||
118 | loadVector(S, buff, size); /* load string into buffer */ | ||
119 | ts = luaS_newlstr(L, buff, size); /* create string */ | ||
120 | } | ||
121 | else { /* long string */ | ||
122 | ts = luaS_createlngstrobj(L, size); /* create string */ | ||
123 | loadVector(S, getstr(ts), size); /* load directly in final place */ | ||
124 | } | ||
125 | luaC_objbarrier(L, p, ts); | ||
126 | return ts; | ||
127 | } | ||
128 | |||
129 | |||
130 | /* | ||
131 | ** Load a non-nullable string into prototype 'p'. | ||
132 | */ | ||
133 | static TString *loadString (LoadState *S, Proto *p) { | ||
134 | TString *st = loadStringN(S, p); | ||
135 | if (st == NULL) | ||
136 | error(S, "bad format for constant string"); | ||
137 | return st; | ||
138 | } | ||
139 | |||
140 | |||
141 | static void loadCode (LoadState *S, Proto *f) { | ||
142 | int n = loadInt(S); | ||
143 | f->code = luaM_newvectorchecked(S->L, n, Instruction); | ||
144 | f->sizecode = n; | ||
145 | loadVector(S, f->code, n); | ||
146 | } | ||
147 | |||
148 | |||
149 | static void loadFunction(LoadState *S, Proto *f, TString *psource); | ||
150 | |||
151 | |||
152 | static void loadConstants (LoadState *S, Proto *f) { | ||
153 | int i; | ||
154 | int n = loadInt(S); | ||
155 | f->k = luaM_newvectorchecked(S->L, n, TValue); | ||
156 | f->sizek = n; | ||
157 | for (i = 0; i < n; i++) | ||
158 | setnilvalue(&f->k[i]); | ||
159 | for (i = 0; i < n; i++) { | ||
160 | TValue *o = &f->k[i]; | ||
161 | int t = loadByte(S); | ||
162 | switch (t) { | ||
163 | case LUA_VNIL: | ||
164 | setnilvalue(o); | ||
165 | break; | ||
166 | case LUA_VFALSE: | ||
167 | setbfvalue(o); | ||
168 | break; | ||
169 | case LUA_VTRUE: | ||
170 | setbtvalue(o); | ||
171 | break; | ||
172 | case LUA_VNUMFLT: | ||
173 | setfltvalue(o, loadNumber(S)); | ||
174 | break; | ||
175 | case LUA_VNUMINT: | ||
176 | setivalue(o, loadInteger(S)); | ||
177 | break; | ||
178 | case LUA_VSHRSTR: | ||
179 | case LUA_VLNGSTR: | ||
180 | setsvalue2n(S->L, o, loadString(S, f)); | ||
181 | break; | ||
182 | default: lua_assert(0); | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | |||
188 | static void loadProtos (LoadState *S, Proto *f) { | ||
189 | int i; | ||
190 | int n = loadInt(S); | ||
191 | f->p = luaM_newvectorchecked(S->L, n, Proto *); | ||
192 | f->sizep = n; | ||
193 | for (i = 0; i < n; i++) | ||
194 | f->p[i] = NULL; | ||
195 | for (i = 0; i < n; i++) { | ||
196 | f->p[i] = luaF_newproto(S->L); | ||
197 | luaC_objbarrier(S->L, f, f->p[i]); | ||
198 | loadFunction(S, f->p[i], f->source); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | |||
203 | static void loadUpvalues (LoadState *S, Proto *f) { | ||
204 | int i, n; | ||
205 | n = loadInt(S); | ||
206 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); | ||
207 | f->sizeupvalues = n; | ||
208 | for (i = 0; i < n; i++) { | ||
209 | f->upvalues[i].name = NULL; | ||
210 | f->upvalues[i].instack = loadByte(S); | ||
211 | f->upvalues[i].idx = loadByte(S); | ||
212 | f->upvalues[i].kind = loadByte(S); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | static void loadDebug (LoadState *S, Proto *f) { | ||
218 | int i, n; | ||
219 | n = loadInt(S); | ||
220 | f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); | ||
221 | f->sizelineinfo = n; | ||
222 | loadVector(S, f->lineinfo, n); | ||
223 | n = loadInt(S); | ||
224 | f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); | ||
225 | f->sizeabslineinfo = n; | ||
226 | for (i = 0; i < n; i++) { | ||
227 | f->abslineinfo[i].pc = loadInt(S); | ||
228 | f->abslineinfo[i].line = loadInt(S); | ||
229 | } | ||
230 | n = loadInt(S); | ||
231 | f->locvars = luaM_newvectorchecked(S->L, n, LocVar); | ||
232 | f->sizelocvars = n; | ||
233 | for (i = 0; i < n; i++) | ||
234 | f->locvars[i].varname = NULL; | ||
235 | for (i = 0; i < n; i++) { | ||
236 | f->locvars[i].varname = loadStringN(S, f); | ||
237 | f->locvars[i].startpc = loadInt(S); | ||
238 | f->locvars[i].endpc = loadInt(S); | ||
239 | } | ||
240 | n = loadInt(S); | ||
241 | for (i = 0; i < n; i++) | ||
242 | f->upvalues[i].name = loadStringN(S, f); | ||
243 | } | ||
244 | |||
245 | |||
246 | static void loadFunction (LoadState *S, Proto *f, TString *psource) { | ||
247 | f->source = loadStringN(S, f); | ||
248 | if (f->source == NULL) /* no source in dump? */ | ||
249 | f->source = psource; /* reuse parent's source */ | ||
250 | f->linedefined = loadInt(S); | ||
251 | f->lastlinedefined = loadInt(S); | ||
252 | f->numparams = loadByte(S); | ||
253 | f->is_vararg = loadByte(S); | ||
254 | f->maxstacksize = loadByte(S); | ||
255 | loadCode(S, f); | ||
256 | loadConstants(S, f); | ||
257 | loadUpvalues(S, f); | ||
258 | loadProtos(S, f); | ||
259 | loadDebug(S, f); | ||
260 | } | ||
261 | |||
262 | |||
263 | static void checkliteral (LoadState *S, const char *s, const char *msg) { | ||
264 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ | ||
265 | size_t len = strlen(s); | ||
266 | loadVector(S, buff, len); | ||
267 | if (memcmp(s, buff, len) != 0) | ||
268 | error(S, msg); | ||
269 | } | ||
270 | |||
271 | |||
272 | static void fchecksize (LoadState *S, size_t size, const char *tname) { | ||
273 | if (loadByte(S) != size) | ||
274 | error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); | ||
275 | } | ||
276 | |||
277 | |||
278 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) | ||
279 | |||
280 | static void checkHeader (LoadState *S) { | ||
281 | /* skip 1st char (already read and checked) */ | ||
282 | checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); | ||
283 | if (loadByte(S) != LUAC_VERSION) | ||
284 | error(S, "version mismatch"); | ||
285 | if (loadByte(S) != LUAC_FORMAT) | ||
286 | error(S, "format mismatch"); | ||
287 | checkliteral(S, LUAC_DATA, "corrupted chunk"); | ||
288 | checksize(S, Instruction); | ||
289 | checksize(S, lua_Integer); | ||
290 | checksize(S, lua_Number); | ||
291 | if (loadInteger(S) != LUAC_INT) | ||
292 | error(S, "integer format mismatch"); | ||
293 | if (loadNumber(S) != LUAC_NUM) | ||
294 | error(S, "float format mismatch"); | ||
295 | } | ||
296 | |||
297 | |||
298 | /* | ||
299 | ** Load precompiled chunk. | ||
300 | */ | ||
301 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { | ||
302 | LoadState S; | ||
303 | LClosure *cl; | ||
304 | if (*name == '@' || *name == '=') | ||
305 | S.name = name + 1; | ||
306 | else if (*name == LUA_SIGNATURE[0]) | ||
307 | S.name = "binary string"; | ||
308 | else | ||
309 | S.name = name; | ||
310 | S.L = L; | ||
311 | S.Z = Z; | ||
312 | checkHeader(&S); | ||
313 | cl = luaF_newLclosure(L, loadByte(&S)); | ||
314 | setclLvalue2s(L, L->top, cl); | ||
315 | luaD_inctop(L); | ||
316 | cl->p = luaF_newproto(L); | ||
317 | luaC_objbarrier(L, cl, cl->p); | ||
318 | loadFunction(&S, cl->p, NULL); | ||
319 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); | ||
320 | luai_verifycode(L, cl->p); | ||
321 | return cl; | ||
322 | } | ||
323 | |||
diff --git a/src/lua-5.3/lundump.h b/src/lua/lundump.h index ce492d6..f3748a9 100644 --- a/src/lua-5.3/lundump.h +++ b/src/lua/lundump.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lundump.h $ |
3 | ** load precompiled Lua chunks | 3 | ** load precompiled Lua chunks |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -18,8 +18,12 @@ | |||
18 | #define LUAC_INT 0x5678 | 18 | #define LUAC_INT 0x5678 |
19 | #define LUAC_NUM cast_num(370.5) | 19 | #define LUAC_NUM cast_num(370.5) |
20 | 20 | ||
21 | #define MYINT(s) (s[0]-'0') | 21 | /* |
22 | ** Encode major-minor version in one byte, one nibble for each | ||
23 | */ | ||
24 | #define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ | ||
22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) | 25 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) |
26 | |||
23 | #define LUAC_FORMAT 0 /* this is the official format */ | 27 | #define LUAC_FORMAT 0 /* this is the official format */ |
24 | 28 | ||
25 | /* load one chunk; from lundump.c */ | 29 | /* load one chunk; from lundump.c */ |
diff --git a/src/lua-5.3/lutf8lib.c b/src/lua/lutf8lib.c index 10bd238..901d985 100644 --- a/src/lua-5.3/lutf8lib.c +++ b/src/lua/lutf8lib.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $ | 2 | ** $Id: lutf8lib.c $ |
3 | ** Standard library for UTF-8 manipulation | 3 | ** Standard library for UTF-8 manipulation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -20,7 +20,20 @@ | |||
20 | #include "lauxlib.h" | 20 | #include "lauxlib.h" |
21 | #include "lualib.h" | 21 | #include "lualib.h" |
22 | 22 | ||
23 | #define MAXUNICODE 0x10FFFF | 23 | |
24 | #define MAXUNICODE 0x10FFFFu | ||
25 | |||
26 | #define MAXUTF 0x7FFFFFFFu | ||
27 | |||
28 | /* | ||
29 | ** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits. | ||
30 | */ | ||
31 | #if (UINT_MAX >> 30) >= 1 | ||
32 | typedef unsigned int utfint; | ||
33 | #else | ||
34 | typedef unsigned long utfint; | ||
35 | #endif | ||
36 | |||
24 | 37 | ||
25 | #define iscont(p) ((*(p) & 0xC0) == 0x80) | 38 | #define iscont(p) ((*(p) & 0xC0) == 0x80) |
26 | 39 | ||
@@ -35,53 +48,62 @@ static lua_Integer u_posrelat (lua_Integer pos, size_t len) { | |||
35 | 48 | ||
36 | 49 | ||
37 | /* | 50 | /* |
38 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. | 51 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is |
52 | ** invalid. The array 'limits' stores the minimum value for each | ||
53 | ** sequence length, to check for overlong representations. Its first | ||
54 | ** entry forces an error for non-ascii bytes with no continuation | ||
55 | ** bytes (count == 0). | ||
39 | */ | 56 | */ |
40 | static const char *utf8_decode (const char *o, int *val) { | 57 | static const char *utf8_decode (const char *s, utfint *val, int strict) { |
41 | static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; | 58 | static const utfint limits[] = |
42 | const unsigned char *s = (const unsigned char *)o; | 59 | {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; |
43 | unsigned int c = s[0]; | 60 | unsigned int c = (unsigned char)s[0]; |
44 | unsigned int res = 0; /* final result */ | 61 | utfint res = 0; /* final result */ |
45 | if (c < 0x80) /* ascii? */ | 62 | if (c < 0x80) /* ascii? */ |
46 | res = c; | 63 | res = c; |
47 | else { | 64 | else { |
48 | int count = 0; /* to count number of continuation bytes */ | 65 | int count = 0; /* to count number of continuation bytes */ |
49 | while (c & 0x40) { /* still have continuation bytes? */ | 66 | for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ |
50 | int cc = s[++count]; /* read next byte */ | 67 | unsigned int cc = (unsigned char)s[++count]; /* read next byte */ |
51 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ | 68 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ |
52 | return NULL; /* invalid byte sequence */ | 69 | return NULL; /* invalid byte sequence */ |
53 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ | 70 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ |
54 | c <<= 1; /* to test next bit */ | ||
55 | } | 71 | } |
56 | res |= ((c & 0x7F) << (count * 5)); /* add first byte */ | 72 | res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ |
57 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) | 73 | if (count > 5 || res > MAXUTF || res < limits[count]) |
58 | return NULL; /* invalid byte sequence */ | 74 | return NULL; /* invalid byte sequence */ |
59 | s += count; /* skip continuation bytes read */ | 75 | s += count; /* skip continuation bytes read */ |
60 | } | 76 | } |
77 | if (strict) { | ||
78 | /* check for invalid code points; too large or surrogates */ | ||
79 | if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu)) | ||
80 | return NULL; | ||
81 | } | ||
61 | if (val) *val = res; | 82 | if (val) *val = res; |
62 | return (const char *)s + 1; /* +1 to include first byte */ | 83 | return s + 1; /* +1 to include first byte */ |
63 | } | 84 | } |
64 | 85 | ||
65 | 86 | ||
66 | /* | 87 | /* |
67 | ** utf8len(s [, i [, j]]) --> number of characters that start in the | 88 | ** utf8len(s [, i [, j [, lax]]]) --> number of characters that |
68 | ** range [i,j], or nil + current position if 's' is not well formed in | 89 | ** start in the range [i,j], or nil + current position if 's' is not |
69 | ** that interval | 90 | ** well formed in that interval |
70 | */ | 91 | */ |
71 | static int utflen (lua_State *L) { | 92 | static int utflen (lua_State *L) { |
72 | int n = 0; | 93 | lua_Integer n = 0; /* counter for the number of characters */ |
73 | size_t len; | 94 | size_t len; /* string length in bytes */ |
74 | const char *s = luaL_checklstring(L, 1, &len); | 95 | const char *s = luaL_checklstring(L, 1, &len); |
75 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); | 96 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); |
76 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); | 97 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); |
98 | int lax = lua_toboolean(L, 4); | ||
77 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, | 99 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, |
78 | "initial position out of string"); | 100 | "initial position out of bounds"); |
79 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, | 101 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, |
80 | "final position out of string"); | 102 | "final position out of bounds"); |
81 | while (posi <= posj) { | 103 | while (posi <= posj) { |
82 | const char *s1 = utf8_decode(s + posi, NULL); | 104 | const char *s1 = utf8_decode(s + posi, NULL, !lax); |
83 | if (s1 == NULL) { /* conversion error? */ | 105 | if (s1 == NULL) { /* conversion error? */ |
84 | lua_pushnil(L); /* return nil ... */ | 106 | luaL_pushfail(L); /* return fail ... */ |
85 | lua_pushinteger(L, posi + 1); /* ... and current position */ | 107 | lua_pushinteger(L, posi + 1); /* ... and current position */ |
86 | return 2; | 108 | return 2; |
87 | } | 109 | } |
@@ -94,28 +116,29 @@ static int utflen (lua_State *L) { | |||
94 | 116 | ||
95 | 117 | ||
96 | /* | 118 | /* |
97 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters | 119 | ** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all |
98 | ** that start in the range [i,j] | 120 | ** characters that start in the range [i,j] |
99 | */ | 121 | */ |
100 | static int codepoint (lua_State *L) { | 122 | static int codepoint (lua_State *L) { |
101 | size_t len; | 123 | size_t len; |
102 | const char *s = luaL_checklstring(L, 1, &len); | 124 | const char *s = luaL_checklstring(L, 1, &len); |
103 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); | 125 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); |
104 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); | 126 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); |
127 | int lax = lua_toboolean(L, 4); | ||
105 | int n; | 128 | int n; |
106 | const char *se; | 129 | const char *se; |
107 | luaL_argcheck(L, posi >= 1, 2, "out of range"); | 130 | luaL_argcheck(L, posi >= 1, 2, "out of bounds"); |
108 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); | 131 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds"); |
109 | if (posi > pose) return 0; /* empty interval; return no values */ | 132 | if (posi > pose) return 0; /* empty interval; return no values */ |
110 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ | 133 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ |
111 | return luaL_error(L, "string slice too long"); | 134 | return luaL_error(L, "string slice too long"); |
112 | n = (int)(pose - posi) + 1; | 135 | n = (int)(pose - posi) + 1; /* upper bound for number of returns */ |
113 | luaL_checkstack(L, n, "string slice too long"); | 136 | luaL_checkstack(L, n, "string slice too long"); |
114 | n = 0; | 137 | n = 0; /* count the number of returns */ |
115 | se = s + pose; | 138 | se = s + pose; /* string end */ |
116 | for (s += posi - 1; s < se;) { | 139 | for (s += posi - 1; s < se;) { |
117 | int code; | 140 | utfint code; |
118 | s = utf8_decode(s, &code); | 141 | s = utf8_decode(s, &code, !lax); |
119 | if (s == NULL) | 142 | if (s == NULL) |
120 | return luaL_error(L, "invalid UTF-8 code"); | 143 | return luaL_error(L, "invalid UTF-8 code"); |
121 | lua_pushinteger(L, code); | 144 | lua_pushinteger(L, code); |
@@ -126,8 +149,8 @@ static int codepoint (lua_State *L) { | |||
126 | 149 | ||
127 | 150 | ||
128 | static void pushutfchar (lua_State *L, int arg) { | 151 | static void pushutfchar (lua_State *L, int arg) { |
129 | lua_Integer code = luaL_checkinteger(L, arg); | 152 | lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg); |
130 | luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); | 153 | luaL_argcheck(L, code <= MAXUTF, arg, "value out of range"); |
131 | lua_pushfstring(L, "%U", (long)code); | 154 | lua_pushfstring(L, "%U", (long)code); |
132 | } | 155 | } |
133 | 156 | ||
@@ -164,7 +187,7 @@ static int byteoffset (lua_State *L) { | |||
164 | lua_Integer posi = (n >= 0) ? 1 : len + 1; | 187 | lua_Integer posi = (n >= 0) ? 1 : len + 1; |
165 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); | 188 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); |
166 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, | 189 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, |
167 | "position out of range"); | 190 | "position out of bounds"); |
168 | if (n == 0) { | 191 | if (n == 0) { |
169 | /* find beginning of current byte sequence */ | 192 | /* find beginning of current byte sequence */ |
170 | while (posi > 0 && iscont(s + posi)) posi--; | 193 | while (posi > 0 && iscont(s + posi)) posi--; |
@@ -193,12 +216,12 @@ static int byteoffset (lua_State *L) { | |||
193 | if (n == 0) /* did it find given character? */ | 216 | if (n == 0) /* did it find given character? */ |
194 | lua_pushinteger(L, posi + 1); | 217 | lua_pushinteger(L, posi + 1); |
195 | else /* no such character */ | 218 | else /* no such character */ |
196 | lua_pushnil(L); | 219 | luaL_pushfail(L); |
197 | return 1; | 220 | return 1; |
198 | } | 221 | } |
199 | 222 | ||
200 | 223 | ||
201 | static int iter_aux (lua_State *L) { | 224 | static int iter_aux (lua_State *L, int strict) { |
202 | size_t len; | 225 | size_t len; |
203 | const char *s = luaL_checklstring(L, 1, &len); | 226 | const char *s = luaL_checklstring(L, 1, &len); |
204 | lua_Integer n = lua_tointeger(L, 2) - 1; | 227 | lua_Integer n = lua_tointeger(L, 2) - 1; |
@@ -211,9 +234,9 @@ static int iter_aux (lua_State *L) { | |||
211 | if (n >= (lua_Integer)len) | 234 | if (n >= (lua_Integer)len) |
212 | return 0; /* no more codepoints */ | 235 | return 0; /* no more codepoints */ |
213 | else { | 236 | else { |
214 | int code; | 237 | utfint code; |
215 | const char *next = utf8_decode(s + n, &code); | 238 | const char *next = utf8_decode(s + n, &code, strict); |
216 | if (next == NULL || iscont(next)) | 239 | if (next == NULL) |
217 | return luaL_error(L, "invalid UTF-8 code"); | 240 | return luaL_error(L, "invalid UTF-8 code"); |
218 | lua_pushinteger(L, n + 1); | 241 | lua_pushinteger(L, n + 1); |
219 | lua_pushinteger(L, code); | 242 | lua_pushinteger(L, code); |
@@ -222,9 +245,19 @@ static int iter_aux (lua_State *L) { | |||
222 | } | 245 | } |
223 | 246 | ||
224 | 247 | ||
248 | static int iter_auxstrict (lua_State *L) { | ||
249 | return iter_aux(L, 1); | ||
250 | } | ||
251 | |||
252 | static int iter_auxlax (lua_State *L) { | ||
253 | return iter_aux(L, 0); | ||
254 | } | ||
255 | |||
256 | |||
225 | static int iter_codes (lua_State *L) { | 257 | static int iter_codes (lua_State *L) { |
258 | int lax = lua_toboolean(L, 2); | ||
226 | luaL_checkstring(L, 1); | 259 | luaL_checkstring(L, 1); |
227 | lua_pushcfunction(L, iter_aux); | 260 | lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict); |
228 | lua_pushvalue(L, 1); | 261 | lua_pushvalue(L, 1); |
229 | lua_pushinteger(L, 0); | 262 | lua_pushinteger(L, 0); |
230 | return 3; | 263 | return 3; |
@@ -232,7 +265,7 @@ static int iter_codes (lua_State *L) { | |||
232 | 265 | ||
233 | 266 | ||
234 | /* pattern to match a single UTF-8 character */ | 267 | /* pattern to match a single UTF-8 character */ |
235 | #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" | 268 | #define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" |
236 | 269 | ||
237 | 270 | ||
238 | static const luaL_Reg funcs[] = { | 271 | static const luaL_Reg funcs[] = { |
diff --git a/src/lua/lvm.c b/src/lua/lvm.c new file mode 100644 index 0000000..e7781db --- /dev/null +++ b/src/lua/lvm.c | |||
@@ -0,0 +1,1812 @@ | |||
1 | /* | ||
2 | ** $Id: lvm.c $ | ||
3 | ** Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #define lvm_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | #include "lprefix.h" | ||
11 | |||
12 | #include <float.h> | ||
13 | #include <limits.h> | ||
14 | #include <math.h> | ||
15 | #include <stdio.h> | ||
16 | #include <stdlib.h> | ||
17 | #include <string.h> | ||
18 | |||
19 | #include "lua.h" | ||
20 | |||
21 | #include "ldebug.h" | ||
22 | #include "ldo.h" | ||
23 | #include "lfunc.h" | ||
24 | #include "lgc.h" | ||
25 | #include "lobject.h" | ||
26 | #include "lopcodes.h" | ||
27 | #include "lstate.h" | ||
28 | #include "lstring.h" | ||
29 | #include "ltable.h" | ||
30 | #include "ltm.h" | ||
31 | #include "lvm.h" | ||
32 | |||
33 | |||
34 | /* | ||
35 | ** By default, use jump tables in the main interpreter loop on gcc | ||
36 | ** and compatible compilers. | ||
37 | */ | ||
38 | #if !defined(LUA_USE_JUMPTABLE) | ||
39 | #if defined(__GNUC__) | ||
40 | #define LUA_USE_JUMPTABLE 1 | ||
41 | #else | ||
42 | #define LUA_USE_JUMPTABLE 0 | ||
43 | #endif | ||
44 | #endif | ||
45 | |||
46 | |||
47 | |||
48 | /* limit for table tag-method chains (to avoid infinite loops) */ | ||
49 | #define MAXTAGLOOP 2000 | ||
50 | |||
51 | |||
52 | /* | ||
53 | ** 'l_intfitsf' checks whether a given integer is in the range that | ||
54 | ** can be converted to a float without rounding. Used in comparisons. | ||
55 | */ | ||
56 | |||
57 | /* number of bits in the mantissa of a float */ | ||
58 | #define NBM (l_floatatt(MANT_DIG)) | ||
59 | |||
60 | /* | ||
61 | ** Check whether some integers may not fit in a float, testing whether | ||
62 | ** (maxinteger >> NBM) > 0. (That implies (1 << NBM) <= maxinteger.) | ||
63 | ** (The shifts are done in parts, to avoid shifting by more than the size | ||
64 | ** of an integer. In a worst case, NBM == 113 for long double and | ||
65 | ** sizeof(long) == 32.) | ||
66 | */ | ||
67 | #if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \ | ||
68 | >> (NBM - (3 * (NBM / 4)))) > 0 | ||
69 | |||
70 | /* limit for integers that fit in a float */ | ||
71 | #define MAXINTFITSF ((lua_Unsigned)1 << NBM) | ||
72 | |||
73 | /* check whether 'i' is in the interval [-MAXINTFITSF, MAXINTFITSF] */ | ||
74 | #define l_intfitsf(i) ((MAXINTFITSF + l_castS2U(i)) <= (2 * MAXINTFITSF)) | ||
75 | |||
76 | #else /* all integers fit in a float precisely */ | ||
77 | |||
78 | #define l_intfitsf(i) 1 | ||
79 | |||
80 | #endif | ||
81 | |||
82 | |||
83 | /* | ||
84 | ** Try to convert a value from string to a number value. | ||
85 | ** If the value is not a string or is a string not representing | ||
86 | ** a valid numeral (or if coercions from strings to numbers | ||
87 | ** are disabled via macro 'cvt2num'), do not modify 'result' | ||
88 | ** and return 0. | ||
89 | */ | ||
90 | static int l_strton (const TValue *obj, TValue *result) { | ||
91 | lua_assert(obj != result); | ||
92 | if (!cvt2num(obj)) /* is object not a string? */ | ||
93 | return 0; | ||
94 | else | ||
95 | return (luaO_str2num(svalue(obj), result) == vslen(obj) + 1); | ||
96 | } | ||
97 | |||
98 | |||
99 | /* | ||
100 | ** Try to convert a value to a float. The float case is already handled | ||
101 | ** by the macro 'tonumber'. | ||
102 | */ | ||
103 | int luaV_tonumber_ (const TValue *obj, lua_Number *n) { | ||
104 | TValue v; | ||
105 | if (ttisinteger(obj)) { | ||
106 | *n = cast_num(ivalue(obj)); | ||
107 | return 1; | ||
108 | } | ||
109 | else if (l_strton(obj, &v)) { /* string coercible to number? */ | ||
110 | *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ | ||
111 | return 1; | ||
112 | } | ||
113 | else | ||
114 | return 0; /* conversion failed */ | ||
115 | } | ||
116 | |||
117 | |||
118 | /* | ||
119 | ** try to convert a float to an integer, rounding according to 'mode'. | ||
120 | */ | ||
121 | int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode) { | ||
122 | lua_Number f = l_floor(n); | ||
123 | if (n != f) { /* not an integral value? */ | ||
124 | if (mode == F2Ieq) return 0; /* fails if mode demands integral value */ | ||
125 | else if (mode == F2Iceil) /* needs ceil? */ | ||
126 | f += 1; /* convert floor to ceil (remember: n != f) */ | ||
127 | } | ||
128 | return lua_numbertointeger(f, p); | ||
129 | } | ||
130 | |||
131 | |||
132 | /* | ||
133 | ** try to convert a value to an integer, rounding according to 'mode', | ||
134 | ** without string coercion. | ||
135 | ** ("Fast track" handled by macro 'tointegerns'.) | ||
136 | */ | ||
137 | int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode) { | ||
138 | if (ttisfloat(obj)) | ||
139 | return luaV_flttointeger(fltvalue(obj), p, mode); | ||
140 | else if (ttisinteger(obj)) { | ||
141 | *p = ivalue(obj); | ||
142 | return 1; | ||
143 | } | ||
144 | else | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | |||
149 | /* | ||
150 | ** try to convert a value to an integer. | ||
151 | */ | ||
152 | int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode) { | ||
153 | TValue v; | ||
154 | if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ | ||
155 | obj = &v; /* change it to point to its corresponding number */ | ||
156 | return luaV_tointegerns(obj, p, mode); | ||
157 | } | ||
158 | |||
159 | |||
160 | /* | ||
161 | ** Try to convert a 'for' limit to an integer, preserving the semantics | ||
162 | ** of the loop. Return true if the loop must not run; otherwise, '*p' | ||
163 | ** gets the integer limit. | ||
164 | ** (The following explanation assumes a positive step; it is valid for | ||
165 | ** negative steps mutatis mutandis.) | ||
166 | ** If the limit is an integer or can be converted to an integer, | ||
167 | ** rounding down, that is the limit. | ||
168 | ** Otherwise, check whether the limit can be converted to a float. If | ||
169 | ** the float is too large, clip it to LUA_MAXINTEGER. If the float | ||
170 | ** is too negative, the loop should not run, because any initial | ||
171 | ** integer value is greater than such limit; so, the function returns | ||
172 | ** true to signal that. (For this latter case, no integer limit would be | ||
173 | ** correct; even a limit of LUA_MININTEGER would run the loop once for | ||
174 | ** an initial value equal to LUA_MININTEGER.) | ||
175 | */ | ||
176 | static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, | ||
177 | lua_Integer *p, lua_Integer step) { | ||
178 | if (!luaV_tointeger(lim, p, (step < 0 ? F2Iceil : F2Ifloor))) { | ||
179 | /* not coercible to in integer */ | ||
180 | lua_Number flim; /* try to convert to float */ | ||
181 | if (!tonumber(lim, &flim)) /* cannot convert to float? */ | ||
182 | luaG_forerror(L, lim, "limit"); | ||
183 | /* else 'flim' is a float out of integer bounds */ | ||
184 | if (luai_numlt(0, flim)) { /* if it is positive, it is too large */ | ||
185 | if (step < 0) return 1; /* initial value must be less than it */ | ||
186 | *p = LUA_MAXINTEGER; /* truncate */ | ||
187 | } | ||
188 | else { /* it is less than min integer */ | ||
189 | if (step > 0) return 1; /* initial value must be greater than it */ | ||
190 | *p = LUA_MININTEGER; /* truncate */ | ||
191 | } | ||
192 | } | ||
193 | return (step > 0 ? init > *p : init < *p); /* not to run? */ | ||
194 | } | ||
195 | |||
196 | |||
197 | /* | ||
198 | ** Prepare a numerical for loop (opcode OP_FORPREP). | ||
199 | ** Return true to skip the loop. Otherwise, | ||
200 | ** after preparation, stack will be as follows: | ||
201 | ** ra : internal index (safe copy of the control variable) | ||
202 | ** ra + 1 : loop counter (integer loops) or limit (float loops) | ||
203 | ** ra + 2 : step | ||
204 | ** ra + 3 : control variable | ||
205 | */ | ||
206 | static int forprep (lua_State *L, StkId ra) { | ||
207 | TValue *pinit = s2v(ra); | ||
208 | TValue *plimit = s2v(ra + 1); | ||
209 | TValue *pstep = s2v(ra + 2); | ||
210 | if (ttisinteger(pinit) && ttisinteger(pstep)) { /* integer loop? */ | ||
211 | lua_Integer init = ivalue(pinit); | ||
212 | lua_Integer step = ivalue(pstep); | ||
213 | lua_Integer limit; | ||
214 | if (step == 0) | ||
215 | luaG_runerror(L, "'for' step is zero"); | ||
216 | setivalue(s2v(ra + 3), init); /* control variable */ | ||
217 | if (forlimit(L, init, plimit, &limit, step)) | ||
218 | return 1; /* skip the loop */ | ||
219 | else { /* prepare loop counter */ | ||
220 | lua_Unsigned count; | ||
221 | if (step > 0) { /* ascending loop? */ | ||
222 | count = l_castS2U(limit) - l_castS2U(init); | ||
223 | if (step != 1) /* avoid division in the too common case */ | ||
224 | count /= l_castS2U(step); | ||
225 | } | ||
226 | else { /* step < 0; descending loop */ | ||
227 | count = l_castS2U(init) - l_castS2U(limit); | ||
228 | /* 'step+1' avoids negating 'mininteger' */ | ||
229 | count /= l_castS2U(-(step + 1)) + 1u; | ||
230 | } | ||
231 | /* store the counter in place of the limit (which won't be | ||
232 | needed anymore */ | ||
233 | setivalue(plimit, l_castU2S(count)); | ||
234 | } | ||
235 | } | ||
236 | else { /* try making all values floats */ | ||
237 | lua_Number init; lua_Number limit; lua_Number step; | ||
238 | if (unlikely(!tonumber(plimit, &limit))) | ||
239 | luaG_forerror(L, plimit, "limit"); | ||
240 | if (unlikely(!tonumber(pstep, &step))) | ||
241 | luaG_forerror(L, pstep, "step"); | ||
242 | if (unlikely(!tonumber(pinit, &init))) | ||
243 | luaG_forerror(L, pinit, "initial value"); | ||
244 | if (step == 0) | ||
245 | luaG_runerror(L, "'for' step is zero"); | ||
246 | if (luai_numlt(0, step) ? luai_numlt(limit, init) | ||
247 | : luai_numlt(init, limit)) | ||
248 | return 1; /* skip the loop */ | ||
249 | else { | ||
250 | /* make sure internal values are all floats */ | ||
251 | setfltvalue(plimit, limit); | ||
252 | setfltvalue(pstep, step); | ||
253 | setfltvalue(s2v(ra), init); /* internal index */ | ||
254 | setfltvalue(s2v(ra + 3), init); /* control variable */ | ||
255 | } | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | |||
261 | /* | ||
262 | ** Execute a step of a float numerical for loop, returning | ||
263 | ** true iff the loop must continue. (The integer case is | ||
264 | ** written online with opcode OP_FORLOOP, for performance.) | ||
265 | */ | ||
266 | static int floatforloop (StkId ra) { | ||
267 | lua_Number step = fltvalue(s2v(ra + 2)); | ||
268 | lua_Number limit = fltvalue(s2v(ra + 1)); | ||
269 | lua_Number idx = fltvalue(s2v(ra)); /* internal index */ | ||
270 | idx = luai_numadd(L, idx, step); /* increment index */ | ||
271 | if (luai_numlt(0, step) ? luai_numle(idx, limit) | ||
272 | : luai_numle(limit, idx)) { | ||
273 | chgfltvalue(s2v(ra), idx); /* update internal index */ | ||
274 | setfltvalue(s2v(ra + 3), idx); /* and control variable */ | ||
275 | return 1; /* jump back */ | ||
276 | } | ||
277 | else | ||
278 | return 0; /* finish the loop */ | ||
279 | } | ||
280 | |||
281 | |||
282 | /* | ||
283 | ** Finish the table access 'val = t[key]'. | ||
284 | ** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to | ||
285 | ** t[k] entry (which must be empty). | ||
286 | */ | ||
287 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | ||
288 | const TValue *slot) { | ||
289 | int loop; /* counter to avoid infinite loops */ | ||
290 | const TValue *tm; /* metamethod */ | ||
291 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | ||
292 | if (slot == NULL) { /* 't' is not a table? */ | ||
293 | lua_assert(!ttistable(t)); | ||
294 | tm = luaT_gettmbyobj(L, t, TM_INDEX); | ||
295 | if (unlikely(notm(tm))) | ||
296 | luaG_typeerror(L, t, "index"); /* no metamethod */ | ||
297 | /* else will try the metamethod */ | ||
298 | } | ||
299 | else { /* 't' is a table */ | ||
300 | lua_assert(isempty(slot)); | ||
301 | tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ | ||
302 | if (tm == NULL) { /* no metamethod? */ | ||
303 | setnilvalue(s2v(val)); /* result is nil */ | ||
304 | return; | ||
305 | } | ||
306 | /* else will try the metamethod */ | ||
307 | } | ||
308 | if (ttisfunction(tm)) { /* is metamethod a function? */ | ||
309 | luaT_callTMres(L, tm, t, key, val); /* call it */ | ||
310 | return; | ||
311 | } | ||
312 | t = tm; /* else try to access 'tm[key]' */ | ||
313 | if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */ | ||
314 | setobj2s(L, val, slot); /* done */ | ||
315 | return; | ||
316 | } | ||
317 | /* else repeat (tail call 'luaV_finishget') */ | ||
318 | } | ||
319 | luaG_runerror(L, "'__index' chain too long; possible loop"); | ||
320 | } | ||
321 | |||
322 | |||
323 | /* | ||
324 | ** Finish a table assignment 't[key] = val'. | ||
325 | ** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points | ||
326 | ** to the entry 't[key]', or to a value with an absent key if there | ||
327 | ** is no such entry. (The value at 'slot' must be empty, otherwise | ||
328 | ** 'luaV_fastget' would have done the job.) | ||
329 | */ | ||
330 | void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | ||
331 | TValue *val, const TValue *slot) { | ||
332 | int loop; /* counter to avoid infinite loops */ | ||
333 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | ||
334 | const TValue *tm; /* '__newindex' metamethod */ | ||
335 | if (slot != NULL) { /* is 't' a table? */ | ||
336 | Table *h = hvalue(t); /* save 't' table */ | ||
337 | lua_assert(isempty(slot)); /* slot must be empty */ | ||
338 | tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ | ||
339 | if (tm == NULL) { /* no metamethod? */ | ||
340 | if (isabstkey(slot)) /* no previous entry? */ | ||
341 | slot = luaH_newkey(L, h, key); /* create one */ | ||
342 | /* no metamethod and (now) there is an entry with given key */ | ||
343 | setobj2t(L, cast(TValue *, slot), val); /* set its new value */ | ||
344 | invalidateTMcache(h); | ||
345 | luaC_barrierback(L, obj2gco(h), val); | ||
346 | return; | ||
347 | } | ||
348 | /* else will try the metamethod */ | ||
349 | } | ||
350 | else { /* not a table; check metamethod */ | ||
351 | tm = luaT_gettmbyobj(L, t, TM_NEWINDEX); | ||
352 | if (unlikely(notm(tm))) | ||
353 | luaG_typeerror(L, t, "index"); | ||
354 | } | ||
355 | /* try the metamethod */ | ||
356 | if (ttisfunction(tm)) { | ||
357 | luaT_callTM(L, tm, t, key, val); | ||
358 | return; | ||
359 | } | ||
360 | t = tm; /* else repeat assignment over 'tm' */ | ||
361 | if (luaV_fastget(L, t, key, slot, luaH_get)) { | ||
362 | luaV_finishfastset(L, t, slot, val); | ||
363 | return; /* done */ | ||
364 | } | ||
365 | /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ | ||
366 | } | ||
367 | luaG_runerror(L, "'__newindex' chain too long; possible loop"); | ||
368 | } | ||
369 | |||
370 | |||
371 | /* | ||
372 | ** Compare two strings 'ls' x 'rs', returning an integer less-equal- | ||
373 | ** -greater than zero if 'ls' is less-equal-greater than 'rs'. | ||
374 | ** The code is a little tricky because it allows '\0' in the strings | ||
375 | ** and it uses 'strcoll' (to respect locales) for each segments | ||
376 | ** of the strings. | ||
377 | */ | ||
378 | static int l_strcmp (const TString *ls, const TString *rs) { | ||
379 | const char *l = getstr(ls); | ||
380 | size_t ll = tsslen(ls); | ||
381 | const char *r = getstr(rs); | ||
382 | size_t lr = tsslen(rs); | ||
383 | for (;;) { /* for each segment */ | ||
384 | int temp = strcoll(l, r); | ||
385 | if (temp != 0) /* not equal? */ | ||
386 | return temp; /* done */ | ||
387 | else { /* strings are equal up to a '\0' */ | ||
388 | size_t len = strlen(l); /* index of first '\0' in both strings */ | ||
389 | if (len == lr) /* 'rs' is finished? */ | ||
390 | return (len == ll) ? 0 : 1; /* check 'ls' */ | ||
391 | else if (len == ll) /* 'ls' is finished? */ | ||
392 | return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ | ||
393 | /* both strings longer than 'len'; go on comparing after the '\0' */ | ||
394 | len++; | ||
395 | l += len; ll -= len; r += len; lr -= len; | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
400 | |||
401 | /* | ||
402 | ** Check whether integer 'i' is less than float 'f'. If 'i' has an | ||
403 | ** exact representation as a float ('l_intfitsf'), compare numbers as | ||
404 | ** floats. Otherwise, use the equivalence 'i < f <=> i < ceil(f)'. | ||
405 | ** If 'ceil(f)' is out of integer range, either 'f' is greater than | ||
406 | ** all integers or less than all integers. | ||
407 | ** (The test with 'l_intfitsf' is only for performance; the else | ||
408 | ** case is correct for all values, but it is slow due to the conversion | ||
409 | ** from float to int.) | ||
410 | ** When 'f' is NaN, comparisons must result in false. | ||
411 | */ | ||
412 | static int LTintfloat (lua_Integer i, lua_Number f) { | ||
413 | if (l_intfitsf(i)) | ||
414 | return luai_numlt(cast_num(i), f); /* compare them as floats */ | ||
415 | else { /* i < f <=> i < ceil(f) */ | ||
416 | lua_Integer fi; | ||
417 | if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ | ||
418 | return i < fi; /* compare them as integers */ | ||
419 | else /* 'f' is either greater or less than all integers */ | ||
420 | return f > 0; /* greater? */ | ||
421 | } | ||
422 | } | ||
423 | |||
424 | |||
425 | /* | ||
426 | ** Check whether integer 'i' is less than or equal to float 'f'. | ||
427 | ** See comments on previous function. | ||
428 | */ | ||
429 | static int LEintfloat (lua_Integer i, lua_Number f) { | ||
430 | if (l_intfitsf(i)) | ||
431 | return luai_numle(cast_num(i), f); /* compare them as floats */ | ||
432 | else { /* i <= f <=> i <= floor(f) */ | ||
433 | lua_Integer fi; | ||
434 | if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ | ||
435 | return i <= fi; /* compare them as integers */ | ||
436 | else /* 'f' is either greater or less than all integers */ | ||
437 | return f > 0; /* greater? */ | ||
438 | } | ||
439 | } | ||
440 | |||
441 | |||
442 | /* | ||
443 | ** Check whether float 'f' is less than integer 'i'. | ||
444 | ** See comments on previous function. | ||
445 | */ | ||
446 | static int LTfloatint (lua_Number f, lua_Integer i) { | ||
447 | if (l_intfitsf(i)) | ||
448 | return luai_numlt(f, cast_num(i)); /* compare them as floats */ | ||
449 | else { /* f < i <=> floor(f) < i */ | ||
450 | lua_Integer fi; | ||
451 | if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ | ||
452 | return fi < i; /* compare them as integers */ | ||
453 | else /* 'f' is either greater or less than all integers */ | ||
454 | return f < 0; /* less? */ | ||
455 | } | ||
456 | } | ||
457 | |||
458 | |||
459 | /* | ||
460 | ** Check whether float 'f' is less than or equal to integer 'i'. | ||
461 | ** See comments on previous function. | ||
462 | */ | ||
463 | static int LEfloatint (lua_Number f, lua_Integer i) { | ||
464 | if (l_intfitsf(i)) | ||
465 | return luai_numle(f, cast_num(i)); /* compare them as floats */ | ||
466 | else { /* f <= i <=> ceil(f) <= i */ | ||
467 | lua_Integer fi; | ||
468 | if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ | ||
469 | return fi <= i; /* compare them as integers */ | ||
470 | else /* 'f' is either greater or less than all integers */ | ||
471 | return f < 0; /* less? */ | ||
472 | } | ||
473 | } | ||
474 | |||
475 | |||
476 | /* | ||
477 | ** Return 'l < r', for numbers. | ||
478 | */ | ||
479 | static int LTnum (const TValue *l, const TValue *r) { | ||
480 | lua_assert(ttisnumber(l) && ttisnumber(r)); | ||
481 | if (ttisinteger(l)) { | ||
482 | lua_Integer li = ivalue(l); | ||
483 | if (ttisinteger(r)) | ||
484 | return li < ivalue(r); /* both are integers */ | ||
485 | else /* 'l' is int and 'r' is float */ | ||
486 | return LTintfloat(li, fltvalue(r)); /* l < r ? */ | ||
487 | } | ||
488 | else { | ||
489 | lua_Number lf = fltvalue(l); /* 'l' must be float */ | ||
490 | if (ttisfloat(r)) | ||
491 | return luai_numlt(lf, fltvalue(r)); /* both are float */ | ||
492 | else /* 'l' is float and 'r' is int */ | ||
493 | return LTfloatint(lf, ivalue(r)); | ||
494 | } | ||
495 | } | ||
496 | |||
497 | |||
498 | /* | ||
499 | ** Return 'l <= r', for numbers. | ||
500 | */ | ||
501 | static int LEnum (const TValue *l, const TValue *r) { | ||
502 | lua_assert(ttisnumber(l) && ttisnumber(r)); | ||
503 | if (ttisinteger(l)) { | ||
504 | lua_Integer li = ivalue(l); | ||
505 | if (ttisinteger(r)) | ||
506 | return li <= ivalue(r); /* both are integers */ | ||
507 | else /* 'l' is int and 'r' is float */ | ||
508 | return LEintfloat(li, fltvalue(r)); /* l <= r ? */ | ||
509 | } | ||
510 | else { | ||
511 | lua_Number lf = fltvalue(l); /* 'l' must be float */ | ||
512 | if (ttisfloat(r)) | ||
513 | return luai_numle(lf, fltvalue(r)); /* both are float */ | ||
514 | else /* 'l' is float and 'r' is int */ | ||
515 | return LEfloatint(lf, ivalue(r)); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | |||
520 | /* | ||
521 | ** return 'l < r' for non-numbers. | ||
522 | */ | ||
523 | static int lessthanothers (lua_State *L, const TValue *l, const TValue *r) { | ||
524 | lua_assert(!ttisnumber(l) || !ttisnumber(r)); | ||
525 | if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | ||
526 | return l_strcmp(tsvalue(l), tsvalue(r)) < 0; | ||
527 | else | ||
528 | return luaT_callorderTM(L, l, r, TM_LT); | ||
529 | } | ||
530 | |||
531 | |||
532 | /* | ||
533 | ** Main operation less than; return 'l < r'. | ||
534 | */ | ||
535 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | ||
536 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ | ||
537 | return LTnum(l, r); | ||
538 | else return lessthanothers(L, l, r); | ||
539 | } | ||
540 | |||
541 | |||
542 | /* | ||
543 | ** return 'l <= r' for non-numbers. | ||
544 | */ | ||
545 | static int lessequalothers (lua_State *L, const TValue *l, const TValue *r) { | ||
546 | lua_assert(!ttisnumber(l) || !ttisnumber(r)); | ||
547 | if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | ||
548 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; | ||
549 | else | ||
550 | return luaT_callorderTM(L, l, r, TM_LE); | ||
551 | } | ||
552 | |||
553 | |||
554 | /* | ||
555 | ** Main operation less than or equal to; return 'l <= r'. | ||
556 | */ | ||
557 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | ||
558 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ | ||
559 | return LEnum(l, r); | ||
560 | else return lessequalothers(L, l, r); | ||
561 | } | ||
562 | |||
563 | |||
564 | /* | ||
565 | ** Main operation for equality of Lua values; return 't1 == t2'. | ||
566 | ** L == NULL means raw equality (no metamethods) | ||
567 | */ | ||
568 | int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | ||
569 | const TValue *tm; | ||
570 | if (ttypetag(t1) != ttypetag(t2)) { /* not the same variant? */ | ||
571 | if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER) | ||
572 | return 0; /* only numbers can be equal with different variants */ | ||
573 | else { /* two numbers with different variants */ | ||
574 | lua_Integer i1, i2; /* compare them as integers */ | ||
575 | return (tointegerns(t1, &i1) && tointegerns(t2, &i2) && i1 == i2); | ||
576 | } | ||
577 | } | ||
578 | /* values have same type and same variant */ | ||
579 | switch (ttypetag(t1)) { | ||
580 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: return 1; | ||
581 | case LUA_VNUMINT: return (ivalue(t1) == ivalue(t2)); | ||
582 | case LUA_VNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); | ||
583 | case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | ||
584 | case LUA_VLCF: return fvalue(t1) == fvalue(t2); | ||
585 | case LUA_VSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); | ||
586 | case LUA_VLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2)); | ||
587 | case LUA_VUSERDATA: { | ||
588 | if (uvalue(t1) == uvalue(t2)) return 1; | ||
589 | else if (L == NULL) return 0; | ||
590 | tm = fasttm(L, uvalue(t1)->metatable, TM_EQ); | ||
591 | if (tm == NULL) | ||
592 | tm = fasttm(L, uvalue(t2)->metatable, TM_EQ); | ||
593 | break; /* will try TM */ | ||
594 | } | ||
595 | case LUA_VTABLE: { | ||
596 | if (hvalue(t1) == hvalue(t2)) return 1; | ||
597 | else if (L == NULL) return 0; | ||
598 | tm = fasttm(L, hvalue(t1)->metatable, TM_EQ); | ||
599 | if (tm == NULL) | ||
600 | tm = fasttm(L, hvalue(t2)->metatable, TM_EQ); | ||
601 | break; /* will try TM */ | ||
602 | } | ||
603 | default: | ||
604 | return gcvalue(t1) == gcvalue(t2); | ||
605 | } | ||
606 | if (tm == NULL) /* no TM? */ | ||
607 | return 0; /* objects are different */ | ||
608 | else { | ||
609 | luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */ | ||
610 | return !l_isfalse(s2v(L->top)); | ||
611 | } | ||
612 | } | ||
613 | |||
614 | |||
615 | /* macro used by 'luaV_concat' to ensure that element at 'o' is a string */ | ||
616 | #define tostring(L,o) \ | ||
617 | (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) | ||
618 | |||
619 | #define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) | ||
620 | |||
621 | /* copy strings in stack from top - n up to top - 1 to buffer */ | ||
622 | static void copy2buff (StkId top, int n, char *buff) { | ||
623 | size_t tl = 0; /* size already copied */ | ||
624 | do { | ||
625 | size_t l = vslen(s2v(top - n)); /* length of string being copied */ | ||
626 | memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char)); | ||
627 | tl += l; | ||
628 | } while (--n > 0); | ||
629 | } | ||
630 | |||
631 | |||
632 | /* | ||
633 | ** Main operation for concatenation: concat 'total' values in the stack, | ||
634 | ** from 'L->top - total' up to 'L->top - 1'. | ||
635 | */ | ||
636 | void luaV_concat (lua_State *L, int total) { | ||
637 | lua_assert(total >= 2); | ||
638 | do { | ||
639 | StkId top = L->top; | ||
640 | int n = 2; /* number of elements handled in this pass (at least 2) */ | ||
641 | if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) || | ||
642 | !tostring(L, s2v(top - 1))) | ||
643 | luaT_tryconcatTM(L); | ||
644 | else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ | ||
645 | cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ | ||
646 | else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */ | ||
647 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ | ||
648 | } | ||
649 | else { | ||
650 | /* at least two non-empty string values; get as many as possible */ | ||
651 | size_t tl = vslen(s2v(top - 1)); | ||
652 | TString *ts; | ||
653 | /* collect total length and number of strings */ | ||
654 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | ||
655 | size_t l = vslen(s2v(top - n - 1)); | ||
656 | if (unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) | ||
657 | luaG_runerror(L, "string length overflow"); | ||
658 | tl += l; | ||
659 | } | ||
660 | if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ | ||
661 | char buff[LUAI_MAXSHORTLEN]; | ||
662 | copy2buff(top, n, buff); /* copy strings to buffer */ | ||
663 | ts = luaS_newlstr(L, buff, tl); | ||
664 | } | ||
665 | else { /* long string; copy strings directly to final result */ | ||
666 | ts = luaS_createlngstrobj(L, tl); | ||
667 | copy2buff(top, n, getstr(ts)); | ||
668 | } | ||
669 | setsvalue2s(L, top - n, ts); /* create result */ | ||
670 | } | ||
671 | total -= n-1; /* got 'n' strings to create 1 new */ | ||
672 | L->top -= n-1; /* popped 'n' strings and pushed one */ | ||
673 | } while (total > 1); /* repeat until only 1 result left */ | ||
674 | } | ||
675 | |||
676 | |||
677 | /* | ||
678 | ** Main operation 'ra = #rb'. | ||
679 | */ | ||
680 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { | ||
681 | const TValue *tm; | ||
682 | switch (ttypetag(rb)) { | ||
683 | case LUA_VTABLE: { | ||
684 | Table *h = hvalue(rb); | ||
685 | tm = fasttm(L, h->metatable, TM_LEN); | ||
686 | if (tm) break; /* metamethod? break switch to call it */ | ||
687 | setivalue(s2v(ra), luaH_getn(h)); /* else primitive len */ | ||
688 | return; | ||
689 | } | ||
690 | case LUA_VSHRSTR: { | ||
691 | setivalue(s2v(ra), tsvalue(rb)->shrlen); | ||
692 | return; | ||
693 | } | ||
694 | case LUA_VLNGSTR: { | ||
695 | setivalue(s2v(ra), tsvalue(rb)->u.lnglen); | ||
696 | return; | ||
697 | } | ||
698 | default: { /* try metamethod */ | ||
699 | tm = luaT_gettmbyobj(L, rb, TM_LEN); | ||
700 | if (unlikely(notm(tm))) /* no metamethod? */ | ||
701 | luaG_typeerror(L, rb, "get length of"); | ||
702 | break; | ||
703 | } | ||
704 | } | ||
705 | luaT_callTMres(L, tm, rb, rb, ra); | ||
706 | } | ||
707 | |||
708 | |||
709 | /* | ||
710 | ** Integer division; return 'm // n', that is, floor(m/n). | ||
711 | ** C division truncates its result (rounds towards zero). | ||
712 | ** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer, | ||
713 | ** otherwise 'floor(q) == trunc(q) - 1'. | ||
714 | */ | ||
715 | lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) { | ||
716 | if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ | ||
717 | if (n == 0) | ||
718 | luaG_runerror(L, "attempt to divide by zero"); | ||
719 | return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ | ||
720 | } | ||
721 | else { | ||
722 | lua_Integer q = m / n; /* perform C division */ | ||
723 | if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */ | ||
724 | q -= 1; /* correct result for different rounding */ | ||
725 | return q; | ||
726 | } | ||
727 | } | ||
728 | |||
729 | |||
730 | /* | ||
731 | ** Integer modulus; return 'm % n'. (Assume that C '%' with | ||
732 | ** negative operands follows C99 behavior. See previous comment | ||
733 | ** about luaV_idiv.) | ||
734 | */ | ||
735 | lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { | ||
736 | if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ | ||
737 | if (n == 0) | ||
738 | luaG_runerror(L, "attempt to perform 'n%%0'"); | ||
739 | return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ | ||
740 | } | ||
741 | else { | ||
742 | lua_Integer r = m % n; | ||
743 | if (r != 0 && (r ^ n) < 0) /* 'm/n' would be non-integer negative? */ | ||
744 | r += n; /* correct result for different rounding */ | ||
745 | return r; | ||
746 | } | ||
747 | } | ||
748 | |||
749 | |||
750 | /* | ||
751 | ** Float modulus | ||
752 | */ | ||
753 | lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { | ||
754 | lua_Number r; | ||
755 | luai_nummod(L, m, n, r); | ||
756 | return r; | ||
757 | } | ||
758 | |||
759 | |||
760 | /* number of bits in an integer */ | ||
761 | #define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) | ||
762 | |||
763 | /* | ||
764 | ** Shift left operation. (Shift right just negates 'y'.) | ||
765 | */ | ||
766 | #define luaV_shiftr(x,y) luaV_shiftl(x,-(y)) | ||
767 | |||
768 | lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { | ||
769 | if (y < 0) { /* shift right? */ | ||
770 | if (y <= -NBITS) return 0; | ||
771 | else return intop(>>, x, -y); | ||
772 | } | ||
773 | else { /* shift left */ | ||
774 | if (y >= NBITS) return 0; | ||
775 | else return intop(<<, x, y); | ||
776 | } | ||
777 | } | ||
778 | |||
779 | |||
780 | /* | ||
781 | ** create a new Lua closure, push it in the stack, and initialize | ||
782 | ** its upvalues. | ||
783 | */ | ||
784 | static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | ||
785 | StkId ra) { | ||
786 | int nup = p->sizeupvalues; | ||
787 | Upvaldesc *uv = p->upvalues; | ||
788 | int i; | ||
789 | LClosure *ncl = luaF_newLclosure(L, nup); | ||
790 | ncl->p = p; | ||
791 | setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */ | ||
792 | for (i = 0; i < nup; i++) { /* fill in its upvalues */ | ||
793 | if (uv[i].instack) /* upvalue refers to local variable? */ | ||
794 | ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx); | ||
795 | else /* get upvalue from enclosing function */ | ||
796 | ncl->upvals[i] = encup[uv[i].idx]; | ||
797 | luaC_objbarrier(L, ncl, ncl->upvals[i]); | ||
798 | } | ||
799 | } | ||
800 | |||
801 | |||
802 | /* | ||
803 | ** finish execution of an opcode interrupted by a yield | ||
804 | */ | ||
805 | void luaV_finishOp (lua_State *L) { | ||
806 | CallInfo *ci = L->ci; | ||
807 | StkId base = ci->func + 1; | ||
808 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | ||
809 | OpCode op = GET_OPCODE(inst); | ||
810 | switch (op) { /* finish its execution */ | ||
811 | case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { | ||
812 | setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top); | ||
813 | break; | ||
814 | } | ||
815 | case OP_UNM: case OP_BNOT: case OP_LEN: | ||
816 | case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: | ||
817 | case OP_GETFIELD: case OP_SELF: { | ||
818 | setobjs2s(L, base + GETARG_A(inst), --L->top); | ||
819 | break; | ||
820 | } | ||
821 | case OP_LT: case OP_LE: | ||
822 | case OP_LTI: case OP_LEI: | ||
823 | case OP_GTI: case OP_GEI: | ||
824 | case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */ | ||
825 | int res = !l_isfalse(s2v(L->top - 1)); | ||
826 | L->top--; | ||
827 | #if defined(LUA_COMPAT_LT_LE) | ||
828 | if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ | ||
829 | ci->callstatus ^= CIST_LEQ; /* clear mark */ | ||
830 | res = !res; /* negate result */ | ||
831 | } | ||
832 | #endif | ||
833 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); | ||
834 | if (res != GETARG_k(inst)) /* condition failed? */ | ||
835 | ci->u.l.savedpc++; /* skip jump instruction */ | ||
836 | break; | ||
837 | } | ||
838 | case OP_CONCAT: { | ||
839 | StkId top = L->top - 1; /* top when 'luaT_tryconcatTM' was called */ | ||
840 | int a = GETARG_A(inst); /* first element to concatenate */ | ||
841 | int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */ | ||
842 | setobjs2s(L, top - 2, top); /* put TM result in proper position */ | ||
843 | if (total > 1) { /* are there elements to concat? */ | ||
844 | L->top = top - 1; /* top is one after last element (at top-2) */ | ||
845 | luaV_concat(L, total); /* concat them (may yield again) */ | ||
846 | } | ||
847 | break; | ||
848 | } | ||
849 | default: { | ||
850 | /* only these other opcodes can yield */ | ||
851 | lua_assert(op == OP_TFORCALL || op == OP_CALL || | ||
852 | op == OP_TAILCALL || op == OP_SETTABUP || op == OP_SETTABLE || | ||
853 | op == OP_SETI || op == OP_SETFIELD); | ||
854 | break; | ||
855 | } | ||
856 | } | ||
857 | } | ||
858 | |||
859 | |||
860 | |||
861 | |||
862 | /* | ||
863 | ** {================================================================== | ||
864 | ** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute' | ||
865 | ** =================================================================== | ||
866 | */ | ||
867 | |||
868 | #define l_addi(L,a,b) intop(+, a, b) | ||
869 | #define l_subi(L,a,b) intop(-, a, b) | ||
870 | #define l_muli(L,a,b) intop(*, a, b) | ||
871 | #define l_band(a,b) intop(&, a, b) | ||
872 | #define l_bor(a,b) intop(|, a, b) | ||
873 | #define l_bxor(a,b) intop(^, a, b) | ||
874 | |||
875 | #define l_lti(a,b) (a < b) | ||
876 | #define l_lei(a,b) (a <= b) | ||
877 | #define l_gti(a,b) (a > b) | ||
878 | #define l_gei(a,b) (a >= b) | ||
879 | |||
880 | |||
881 | /* | ||
882 | ** Arithmetic operations with immediate operands. 'iop' is the integer | ||
883 | ** operation, 'fop' is the float operation. | ||
884 | */ | ||
885 | #define op_arithI(L,iop,fop) { \ | ||
886 | TValue *v1 = vRB(i); \ | ||
887 | int imm = GETARG_sC(i); \ | ||
888 | if (ttisinteger(v1)) { \ | ||
889 | lua_Integer iv1 = ivalue(v1); \ | ||
890 | pc++; setivalue(s2v(ra), iop(L, iv1, imm)); \ | ||
891 | } \ | ||
892 | else if (ttisfloat(v1)) { \ | ||
893 | lua_Number nb = fltvalue(v1); \ | ||
894 | lua_Number fimm = cast_num(imm); \ | ||
895 | pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \ | ||
896 | }} | ||
897 | |||
898 | |||
899 | /* | ||
900 | ** Auxiliary function for arithmetic operations over floats and others | ||
901 | ** with two register operands. | ||
902 | */ | ||
903 | #define op_arithf_aux(L,v1,v2,fop) { \ | ||
904 | lua_Number n1; lua_Number n2; \ | ||
905 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | ||
906 | pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ | ||
907 | }} | ||
908 | |||
909 | |||
910 | /* | ||
911 | ** Arithmetic operations over floats and others with register operands. | ||
912 | */ | ||
913 | #define op_arithf(L,fop) { \ | ||
914 | TValue *v1 = vRB(i); \ | ||
915 | TValue *v2 = vRC(i); \ | ||
916 | op_arithf_aux(L, v1, v2, fop); } | ||
917 | |||
918 | |||
919 | /* | ||
920 | ** Arithmetic operations with K operands for floats. | ||
921 | */ | ||
922 | #define op_arithfK(L,fop) { \ | ||
923 | TValue *v1 = vRB(i); \ | ||
924 | TValue *v2 = KC(i); \ | ||
925 | op_arithf_aux(L, v1, v2, fop); } | ||
926 | |||
927 | |||
928 | /* | ||
929 | ** Arithmetic operations over integers and floats. | ||
930 | */ | ||
931 | #define op_arith_aux(L,v1,v2,iop,fop) { \ | ||
932 | if (ttisinteger(v1) && ttisinteger(v2)) { \ | ||
933 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ | ||
934 | pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ | ||
935 | } \ | ||
936 | else op_arithf_aux(L, v1, v2, fop); } | ||
937 | |||
938 | |||
939 | /* | ||
940 | ** Arithmetic operations with register operands. | ||
941 | */ | ||
942 | #define op_arith(L,iop,fop) { \ | ||
943 | TValue *v1 = vRB(i); \ | ||
944 | TValue *v2 = vRC(i); \ | ||
945 | op_arith_aux(L, v1, v2, iop, fop); } | ||
946 | |||
947 | |||
948 | /* | ||
949 | ** Arithmetic operations with K operands. | ||
950 | */ | ||
951 | #define op_arithK(L,iop,fop) { \ | ||
952 | TValue *v1 = vRB(i); \ | ||
953 | TValue *v2 = KC(i); \ | ||
954 | op_arith_aux(L, v1, v2, iop, fop); } | ||
955 | |||
956 | |||
957 | /* | ||
958 | ** Bitwise operations with constant operand. | ||
959 | */ | ||
960 | #define op_bitwiseK(L,op) { \ | ||
961 | TValue *v1 = vRB(i); \ | ||
962 | TValue *v2 = KC(i); \ | ||
963 | lua_Integer i1; \ | ||
964 | lua_Integer i2 = ivalue(v2); \ | ||
965 | if (tointegerns(v1, &i1)) { \ | ||
966 | pc++; setivalue(s2v(ra), op(i1, i2)); \ | ||
967 | }} | ||
968 | |||
969 | |||
970 | /* | ||
971 | ** Bitwise operations with register operands. | ||
972 | */ | ||
973 | #define op_bitwise(L,op) { \ | ||
974 | TValue *v1 = vRB(i); \ | ||
975 | TValue *v2 = vRC(i); \ | ||
976 | lua_Integer i1; lua_Integer i2; \ | ||
977 | if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ | ||
978 | pc++; setivalue(s2v(ra), op(i1, i2)); \ | ||
979 | }} | ||
980 | |||
981 | |||
982 | /* | ||
983 | ** Order operations with register operands. 'opn' actually works | ||
984 | ** for all numbers, but the fast track improves performance for | ||
985 | ** integers. | ||
986 | */ | ||
987 | #define op_order(L,opi,opn,other) { \ | ||
988 | int cond; \ | ||
989 | TValue *rb = vRB(i); \ | ||
990 | if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \ | ||
991 | lua_Integer ia = ivalue(s2v(ra)); \ | ||
992 | lua_Integer ib = ivalue(rb); \ | ||
993 | cond = opi(ia, ib); \ | ||
994 | } \ | ||
995 | else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ | ||
996 | cond = opn(s2v(ra), rb); \ | ||
997 | else \ | ||
998 | Protect(cond = other(L, s2v(ra), rb)); \ | ||
999 | docondjump(); } | ||
1000 | |||
1001 | |||
1002 | /* | ||
1003 | ** Order operations with immediate operand. (Immediate operand is | ||
1004 | ** always small enough to have an exact representation as a float.) | ||
1005 | */ | ||
1006 | #define op_orderI(L,opi,opf,inv,tm) { \ | ||
1007 | int cond; \ | ||
1008 | int im = GETARG_sB(i); \ | ||
1009 | if (ttisinteger(s2v(ra))) \ | ||
1010 | cond = opi(ivalue(s2v(ra)), im); \ | ||
1011 | else if (ttisfloat(s2v(ra))) { \ | ||
1012 | lua_Number fa = fltvalue(s2v(ra)); \ | ||
1013 | lua_Number fim = cast_num(im); \ | ||
1014 | cond = opf(fa, fim); \ | ||
1015 | } \ | ||
1016 | else { \ | ||
1017 | int isf = GETARG_C(i); \ | ||
1018 | Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \ | ||
1019 | } \ | ||
1020 | docondjump(); } | ||
1021 | |||
1022 | /* }================================================================== */ | ||
1023 | |||
1024 | |||
1025 | /* | ||
1026 | ** {================================================================== | ||
1027 | ** Function 'luaV_execute': main interpreter loop | ||
1028 | ** =================================================================== | ||
1029 | */ | ||
1030 | |||
1031 | /* | ||
1032 | ** some macros for common tasks in 'luaV_execute' | ||
1033 | */ | ||
1034 | |||
1035 | |||
1036 | #define RA(i) (base+GETARG_A(i)) | ||
1037 | #define RB(i) (base+GETARG_B(i)) | ||
1038 | #define vRB(i) s2v(RB(i)) | ||
1039 | #define KB(i) (k+GETARG_B(i)) | ||
1040 | #define RC(i) (base+GETARG_C(i)) | ||
1041 | #define vRC(i) s2v(RC(i)) | ||
1042 | #define KC(i) (k+GETARG_C(i)) | ||
1043 | #define RKC(i) ((TESTARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i))) | ||
1044 | |||
1045 | |||
1046 | |||
1047 | #define updatetrap(ci) (trap = ci->u.l.trap) | ||
1048 | |||
1049 | #define updatebase(ci) (base = ci->func + 1) | ||
1050 | |||
1051 | |||
1052 | #define updatestack(ci) { if (trap) { updatebase(ci); ra = RA(i); } } | ||
1053 | |||
1054 | |||
1055 | /* | ||
1056 | ** Execute a jump instruction. The 'updatetrap' allows signals to stop | ||
1057 | ** tight loops. (Without it, the local copy of 'trap' could never change.) | ||
1058 | */ | ||
1059 | #define dojump(ci,i,e) { pc += GETARG_sJ(i) + e; updatetrap(ci); } | ||
1060 | |||
1061 | |||
1062 | /* for test instructions, execute the jump instruction that follows it */ | ||
1063 | #define donextjump(ci) { Instruction ni = *pc; dojump(ci, ni, 1); } | ||
1064 | |||
1065 | /* | ||
1066 | ** do a conditional jump: skip next instruction if 'cond' is not what | ||
1067 | ** was expected (parameter 'k'), else do next instruction, which must | ||
1068 | ** be a jump. | ||
1069 | */ | ||
1070 | #define docondjump() if (cond != GETARG_k(i)) pc++; else donextjump(ci); | ||
1071 | |||
1072 | |||
1073 | /* | ||
1074 | ** Correct global 'pc'. | ||
1075 | */ | ||
1076 | #define savepc(L) (ci->u.l.savedpc = pc) | ||
1077 | |||
1078 | |||
1079 | /* | ||
1080 | ** Whenever code can raise errors, the global 'pc' and the global | ||
1081 | ** 'top' must be correct to report occasional errors. | ||
1082 | */ | ||
1083 | #define savestate(L,ci) (savepc(L), L->top = ci->top) | ||
1084 | |||
1085 | |||
1086 | /* | ||
1087 | ** Protect code that, in general, can raise errors, reallocate the | ||
1088 | ** stack, and change the hooks. | ||
1089 | */ | ||
1090 | #define Protect(exp) (savestate(L,ci), (exp), updatetrap(ci)) | ||
1091 | |||
1092 | /* special version that does not change the top */ | ||
1093 | #define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) | ||
1094 | |||
1095 | /* | ||
1096 | ** Protect code that will finish the loop (returns) or can only raise | ||
1097 | ** errors. (That is, it will not return to the interpreter main loop | ||
1098 | ** after changing the stack or hooks.) | ||
1099 | */ | ||
1100 | #define halfProtect(exp) (savestate(L,ci), (exp)) | ||
1101 | |||
1102 | /* idem, but without changing the stack */ | ||
1103 | #define halfProtectNT(exp) (savepc(L), (exp)) | ||
1104 | |||
1105 | |||
1106 | #define checkGC(L,c) \ | ||
1107 | { luaC_condGC(L, L->top = (c), /* limit of live values */ \ | ||
1108 | updatetrap(ci)); \ | ||
1109 | luai_threadyield(L); } | ||
1110 | |||
1111 | |||
1112 | /* fetch an instruction and prepare its execution */ | ||
1113 | #define vmfetch() { \ | ||
1114 | if (trap) { /* stack reallocation or hooks? */ \ | ||
1115 | trap = luaG_traceexec(L, pc); /* handle hooks */ \ | ||
1116 | updatebase(ci); /* correct stack */ \ | ||
1117 | } \ | ||
1118 | i = *(pc++); \ | ||
1119 | ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \ | ||
1120 | } | ||
1121 | |||
1122 | #define vmdispatch(o) switch(o) | ||
1123 | #define vmcase(l) case l: | ||
1124 | #define vmbreak break | ||
1125 | |||
1126 | |||
1127 | void luaV_execute (lua_State *L, CallInfo *ci) { | ||
1128 | LClosure *cl; | ||
1129 | TValue *k; | ||
1130 | StkId base; | ||
1131 | const Instruction *pc; | ||
1132 | int trap; | ||
1133 | #if LUA_USE_JUMPTABLE | ||
1134 | #include "ljumptab.h" | ||
1135 | #endif | ||
1136 | tailcall: | ||
1137 | trap = L->hookmask; | ||
1138 | cl = clLvalue(s2v(ci->func)); | ||
1139 | k = cl->p->k; | ||
1140 | pc = ci->u.l.savedpc; | ||
1141 | if (trap) { | ||
1142 | if (cl->p->is_vararg) | ||
1143 | trap = 0; /* hooks will start after VARARGPREP instruction */ | ||
1144 | else if (pc == cl->p->code) /* first instruction (not resuming)? */ | ||
1145 | luaD_hookcall(L, ci); | ||
1146 | ci->u.l.trap = 1; /* there may be other hooks */ | ||
1147 | } | ||
1148 | base = ci->func + 1; | ||
1149 | /* main loop of interpreter */ | ||
1150 | for (;;) { | ||
1151 | Instruction i; /* instruction being executed */ | ||
1152 | StkId ra; /* instruction's A register */ | ||
1153 | vmfetch(); | ||
1154 | lua_assert(base == ci->func + 1); | ||
1155 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); | ||
1156 | /* invalidate top for instructions not expecting it */ | ||
1157 | lua_assert(isIT(i) || (cast_void(L->top = base), 1)); | ||
1158 | vmdispatch (GET_OPCODE(i)) { | ||
1159 | vmcase(OP_MOVE) { | ||
1160 | setobjs2s(L, ra, RB(i)); | ||
1161 | vmbreak; | ||
1162 | } | ||
1163 | vmcase(OP_LOADI) { | ||
1164 | lua_Integer b = GETARG_sBx(i); | ||
1165 | setivalue(s2v(ra), b); | ||
1166 | vmbreak; | ||
1167 | } | ||
1168 | vmcase(OP_LOADF) { | ||
1169 | int b = GETARG_sBx(i); | ||
1170 | setfltvalue(s2v(ra), cast_num(b)); | ||
1171 | vmbreak; | ||
1172 | } | ||
1173 | vmcase(OP_LOADK) { | ||
1174 | TValue *rb = k + GETARG_Bx(i); | ||
1175 | setobj2s(L, ra, rb); | ||
1176 | vmbreak; | ||
1177 | } | ||
1178 | vmcase(OP_LOADKX) { | ||
1179 | TValue *rb; | ||
1180 | rb = k + GETARG_Ax(*pc); pc++; | ||
1181 | setobj2s(L, ra, rb); | ||
1182 | vmbreak; | ||
1183 | } | ||
1184 | vmcase(OP_LOADFALSE) { | ||
1185 | setbfvalue(s2v(ra)); | ||
1186 | vmbreak; | ||
1187 | } | ||
1188 | vmcase(OP_LFALSESKIP) { | ||
1189 | setbfvalue(s2v(ra)); | ||
1190 | pc++; /* skip next instruction */ | ||
1191 | vmbreak; | ||
1192 | } | ||
1193 | vmcase(OP_LOADTRUE) { | ||
1194 | setbtvalue(s2v(ra)); | ||
1195 | vmbreak; | ||
1196 | } | ||
1197 | vmcase(OP_LOADNIL) { | ||
1198 | int b = GETARG_B(i); | ||
1199 | do { | ||
1200 | setnilvalue(s2v(ra++)); | ||
1201 | } while (b--); | ||
1202 | vmbreak; | ||
1203 | } | ||
1204 | vmcase(OP_GETUPVAL) { | ||
1205 | int b = GETARG_B(i); | ||
1206 | setobj2s(L, ra, cl->upvals[b]->v); | ||
1207 | vmbreak; | ||
1208 | } | ||
1209 | vmcase(OP_SETUPVAL) { | ||
1210 | UpVal *uv = cl->upvals[GETARG_B(i)]; | ||
1211 | setobj(L, uv->v, s2v(ra)); | ||
1212 | luaC_barrier(L, uv, s2v(ra)); | ||
1213 | vmbreak; | ||
1214 | } | ||
1215 | vmcase(OP_GETTABUP) { | ||
1216 | const TValue *slot; | ||
1217 | TValue *upval = cl->upvals[GETARG_B(i)]->v; | ||
1218 | TValue *rc = KC(i); | ||
1219 | TString *key = tsvalue(rc); /* key must be a string */ | ||
1220 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { | ||
1221 | setobj2s(L, ra, slot); | ||
1222 | } | ||
1223 | else | ||
1224 | Protect(luaV_finishget(L, upval, rc, ra, slot)); | ||
1225 | vmbreak; | ||
1226 | } | ||
1227 | vmcase(OP_GETTABLE) { | ||
1228 | const TValue *slot; | ||
1229 | TValue *rb = vRB(i); | ||
1230 | TValue *rc = vRC(i); | ||
1231 | lua_Unsigned n; | ||
1232 | if (ttisinteger(rc) /* fast track for integers? */ | ||
1233 | ? (cast_void(n = ivalue(rc)), luaV_fastgeti(L, rb, n, slot)) | ||
1234 | : luaV_fastget(L, rb, rc, slot, luaH_get)) { | ||
1235 | setobj2s(L, ra, slot); | ||
1236 | } | ||
1237 | else | ||
1238 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | ||
1239 | vmbreak; | ||
1240 | } | ||
1241 | vmcase(OP_GETI) { | ||
1242 | const TValue *slot; | ||
1243 | TValue *rb = vRB(i); | ||
1244 | int c = GETARG_C(i); | ||
1245 | if (luaV_fastgeti(L, rb, c, slot)) { | ||
1246 | setobj2s(L, ra, slot); | ||
1247 | } | ||
1248 | else { | ||
1249 | TValue key; | ||
1250 | setivalue(&key, c); | ||
1251 | Protect(luaV_finishget(L, rb, &key, ra, slot)); | ||
1252 | } | ||
1253 | vmbreak; | ||
1254 | } | ||
1255 | vmcase(OP_GETFIELD) { | ||
1256 | const TValue *slot; | ||
1257 | TValue *rb = vRB(i); | ||
1258 | TValue *rc = KC(i); | ||
1259 | TString *key = tsvalue(rc); /* key must be a string */ | ||
1260 | if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { | ||
1261 | setobj2s(L, ra, slot); | ||
1262 | } | ||
1263 | else | ||
1264 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | ||
1265 | vmbreak; | ||
1266 | } | ||
1267 | vmcase(OP_SETTABUP) { | ||
1268 | const TValue *slot; | ||
1269 | TValue *upval = cl->upvals[GETARG_A(i)]->v; | ||
1270 | TValue *rb = KB(i); | ||
1271 | TValue *rc = RKC(i); | ||
1272 | TString *key = tsvalue(rb); /* key must be a string */ | ||
1273 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { | ||
1274 | luaV_finishfastset(L, upval, slot, rc); | ||
1275 | } | ||
1276 | else | ||
1277 | Protect(luaV_finishset(L, upval, rb, rc, slot)); | ||
1278 | vmbreak; | ||
1279 | } | ||
1280 | vmcase(OP_SETTABLE) { | ||
1281 | const TValue *slot; | ||
1282 | TValue *rb = vRB(i); /* key (table is in 'ra') */ | ||
1283 | TValue *rc = RKC(i); /* value */ | ||
1284 | lua_Unsigned n; | ||
1285 | if (ttisinteger(rb) /* fast track for integers? */ | ||
1286 | ? (cast_void(n = ivalue(rb)), luaV_fastgeti(L, s2v(ra), n, slot)) | ||
1287 | : luaV_fastget(L, s2v(ra), rb, slot, luaH_get)) { | ||
1288 | luaV_finishfastset(L, s2v(ra), slot, rc); | ||
1289 | } | ||
1290 | else | ||
1291 | Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); | ||
1292 | vmbreak; | ||
1293 | } | ||
1294 | vmcase(OP_SETI) { | ||
1295 | const TValue *slot; | ||
1296 | int c = GETARG_B(i); | ||
1297 | TValue *rc = RKC(i); | ||
1298 | if (luaV_fastgeti(L, s2v(ra), c, slot)) { | ||
1299 | luaV_finishfastset(L, s2v(ra), slot, rc); | ||
1300 | } | ||
1301 | else { | ||
1302 | TValue key; | ||
1303 | setivalue(&key, c); | ||
1304 | Protect(luaV_finishset(L, s2v(ra), &key, rc, slot)); | ||
1305 | } | ||
1306 | vmbreak; | ||
1307 | } | ||
1308 | vmcase(OP_SETFIELD) { | ||
1309 | const TValue *slot; | ||
1310 | TValue *rb = KB(i); | ||
1311 | TValue *rc = RKC(i); | ||
1312 | TString *key = tsvalue(rb); /* key must be a string */ | ||
1313 | if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { | ||
1314 | luaV_finishfastset(L, s2v(ra), slot, rc); | ||
1315 | } | ||
1316 | else | ||
1317 | Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); | ||
1318 | vmbreak; | ||
1319 | } | ||
1320 | vmcase(OP_NEWTABLE) { | ||
1321 | int b = GETARG_B(i); /* log2(hash size) + 1 */ | ||
1322 | int c = GETARG_C(i); /* array size */ | ||
1323 | Table *t; | ||
1324 | if (b > 0) | ||
1325 | b = 1 << (b - 1); /* size is 2^(b - 1) */ | ||
1326 | lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0)); | ||
1327 | if (TESTARG_k(i)) /* non-zero extra argument? */ | ||
1328 | c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ | ||
1329 | pc++; /* skip extra argument */ | ||
1330 | L->top = ra + 1; /* correct top in case of emergency GC */ | ||
1331 | t = luaH_new(L); /* memory allocation */ | ||
1332 | sethvalue2s(L, ra, t); | ||
1333 | if (b != 0 || c != 0) | ||
1334 | luaH_resize(L, t, c, b); /* idem */ | ||
1335 | checkGC(L, ra + 1); | ||
1336 | vmbreak; | ||
1337 | } | ||
1338 | vmcase(OP_SELF) { | ||
1339 | const TValue *slot; | ||
1340 | TValue *rb = vRB(i); | ||
1341 | TValue *rc = RKC(i); | ||
1342 | TString *key = tsvalue(rc); /* key must be a string */ | ||
1343 | setobj2s(L, ra + 1, rb); | ||
1344 | if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { | ||
1345 | setobj2s(L, ra, slot); | ||
1346 | } | ||
1347 | else | ||
1348 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | ||
1349 | vmbreak; | ||
1350 | } | ||
1351 | vmcase(OP_ADDI) { | ||
1352 | op_arithI(L, l_addi, luai_numadd); | ||
1353 | vmbreak; | ||
1354 | } | ||
1355 | vmcase(OP_ADDK) { | ||
1356 | op_arithK(L, l_addi, luai_numadd); | ||
1357 | vmbreak; | ||
1358 | } | ||
1359 | vmcase(OP_SUBK) { | ||
1360 | op_arithK(L, l_subi, luai_numsub); | ||
1361 | vmbreak; | ||
1362 | } | ||
1363 | vmcase(OP_MULK) { | ||
1364 | op_arithK(L, l_muli, luai_nummul); | ||
1365 | vmbreak; | ||
1366 | } | ||
1367 | vmcase(OP_MODK) { | ||
1368 | op_arithK(L, luaV_mod, luaV_modf); | ||
1369 | vmbreak; | ||
1370 | } | ||
1371 | vmcase(OP_POWK) { | ||
1372 | op_arithfK(L, luai_numpow); | ||
1373 | vmbreak; | ||
1374 | } | ||
1375 | vmcase(OP_DIVK) { | ||
1376 | op_arithfK(L, luai_numdiv); | ||
1377 | vmbreak; | ||
1378 | } | ||
1379 | vmcase(OP_IDIVK) { | ||
1380 | op_arithK(L, luaV_idiv, luai_numidiv); | ||
1381 | vmbreak; | ||
1382 | } | ||
1383 | vmcase(OP_BANDK) { | ||
1384 | op_bitwiseK(L, l_band); | ||
1385 | vmbreak; | ||
1386 | } | ||
1387 | vmcase(OP_BORK) { | ||
1388 | op_bitwiseK(L, l_bor); | ||
1389 | vmbreak; | ||
1390 | } | ||
1391 | vmcase(OP_BXORK) { | ||
1392 | op_bitwiseK(L, l_bxor); | ||
1393 | vmbreak; | ||
1394 | } | ||
1395 | vmcase(OP_SHRI) { | ||
1396 | TValue *rb = vRB(i); | ||
1397 | int ic = GETARG_sC(i); | ||
1398 | lua_Integer ib; | ||
1399 | if (tointegerns(rb, &ib)) { | ||
1400 | pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic)); | ||
1401 | } | ||
1402 | vmbreak; | ||
1403 | } | ||
1404 | vmcase(OP_SHLI) { | ||
1405 | TValue *rb = vRB(i); | ||
1406 | int ic = GETARG_sC(i); | ||
1407 | lua_Integer ib; | ||
1408 | if (tointegerns(rb, &ib)) { | ||
1409 | pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib)); | ||
1410 | } | ||
1411 | vmbreak; | ||
1412 | } | ||
1413 | vmcase(OP_ADD) { | ||
1414 | op_arith(L, l_addi, luai_numadd); | ||
1415 | vmbreak; | ||
1416 | } | ||
1417 | vmcase(OP_SUB) { | ||
1418 | op_arith(L, l_subi, luai_numsub); | ||
1419 | vmbreak; | ||
1420 | } | ||
1421 | vmcase(OP_MUL) { | ||
1422 | op_arith(L, l_muli, luai_nummul); | ||
1423 | vmbreak; | ||
1424 | } | ||
1425 | vmcase(OP_MOD) { | ||
1426 | op_arith(L, luaV_mod, luaV_modf); | ||
1427 | vmbreak; | ||
1428 | } | ||
1429 | vmcase(OP_POW) { | ||
1430 | op_arithf(L, luai_numpow); | ||
1431 | vmbreak; | ||
1432 | } | ||
1433 | vmcase(OP_DIV) { /* float division (always with floats) */ | ||
1434 | op_arithf(L, luai_numdiv); | ||
1435 | vmbreak; | ||
1436 | } | ||
1437 | vmcase(OP_IDIV) { /* floor division */ | ||
1438 | op_arith(L, luaV_idiv, luai_numidiv); | ||
1439 | vmbreak; | ||
1440 | } | ||
1441 | vmcase(OP_BAND) { | ||
1442 | op_bitwise(L, l_band); | ||
1443 | vmbreak; | ||
1444 | } | ||
1445 | vmcase(OP_BOR) { | ||
1446 | op_bitwise(L, l_bor); | ||
1447 | vmbreak; | ||
1448 | } | ||
1449 | vmcase(OP_BXOR) { | ||
1450 | op_bitwise(L, l_bxor); | ||
1451 | vmbreak; | ||
1452 | } | ||
1453 | vmcase(OP_SHR) { | ||
1454 | op_bitwise(L, luaV_shiftr); | ||
1455 | vmbreak; | ||
1456 | } | ||
1457 | vmcase(OP_SHL) { | ||
1458 | op_bitwise(L, luaV_shiftl); | ||
1459 | vmbreak; | ||
1460 | } | ||
1461 | vmcase(OP_MMBIN) { | ||
1462 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1463 | TValue *rb = vRB(i); | ||
1464 | TMS tm = (TMS)GETARG_C(i); | ||
1465 | StkId result = RA(pi); | ||
1466 | lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR); | ||
1467 | Protect(luaT_trybinTM(L, s2v(ra), rb, result, tm)); | ||
1468 | vmbreak; | ||
1469 | } | ||
1470 | vmcase(OP_MMBINI) { | ||
1471 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1472 | int imm = GETARG_sB(i); | ||
1473 | TMS tm = (TMS)GETARG_C(i); | ||
1474 | int flip = GETARG_k(i); | ||
1475 | StkId result = RA(pi); | ||
1476 | Protect(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm)); | ||
1477 | vmbreak; | ||
1478 | } | ||
1479 | vmcase(OP_MMBINK) { | ||
1480 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1481 | TValue *imm = KB(i); | ||
1482 | TMS tm = (TMS)GETARG_C(i); | ||
1483 | int flip = GETARG_k(i); | ||
1484 | StkId result = RA(pi); | ||
1485 | Protect(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm)); | ||
1486 | vmbreak; | ||
1487 | } | ||
1488 | vmcase(OP_UNM) { | ||
1489 | TValue *rb = vRB(i); | ||
1490 | lua_Number nb; | ||
1491 | if (ttisinteger(rb)) { | ||
1492 | lua_Integer ib = ivalue(rb); | ||
1493 | setivalue(s2v(ra), intop(-, 0, ib)); | ||
1494 | } | ||
1495 | else if (tonumberns(rb, nb)) { | ||
1496 | setfltvalue(s2v(ra), luai_numunm(L, nb)); | ||
1497 | } | ||
1498 | else | ||
1499 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); | ||
1500 | vmbreak; | ||
1501 | } | ||
1502 | vmcase(OP_BNOT) { | ||
1503 | TValue *rb = vRB(i); | ||
1504 | lua_Integer ib; | ||
1505 | if (tointegerns(rb, &ib)) { | ||
1506 | setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); | ||
1507 | } | ||
1508 | else | ||
1509 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); | ||
1510 | vmbreak; | ||
1511 | } | ||
1512 | vmcase(OP_NOT) { | ||
1513 | TValue *rb = vRB(i); | ||
1514 | if (l_isfalse(rb)) | ||
1515 | setbtvalue(s2v(ra)); | ||
1516 | else | ||
1517 | setbfvalue(s2v(ra)); | ||
1518 | vmbreak; | ||
1519 | } | ||
1520 | vmcase(OP_LEN) { | ||
1521 | Protect(luaV_objlen(L, ra, vRB(i))); | ||
1522 | vmbreak; | ||
1523 | } | ||
1524 | vmcase(OP_CONCAT) { | ||
1525 | int n = GETARG_B(i); /* number of elements to concatenate */ | ||
1526 | L->top = ra + n; /* mark the end of concat operands */ | ||
1527 | ProtectNT(luaV_concat(L, n)); | ||
1528 | checkGC(L, L->top); /* 'luaV_concat' ensures correct top */ | ||
1529 | vmbreak; | ||
1530 | } | ||
1531 | vmcase(OP_CLOSE) { | ||
1532 | Protect(luaF_close(L, ra, LUA_OK)); | ||
1533 | vmbreak; | ||
1534 | } | ||
1535 | vmcase(OP_TBC) { | ||
1536 | /* create new to-be-closed upvalue */ | ||
1537 | halfProtect(luaF_newtbcupval(L, ra)); | ||
1538 | vmbreak; | ||
1539 | } | ||
1540 | vmcase(OP_JMP) { | ||
1541 | dojump(ci, i, 0); | ||
1542 | vmbreak; | ||
1543 | } | ||
1544 | vmcase(OP_EQ) { | ||
1545 | int cond; | ||
1546 | TValue *rb = vRB(i); | ||
1547 | Protect(cond = luaV_equalobj(L, s2v(ra), rb)); | ||
1548 | docondjump(); | ||
1549 | vmbreak; | ||
1550 | } | ||
1551 | vmcase(OP_LT) { | ||
1552 | op_order(L, l_lti, LTnum, lessthanothers); | ||
1553 | vmbreak; | ||
1554 | } | ||
1555 | vmcase(OP_LE) { | ||
1556 | op_order(L, l_lei, LEnum, lessequalothers); | ||
1557 | vmbreak; | ||
1558 | } | ||
1559 | vmcase(OP_EQK) { | ||
1560 | TValue *rb = KB(i); | ||
1561 | /* basic types do not use '__eq'; we can use raw equality */ | ||
1562 | int cond = luaV_rawequalobj(s2v(ra), rb); | ||
1563 | docondjump(); | ||
1564 | vmbreak; | ||
1565 | } | ||
1566 | vmcase(OP_EQI) { | ||
1567 | int cond; | ||
1568 | int im = GETARG_sB(i); | ||
1569 | if (ttisinteger(s2v(ra))) | ||
1570 | cond = (ivalue(s2v(ra)) == im); | ||
1571 | else if (ttisfloat(s2v(ra))) | ||
1572 | cond = luai_numeq(fltvalue(s2v(ra)), cast_num(im)); | ||
1573 | else | ||
1574 | cond = 0; /* other types cannot be equal to a number */ | ||
1575 | docondjump(); | ||
1576 | vmbreak; | ||
1577 | } | ||
1578 | vmcase(OP_LTI) { | ||
1579 | op_orderI(L, l_lti, luai_numlt, 0, TM_LT); | ||
1580 | vmbreak; | ||
1581 | } | ||
1582 | vmcase(OP_LEI) { | ||
1583 | op_orderI(L, l_lei, luai_numle, 0, TM_LE); | ||
1584 | vmbreak; | ||
1585 | } | ||
1586 | vmcase(OP_GTI) { | ||
1587 | op_orderI(L, l_gti, luai_numgt, 1, TM_LT); | ||
1588 | vmbreak; | ||
1589 | } | ||
1590 | vmcase(OP_GEI) { | ||
1591 | op_orderI(L, l_gei, luai_numge, 1, TM_LE); | ||
1592 | vmbreak; | ||
1593 | } | ||
1594 | vmcase(OP_TEST) { | ||
1595 | int cond = !l_isfalse(s2v(ra)); | ||
1596 | docondjump(); | ||
1597 | vmbreak; | ||
1598 | } | ||
1599 | vmcase(OP_TESTSET) { | ||
1600 | TValue *rb = vRB(i); | ||
1601 | if (l_isfalse(rb) == GETARG_k(i)) | ||
1602 | pc++; | ||
1603 | else { | ||
1604 | setobj2s(L, ra, rb); | ||
1605 | donextjump(ci); | ||
1606 | } | ||
1607 | vmbreak; | ||
1608 | } | ||
1609 | vmcase(OP_CALL) { | ||
1610 | int b = GETARG_B(i); | ||
1611 | int nresults = GETARG_C(i) - 1; | ||
1612 | if (b != 0) /* fixed number of arguments? */ | ||
1613 | L->top = ra + b; /* top signals number of arguments */ | ||
1614 | /* else previous instruction set top */ | ||
1615 | ProtectNT(luaD_call(L, ra, nresults)); | ||
1616 | vmbreak; | ||
1617 | } | ||
1618 | vmcase(OP_TAILCALL) { | ||
1619 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ | ||
1620 | int nparams1 = GETARG_C(i); | ||
1621 | /* delat is virtual 'func' - real 'func' (vararg functions) */ | ||
1622 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; | ||
1623 | if (b != 0) | ||
1624 | L->top = ra + b; | ||
1625 | else /* previous instruction set top */ | ||
1626 | b = cast_int(L->top - ra); | ||
1627 | savepc(ci); /* some calls here can raise errors */ | ||
1628 | if (TESTARG_k(i)) { | ||
1629 | /* close upvalues from current call; the compiler ensures | ||
1630 | that there are no to-be-closed variables here, so this | ||
1631 | call cannot change the stack */ | ||
1632 | luaF_close(L, base, NOCLOSINGMETH); | ||
1633 | lua_assert(base == ci->func + 1); | ||
1634 | } | ||
1635 | while (!ttisfunction(s2v(ra))) { /* not a function? */ | ||
1636 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ | ||
1637 | b++; /* there is now one extra argument */ | ||
1638 | checkstackp(L, 1, ra); | ||
1639 | } | ||
1640 | if (!ttisLclosure(s2v(ra))) { /* C function? */ | ||
1641 | luaD_call(L, ra, LUA_MULTRET); /* call it */ | ||
1642 | updatetrap(ci); | ||
1643 | updatestack(ci); /* stack may have been relocated */ | ||
1644 | ci->func -= delta; | ||
1645 | luaD_poscall(L, ci, cast_int(L->top - ra)); | ||
1646 | return; | ||
1647 | } | ||
1648 | ci->func -= delta; | ||
1649 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | ||
1650 | goto tailcall; | ||
1651 | } | ||
1652 | vmcase(OP_RETURN) { | ||
1653 | int n = GETARG_B(i) - 1; /* number of results */ | ||
1654 | int nparams1 = GETARG_C(i); | ||
1655 | if (n < 0) /* not fixed? */ | ||
1656 | n = cast_int(L->top - ra); /* get what is available */ | ||
1657 | savepc(ci); | ||
1658 | if (TESTARG_k(i)) { /* may there be open upvalues? */ | ||
1659 | if (L->top < ci->top) | ||
1660 | L->top = ci->top; | ||
1661 | luaF_close(L, base, LUA_OK); | ||
1662 | updatetrap(ci); | ||
1663 | updatestack(ci); | ||
1664 | } | ||
1665 | if (nparams1) /* vararg function? */ | ||
1666 | ci->func -= ci->u.l.nextraargs + nparams1; | ||
1667 | L->top = ra + n; /* set call for 'luaD_poscall' */ | ||
1668 | luaD_poscall(L, ci, n); | ||
1669 | return; | ||
1670 | } | ||
1671 | vmcase(OP_RETURN0) { | ||
1672 | if (L->hookmask) { | ||
1673 | L->top = ra; | ||
1674 | halfProtectNT(luaD_poscall(L, ci, 0)); /* no hurry... */ | ||
1675 | } | ||
1676 | else { /* do the 'poscall' here */ | ||
1677 | int nres = ci->nresults; | ||
1678 | L->ci = ci->previous; /* back to caller */ | ||
1679 | L->top = base - 1; | ||
1680 | while (nres-- > 0) | ||
1681 | setnilvalue(s2v(L->top++)); /* all results are nil */ | ||
1682 | } | ||
1683 | return; | ||
1684 | } | ||
1685 | vmcase(OP_RETURN1) { | ||
1686 | if (L->hookmask) { | ||
1687 | L->top = ra + 1; | ||
1688 | halfProtectNT(luaD_poscall(L, ci, 1)); /* no hurry... */ | ||
1689 | } | ||
1690 | else { /* do the 'poscall' here */ | ||
1691 | int nres = ci->nresults; | ||
1692 | L->ci = ci->previous; /* back to caller */ | ||
1693 | if (nres == 0) | ||
1694 | L->top = base - 1; /* asked for no results */ | ||
1695 | else { | ||
1696 | setobjs2s(L, base - 1, ra); /* at least this result */ | ||
1697 | L->top = base; | ||
1698 | while (--nres > 0) /* complete missing results */ | ||
1699 | setnilvalue(s2v(L->top++)); | ||
1700 | } | ||
1701 | } | ||
1702 | return; | ||
1703 | } | ||
1704 | vmcase(OP_FORLOOP) { | ||
1705 | if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ | ||
1706 | lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1))); | ||
1707 | if (count > 0) { /* still more iterations? */ | ||
1708 | lua_Integer step = ivalue(s2v(ra + 2)); | ||
1709 | lua_Integer idx = ivalue(s2v(ra)); /* internal index */ | ||
1710 | chgivalue(s2v(ra + 1), count - 1); /* update counter */ | ||
1711 | idx = intop(+, idx, step); /* add step to index */ | ||
1712 | chgivalue(s2v(ra), idx); /* update internal index */ | ||
1713 | setivalue(s2v(ra + 3), idx); /* and control variable */ | ||
1714 | pc -= GETARG_Bx(i); /* jump back */ | ||
1715 | } | ||
1716 | } | ||
1717 | else if (floatforloop(ra)) /* float loop */ | ||
1718 | pc -= GETARG_Bx(i); /* jump back */ | ||
1719 | updatetrap(ci); /* allows a signal to break the loop */ | ||
1720 | vmbreak; | ||
1721 | } | ||
1722 | vmcase(OP_FORPREP) { | ||
1723 | savestate(L, ci); /* in case of errors */ | ||
1724 | if (forprep(L, ra)) | ||
1725 | pc += GETARG_Bx(i) + 1; /* skip the loop */ | ||
1726 | vmbreak; | ||
1727 | } | ||
1728 | vmcase(OP_TFORPREP) { | ||
1729 | /* create to-be-closed upvalue (if needed) */ | ||
1730 | halfProtect(luaF_newtbcupval(L, ra + 3)); | ||
1731 | pc += GETARG_Bx(i); | ||
1732 | i = *(pc++); /* go to next instruction */ | ||
1733 | lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i)); | ||
1734 | goto l_tforcall; | ||
1735 | } | ||
1736 | vmcase(OP_TFORCALL) { | ||
1737 | l_tforcall: | ||
1738 | /* 'ra' has the iterator function, 'ra + 1' has the state, | ||
1739 | 'ra + 2' has the control variable, and 'ra + 3' has the | ||
1740 | to-be-closed variable. The call will use the stack after | ||
1741 | these values (starting at 'ra + 4') | ||
1742 | */ | ||
1743 | /* push function, state, and control variable */ | ||
1744 | memcpy(ra + 4, ra, 3 * sizeof(*ra)); | ||
1745 | L->top = ra + 4 + 3; | ||
1746 | ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ | ||
1747 | updatestack(ci); /* stack may have changed */ | ||
1748 | i = *(pc++); /* go to next instruction */ | ||
1749 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); | ||
1750 | goto l_tforloop; | ||
1751 | } | ||
1752 | vmcase(OP_TFORLOOP) { | ||
1753 | l_tforloop: | ||
1754 | if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ | ||
1755 | setobjs2s(L, ra + 2, ra + 4); /* save control variable */ | ||
1756 | pc -= GETARG_Bx(i); /* jump back */ | ||
1757 | } | ||
1758 | vmbreak; | ||
1759 | } | ||
1760 | vmcase(OP_SETLIST) { | ||
1761 | int n = GETARG_B(i); | ||
1762 | unsigned int last = GETARG_C(i); | ||
1763 | Table *h = hvalue(s2v(ra)); | ||
1764 | if (n == 0) | ||
1765 | n = cast_int(L->top - ra) - 1; /* get up to the top */ | ||
1766 | else | ||
1767 | L->top = ci->top; /* correct top in case of emergency GC */ | ||
1768 | last += n; | ||
1769 | if (TESTARG_k(i)) { | ||
1770 | last += GETARG_Ax(*pc) * (MAXARG_C + 1); | ||
1771 | pc++; | ||
1772 | } | ||
1773 | if (last > luaH_realasize(h)) /* needs more space? */ | ||
1774 | luaH_resizearray(L, h, last); /* preallocate it at once */ | ||
1775 | for (; n > 0; n--) { | ||
1776 | TValue *val = s2v(ra + n); | ||
1777 | setobj2t(L, &h->array[last - 1], val); | ||
1778 | last--; | ||
1779 | luaC_barrierback(L, obj2gco(h), val); | ||
1780 | } | ||
1781 | vmbreak; | ||
1782 | } | ||
1783 | vmcase(OP_CLOSURE) { | ||
1784 | Proto *p = cl->p->p[GETARG_Bx(i)]; | ||
1785 | halfProtect(pushclosure(L, p, cl->upvals, base, ra)); | ||
1786 | checkGC(L, ra + 1); | ||
1787 | vmbreak; | ||
1788 | } | ||
1789 | vmcase(OP_VARARG) { | ||
1790 | int n = GETARG_C(i) - 1; /* required results */ | ||
1791 | Protect(luaT_getvarargs(L, ci, ra, n)); | ||
1792 | vmbreak; | ||
1793 | } | ||
1794 | vmcase(OP_VARARGPREP) { | ||
1795 | luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p); | ||
1796 | updatetrap(ci); | ||
1797 | if (trap) { | ||
1798 | luaD_hookcall(L, ci); | ||
1799 | L->oldpc = pc + 1; /* next opcode will be seen as a "new" line */ | ||
1800 | } | ||
1801 | updatebase(ci); /* function has new base after adjustment */ | ||
1802 | vmbreak; | ||
1803 | } | ||
1804 | vmcase(OP_EXTRAARG) { | ||
1805 | lua_assert(0); | ||
1806 | vmbreak; | ||
1807 | } | ||
1808 | } | ||
1809 | } | ||
1810 | } | ||
1811 | |||
1812 | /* }================================================================== */ | ||
diff --git a/src/lua/lvm.h b/src/lua/lvm.h new file mode 100644 index 0000000..2d4ac16 --- /dev/null +++ b/src/lua/lvm.h | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | ** $Id: lvm.h $ | ||
3 | ** Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lvm_h | ||
8 | #define lvm_h | ||
9 | |||
10 | |||
11 | #include "ldo.h" | ||
12 | #include "lobject.h" | ||
13 | #include "ltm.h" | ||
14 | |||
15 | |||
16 | #if !defined(LUA_NOCVTN2S) | ||
17 | #define cvt2str(o) ttisnumber(o) | ||
18 | #else | ||
19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ | ||
20 | #endif | ||
21 | |||
22 | |||
23 | #if !defined(LUA_NOCVTS2N) | ||
24 | #define cvt2num(o) ttisstring(o) | ||
25 | #else | ||
26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ | ||
27 | #endif | ||
28 | |||
29 | |||
30 | /* | ||
31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers | ||
32 | ** by flooring them (instead of raising an error if they are not | ||
33 | ** integral values) | ||
34 | */ | ||
35 | #if !defined(LUA_FLOORN2I) | ||
36 | #define LUA_FLOORN2I F2Ieq | ||
37 | #endif | ||
38 | |||
39 | |||
40 | /* | ||
41 | ** Rounding modes for float->integer coercion | ||
42 | */ | ||
43 | typedef enum { | ||
44 | F2Ieq, /* no rounding; accepts only integral values */ | ||
45 | F2Ifloor, /* takes the floor of the number */ | ||
46 | F2Iceil /* takes the ceil of the number */ | ||
47 | } F2Imod; | ||
48 | |||
49 | |||
50 | /* convert an object to a float (including string coercion) */ | ||
51 | #define tonumber(o,n) \ | ||
52 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) | ||
53 | |||
54 | |||
55 | /* convert an object to a float (without string coercion) */ | ||
56 | #define tonumberns(o,n) \ | ||
57 | (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ | ||
58 | (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) | ||
59 | |||
60 | |||
61 | /* convert an object to an integer (including string coercion) */ | ||
62 | #define tointeger(o,i) \ | ||
63 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) | ||
64 | |||
65 | |||
66 | /* convert an object to an integer (without string coercion) */ | ||
67 | #define tointegerns(o,i) \ | ||
68 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointegerns(o,i,LUA_FLOORN2I)) | ||
69 | |||
70 | |||
71 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) | ||
72 | |||
73 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) | ||
74 | |||
75 | |||
76 | /* | ||
77 | ** fast track for 'gettable': if 't' is a table and 't[k]' is present, | ||
78 | ** return 1 with 'slot' pointing to 't[k]' (position of final result). | ||
79 | ** Otherwise, return 0 (meaning it will have to check metamethod) | ||
80 | ** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL | ||
81 | ** (otherwise). 'f' is the raw get function to use. | ||
82 | */ | ||
83 | #define luaV_fastget(L,t,k,slot,f) \ | ||
84 | (!ttistable(t) \ | ||
85 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ | ||
86 | : (slot = f(hvalue(t), k), /* else, do raw access */ \ | ||
87 | !isempty(slot))) /* result not empty? */ | ||
88 | |||
89 | |||
90 | /* | ||
91 | ** Special case of 'luaV_fastget' for integers, inlining the fast case | ||
92 | ** of 'luaH_getint'. | ||
93 | */ | ||
94 | #define luaV_fastgeti(L,t,k,slot) \ | ||
95 | (!ttistable(t) \ | ||
96 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ | ||
97 | : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ | ||
98 | ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ | ||
99 | !isempty(slot))) /* result not empty? */ | ||
100 | |||
101 | |||
102 | /* | ||
103 | ** Finish a fast set operation (when fast get succeeds). In that case, | ||
104 | ** 'slot' points to the place to put the value. | ||
105 | */ | ||
106 | #define luaV_finishfastset(L,t,slot,v) \ | ||
107 | { setobj2t(L, cast(TValue *,slot), v); \ | ||
108 | luaC_barrierback(L, gcvalue(t), v); } | ||
109 | |||
110 | |||
111 | |||
112 | |||
113 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); | ||
114 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); | ||
115 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); | ||
116 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); | ||
117 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); | ||
118 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, | ||
119 | F2Imod mode); | ||
120 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); | ||
121 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, | ||
122 | StkId val, const TValue *slot); | ||
123 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | ||
124 | TValue *val, const TValue *slot); | ||
125 | LUAI_FUNC void luaV_finishOp (lua_State *L); | ||
126 | LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); | ||
127 | LUAI_FUNC void luaV_concat (lua_State *L, int total); | ||
128 | LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); | ||
129 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); | ||
130 | LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); | ||
131 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); | ||
132 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); | ||
133 | |||
134 | #endif | ||
diff --git a/src/lua-5.3/lzio.c b/src/lua/lzio.c index 6f79094..cd0a02d 100644 --- a/src/lua-5.3/lzio.c +++ b/src/lua/lzio.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lzio.c $ |
3 | ** Buffered streams | 3 | ** Buffered streams |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
diff --git a/src/lua-5.3/lzio.h b/src/lua/lzio.h index d897870..38f397f 100644 --- a/src/lua-5.3/lzio.h +++ b/src/lua/lzio.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $ | 2 | ** $Id: lzio.h $ |
3 | ** Buffered streams | 3 | ** Buffered streams |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
diff --git a/src/lua-5.3/makefile b/src/lua/makefile index 0835d9c..397c817 100644 --- a/src/lua-5.3/makefile +++ b/src/lua/makefile | |||
@@ -44,7 +44,7 @@ LOCAL = $(TESTS) $(CWARNS) -g | |||
44 | 44 | ||
45 | 45 | ||
46 | # enable Linux goodies | 46 | # enable Linux goodies |
47 | MYCFLAGS= $(LOCAL) -std=c99 -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1 | 47 | MYCFLAGS= $(LOCAL) -std=c99 |
48 | MYLDFLAGS= $(LOCAL) -Wl | 48 | MYLDFLAGS= $(LOCAL) -Wl |
49 | MYLIBS= -ldl -lreadline | 49 | MYLIBS= -ldl -lreadline |
50 | 50 | ||
@@ -68,7 +68,7 @@ CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ | |||
68 | ltm.o lundump.o lvm.o lzio.o | 68 | ltm.o lundump.o lvm.o lzio.o |
69 | AUX_O= lauxlib.o | 69 | AUX_O= lauxlib.o |
70 | LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \ | 70 | LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \ |
71 | lutf8lib.o lbitlib.o loadlib.o lcorolib.o linit.o | 71 | lutf8lib.o loadlib.o lcorolib.o linit.o |
72 | 72 | ||
73 | ALL_T= $(CORE_T) | 73 | ALL_T= $(CORE_T) |
74 | ALL_O= $(CORE_O) $(AUX_O) $(LIB_O) | 74 | ALL_O= $(CORE_O) $(AUX_O) $(LIB_O) |
@@ -117,7 +117,6 @@ lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ | |||
117 | ltable.h lundump.h lvm.h | 117 | ltable.h lundump.h lvm.h |
118 | lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h | 118 | lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h |
119 | lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | 119 | lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h |
120 | lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | ||
121 | lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ | 120 | lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ |
122 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ | 121 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ |
123 | ldo.h lgc.h lstring.h ltable.h lvm.h | 122 | ldo.h lgc.h lstring.h ltable.h lvm.h |