diff options
author | Mike Pall <mike> | 2012-06-09 15:02:02 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-06-09 15:03:40 +0200 |
commit | 0a6c8338d240dd318db2f5269414dcf7ddc9ed35 (patch) | |
tree | 953561aad7b19aaefda674a1962d47c754d552f6 /src | |
parent | 6c8aaef2bbb005a2176e35c08f85957a9bc428d0 (diff) | |
download | luajit-0a6c8338d240dd318db2f5269414dcf7ddc9ed35.tar.gz luajit-0a6c8338d240dd318db2f5269414dcf7ddc9ed35.tar.bz2 luajit-0a6c8338d240dd318db2f5269414dcf7ddc9ed35.zip |
Add minified Lua interpreter (minilua). Used by the build process.
Diffstat (limited to 'src')
-rw-r--r-- | src/host/README | 4 | ||||
-rw-r--r-- | src/host/genminilua.lua | 363 | ||||
-rw-r--r-- | src/host/minilua.c | 7906 |
3 files changed, 8273 insertions, 0 deletions
diff --git a/src/host/README b/src/host/README new file mode 100644 index 00000000..abfcdaa7 --- /dev/null +++ b/src/host/README | |||
@@ -0,0 +1,4 @@ | |||
1 | The files in this directory are only used during the build process of LuaJIT. | ||
2 | For cross-compilation, they must be executed on the host, not on the target. | ||
3 | |||
4 | These files should NOT be installed! | ||
diff --git a/src/host/genminilua.lua b/src/host/genminilua.lua new file mode 100644 index 00000000..7282cf16 --- /dev/null +++ b/src/host/genminilua.lua | |||
@@ -0,0 +1,363 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- Lua script to generate a customized, minified version of Lua. | ||
3 | -- The resulting 'minilua' is used for the build process of LuaJIT. | ||
4 | ---------------------------------------------------------------------------- | ||
5 | -- Copyright (C) 2005-2012 Mike Pall. All rights reserved. | ||
6 | -- Released under the MIT license. See Copyright Notice in luajit.h | ||
7 | ---------------------------------------------------------------------------- | ||
8 | |||
9 | local sub, match, gsub = string.sub, string.match, string.gsub | ||
10 | |||
11 | local LUA_VERSION = "5.1.5" | ||
12 | local LUA_SOURCE | ||
13 | |||
14 | local function usage() | ||
15 | io.stderr:write("Usage: ", arg and arg[0] or "genminilua", | ||
16 | " lua-", LUA_VERSION, "-source-dir\n") | ||
17 | os.exit(1) | ||
18 | end | ||
19 | |||
20 | local function find_sources() | ||
21 | LUA_SOURCE = arg and arg[1] | ||
22 | if not LUA_SOURCE then usage() end | ||
23 | if sub(LUA_SOURCE, -1) ~= "/" then LUA_SOURCE = LUA_SOURCE.."/" end | ||
24 | local fp = io.open(LUA_SOURCE .. "lua.h") | ||
25 | if not fp then | ||
26 | LUA_SOURCE = LUA_SOURCE.."src/" | ||
27 | fp = io.open(LUA_SOURCE .. "lua.h") | ||
28 | if not fp then usage() end | ||
29 | end | ||
30 | local all = fp:read("*a") | ||
31 | fp:close() | ||
32 | if not match(all, 'LUA_RELEASE%s*"Lua '..LUA_VERSION..'"') then | ||
33 | io.stderr:write("Error: version mismatch\n") | ||
34 | usage() | ||
35 | end | ||
36 | end | ||
37 | |||
38 | local LUA_FILES = { | ||
39 | "lmem.c", "lobject.c", "ltm.c", "lfunc.c", "ldo.c", "lstring.c", "ltable.c", | ||
40 | "lgc.c", "lstate.c", "ldebug.c", "lzio.c", "lopcodes.c", | ||
41 | "llex.c", "lcode.c", "lparser.c", "lvm.c", "lapi.c", "lauxlib.c", | ||
42 | "lbaselib.c", "ltablib.c", "liolib.c", "loslib.c", "lstrlib.c", "linit.c", | ||
43 | } | ||
44 | |||
45 | local REMOVE_LIB = {} | ||
46 | gsub([[ | ||
47 | collectgarbage dofile gcinfo getfenv getmetatable load print rawequal rawset | ||
48 | select tostring xpcall | ||
49 | foreach foreachi getn maxn setn | ||
50 | popen tmpfile seek setvbuf __tostring | ||
51 | clock date difftime execute getenv rename setlocale time tmpname | ||
52 | dump gfind len reverse | ||
53 | LUA_LOADLIBNAME LUA_MATHLIBNAME LUA_DBLIBNAME | ||
54 | ]], "%S+", function(name) | ||
55 | REMOVE_LIB[name] = true | ||
56 | end) | ||
57 | |||
58 | local REMOVE_EXTINC = { ["<assert.h>"] = true, ["<locale.h>"] = true, } | ||
59 | |||
60 | local CUSTOM_MAIN = [[ | ||
61 | int main(int argc, char **argv){ | ||
62 | lua_State *L = luaL_newstate(); | ||
63 | int i; | ||
64 | luaL_openlibs(L); | ||
65 | if (argc < 2) return 1; | ||
66 | lua_createtable(L, 0, 1); | ||
67 | lua_pushstring(L, argv[1]); | ||
68 | lua_rawseti(L, -2, 0); | ||
69 | lua_setglobal(L, "arg"); | ||
70 | if (luaL_loadfile(L, argv[1])) | ||
71 | goto err; | ||
72 | for (i = 2; i < argc; i++) | ||
73 | lua_pushstring(L, argv[i]); | ||
74 | if (lua_pcall(L, argc - 2, 0, 0)) { | ||
75 | err: | ||
76 | fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); | ||
77 | return 1; | ||
78 | } | ||
79 | lua_close(L); | ||
80 | return 0; | ||
81 | } | ||
82 | ]] | ||
83 | |||
84 | local function read_sources() | ||
85 | local t = {} | ||
86 | for i, name in ipairs(LUA_FILES) do | ||
87 | local fp = assert(io.open(LUA_SOURCE..name, "r")) | ||
88 | t[i] = fp:read("*a") | ||
89 | assert(fp:close()) | ||
90 | end | ||
91 | t[#t+1] = CUSTOM_MAIN | ||
92 | return table.concat(t) | ||
93 | end | ||
94 | |||
95 | local includes = {} | ||
96 | |||
97 | local function merge_includes(src) | ||
98 | return gsub(src, '#include%s*"([^"]*)"%s*\n', function(name) | ||
99 | if includes[name] then return "" end | ||
100 | includes[name] = true | ||
101 | local fp = assert(io.open(LUA_SOURCE..name, "r")) | ||
102 | local src = fp:read("*a") | ||
103 | assert(fp:close()) | ||
104 | src = gsub(src, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "") | ||
105 | src = gsub(src, "#endif%s*$", "") | ||
106 | return merge_includes(src) | ||
107 | end) | ||
108 | end | ||
109 | |||
110 | local function get_license(src) | ||
111 | return match(src, "/%*+\n%* Copyright %(.-%*/\n") | ||
112 | end | ||
113 | |||
114 | local function fold_lines(src) | ||
115 | return gsub(src, "\\\n", " ") | ||
116 | end | ||
117 | |||
118 | local strings = {} | ||
119 | |||
120 | local function save_str(str) | ||
121 | local n = #strings+1 | ||
122 | strings[n] = str | ||
123 | return "\1"..n.."\2" | ||
124 | end | ||
125 | |||
126 | local function save_strings(src) | ||
127 | src = gsub(src, '"[^"\n]*"', save_str) | ||
128 | return gsub(src, "'[^'\n]*'", save_str) | ||
129 | end | ||
130 | |||
131 | local function restore_strings(src) | ||
132 | return gsub(src, "\1(%d+)\2", function(numstr) | ||
133 | return strings[tonumber(numstr)] | ||
134 | end) | ||
135 | end | ||
136 | |||
137 | local function def_istrue(def) | ||
138 | return def == "INT_MAX > 2147483640L" or | ||
139 | def == "LUAI_BITSINT >= 32" or | ||
140 | def == "SIZE_Bx < LUAI_BITSINT-1" or | ||
141 | def == "cast" or | ||
142 | def == "defined(LUA_CORE)" or | ||
143 | def == "MINSTRTABSIZE" or | ||
144 | def == "LUA_MINBUFFER" or | ||
145 | def == "HARDSTACKTESTS" or | ||
146 | def == "UNUSED" | ||
147 | end | ||
148 | |||
149 | local head, defs = {}, {} | ||
150 | |||
151 | local function preprocess(src) | ||
152 | local t = { match(src, "^(.-)#") } | ||
153 | local lvl, on, oldon = 0, true, {} | ||
154 | for pp, def, txt in string.gmatch(src, "#(%w+) *([^\n]*)\n([^#]*)") do | ||
155 | if pp == "if" or pp == "ifdef" or pp == "ifndef" then | ||
156 | lvl = lvl + 1 | ||
157 | oldon[lvl] = on | ||
158 | on = def_istrue(def) | ||
159 | elseif pp == "else" then | ||
160 | if oldon[lvl] then | ||
161 | if on == false then on = true else on = false end | ||
162 | end | ||
163 | elseif pp == "elif" then | ||
164 | if oldon[lvl] then | ||
165 | on = def_istrue(def) | ||
166 | end | ||
167 | elseif pp == "endif" then | ||
168 | on = oldon[lvl] | ||
169 | lvl = lvl - 1 | ||
170 | elseif on then | ||
171 | if pp == "include" then | ||
172 | if not head[def] and not REMOVE_EXTINC[def] then | ||
173 | head[def] = true | ||
174 | head[#head+1] = "#include "..def.."\n" | ||
175 | end | ||
176 | elseif pp == "define" then | ||
177 | local k, sp, v = match(def, "([%w_]+)(%s*)(.*)") | ||
178 | if k and not (sp == "" and sub(v, 1, 1) == "(") then | ||
179 | defs[k] = gsub(v, "%a[%w_]*", function(tok) | ||
180 | return defs[tok] or tok | ||
181 | end) | ||
182 | else | ||
183 | t[#t+1] = "#define "..def.."\n" | ||
184 | end | ||
185 | elseif pp ~= "undef" then | ||
186 | error("unexpected directive: "..pp.." "..def) | ||
187 | end | ||
188 | end | ||
189 | if on then t[#t+1] = txt end | ||
190 | end | ||
191 | return gsub(table.concat(t), "%a[%w_]*", function(tok) | ||
192 | return defs[tok] or tok | ||
193 | end) | ||
194 | end | ||
195 | |||
196 | local function merge_header(src, license) | ||
197 | local hdr = string.format([[ | ||
198 | /* This is a heavily customized and minimized copy of Lua %s. */ | ||
199 | /* It's only used to build LuaJIT. It does NOT have all standard functions! */ | ||
200 | ]], LUA_VERSION) | ||
201 | return hdr..license..table.concat(head)..src | ||
202 | end | ||
203 | |||
204 | local function strip_unused1(src) | ||
205 | return gsub(src, '( {"?([%w_]+)"?,%s+%a[%w_]*},\n)', function(line, func) | ||
206 | return REMOVE_LIB[func] and "" or line | ||
207 | end) | ||
208 | end | ||
209 | |||
210 | local function strip_unused2(src) | ||
211 | return gsub(src, "Symbolic Execution.-}=", "") | ||
212 | end | ||
213 | |||
214 | local function strip_unused3(src) | ||
215 | src = gsub(src, "extern", "static") | ||
216 | src = gsub(src, "\nstatic([^\n]-)%(([^)]*)%)%(", "\nstatic%1 %2(") | ||
217 | src = gsub(src, "#define lua_assert[^\n]*\n", "") | ||
218 | src = gsub(src, "lua_assert%b();?", "") | ||
219 | src = gsub(src, "default:\n}", "default:;\n}") | ||
220 | src = gsub(src, "lua_lock%b();", "") | ||
221 | src = gsub(src, "lua_unlock%b();", "") | ||
222 | src = gsub(src, "luai_threadyield%b();", "") | ||
223 | src = gsub(src, "luai_userstateopen%b();", "{}") | ||
224 | src = gsub(src, "luai_userstate%w+%b();", "") | ||
225 | src = gsub(src, "%(%(c==.*luaY_parser%)", "luaY_parser") | ||
226 | src = gsub(src, "trydecpoint%(ls,seminfo%)", | ||
227 | "luaX_lexerror(ls,\"malformed number\",TK_NUMBER)") | ||
228 | src = gsub(src, "int c=luaZ_lookahead%b();", "") | ||
229 | src = gsub(src, "luaL_register%(L,\"coroutine\",co_funcs%);\nreturn 2;", | ||
230 | "return 1;") | ||
231 | src = gsub(src, "getfuncname%b():", "NULL:") | ||
232 | src = gsub(src, "getobjname%b():", "NULL:") | ||
233 | src = gsub(src, "if%([^\n]*hookmask[^\n]*%)\n[^\n]*\n", "") | ||
234 | src = gsub(src, "if%([^\n]*hookmask[^\n]*%)%b{}\n", "") | ||
235 | src = gsub(src, "if%([^\n]*hookmask[^\n]*&&\n[^\n]*%b{}\n", "") | ||
236 | src = gsub(src, "(twoto%b()%()", "%1(size_t)") | ||
237 | src = gsub(src, "i<sizenode", "i<(int)sizenode") | ||
238 | return gsub(src, "\n\n+", "\n") | ||
239 | end | ||
240 | |||
241 | local function strip_comments(src) | ||
242 | return gsub(src, "/%*.-%*/", " ") | ||
243 | end | ||
244 | |||
245 | local function strip_whitespace(src) | ||
246 | src = gsub(src, "^%s+", "") | ||
247 | src = gsub(src, "%s*\n%s*", "\n") | ||
248 | src = gsub(src, "[ \t]+", " ") | ||
249 | src = gsub(src, "(%W) ", "%1") | ||
250 | return gsub(src, " (%W)", "%1") | ||
251 | end | ||
252 | |||
253 | local function rename_tokens1(src) | ||
254 | src = gsub(src, "getline", "getline_") | ||
255 | src = gsub(src, "struct ([%w_]+)", "ZX%1") | ||
256 | return gsub(src, "union ([%w_]+)", "ZY%1") | ||
257 | end | ||
258 | |||
259 | local function rename_tokens2(src) | ||
260 | src = gsub(src, "ZX([%w_]+)", "struct %1") | ||
261 | return gsub(src, "ZY([%w_]+)", "union %1") | ||
262 | end | ||
263 | |||
264 | local function func_gather(src) | ||
265 | local nodes, list = {}, {} | ||
266 | local pos, len = 1, #src | ||
267 | while pos < len do | ||
268 | local d, w = match(src, "^(#define ([%w_]+)[^\n]*\n)", pos) | ||
269 | if d then | ||
270 | local n = #list+1 | ||
271 | list[n] = d | ||
272 | nodes[w] = n | ||
273 | else | ||
274 | local s | ||
275 | d, w, s = match(src, "^(([%w_]+)[^\n]*([{;])\n)", pos) | ||
276 | if not d then | ||
277 | d, w, s = match(src, "^(([%w_]+)[^(]*%b()([{;])\n)", pos) | ||
278 | if not d then d = match(src, "^[^\n]*\n", pos) end | ||
279 | end | ||
280 | if s == "{" then | ||
281 | d = d..sub(match(src, "^%b{}[^;\n]*;?\n", pos+#d-2), 3) | ||
282 | if sub(d, -2) == "{\n" then | ||
283 | d = d..sub(match(src, "^%b{}[^;\n]*;?\n", pos+#d-2), 3) | ||
284 | end | ||
285 | end | ||
286 | local k, v = nil, d | ||
287 | if w == "typedef" then | ||
288 | if match(d, "^typedef enum") then | ||
289 | head[#head+1] = d | ||
290 | else | ||
291 | k = match(d, "([%w_]+);\n$") | ||
292 | if not k then k = match(d, "^.-%(.-([%w_]+)%)%(") end | ||
293 | end | ||
294 | elseif w == "enum" then | ||
295 | head[#head+1] = v | ||
296 | elseif w ~= nil then | ||
297 | k = match(d, "^[^\n]-([%w_]+)[(%[=]") | ||
298 | if k then | ||
299 | if w ~= "static" and k ~= "main" then v = "static "..d end | ||
300 | else | ||
301 | k = w | ||
302 | end | ||
303 | end | ||
304 | if w and k then | ||
305 | local o = nodes[k] | ||
306 | if o then nodes["*"..k] = o end | ||
307 | local n = #list+1 | ||
308 | list[n] = v | ||
309 | nodes[k] = n | ||
310 | end | ||
311 | end | ||
312 | pos = pos + #d | ||
313 | end | ||
314 | return nodes, list | ||
315 | end | ||
316 | |||
317 | local function func_visit(nodes, list, used, n) | ||
318 | local i = nodes[n] | ||
319 | for m in string.gmatch(list[i], "[%w_]+") do | ||
320 | if nodes[m] then | ||
321 | local j = used[m] | ||
322 | if not j then | ||
323 | used[m] = i | ||
324 | func_visit(nodes, list, used, m) | ||
325 | elseif i < j then | ||
326 | used[m] = i | ||
327 | end | ||
328 | end | ||
329 | end | ||
330 | end | ||
331 | |||
332 | local function func_collect(src) | ||
333 | local nodes, list = func_gather(src) | ||
334 | local used = {} | ||
335 | func_visit(nodes, list, used, "main") | ||
336 | for n,i in pairs(nodes) do | ||
337 | local j = used[n] | ||
338 | if j and j < i then used["*"..n] = j end | ||
339 | end | ||
340 | for n,i in pairs(nodes) do | ||
341 | if not used[n] then list[i] = "" end | ||
342 | end | ||
343 | return table.concat(list) | ||
344 | end | ||
345 | |||
346 | find_sources() | ||
347 | local src = read_sources() | ||
348 | src = merge_includes(src) | ||
349 | local license = get_license(src) | ||
350 | src = fold_lines(src) | ||
351 | src = strip_unused1(src) | ||
352 | src = save_strings(src) | ||
353 | src = strip_unused2(src) | ||
354 | src = strip_comments(src) | ||
355 | src = preprocess(src) | ||
356 | src = strip_whitespace(src) | ||
357 | src = strip_unused3(src) | ||
358 | src = rename_tokens1(src) | ||
359 | src = func_collect(src) | ||
360 | src = rename_tokens2(src) | ||
361 | src = restore_strings(src) | ||
362 | src = merge_header(src, license) | ||
363 | io.write(src) | ||
diff --git a/src/host/minilua.c b/src/host/minilua.c new file mode 100644 index 00000000..4db07033 --- /dev/null +++ b/src/host/minilua.c | |||
@@ -0,0 +1,7906 @@ | |||
1 | /* This is a heavily customized and minimized copy of Lua 5.1.5. */ | ||
2 | /* It's only used to build LuaJIT. It does NOT have all standard functions! */ | ||
3 | /****************************************************************************** | ||
4 | * Copyright (C) 1994-2012 Lua.org, PUC-Rio. All rights reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining | ||
7 | * a copy of this software and associated documentation files (the | ||
8 | * "Software"), to deal in the Software without restriction, including | ||
9 | * without limitation the rights to use, copy, modify, merge, publish, | ||
10 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
11 | * permit persons to whom the Software is furnished to do so, subject to | ||
12 | * the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice shall be | ||
15 | * included in all copies or substantial portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
24 | ******************************************************************************/ | ||
25 | #include <stddef.h> | ||
26 | #include <stdarg.h> | ||
27 | #include <limits.h> | ||
28 | #include <math.h> | ||
29 | #include <ctype.h> | ||
30 | #include <stdio.h> | ||
31 | #include <stdlib.h> | ||
32 | #include <string.h> | ||
33 | #include <setjmp.h> | ||
34 | #include <errno.h> | ||
35 | #include <time.h> | ||
36 | typedef enum{ | ||
37 | TM_INDEX, | ||
38 | TM_NEWINDEX, | ||
39 | TM_GC, | ||
40 | TM_MODE, | ||
41 | TM_EQ, | ||
42 | TM_ADD, | ||
43 | TM_SUB, | ||
44 | TM_MUL, | ||
45 | TM_DIV, | ||
46 | TM_MOD, | ||
47 | TM_POW, | ||
48 | TM_UNM, | ||
49 | TM_LEN, | ||
50 | TM_LT, | ||
51 | TM_LE, | ||
52 | TM_CONCAT, | ||
53 | TM_CALL, | ||
54 | TM_N | ||
55 | }TMS; | ||
56 | enum OpMode{iABC,iABx,iAsBx}; | ||
57 | typedef enum{ | ||
58 | OP_MOVE, | ||
59 | OP_LOADK, | ||
60 | OP_LOADBOOL, | ||
61 | OP_LOADNIL, | ||
62 | OP_GETUPVAL, | ||
63 | OP_GETGLOBAL, | ||
64 | OP_GETTABLE, | ||
65 | OP_SETGLOBAL, | ||
66 | OP_SETUPVAL, | ||
67 | OP_SETTABLE, | ||
68 | OP_NEWTABLE, | ||
69 | OP_SELF, | ||
70 | OP_ADD, | ||
71 | OP_SUB, | ||
72 | OP_MUL, | ||
73 | OP_DIV, | ||
74 | OP_MOD, | ||
75 | OP_POW, | ||
76 | OP_UNM, | ||
77 | OP_NOT, | ||
78 | OP_LEN, | ||
79 | OP_CONCAT, | ||
80 | OP_JMP, | ||
81 | OP_EQ, | ||
82 | OP_LT, | ||
83 | OP_LE, | ||
84 | OP_TEST, | ||
85 | OP_TESTSET, | ||
86 | OP_CALL, | ||
87 | OP_TAILCALL, | ||
88 | OP_RETURN, | ||
89 | OP_FORLOOP, | ||
90 | OP_FORPREP, | ||
91 | OP_TFORLOOP, | ||
92 | OP_SETLIST, | ||
93 | OP_CLOSE, | ||
94 | OP_CLOSURE, | ||
95 | OP_VARARG | ||
96 | }OpCode; | ||
97 | enum OpArgMask{ | ||
98 | OpArgN, | ||
99 | OpArgU, | ||
100 | OpArgR, | ||
101 | OpArgK | ||
102 | }; | ||
103 | typedef enum{ | ||
104 | VVOID, | ||
105 | VNIL, | ||
106 | VTRUE, | ||
107 | VFALSE, | ||
108 | VK, | ||
109 | VKNUM, | ||
110 | VLOCAL, | ||
111 | VUPVAL, | ||
112 | VGLOBAL, | ||
113 | VINDEXED, | ||
114 | VJMP, | ||
115 | VRELOCABLE, | ||
116 | VNONRELOC, | ||
117 | VCALL, | ||
118 | VVARARG | ||
119 | }expkind; | ||
120 | enum RESERVED{ | ||
121 | TK_AND=257,TK_BREAK, | ||
122 | TK_DO,TK_ELSE,TK_ELSEIF,TK_END,TK_FALSE,TK_FOR,TK_FUNCTION, | ||
123 | TK_IF,TK_IN,TK_LOCAL,TK_NIL,TK_NOT,TK_OR,TK_REPEAT, | ||
124 | TK_RETURN,TK_THEN,TK_TRUE,TK_UNTIL,TK_WHILE, | ||
125 | TK_CONCAT,TK_DOTS,TK_EQ,TK_GE,TK_LE,TK_NE,TK_NUMBER, | ||
126 | TK_NAME,TK_STRING,TK_EOS | ||
127 | }; | ||
128 | typedef enum BinOpr{ | ||
129 | OPR_ADD,OPR_SUB,OPR_MUL,OPR_DIV,OPR_MOD,OPR_POW, | ||
130 | OPR_CONCAT, | ||
131 | OPR_NE,OPR_EQ, | ||
132 | OPR_LT,OPR_LE,OPR_GT,OPR_GE, | ||
133 | OPR_AND,OPR_OR, | ||
134 | OPR_NOBINOPR | ||
135 | }BinOpr; | ||
136 | typedef enum UnOpr{OPR_MINUS,OPR_NOT,OPR_LEN,OPR_NOUNOPR}UnOpr; | ||
137 | #define LUA_QL(x)"'"x"'" | ||
138 | #define luai_apicheck(L,o){(void)L;} | ||
139 | #define lua_number2str(s,n)sprintf((s),"%.14g",(n)) | ||
140 | #define lua_str2number(s,p)strtod((s),(p)) | ||
141 | #define luai_numadd(a,b)((a)+(b)) | ||
142 | #define luai_numsub(a,b)((a)-(b)) | ||
143 | #define luai_nummul(a,b)((a)*(b)) | ||
144 | #define luai_numdiv(a,b)((a)/(b)) | ||
145 | #define luai_nummod(a,b)((a)-floor((a)/(b))*(b)) | ||
146 | #define luai_numpow(a,b)(pow(a,b)) | ||
147 | #define luai_numunm(a)(-(a)) | ||
148 | #define luai_numeq(a,b)((a)==(b)) | ||
149 | #define luai_numlt(a,b)((a)<(b)) | ||
150 | #define luai_numle(a,b)((a)<=(b)) | ||
151 | #define luai_numisnan(a)(!luai_numeq((a),(a))) | ||
152 | #define lua_number2int(i,d)((i)=(int)(d)) | ||
153 | #define lua_number2integer(i,d)((i)=(lua_Integer)(d)) | ||
154 | #define LUAI_THROW(L,c)longjmp((c)->b,1) | ||
155 | #define LUAI_TRY(L,c,a)if(setjmp((c)->b)==0){a} | ||
156 | #define lua_pclose(L,file)((void)((void)L,file),0) | ||
157 | #define lua_upvalueindex(i)((-10002)-(i)) | ||
158 | typedef struct lua_State lua_State; | ||
159 | typedef int(*lua_CFunction)(lua_State*L); | ||
160 | typedef const char*(*lua_Reader)(lua_State*L,void*ud,size_t*sz); | ||
161 | typedef void*(*lua_Alloc)(void*ud,void*ptr,size_t osize,size_t nsize); | ||
162 | typedef double lua_Number; | ||
163 | typedef ptrdiff_t lua_Integer; | ||
164 | static void lua_settop(lua_State*L,int idx); | ||
165 | static int lua_type(lua_State*L,int idx); | ||
166 | static const char* lua_tolstring(lua_State*L,int idx,size_t*len); | ||
167 | static size_t lua_objlen(lua_State*L,int idx); | ||
168 | static void lua_pushlstring(lua_State*L,const char*s,size_t l); | ||
169 | static void lua_pushcclosure(lua_State*L,lua_CFunction fn,int n); | ||
170 | static void lua_createtable(lua_State*L,int narr,int nrec); | ||
171 | static void lua_setfield(lua_State*L,int idx,const char*k); | ||
172 | #define lua_pop(L,n)lua_settop(L,-(n)-1) | ||
173 | #define lua_newtable(L)lua_createtable(L,0,0) | ||
174 | #define lua_pushcfunction(L,f)lua_pushcclosure(L,(f),0) | ||
175 | #define lua_strlen(L,i)lua_objlen(L,(i)) | ||
176 | #define lua_isfunction(L,n)(lua_type(L,(n))==6) | ||
177 | #define lua_istable(L,n)(lua_type(L,(n))==5) | ||
178 | #define lua_isnil(L,n)(lua_type(L,(n))==0) | ||
179 | #define lua_isboolean(L,n)(lua_type(L,(n))==1) | ||
180 | #define lua_isnone(L,n)(lua_type(L,(n))==(-1)) | ||
181 | #define lua_isnoneornil(L,n)(lua_type(L,(n))<=0) | ||
182 | #define lua_pushliteral(L,s)lua_pushlstring(L,""s,(sizeof(s)/sizeof(char))-1) | ||
183 | #define lua_setglobal(L,s)lua_setfield(L,(-10002),(s)) | ||
184 | #define lua_tostring(L,i)lua_tolstring(L,(i),NULL) | ||
185 | typedef struct lua_Debug lua_Debug; | ||
186 | typedef void(*lua_Hook)(lua_State*L,lua_Debug*ar); | ||
187 | struct lua_Debug{ | ||
188 | int event; | ||
189 | const char*name; | ||
190 | const char*namewhat; | ||
191 | const char*what; | ||
192 | const char*source; | ||
193 | int currentline; | ||
194 | int nups; | ||
195 | int linedefined; | ||
196 | int lastlinedefined; | ||
197 | char short_src[60]; | ||
198 | int i_ci; | ||
199 | }; | ||
200 | typedef unsigned int lu_int32; | ||
201 | typedef size_t lu_mem; | ||
202 | typedef ptrdiff_t l_mem; | ||
203 | typedef unsigned char lu_byte; | ||
204 | #define IntPoint(p)((unsigned int)(lu_mem)(p)) | ||
205 | typedef union{double u;void*s;long l;}L_Umaxalign; | ||
206 | typedef double l_uacNumber; | ||
207 | #define check_exp(c,e)(e) | ||
208 | #define UNUSED(x)((void)(x)) | ||
209 | #define cast(t,exp)((t)(exp)) | ||
210 | #define cast_byte(i)cast(lu_byte,(i)) | ||
211 | #define cast_num(i)cast(lua_Number,(i)) | ||
212 | #define cast_int(i)cast(int,(i)) | ||
213 | typedef lu_int32 Instruction; | ||
214 | #define condhardstacktests(x)((void)0) | ||
215 | typedef union GCObject GCObject; | ||
216 | typedef struct GCheader{ | ||
217 | GCObject*next;lu_byte tt;lu_byte marked; | ||
218 | }GCheader; | ||
219 | typedef union{ | ||
220 | GCObject*gc; | ||
221 | void*p; | ||
222 | lua_Number n; | ||
223 | int b; | ||
224 | }Value; | ||
225 | typedef struct lua_TValue{ | ||
226 | Value value;int tt; | ||
227 | }TValue; | ||
228 | #define ttisnil(o)(ttype(o)==0) | ||
229 | #define ttisnumber(o)(ttype(o)==3) | ||
230 | #define ttisstring(o)(ttype(o)==4) | ||
231 | #define ttistable(o)(ttype(o)==5) | ||
232 | #define ttisfunction(o)(ttype(o)==6) | ||
233 | #define ttisboolean(o)(ttype(o)==1) | ||
234 | #define ttisuserdata(o)(ttype(o)==7) | ||
235 | #define ttisthread(o)(ttype(o)==8) | ||
236 | #define ttislightuserdata(o)(ttype(o)==2) | ||
237 | #define ttype(o)((o)->tt) | ||
238 | #define gcvalue(o)check_exp(iscollectable(o),(o)->value.gc) | ||
239 | #define pvalue(o)check_exp(ttislightuserdata(o),(o)->value.p) | ||
240 | #define nvalue(o)check_exp(ttisnumber(o),(o)->value.n) | ||
241 | #define rawtsvalue(o)check_exp(ttisstring(o),&(o)->value.gc->ts) | ||
242 | #define tsvalue(o)(&rawtsvalue(o)->tsv) | ||
243 | #define rawuvalue(o)check_exp(ttisuserdata(o),&(o)->value.gc->u) | ||
244 | #define uvalue(o)(&rawuvalue(o)->uv) | ||
245 | #define clvalue(o)check_exp(ttisfunction(o),&(o)->value.gc->cl) | ||
246 | #define hvalue(o)check_exp(ttistable(o),&(o)->value.gc->h) | ||
247 | #define bvalue(o)check_exp(ttisboolean(o),(o)->value.b) | ||
248 | #define thvalue(o)check_exp(ttisthread(o),&(o)->value.gc->th) | ||
249 | #define l_isfalse(o)(ttisnil(o)||(ttisboolean(o)&&bvalue(o)==0)) | ||
250 | #define checkconsistency(obj) | ||
251 | #define checkliveness(g,obj) | ||
252 | #define setnilvalue(obj)((obj)->tt=0) | ||
253 | #define setnvalue(obj,x){TValue*i_o=(obj);i_o->value.n=(x);i_o->tt=3;} | ||
254 | #define setbvalue(obj,x){TValue*i_o=(obj);i_o->value.b=(x);i_o->tt=1;} | ||
255 | #define setsvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=4;checkliveness(G(L),i_o);} | ||
256 | #define setuvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=7;checkliveness(G(L),i_o);} | ||
257 | #define setthvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=8;checkliveness(G(L),i_o);} | ||
258 | #define setclvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=6;checkliveness(G(L),i_o);} | ||
259 | #define sethvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=5;checkliveness(G(L),i_o);} | ||
260 | #define setptvalue(L,obj,x){TValue*i_o=(obj);i_o->value.gc=cast(GCObject*,(x));i_o->tt=(8+1);checkliveness(G(L),i_o);} | ||
261 | #define setobj(L,obj1,obj2){const TValue*o2=(obj2);TValue*o1=(obj1);o1->value=o2->value;o1->tt=o2->tt;checkliveness(G(L),o1);} | ||
262 | #define setttype(obj,tt)(ttype(obj)=(tt)) | ||
263 | #define iscollectable(o)(ttype(o)>=4) | ||
264 | typedef TValue*StkId; | ||
265 | typedef union TString{ | ||
266 | L_Umaxalign dummy; | ||
267 | struct{ | ||
268 | GCObject*next;lu_byte tt;lu_byte marked; | ||
269 | lu_byte reserved; | ||
270 | unsigned int hash; | ||
271 | size_t len; | ||
272 | }tsv; | ||
273 | }TString; | ||
274 | #define getstr(ts)cast(const char*,(ts)+1) | ||
275 | #define svalue(o)getstr(rawtsvalue(o)) | ||
276 | typedef union Udata{ | ||
277 | L_Umaxalign dummy; | ||
278 | struct{ | ||
279 | GCObject*next;lu_byte tt;lu_byte marked; | ||
280 | struct Table*metatable; | ||
281 | struct Table*env; | ||
282 | size_t len; | ||
283 | }uv; | ||
284 | }Udata; | ||
285 | typedef struct Proto{ | ||
286 | GCObject*next;lu_byte tt;lu_byte marked; | ||
287 | TValue*k; | ||
288 | Instruction*code; | ||
289 | struct Proto**p; | ||
290 | int*lineinfo; | ||
291 | struct LocVar*locvars; | ||
292 | TString**upvalues; | ||
293 | TString*source; | ||
294 | int sizeupvalues; | ||
295 | int sizek; | ||
296 | int sizecode; | ||
297 | int sizelineinfo; | ||
298 | int sizep; | ||
299 | int sizelocvars; | ||
300 | int linedefined; | ||
301 | int lastlinedefined; | ||
302 | GCObject*gclist; | ||
303 | lu_byte nups; | ||
304 | lu_byte numparams; | ||
305 | lu_byte is_vararg; | ||
306 | lu_byte maxstacksize; | ||
307 | }Proto; | ||
308 | typedef struct LocVar{ | ||
309 | TString*varname; | ||
310 | int startpc; | ||
311 | int endpc; | ||
312 | }LocVar; | ||
313 | typedef struct UpVal{ | ||
314 | GCObject*next;lu_byte tt;lu_byte marked; | ||
315 | TValue*v; | ||
316 | union{ | ||
317 | TValue value; | ||
318 | struct{ | ||
319 | struct UpVal*prev; | ||
320 | struct UpVal*next; | ||
321 | }l; | ||
322 | }u; | ||
323 | }UpVal; | ||
324 | typedef struct CClosure{ | ||
325 | GCObject*next;lu_byte tt;lu_byte marked;lu_byte isC;lu_byte nupvalues;GCObject*gclist;struct Table*env; | ||
326 | lua_CFunction f; | ||
327 | TValue upvalue[1]; | ||
328 | }CClosure; | ||
329 | typedef struct LClosure{ | ||
330 | GCObject*next;lu_byte tt;lu_byte marked;lu_byte isC;lu_byte nupvalues;GCObject*gclist;struct Table*env; | ||
331 | struct Proto*p; | ||
332 | UpVal*upvals[1]; | ||
333 | }LClosure; | ||
334 | typedef union Closure{ | ||
335 | CClosure c; | ||
336 | LClosure l; | ||
337 | }Closure; | ||
338 | #define iscfunction(o)(ttype(o)==6&&clvalue(o)->c.isC) | ||
339 | typedef union TKey{ | ||
340 | struct{ | ||
341 | Value value;int tt; | ||
342 | struct Node*next; | ||
343 | }nk; | ||
344 | TValue tvk; | ||
345 | }TKey; | ||
346 | typedef struct Node{ | ||
347 | TValue i_val; | ||
348 | TKey i_key; | ||
349 | }Node; | ||
350 | typedef struct Table{ | ||
351 | GCObject*next;lu_byte tt;lu_byte marked; | ||
352 | lu_byte flags; | ||
353 | lu_byte lsizenode; | ||
354 | struct Table*metatable; | ||
355 | TValue*array; | ||
356 | Node*node; | ||
357 | Node*lastfree; | ||
358 | GCObject*gclist; | ||
359 | int sizearray; | ||
360 | }Table; | ||
361 | #define lmod(s,size)(check_exp((size&(size-1))==0,(cast(int,(s)&((size)-1))))) | ||
362 | #define twoto(x)((size_t)1<<(x)) | ||
363 | #define sizenode(t)(twoto((t)->lsizenode)) | ||
364 | static const TValue luaO_nilobject_; | ||
365 | #define ceillog2(x)(luaO_log2((x)-1)+1) | ||
366 | static int luaO_log2(unsigned int x); | ||
367 | #define gfasttm(g,et,e)((et)==NULL?NULL:((et)->flags&(1u<<(e)))?NULL:luaT_gettm(et,e,(g)->tmname[e])) | ||
368 | #define fasttm(l,et,e)gfasttm(G(l),et,e) | ||
369 | static const TValue*luaT_gettm(Table*events,TMS event,TString*ename); | ||
370 | #define luaM_reallocv(L,b,on,n,e)((cast(size_t,(n)+1)<=((size_t)(~(size_t)0)-2)/(e))?luaM_realloc_(L,(b),(on)*(e),(n)*(e)):luaM_toobig(L)) | ||
371 | #define luaM_freemem(L,b,s)luaM_realloc_(L,(b),(s),0) | ||
372 | #define luaM_free(L,b)luaM_realloc_(L,(b),sizeof(*(b)),0) | ||
373 | #define luaM_freearray(L,b,n,t)luaM_reallocv(L,(b),n,0,sizeof(t)) | ||
374 | #define luaM_malloc(L,t)luaM_realloc_(L,NULL,0,(t)) | ||
375 | #define luaM_new(L,t)cast(t*,luaM_malloc(L,sizeof(t))) | ||
376 | #define luaM_newvector(L,n,t)cast(t*,luaM_reallocv(L,NULL,0,n,sizeof(t))) | ||
377 | #define luaM_growvector(L,v,nelems,size,t,limit,e)if((nelems)+1>(size))((v)=cast(t*,luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) | ||
378 | #define luaM_reallocvector(L,v,oldn,n,t)((v)=cast(t*,luaM_reallocv(L,v,oldn,n,sizeof(t)))) | ||
379 | static void*luaM_realloc_(lua_State*L,void*block,size_t oldsize, | ||
380 | size_t size); | ||
381 | static void*luaM_toobig(lua_State*L); | ||
382 | static void*luaM_growaux_(lua_State*L,void*block,int*size, | ||
383 | size_t size_elem,int limit, | ||
384 | const char*errormsg); | ||
385 | typedef struct Zio ZIO; | ||
386 | #define char2int(c)cast(int,cast(unsigned char,(c))) | ||
387 | #define zgetc(z)(((z)->n--)>0?char2int(*(z)->p++):luaZ_fill(z)) | ||
388 | typedef struct Mbuffer{ | ||
389 | char*buffer; | ||
390 | size_t n; | ||
391 | size_t buffsize; | ||
392 | }Mbuffer; | ||
393 | #define luaZ_initbuffer(L,buff)((buff)->buffer=NULL,(buff)->buffsize=0) | ||
394 | #define luaZ_buffer(buff)((buff)->buffer) | ||
395 | #define luaZ_sizebuffer(buff)((buff)->buffsize) | ||
396 | #define luaZ_bufflen(buff)((buff)->n) | ||
397 | #define luaZ_resetbuffer(buff)((buff)->n=0) | ||
398 | #define luaZ_resizebuffer(L,buff,size)(luaM_reallocvector(L,(buff)->buffer,(buff)->buffsize,size,char),(buff)->buffsize=size) | ||
399 | #define luaZ_freebuffer(L,buff)luaZ_resizebuffer(L,buff,0) | ||
400 | struct Zio{ | ||
401 | size_t n; | ||
402 | const char*p; | ||
403 | lua_Reader reader; | ||
404 | void*data; | ||
405 | lua_State*L; | ||
406 | }; | ||
407 | static int luaZ_fill(ZIO*z); | ||
408 | struct lua_longjmp; | ||
409 | #define gt(L)(&L->l_gt) | ||
410 | #define registry(L)(&G(L)->l_registry) | ||
411 | typedef struct stringtable{ | ||
412 | GCObject**hash; | ||
413 | lu_int32 nuse; | ||
414 | int size; | ||
415 | }stringtable; | ||
416 | typedef struct CallInfo{ | ||
417 | StkId base; | ||
418 | StkId func; | ||
419 | StkId top; | ||
420 | const Instruction*savedpc; | ||
421 | int nresults; | ||
422 | int tailcalls; | ||
423 | }CallInfo; | ||
424 | #define curr_func(L)(clvalue(L->ci->func)) | ||
425 | #define ci_func(ci)(clvalue((ci)->func)) | ||
426 | #define f_isLua(ci)(!ci_func(ci)->c.isC) | ||
427 | #define isLua(ci)(ttisfunction((ci)->func)&&f_isLua(ci)) | ||
428 | typedef struct global_State{ | ||
429 | stringtable strt; | ||
430 | lua_Alloc frealloc; | ||
431 | void*ud; | ||
432 | lu_byte currentwhite; | ||
433 | lu_byte gcstate; | ||
434 | int sweepstrgc; | ||
435 | GCObject*rootgc; | ||
436 | GCObject**sweepgc; | ||
437 | GCObject*gray; | ||
438 | GCObject*grayagain; | ||
439 | GCObject*weak; | ||
440 | GCObject*tmudata; | ||
441 | Mbuffer buff; | ||
442 | lu_mem GCthreshold; | ||
443 | lu_mem totalbytes; | ||
444 | lu_mem estimate; | ||
445 | lu_mem gcdept; | ||
446 | int gcpause; | ||
447 | int gcstepmul; | ||
448 | lua_CFunction panic; | ||
449 | TValue l_registry; | ||
450 | struct lua_State*mainthread; | ||
451 | UpVal uvhead; | ||
452 | struct Table*mt[(8+1)]; | ||
453 | TString*tmname[TM_N]; | ||
454 | }global_State; | ||
455 | struct lua_State{ | ||
456 | GCObject*next;lu_byte tt;lu_byte marked; | ||
457 | lu_byte status; | ||
458 | StkId top; | ||
459 | StkId base; | ||
460 | global_State*l_G; | ||
461 | CallInfo*ci; | ||
462 | const Instruction*savedpc; | ||
463 | StkId stack_last; | ||
464 | StkId stack; | ||
465 | CallInfo*end_ci; | ||
466 | CallInfo*base_ci; | ||
467 | int stacksize; | ||
468 | int size_ci; | ||
469 | unsigned short nCcalls; | ||
470 | unsigned short baseCcalls; | ||
471 | lu_byte hookmask; | ||
472 | lu_byte allowhook; | ||
473 | int basehookcount; | ||
474 | int hookcount; | ||
475 | lua_Hook hook; | ||
476 | TValue l_gt; | ||
477 | TValue env; | ||
478 | GCObject*openupval; | ||
479 | GCObject*gclist; | ||
480 | struct lua_longjmp*errorJmp; | ||
481 | ptrdiff_t errfunc; | ||
482 | }; | ||
483 | #define G(L)(L->l_G) | ||
484 | union GCObject{ | ||
485 | GCheader gch; | ||
486 | union TString ts; | ||
487 | union Udata u; | ||
488 | union Closure cl; | ||
489 | struct Table h; | ||
490 | struct Proto p; | ||
491 | struct UpVal uv; | ||
492 | struct lua_State th; | ||
493 | }; | ||
494 | #define rawgco2ts(o)check_exp((o)->gch.tt==4,&((o)->ts)) | ||
495 | #define gco2ts(o)(&rawgco2ts(o)->tsv) | ||
496 | #define rawgco2u(o)check_exp((o)->gch.tt==7,&((o)->u)) | ||
497 | #define gco2u(o)(&rawgco2u(o)->uv) | ||
498 | #define gco2cl(o)check_exp((o)->gch.tt==6,&((o)->cl)) | ||
499 | #define gco2h(o)check_exp((o)->gch.tt==5,&((o)->h)) | ||
500 | #define gco2p(o)check_exp((o)->gch.tt==(8+1),&((o)->p)) | ||
501 | #define gco2uv(o)check_exp((o)->gch.tt==(8+2),&((o)->uv)) | ||
502 | #define ngcotouv(o)check_exp((o)==NULL||(o)->gch.tt==(8+2),&((o)->uv)) | ||
503 | #define gco2th(o)check_exp((o)->gch.tt==8,&((o)->th)) | ||
504 | #define obj2gco(v)(cast(GCObject*,(v))) | ||
505 | static void luaE_freethread(lua_State*L,lua_State*L1); | ||
506 | #define pcRel(pc,p)(cast(int,(pc)-(p)->code)-1) | ||
507 | #define getline_(f,pc)(((f)->lineinfo)?(f)->lineinfo[pc]:0) | ||
508 | #define resethookcount(L)(L->hookcount=L->basehookcount) | ||
509 | static void luaG_typeerror(lua_State*L,const TValue*o, | ||
510 | const char*opname); | ||
511 | static void luaG_runerror(lua_State*L,const char*fmt,...); | ||
512 | #define luaD_checkstack(L,n)if((char*)L->stack_last-(char*)L->top<=(n)*(int)sizeof(TValue))luaD_growstack(L,n);else condhardstacktests(luaD_reallocstack(L,L->stacksize-5-1)); | ||
513 | #define incr_top(L){luaD_checkstack(L,1);L->top++;} | ||
514 | #define savestack(L,p)((char*)(p)-(char*)L->stack) | ||
515 | #define restorestack(L,n)((TValue*)((char*)L->stack+(n))) | ||
516 | #define saveci(L,p)((char*)(p)-(char*)L->base_ci) | ||
517 | #define restoreci(L,n)((CallInfo*)((char*)L->base_ci+(n))) | ||
518 | typedef void(*Pfunc)(lua_State*L,void*ud); | ||
519 | static int luaD_poscall(lua_State*L,StkId firstResult); | ||
520 | static void luaD_reallocCI(lua_State*L,int newsize); | ||
521 | static void luaD_reallocstack(lua_State*L,int newsize); | ||
522 | static void luaD_growstack(lua_State*L,int n); | ||
523 | static void luaD_throw(lua_State*L,int errcode); | ||
524 | static void*luaM_growaux_(lua_State*L,void*block,int*size,size_t size_elems, | ||
525 | int limit,const char*errormsg){ | ||
526 | void*newblock; | ||
527 | int newsize; | ||
528 | if(*size>=limit/2){ | ||
529 | if(*size>=limit) | ||
530 | luaG_runerror(L,errormsg); | ||
531 | newsize=limit; | ||
532 | } | ||
533 | else{ | ||
534 | newsize=(*size)*2; | ||
535 | if(newsize<4) | ||
536 | newsize=4; | ||
537 | } | ||
538 | newblock=luaM_reallocv(L,block,*size,newsize,size_elems); | ||
539 | *size=newsize; | ||
540 | return newblock; | ||
541 | } | ||
542 | static void*luaM_toobig(lua_State*L){ | ||
543 | luaG_runerror(L,"memory allocation error: block too big"); | ||
544 | return NULL; | ||
545 | } | ||
546 | static void*luaM_realloc_(lua_State*L,void*block,size_t osize,size_t nsize){ | ||
547 | global_State*g=G(L); | ||
548 | block=(*g->frealloc)(g->ud,block,osize,nsize); | ||
549 | if(block==NULL&&nsize>0) | ||
550 | luaD_throw(L,4); | ||
551 | g->totalbytes=(g->totalbytes-osize)+nsize; | ||
552 | return block; | ||
553 | } | ||
554 | #define resetbits(x,m)((x)&=cast(lu_byte,~(m))) | ||
555 | #define setbits(x,m)((x)|=(m)) | ||
556 | #define testbits(x,m)((x)&(m)) | ||
557 | #define bitmask(b)(1<<(b)) | ||
558 | #define bit2mask(b1,b2)(bitmask(b1)|bitmask(b2)) | ||
559 | #define l_setbit(x,b)setbits(x,bitmask(b)) | ||
560 | #define resetbit(x,b)resetbits(x,bitmask(b)) | ||
561 | #define testbit(x,b)testbits(x,bitmask(b)) | ||
562 | #define set2bits(x,b1,b2)setbits(x,(bit2mask(b1,b2))) | ||
563 | #define reset2bits(x,b1,b2)resetbits(x,(bit2mask(b1,b2))) | ||
564 | #define test2bits(x,b1,b2)testbits(x,(bit2mask(b1,b2))) | ||
565 | #define iswhite(x)test2bits((x)->gch.marked,0,1) | ||
566 | #define isblack(x)testbit((x)->gch.marked,2) | ||
567 | #define isgray(x)(!isblack(x)&&!iswhite(x)) | ||
568 | #define otherwhite(g)(g->currentwhite^bit2mask(0,1)) | ||
569 | #define isdead(g,v)((v)->gch.marked&otherwhite(g)&bit2mask(0,1)) | ||
570 | #define changewhite(x)((x)->gch.marked^=bit2mask(0,1)) | ||
571 | #define gray2black(x)l_setbit((x)->gch.marked,2) | ||
572 | #define valiswhite(x)(iscollectable(x)&&iswhite(gcvalue(x))) | ||
573 | #define luaC_white(g)cast(lu_byte,(g)->currentwhite&bit2mask(0,1)) | ||
574 | #define luaC_checkGC(L){condhardstacktests(luaD_reallocstack(L,L->stacksize-5-1));if(G(L)->totalbytes>=G(L)->GCthreshold)luaC_step(L);} | ||
575 | #define luaC_barrier(L,p,v){if(valiswhite(v)&&isblack(obj2gco(p)))luaC_barrierf(L,obj2gco(p),gcvalue(v));} | ||
576 | #define luaC_barriert(L,t,v){if(valiswhite(v)&&isblack(obj2gco(t)))luaC_barrierback(L,t);} | ||
577 | #define luaC_objbarrier(L,p,o){if(iswhite(obj2gco(o))&&isblack(obj2gco(p)))luaC_barrierf(L,obj2gco(p),obj2gco(o));} | ||
578 | #define luaC_objbarriert(L,t,o){if(iswhite(obj2gco(o))&&isblack(obj2gco(t)))luaC_barrierback(L,t);} | ||
579 | static void luaC_step(lua_State*L); | ||
580 | static void luaC_link(lua_State*L,GCObject*o,lu_byte tt); | ||
581 | static void luaC_linkupval(lua_State*L,UpVal*uv); | ||
582 | static void luaC_barrierf(lua_State*L,GCObject*o,GCObject*v); | ||
583 | static void luaC_barrierback(lua_State*L,Table*t); | ||
584 | #define sizestring(s)(sizeof(union TString)+((s)->len+1)*sizeof(char)) | ||
585 | #define sizeudata(u)(sizeof(union Udata)+(u)->len) | ||
586 | #define luaS_new(L,s)(luaS_newlstr(L,s,strlen(s))) | ||
587 | #define luaS_newliteral(L,s)(luaS_newlstr(L,""s,(sizeof(s)/sizeof(char))-1)) | ||
588 | #define luaS_fix(s)l_setbit((s)->tsv.marked,5) | ||
589 | static TString*luaS_newlstr(lua_State*L,const char*str,size_t l); | ||
590 | #define tostring(L,o)((ttype(o)==4)||(luaV_tostring(L,o))) | ||
591 | #define tonumber(o,n)(ttype(o)==3||(((o)=luaV_tonumber(o,n))!=NULL)) | ||
592 | #define equalobj(L,o1,o2)(ttype(o1)==ttype(o2)&&luaV_equalval(L,o1,o2)) | ||
593 | static int luaV_equalval(lua_State*L,const TValue*t1,const TValue*t2); | ||
594 | static const TValue*luaV_tonumber(const TValue*obj,TValue*n); | ||
595 | static int luaV_tostring(lua_State*L,StkId obj); | ||
596 | static void luaV_execute(lua_State*L,int nexeccalls); | ||
597 | static void luaV_concat(lua_State*L,int total,int last); | ||
598 | static const TValue luaO_nilobject_={{NULL},0}; | ||
599 | static int luaO_int2fb(unsigned int x){ | ||
600 | int e=0; | ||
601 | while(x>=16){ | ||
602 | x=(x+1)>>1; | ||
603 | e++; | ||
604 | } | ||
605 | if(x<8)return x; | ||
606 | else return((e+1)<<3)|(cast_int(x)-8); | ||
607 | } | ||
608 | static int luaO_fb2int(int x){ | ||
609 | int e=(x>>3)&31; | ||
610 | if(e==0)return x; | ||
611 | else return((x&7)+8)<<(e-1); | ||
612 | } | ||
613 | static int luaO_log2(unsigned int x){ | ||
614 | static const lu_byte log_2[256]={ | ||
615 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, | ||
616 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, | ||
617 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, | ||
618 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, | ||
619 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, | ||
620 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, | ||
621 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, | ||
622 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 | ||
623 | }; | ||
624 | int l=-1; | ||
625 | while(x>=256){l+=8;x>>=8;} | ||
626 | return l+log_2[x]; | ||
627 | } | ||
628 | static int luaO_rawequalObj(const TValue*t1,const TValue*t2){ | ||
629 | if(ttype(t1)!=ttype(t2))return 0; | ||
630 | else switch(ttype(t1)){ | ||
631 | case 0: | ||
632 | return 1; | ||
633 | case 3: | ||
634 | return luai_numeq(nvalue(t1),nvalue(t2)); | ||
635 | case 1: | ||
636 | return bvalue(t1)==bvalue(t2); | ||
637 | case 2: | ||
638 | return pvalue(t1)==pvalue(t2); | ||
639 | default: | ||
640 | return gcvalue(t1)==gcvalue(t2); | ||
641 | } | ||
642 | } | ||
643 | static int luaO_str2d(const char*s,lua_Number*result){ | ||
644 | char*endptr; | ||
645 | *result=lua_str2number(s,&endptr); | ||
646 | if(endptr==s)return 0; | ||
647 | if(*endptr=='x'||*endptr=='X') | ||
648 | *result=cast_num(strtoul(s,&endptr,16)); | ||
649 | if(*endptr=='\0')return 1; | ||
650 | while(isspace(cast(unsigned char,*endptr)))endptr++; | ||
651 | if(*endptr!='\0')return 0; | ||
652 | return 1; | ||
653 | } | ||
654 | static void pushstr(lua_State*L,const char*str){ | ||
655 | setsvalue(L,L->top,luaS_new(L,str)); | ||
656 | incr_top(L); | ||
657 | } | ||
658 | static const char*luaO_pushvfstring(lua_State*L,const char*fmt,va_list argp){ | ||
659 | int n=1; | ||
660 | pushstr(L,""); | ||
661 | for(;;){ | ||
662 | const char*e=strchr(fmt,'%'); | ||
663 | if(e==NULL)break; | ||
664 | setsvalue(L,L->top,luaS_newlstr(L,fmt,e-fmt)); | ||
665 | incr_top(L); | ||
666 | switch(*(e+1)){ | ||
667 | case's':{ | ||
668 | const char*s=va_arg(argp,char*); | ||
669 | if(s==NULL)s="(null)"; | ||
670 | pushstr(L,s); | ||
671 | break; | ||
672 | } | ||
673 | case'c':{ | ||
674 | char buff[2]; | ||
675 | buff[0]=cast(char,va_arg(argp,int)); | ||
676 | buff[1]='\0'; | ||
677 | pushstr(L,buff); | ||
678 | break; | ||
679 | } | ||
680 | case'd':{ | ||
681 | setnvalue(L->top,cast_num(va_arg(argp,int))); | ||
682 | incr_top(L); | ||
683 | break; | ||
684 | } | ||
685 | case'f':{ | ||
686 | setnvalue(L->top,cast_num(va_arg(argp,l_uacNumber))); | ||
687 | incr_top(L); | ||
688 | break; | ||
689 | } | ||
690 | case'p':{ | ||
691 | char buff[4*sizeof(void*)+8]; | ||
692 | sprintf(buff,"%p",va_arg(argp,void*)); | ||
693 | pushstr(L,buff); | ||
694 | break; | ||
695 | } | ||
696 | case'%':{ | ||
697 | pushstr(L,"%"); | ||
698 | break; | ||
699 | } | ||
700 | default:{ | ||
701 | char buff[3]; | ||
702 | buff[0]='%'; | ||
703 | buff[1]=*(e+1); | ||
704 | buff[2]='\0'; | ||
705 | pushstr(L,buff); | ||
706 | break; | ||
707 | } | ||
708 | } | ||
709 | n+=2; | ||
710 | fmt=e+2; | ||
711 | } | ||
712 | pushstr(L,fmt); | ||
713 | luaV_concat(L,n+1,cast_int(L->top-L->base)-1); | ||
714 | L->top-=n; | ||
715 | return svalue(L->top-1); | ||
716 | } | ||
717 | static const char*luaO_pushfstring(lua_State*L,const char*fmt,...){ | ||
718 | const char*msg; | ||
719 | va_list argp; | ||
720 | va_start(argp,fmt); | ||
721 | msg=luaO_pushvfstring(L,fmt,argp); | ||
722 | va_end(argp); | ||
723 | return msg; | ||
724 | } | ||
725 | static void luaO_chunkid(char*out,const char*source,size_t bufflen){ | ||
726 | if(*source=='='){ | ||
727 | strncpy(out,source+1,bufflen); | ||
728 | out[bufflen-1]='\0'; | ||
729 | } | ||
730 | else{ | ||
731 | if(*source=='@'){ | ||
732 | size_t l; | ||
733 | source++; | ||
734 | bufflen-=sizeof(" '...' "); | ||
735 | l=strlen(source); | ||
736 | strcpy(out,""); | ||
737 | if(l>bufflen){ | ||
738 | source+=(l-bufflen); | ||
739 | strcat(out,"..."); | ||
740 | } | ||
741 | strcat(out,source); | ||
742 | } | ||
743 | else{ | ||
744 | size_t len=strcspn(source,"\n\r"); | ||
745 | bufflen-=sizeof(" [string \"...\"] "); | ||
746 | if(len>bufflen)len=bufflen; | ||
747 | strcpy(out,"[string \""); | ||
748 | if(source[len]!='\0'){ | ||
749 | strncat(out,source,len); | ||
750 | strcat(out,"..."); | ||
751 | } | ||
752 | else | ||
753 | strcat(out,source); | ||
754 | strcat(out,"\"]"); | ||
755 | } | ||
756 | } | ||
757 | } | ||
758 | #define gnode(t,i)(&(t)->node[i]) | ||
759 | #define gkey(n)(&(n)->i_key.nk) | ||
760 | #define gval(n)(&(n)->i_val) | ||
761 | #define gnext(n)((n)->i_key.nk.next) | ||
762 | #define key2tval(n)(&(n)->i_key.tvk) | ||
763 | static TValue*luaH_setnum(lua_State*L,Table*t,int key); | ||
764 | static const TValue*luaH_getstr(Table*t,TString*key); | ||
765 | static TValue*luaH_set(lua_State*L,Table*t,const TValue*key); | ||
766 | static const char*const luaT_typenames[]={ | ||
767 | "nil","boolean","userdata","number", | ||
768 | "string","table","function","userdata","thread", | ||
769 | "proto","upval" | ||
770 | }; | ||
771 | static void luaT_init(lua_State*L){ | ||
772 | static const char*const luaT_eventname[]={ | ||
773 | "__index","__newindex", | ||
774 | "__gc","__mode","__eq", | ||
775 | "__add","__sub","__mul","__div","__mod", | ||
776 | "__pow","__unm","__len","__lt","__le", | ||
777 | "__concat","__call" | ||
778 | }; | ||
779 | int i; | ||
780 | for(i=0;i<TM_N;i++){ | ||
781 | G(L)->tmname[i]=luaS_new(L,luaT_eventname[i]); | ||
782 | luaS_fix(G(L)->tmname[i]); | ||
783 | } | ||
784 | } | ||
785 | static const TValue*luaT_gettm(Table*events,TMS event,TString*ename){ | ||
786 | const TValue*tm=luaH_getstr(events,ename); | ||
787 | if(ttisnil(tm)){ | ||
788 | events->flags|=cast_byte(1u<<event); | ||
789 | return NULL; | ||
790 | } | ||
791 | else return tm; | ||
792 | } | ||
793 | static const TValue*luaT_gettmbyobj(lua_State*L,const TValue*o,TMS event){ | ||
794 | Table*mt; | ||
795 | switch(ttype(o)){ | ||
796 | case 5: | ||
797 | mt=hvalue(o)->metatable; | ||
798 | break; | ||
799 | case 7: | ||
800 | mt=uvalue(o)->metatable; | ||
801 | break; | ||
802 | default: | ||
803 | mt=G(L)->mt[ttype(o)]; | ||
804 | } | ||
805 | return(mt?luaH_getstr(mt,G(L)->tmname[event]):(&luaO_nilobject_)); | ||
806 | } | ||
807 | #define sizeCclosure(n)(cast(int,sizeof(CClosure))+cast(int,sizeof(TValue)*((n)-1))) | ||
808 | #define sizeLclosure(n)(cast(int,sizeof(LClosure))+cast(int,sizeof(TValue*)*((n)-1))) | ||
809 | static Closure*luaF_newCclosure(lua_State*L,int nelems,Table*e){ | ||
810 | Closure*c=cast(Closure*,luaM_malloc(L,sizeCclosure(nelems))); | ||
811 | luaC_link(L,obj2gco(c),6); | ||
812 | c->c.isC=1; | ||
813 | c->c.env=e; | ||
814 | c->c.nupvalues=cast_byte(nelems); | ||
815 | return c; | ||
816 | } | ||
817 | static Closure*luaF_newLclosure(lua_State*L,int nelems,Table*e){ | ||
818 | Closure*c=cast(Closure*,luaM_malloc(L,sizeLclosure(nelems))); | ||
819 | luaC_link(L,obj2gco(c),6); | ||
820 | c->l.isC=0; | ||
821 | c->l.env=e; | ||
822 | c->l.nupvalues=cast_byte(nelems); | ||
823 | while(nelems--)c->l.upvals[nelems]=NULL; | ||
824 | return c; | ||
825 | } | ||
826 | static UpVal*luaF_newupval(lua_State*L){ | ||
827 | UpVal*uv=luaM_new(L,UpVal); | ||
828 | luaC_link(L,obj2gco(uv),(8+2)); | ||
829 | uv->v=&uv->u.value; | ||
830 | setnilvalue(uv->v); | ||
831 | return uv; | ||
832 | } | ||
833 | static UpVal*luaF_findupval(lua_State*L,StkId level){ | ||
834 | global_State*g=G(L); | ||
835 | GCObject**pp=&L->openupval; | ||
836 | UpVal*p; | ||
837 | UpVal*uv; | ||
838 | while(*pp!=NULL&&(p=ngcotouv(*pp))->v>=level){ | ||
839 | if(p->v==level){ | ||
840 | if(isdead(g,obj2gco(p))) | ||
841 | changewhite(obj2gco(p)); | ||
842 | return p; | ||
843 | } | ||
844 | pp=&p->next; | ||
845 | } | ||
846 | uv=luaM_new(L,UpVal); | ||
847 | uv->tt=(8+2); | ||
848 | uv->marked=luaC_white(g); | ||
849 | uv->v=level; | ||
850 | uv->next=*pp; | ||
851 | *pp=obj2gco(uv); | ||
852 | uv->u.l.prev=&g->uvhead; | ||
853 | uv->u.l.next=g->uvhead.u.l.next; | ||
854 | uv->u.l.next->u.l.prev=uv; | ||
855 | g->uvhead.u.l.next=uv; | ||
856 | return uv; | ||
857 | } | ||
858 | static void unlinkupval(UpVal*uv){ | ||
859 | uv->u.l.next->u.l.prev=uv->u.l.prev; | ||
860 | uv->u.l.prev->u.l.next=uv->u.l.next; | ||
861 | } | ||
862 | static void luaF_freeupval(lua_State*L,UpVal*uv){ | ||
863 | if(uv->v!=&uv->u.value) | ||
864 | unlinkupval(uv); | ||
865 | luaM_free(L,uv); | ||
866 | } | ||
867 | static void luaF_close(lua_State*L,StkId level){ | ||
868 | UpVal*uv; | ||
869 | global_State*g=G(L); | ||
870 | while(L->openupval!=NULL&&(uv=ngcotouv(L->openupval))->v>=level){ | ||
871 | GCObject*o=obj2gco(uv); | ||
872 | L->openupval=uv->next; | ||
873 | if(isdead(g,o)) | ||
874 | luaF_freeupval(L,uv); | ||
875 | else{ | ||
876 | unlinkupval(uv); | ||
877 | setobj(L,&uv->u.value,uv->v); | ||
878 | uv->v=&uv->u.value; | ||
879 | luaC_linkupval(L,uv); | ||
880 | } | ||
881 | } | ||
882 | } | ||
883 | static Proto*luaF_newproto(lua_State*L){ | ||
884 | Proto*f=luaM_new(L,Proto); | ||
885 | luaC_link(L,obj2gco(f),(8+1)); | ||
886 | f->k=NULL; | ||
887 | f->sizek=0; | ||
888 | f->p=NULL; | ||
889 | f->sizep=0; | ||
890 | f->code=NULL; | ||
891 | f->sizecode=0; | ||
892 | f->sizelineinfo=0; | ||
893 | f->sizeupvalues=0; | ||
894 | f->nups=0; | ||
895 | f->upvalues=NULL; | ||
896 | f->numparams=0; | ||
897 | f->is_vararg=0; | ||
898 | f->maxstacksize=0; | ||
899 | f->lineinfo=NULL; | ||
900 | f->sizelocvars=0; | ||
901 | f->locvars=NULL; | ||
902 | f->linedefined=0; | ||
903 | f->lastlinedefined=0; | ||
904 | f->source=NULL; | ||
905 | return f; | ||
906 | } | ||
907 | static void luaF_freeproto(lua_State*L,Proto*f){ | ||
908 | luaM_freearray(L,f->code,f->sizecode,Instruction); | ||
909 | luaM_freearray(L,f->p,f->sizep,Proto*); | ||
910 | luaM_freearray(L,f->k,f->sizek,TValue); | ||
911 | luaM_freearray(L,f->lineinfo,f->sizelineinfo,int); | ||
912 | luaM_freearray(L,f->locvars,f->sizelocvars,struct LocVar); | ||
913 | luaM_freearray(L,f->upvalues,f->sizeupvalues,TString*); | ||
914 | luaM_free(L,f); | ||
915 | } | ||
916 | static void luaF_freeclosure(lua_State*L,Closure*c){ | ||
917 | int size=(c->c.isC)?sizeCclosure(c->c.nupvalues): | ||
918 | sizeLclosure(c->l.nupvalues); | ||
919 | luaM_freemem(L,c,size); | ||
920 | } | ||
921 | #define MASK1(n,p)((~((~(Instruction)0)<<n))<<p) | ||
922 | #define MASK0(n,p)(~MASK1(n,p)) | ||
923 | #define GET_OPCODE(i)(cast(OpCode,((i)>>0)&MASK1(6,0))) | ||
924 | #define SET_OPCODE(i,o)((i)=(((i)&MASK0(6,0))|((cast(Instruction,o)<<0)&MASK1(6,0)))) | ||
925 | #define GETARG_A(i)(cast(int,((i)>>(0+6))&MASK1(8,0))) | ||
926 | #define SETARG_A(i,u)((i)=(((i)&MASK0(8,(0+6)))|((cast(Instruction,u)<<(0+6))&MASK1(8,(0+6))))) | ||
927 | #define GETARG_B(i)(cast(int,((i)>>(((0+6)+8)+9))&MASK1(9,0))) | ||
928 | #define SETARG_B(i,b)((i)=(((i)&MASK0(9,(((0+6)+8)+9)))|((cast(Instruction,b)<<(((0+6)+8)+9))&MASK1(9,(((0+6)+8)+9))))) | ||
929 | #define GETARG_C(i)(cast(int,((i)>>((0+6)+8))&MASK1(9,0))) | ||
930 | #define SETARG_C(i,b)((i)=(((i)&MASK0(9,((0+6)+8)))|((cast(Instruction,b)<<((0+6)+8))&MASK1(9,((0+6)+8))))) | ||
931 | #define GETARG_Bx(i)(cast(int,((i)>>((0+6)+8))&MASK1((9+9),0))) | ||
932 | #define SETARG_Bx(i,b)((i)=(((i)&MASK0((9+9),((0+6)+8)))|((cast(Instruction,b)<<((0+6)+8))&MASK1((9+9),((0+6)+8))))) | ||
933 | #define GETARG_sBx(i)(GETARG_Bx(i)-(((1<<(9+9))-1)>>1)) | ||
934 | #define SETARG_sBx(i,b)SETARG_Bx((i),cast(unsigned int,(b)+(((1<<(9+9))-1)>>1))) | ||
935 | #define CREATE_ABC(o,a,b,c)((cast(Instruction,o)<<0)|(cast(Instruction,a)<<(0+6))|(cast(Instruction,b)<<(((0+6)+8)+9))|(cast(Instruction,c)<<((0+6)+8))) | ||
936 | #define CREATE_ABx(o,a,bc)((cast(Instruction,o)<<0)|(cast(Instruction,a)<<(0+6))|(cast(Instruction,bc)<<((0+6)+8))) | ||
937 | #define ISK(x)((x)&(1<<(9-1))) | ||
938 | #define INDEXK(r)((int)(r)&~(1<<(9-1))) | ||
939 | #define RKASK(x)((x)|(1<<(9-1))) | ||
940 | static const lu_byte luaP_opmodes[(cast(int,OP_VARARG)+1)]; | ||
941 | #define getBMode(m)(cast(enum OpArgMask,(luaP_opmodes[m]>>4)&3)) | ||
942 | #define getCMode(m)(cast(enum OpArgMask,(luaP_opmodes[m]>>2)&3)) | ||
943 | #define testTMode(m)(luaP_opmodes[m]&(1<<7)) | ||
944 | typedef struct expdesc{ | ||
945 | expkind k; | ||
946 | union{ | ||
947 | struct{int info,aux;}s; | ||
948 | lua_Number nval; | ||
949 | }u; | ||
950 | int t; | ||
951 | int f; | ||
952 | }expdesc; | ||
953 | typedef struct upvaldesc{ | ||
954 | lu_byte k; | ||
955 | lu_byte info; | ||
956 | }upvaldesc; | ||
957 | struct BlockCnt; | ||
958 | typedef struct FuncState{ | ||
959 | Proto*f; | ||
960 | Table*h; | ||
961 | struct FuncState*prev; | ||
962 | struct LexState*ls; | ||
963 | struct lua_State*L; | ||
964 | struct BlockCnt*bl; | ||
965 | int pc; | ||
966 | int lasttarget; | ||
967 | int jpc; | ||
968 | int freereg; | ||
969 | int nk; | ||
970 | int np; | ||
971 | short nlocvars; | ||
972 | lu_byte nactvar; | ||
973 | upvaldesc upvalues[60]; | ||
974 | unsigned short actvar[200]; | ||
975 | }FuncState; | ||
976 | static Proto*luaY_parser(lua_State*L,ZIO*z,Mbuffer*buff, | ||
977 | const char*name); | ||
978 | struct lua_longjmp{ | ||
979 | struct lua_longjmp*previous; | ||
980 | jmp_buf b; | ||
981 | volatile int status; | ||
982 | }; | ||
983 | static void luaD_seterrorobj(lua_State*L,int errcode,StkId oldtop){ | ||
984 | switch(errcode){ | ||
985 | case 4:{ | ||
986 | setsvalue(L,oldtop,luaS_newliteral(L,"not enough memory")); | ||
987 | break; | ||
988 | } | ||
989 | case 5:{ | ||
990 | setsvalue(L,oldtop,luaS_newliteral(L,"error in error handling")); | ||
991 | break; | ||
992 | } | ||
993 | case 3: | ||
994 | case 2:{ | ||
995 | setobj(L,oldtop,L->top-1); | ||
996 | break; | ||
997 | } | ||
998 | } | ||
999 | L->top=oldtop+1; | ||
1000 | } | ||
1001 | static void restore_stack_limit(lua_State*L){ | ||
1002 | if(L->size_ci>20000){ | ||
1003 | int inuse=cast_int(L->ci-L->base_ci); | ||
1004 | if(inuse+1<20000) | ||
1005 | luaD_reallocCI(L,20000); | ||
1006 | } | ||
1007 | } | ||
1008 | static void resetstack(lua_State*L,int status){ | ||
1009 | L->ci=L->base_ci; | ||
1010 | L->base=L->ci->base; | ||
1011 | luaF_close(L,L->base); | ||
1012 | luaD_seterrorobj(L,status,L->base); | ||
1013 | L->nCcalls=L->baseCcalls; | ||
1014 | L->allowhook=1; | ||
1015 | restore_stack_limit(L); | ||
1016 | L->errfunc=0; | ||
1017 | L->errorJmp=NULL; | ||
1018 | } | ||
1019 | static void luaD_throw(lua_State*L,int errcode){ | ||
1020 | if(L->errorJmp){ | ||
1021 | L->errorJmp->status=errcode; | ||
1022 | LUAI_THROW(L,L->errorJmp); | ||
1023 | } | ||
1024 | else{ | ||
1025 | L->status=cast_byte(errcode); | ||
1026 | if(G(L)->panic){ | ||
1027 | resetstack(L,errcode); | ||
1028 | G(L)->panic(L); | ||
1029 | } | ||
1030 | exit(EXIT_FAILURE); | ||
1031 | } | ||
1032 | } | ||
1033 | static int luaD_rawrunprotected(lua_State*L,Pfunc f,void*ud){ | ||
1034 | struct lua_longjmp lj; | ||
1035 | lj.status=0; | ||
1036 | lj.previous=L->errorJmp; | ||
1037 | L->errorJmp=&lj; | ||
1038 | LUAI_TRY(L,&lj, | ||
1039 | (*f)(L,ud); | ||
1040 | ); | ||
1041 | L->errorJmp=lj.previous; | ||
1042 | return lj.status; | ||
1043 | } | ||
1044 | static void correctstack(lua_State*L,TValue*oldstack){ | ||
1045 | CallInfo*ci; | ||
1046 | GCObject*up; | ||
1047 | L->top=(L->top-oldstack)+L->stack; | ||
1048 | for(up=L->openupval;up!=NULL;up=up->gch.next) | ||
1049 | gco2uv(up)->v=(gco2uv(up)->v-oldstack)+L->stack; | ||
1050 | for(ci=L->base_ci;ci<=L->ci;ci++){ | ||
1051 | ci->top=(ci->top-oldstack)+L->stack; | ||
1052 | ci->base=(ci->base-oldstack)+L->stack; | ||
1053 | ci->func=(ci->func-oldstack)+L->stack; | ||
1054 | } | ||
1055 | L->base=(L->base-oldstack)+L->stack; | ||
1056 | } | ||
1057 | static void luaD_reallocstack(lua_State*L,int newsize){ | ||
1058 | TValue*oldstack=L->stack; | ||
1059 | int realsize=newsize+1+5; | ||
1060 | luaM_reallocvector(L,L->stack,L->stacksize,realsize,TValue); | ||
1061 | L->stacksize=realsize; | ||
1062 | L->stack_last=L->stack+newsize; | ||
1063 | correctstack(L,oldstack); | ||
1064 | } | ||
1065 | static void luaD_reallocCI(lua_State*L,int newsize){ | ||
1066 | CallInfo*oldci=L->base_ci; | ||
1067 | luaM_reallocvector(L,L->base_ci,L->size_ci,newsize,CallInfo); | ||
1068 | L->size_ci=newsize; | ||
1069 | L->ci=(L->ci-oldci)+L->base_ci; | ||
1070 | L->end_ci=L->base_ci+L->size_ci-1; | ||
1071 | } | ||
1072 | static void luaD_growstack(lua_State*L,int n){ | ||
1073 | if(n<=L->stacksize) | ||
1074 | luaD_reallocstack(L,2*L->stacksize); | ||
1075 | else | ||
1076 | luaD_reallocstack(L,L->stacksize+n); | ||
1077 | } | ||
1078 | static CallInfo*growCI(lua_State*L){ | ||
1079 | if(L->size_ci>20000) | ||
1080 | luaD_throw(L,5); | ||
1081 | else{ | ||
1082 | luaD_reallocCI(L,2*L->size_ci); | ||
1083 | if(L->size_ci>20000) | ||
1084 | luaG_runerror(L,"stack overflow"); | ||
1085 | } | ||
1086 | return++L->ci; | ||
1087 | } | ||
1088 | static StkId adjust_varargs(lua_State*L,Proto*p,int actual){ | ||
1089 | int i; | ||
1090 | int nfixargs=p->numparams; | ||
1091 | Table*htab=NULL; | ||
1092 | StkId base,fixed; | ||
1093 | for(;actual<nfixargs;++actual) | ||
1094 | setnilvalue(L->top++); | ||
1095 | fixed=L->top-actual; | ||
1096 | base=L->top; | ||
1097 | for(i=0;i<nfixargs;i++){ | ||
1098 | setobj(L,L->top++,fixed+i); | ||
1099 | setnilvalue(fixed+i); | ||
1100 | } | ||
1101 | if(htab){ | ||
1102 | sethvalue(L,L->top++,htab); | ||
1103 | } | ||
1104 | return base; | ||
1105 | } | ||
1106 | static StkId tryfuncTM(lua_State*L,StkId func){ | ||
1107 | const TValue*tm=luaT_gettmbyobj(L,func,TM_CALL); | ||
1108 | StkId p; | ||
1109 | ptrdiff_t funcr=savestack(L,func); | ||
1110 | if(!ttisfunction(tm)) | ||
1111 | luaG_typeerror(L,func,"call"); | ||
1112 | for(p=L->top;p>func;p--)setobj(L,p,p-1); | ||
1113 | incr_top(L); | ||
1114 | func=restorestack(L,funcr); | ||
1115 | setobj(L,func,tm); | ||
1116 | return func; | ||
1117 | } | ||
1118 | #define inc_ci(L)((L->ci==L->end_ci)?growCI(L):(condhardstacktests(luaD_reallocCI(L,L->size_ci)),++L->ci)) | ||
1119 | static int luaD_precall(lua_State*L,StkId func,int nresults){ | ||
1120 | LClosure*cl; | ||
1121 | ptrdiff_t funcr; | ||
1122 | if(!ttisfunction(func)) | ||
1123 | func=tryfuncTM(L,func); | ||
1124 | funcr=savestack(L,func); | ||
1125 | cl=&clvalue(func)->l; | ||
1126 | L->ci->savedpc=L->savedpc; | ||
1127 | if(!cl->isC){ | ||
1128 | CallInfo*ci; | ||
1129 | StkId st,base; | ||
1130 | Proto*p=cl->p; | ||
1131 | luaD_checkstack(L,p->maxstacksize); | ||
1132 | func=restorestack(L,funcr); | ||
1133 | if(!p->is_vararg){ | ||
1134 | base=func+1; | ||
1135 | if(L->top>base+p->numparams) | ||
1136 | L->top=base+p->numparams; | ||
1137 | } | ||
1138 | else{ | ||
1139 | int nargs=cast_int(L->top-func)-1; | ||
1140 | base=adjust_varargs(L,p,nargs); | ||
1141 | func=restorestack(L,funcr); | ||
1142 | } | ||
1143 | ci=inc_ci(L); | ||
1144 | ci->func=func; | ||
1145 | L->base=ci->base=base; | ||
1146 | ci->top=L->base+p->maxstacksize; | ||
1147 | L->savedpc=p->code; | ||
1148 | ci->tailcalls=0; | ||
1149 | ci->nresults=nresults; | ||
1150 | for(st=L->top;st<ci->top;st++) | ||
1151 | setnilvalue(st); | ||
1152 | L->top=ci->top; | ||
1153 | return 0; | ||
1154 | } | ||
1155 | else{ | ||
1156 | CallInfo*ci; | ||
1157 | int n; | ||
1158 | luaD_checkstack(L,20); | ||
1159 | ci=inc_ci(L); | ||
1160 | ci->func=restorestack(L,funcr); | ||
1161 | L->base=ci->base=ci->func+1; | ||
1162 | ci->top=L->top+20; | ||
1163 | ci->nresults=nresults; | ||
1164 | n=(*curr_func(L)->c.f)(L); | ||
1165 | if(n<0) | ||
1166 | return 2; | ||
1167 | else{ | ||
1168 | luaD_poscall(L,L->top-n); | ||
1169 | return 1; | ||
1170 | } | ||
1171 | } | ||
1172 | } | ||
1173 | static int luaD_poscall(lua_State*L,StkId firstResult){ | ||
1174 | StkId res; | ||
1175 | int wanted,i; | ||
1176 | CallInfo*ci; | ||
1177 | ci=L->ci--; | ||
1178 | res=ci->func; | ||
1179 | wanted=ci->nresults; | ||
1180 | L->base=(ci-1)->base; | ||
1181 | L->savedpc=(ci-1)->savedpc; | ||
1182 | for(i=wanted;i!=0&&firstResult<L->top;i--) | ||
1183 | setobj(L,res++,firstResult++); | ||
1184 | while(i-->0) | ||
1185 | setnilvalue(res++); | ||
1186 | L->top=res; | ||
1187 | return(wanted-(-1)); | ||
1188 | } | ||
1189 | static void luaD_call(lua_State*L,StkId func,int nResults){ | ||
1190 | if(++L->nCcalls>=200){ | ||
1191 | if(L->nCcalls==200) | ||
1192 | luaG_runerror(L,"C stack overflow"); | ||
1193 | else if(L->nCcalls>=(200+(200>>3))) | ||
1194 | luaD_throw(L,5); | ||
1195 | } | ||
1196 | if(luaD_precall(L,func,nResults)==0) | ||
1197 | luaV_execute(L,1); | ||
1198 | L->nCcalls--; | ||
1199 | luaC_checkGC(L); | ||
1200 | } | ||
1201 | static void resume(lua_State*L,void*ud){ | ||
1202 | StkId firstArg=cast(StkId,ud); | ||
1203 | CallInfo*ci=L->ci; | ||
1204 | if(L->status==0){ | ||
1205 | if(luaD_precall(L,firstArg-1,(-1))!=0) | ||
1206 | return; | ||
1207 | } | ||
1208 | else{ | ||
1209 | L->status=0; | ||
1210 | if(!f_isLua(ci)){ | ||
1211 | if(luaD_poscall(L,firstArg)) | ||
1212 | L->top=L->ci->top; | ||
1213 | } | ||
1214 | else | ||
1215 | L->base=L->ci->base; | ||
1216 | } | ||
1217 | luaV_execute(L,cast_int(L->ci-L->base_ci)); | ||
1218 | } | ||
1219 | static int resume_error(lua_State*L,const char*msg){ | ||
1220 | L->top=L->ci->base; | ||
1221 | setsvalue(L,L->top,luaS_new(L,msg)); | ||
1222 | incr_top(L); | ||
1223 | return 2; | ||
1224 | } | ||
1225 | static int lua_resume(lua_State*L,int nargs){ | ||
1226 | int status; | ||
1227 | if(L->status!=1&&(L->status!=0||L->ci!=L->base_ci)) | ||
1228 | return resume_error(L,"cannot resume non-suspended coroutine"); | ||
1229 | if(L->nCcalls>=200) | ||
1230 | return resume_error(L,"C stack overflow"); | ||
1231 | L->baseCcalls=++L->nCcalls; | ||
1232 | status=luaD_rawrunprotected(L,resume,L->top-nargs); | ||
1233 | if(status!=0){ | ||
1234 | L->status=cast_byte(status); | ||
1235 | luaD_seterrorobj(L,status,L->top); | ||
1236 | L->ci->top=L->top; | ||
1237 | } | ||
1238 | else{ | ||
1239 | status=L->status; | ||
1240 | } | ||
1241 | --L->nCcalls; | ||
1242 | return status; | ||
1243 | } | ||
1244 | static int lua_yield(lua_State*L,int nresults){ | ||
1245 | if(L->nCcalls>L->baseCcalls) | ||
1246 | luaG_runerror(L,"attempt to yield across metamethod/C-call boundary"); | ||
1247 | L->base=L->top-nresults; | ||
1248 | L->status=1; | ||
1249 | return-1; | ||
1250 | } | ||
1251 | static int luaD_pcall(lua_State*L,Pfunc func,void*u, | ||
1252 | ptrdiff_t old_top,ptrdiff_t ef){ | ||
1253 | int status; | ||
1254 | unsigned short oldnCcalls=L->nCcalls; | ||
1255 | ptrdiff_t old_ci=saveci(L,L->ci); | ||
1256 | lu_byte old_allowhooks=L->allowhook; | ||
1257 | ptrdiff_t old_errfunc=L->errfunc; | ||
1258 | L->errfunc=ef; | ||
1259 | status=luaD_rawrunprotected(L,func,u); | ||
1260 | if(status!=0){ | ||
1261 | StkId oldtop=restorestack(L,old_top); | ||
1262 | luaF_close(L,oldtop); | ||
1263 | luaD_seterrorobj(L,status,oldtop); | ||
1264 | L->nCcalls=oldnCcalls; | ||
1265 | L->ci=restoreci(L,old_ci); | ||
1266 | L->base=L->ci->base; | ||
1267 | L->savedpc=L->ci->savedpc; | ||
1268 | L->allowhook=old_allowhooks; | ||
1269 | restore_stack_limit(L); | ||
1270 | } | ||
1271 | L->errfunc=old_errfunc; | ||
1272 | return status; | ||
1273 | } | ||
1274 | struct SParser{ | ||
1275 | ZIO*z; | ||
1276 | Mbuffer buff; | ||
1277 | const char*name; | ||
1278 | }; | ||
1279 | static void f_parser(lua_State*L,void*ud){ | ||
1280 | int i; | ||
1281 | Proto*tf; | ||
1282 | Closure*cl; | ||
1283 | struct SParser*p=cast(struct SParser*,ud); | ||
1284 | luaC_checkGC(L); | ||
1285 | tf=luaY_parser(L,p->z, | ||
1286 | &p->buff,p->name); | ||
1287 | cl=luaF_newLclosure(L,tf->nups,hvalue(gt(L))); | ||
1288 | cl->l.p=tf; | ||
1289 | for(i=0;i<tf->nups;i++) | ||
1290 | cl->l.upvals[i]=luaF_newupval(L); | ||
1291 | setclvalue(L,L->top,cl); | ||
1292 | incr_top(L); | ||
1293 | } | ||
1294 | static int luaD_protectedparser(lua_State*L,ZIO*z,const char*name){ | ||
1295 | struct SParser p; | ||
1296 | int status; | ||
1297 | p.z=z;p.name=name; | ||
1298 | luaZ_initbuffer(L,&p.buff); | ||
1299 | status=luaD_pcall(L,f_parser,&p,savestack(L,L->top),L->errfunc); | ||
1300 | luaZ_freebuffer(L,&p.buff); | ||
1301 | return status; | ||
1302 | } | ||
1303 | static void luaS_resize(lua_State*L,int newsize){ | ||
1304 | GCObject**newhash; | ||
1305 | stringtable*tb; | ||
1306 | int i; | ||
1307 | if(G(L)->gcstate==2) | ||
1308 | return; | ||
1309 | newhash=luaM_newvector(L,newsize,GCObject*); | ||
1310 | tb=&G(L)->strt; | ||
1311 | for(i=0;i<newsize;i++)newhash[i]=NULL; | ||
1312 | for(i=0;i<tb->size;i++){ | ||
1313 | GCObject*p=tb->hash[i]; | ||
1314 | while(p){ | ||
1315 | GCObject*next=p->gch.next; | ||
1316 | unsigned int h=gco2ts(p)->hash; | ||
1317 | int h1=lmod(h,newsize); | ||
1318 | p->gch.next=newhash[h1]; | ||
1319 | newhash[h1]=p; | ||
1320 | p=next; | ||
1321 | } | ||
1322 | } | ||
1323 | luaM_freearray(L,tb->hash,tb->size,TString*); | ||
1324 | tb->size=newsize; | ||
1325 | tb->hash=newhash; | ||
1326 | } | ||
1327 | static TString*newlstr(lua_State*L,const char*str,size_t l, | ||
1328 | unsigned int h){ | ||
1329 | TString*ts; | ||
1330 | stringtable*tb; | ||
1331 | if(l+1>(((size_t)(~(size_t)0)-2)-sizeof(TString))/sizeof(char)) | ||
1332 | luaM_toobig(L); | ||
1333 | ts=cast(TString*,luaM_malloc(L,(l+1)*sizeof(char)+sizeof(TString))); | ||
1334 | ts->tsv.len=l; | ||
1335 | ts->tsv.hash=h; | ||
1336 | ts->tsv.marked=luaC_white(G(L)); | ||
1337 | ts->tsv.tt=4; | ||
1338 | ts->tsv.reserved=0; | ||
1339 | memcpy(ts+1,str,l*sizeof(char)); | ||
1340 | ((char*)(ts+1))[l]='\0'; | ||
1341 | tb=&G(L)->strt; | ||
1342 | h=lmod(h,tb->size); | ||
1343 | ts->tsv.next=tb->hash[h]; | ||
1344 | tb->hash[h]=obj2gco(ts); | ||
1345 | tb->nuse++; | ||
1346 | if(tb->nuse>cast(lu_int32,tb->size)&&tb->size<=(INT_MAX-2)/2) | ||
1347 | luaS_resize(L,tb->size*2); | ||
1348 | return ts; | ||
1349 | } | ||
1350 | static TString*luaS_newlstr(lua_State*L,const char*str,size_t l){ | ||
1351 | GCObject*o; | ||
1352 | unsigned int h=cast(unsigned int,l); | ||
1353 | size_t step=(l>>5)+1; | ||
1354 | size_t l1; | ||
1355 | for(l1=l;l1>=step;l1-=step) | ||
1356 | h=h^((h<<5)+(h>>2)+cast(unsigned char,str[l1-1])); | ||
1357 | for(o=G(L)->strt.hash[lmod(h,G(L)->strt.size)]; | ||
1358 | o!=NULL; | ||
1359 | o=o->gch.next){ | ||
1360 | TString*ts=rawgco2ts(o); | ||
1361 | if(ts->tsv.len==l&&(memcmp(str,getstr(ts),l)==0)){ | ||
1362 | if(isdead(G(L),o))changewhite(o); | ||
1363 | return ts; | ||
1364 | } | ||
1365 | } | ||
1366 | return newlstr(L,str,l,h); | ||
1367 | } | ||
1368 | static Udata*luaS_newudata(lua_State*L,size_t s,Table*e){ | ||
1369 | Udata*u; | ||
1370 | if(s>((size_t)(~(size_t)0)-2)-sizeof(Udata)) | ||
1371 | luaM_toobig(L); | ||
1372 | u=cast(Udata*,luaM_malloc(L,s+sizeof(Udata))); | ||
1373 | u->uv.marked=luaC_white(G(L)); | ||
1374 | u->uv.tt=7; | ||
1375 | u->uv.len=s; | ||
1376 | u->uv.metatable=NULL; | ||
1377 | u->uv.env=e; | ||
1378 | u->uv.next=G(L)->mainthread->next; | ||
1379 | G(L)->mainthread->next=obj2gco(u); | ||
1380 | return u; | ||
1381 | } | ||
1382 | #define hashpow2(t,n)(gnode(t,lmod((n),sizenode(t)))) | ||
1383 | #define hashstr(t,str)hashpow2(t,(str)->tsv.hash) | ||
1384 | #define hashboolean(t,p)hashpow2(t,p) | ||
1385 | #define hashmod(t,n)(gnode(t,((n)%((sizenode(t)-1)|1)))) | ||
1386 | #define hashpointer(t,p)hashmod(t,IntPoint(p)) | ||
1387 | static const Node dummynode_={ | ||
1388 | {{NULL},0}, | ||
1389 | {{{NULL},0,NULL}} | ||
1390 | }; | ||
1391 | static Node*hashnum(const Table*t,lua_Number n){ | ||
1392 | unsigned int a[cast_int(sizeof(lua_Number)/sizeof(int))]; | ||
1393 | int i; | ||
1394 | if(luai_numeq(n,0)) | ||
1395 | return gnode(t,0); | ||
1396 | memcpy(a,&n,sizeof(a)); | ||
1397 | for(i=1;i<cast_int(sizeof(lua_Number)/sizeof(int));i++)a[0]+=a[i]; | ||
1398 | return hashmod(t,a[0]); | ||
1399 | } | ||
1400 | static Node*mainposition(const Table*t,const TValue*key){ | ||
1401 | switch(ttype(key)){ | ||
1402 | case 3: | ||
1403 | return hashnum(t,nvalue(key)); | ||
1404 | case 4: | ||
1405 | return hashstr(t,rawtsvalue(key)); | ||
1406 | case 1: | ||
1407 | return hashboolean(t,bvalue(key)); | ||
1408 | case 2: | ||
1409 | return hashpointer(t,pvalue(key)); | ||
1410 | default: | ||
1411 | return hashpointer(t,gcvalue(key)); | ||
1412 | } | ||
1413 | } | ||
1414 | static int arrayindex(const TValue*key){ | ||
1415 | if(ttisnumber(key)){ | ||
1416 | lua_Number n=nvalue(key); | ||
1417 | int k; | ||
1418 | lua_number2int(k,n); | ||
1419 | if(luai_numeq(cast_num(k),n)) | ||
1420 | return k; | ||
1421 | } | ||
1422 | return-1; | ||
1423 | } | ||
1424 | static int findindex(lua_State*L,Table*t,StkId key){ | ||
1425 | int i; | ||
1426 | if(ttisnil(key))return-1; | ||
1427 | i=arrayindex(key); | ||
1428 | if(0<i&&i<=t->sizearray) | ||
1429 | return i-1; | ||
1430 | else{ | ||
1431 | Node*n=mainposition(t,key); | ||
1432 | do{ | ||
1433 | if(luaO_rawequalObj(key2tval(n),key)|| | ||
1434 | (ttype(gkey(n))==(8+3)&&iscollectable(key)&& | ||
1435 | gcvalue(gkey(n))==gcvalue(key))){ | ||
1436 | i=cast_int(n-gnode(t,0)); | ||
1437 | return i+t->sizearray; | ||
1438 | } | ||
1439 | else n=gnext(n); | ||
1440 | }while(n); | ||
1441 | luaG_runerror(L,"invalid key to "LUA_QL("next")); | ||
1442 | return 0; | ||
1443 | } | ||
1444 | } | ||
1445 | static int luaH_next(lua_State*L,Table*t,StkId key){ | ||
1446 | int i=findindex(L,t,key); | ||
1447 | for(i++;i<t->sizearray;i++){ | ||
1448 | if(!ttisnil(&t->array[i])){ | ||
1449 | setnvalue(key,cast_num(i+1)); | ||
1450 | setobj(L,key+1,&t->array[i]); | ||
1451 | return 1; | ||
1452 | } | ||
1453 | } | ||
1454 | for(i-=t->sizearray;i<(int)sizenode(t);i++){ | ||
1455 | if(!ttisnil(gval(gnode(t,i)))){ | ||
1456 | setobj(L,key,key2tval(gnode(t,i))); | ||
1457 | setobj(L,key+1,gval(gnode(t,i))); | ||
1458 | return 1; | ||
1459 | } | ||
1460 | } | ||
1461 | return 0; | ||
1462 | } | ||
1463 | static int computesizes(int nums[],int*narray){ | ||
1464 | int i; | ||
1465 | int twotoi; | ||
1466 | int a=0; | ||
1467 | int na=0; | ||
1468 | int n=0; | ||
1469 | for(i=0,twotoi=1;twotoi/2<*narray;i++,twotoi*=2){ | ||
1470 | if(nums[i]>0){ | ||
1471 | a+=nums[i]; | ||
1472 | if(a>twotoi/2){ | ||
1473 | n=twotoi; | ||
1474 | na=a; | ||
1475 | } | ||
1476 | } | ||
1477 | if(a==*narray)break; | ||
1478 | } | ||
1479 | *narray=n; | ||
1480 | return na; | ||
1481 | } | ||
1482 | static int countint(const TValue*key,int*nums){ | ||
1483 | int k=arrayindex(key); | ||
1484 | if(0<k&&k<=(1<<(32-2))){ | ||
1485 | nums[ceillog2(k)]++; | ||
1486 | return 1; | ||
1487 | } | ||
1488 | else | ||
1489 | return 0; | ||
1490 | } | ||
1491 | static int numusearray(const Table*t,int*nums){ | ||
1492 | int lg; | ||
1493 | int ttlg; | ||
1494 | int ause=0; | ||
1495 | int i=1; | ||
1496 | for(lg=0,ttlg=1;lg<=(32-2);lg++,ttlg*=2){ | ||
1497 | int lc=0; | ||
1498 | int lim=ttlg; | ||
1499 | if(lim>t->sizearray){ | ||
1500 | lim=t->sizearray; | ||
1501 | if(i>lim) | ||
1502 | break; | ||
1503 | } | ||
1504 | for(;i<=lim;i++){ | ||
1505 | if(!ttisnil(&t->array[i-1])) | ||
1506 | lc++; | ||
1507 | } | ||
1508 | nums[lg]+=lc; | ||
1509 | ause+=lc; | ||
1510 | } | ||
1511 | return ause; | ||
1512 | } | ||
1513 | static int numusehash(const Table*t,int*nums,int*pnasize){ | ||
1514 | int totaluse=0; | ||
1515 | int ause=0; | ||
1516 | int i=sizenode(t); | ||
1517 | while(i--){ | ||
1518 | Node*n=&t->node[i]; | ||
1519 | if(!ttisnil(gval(n))){ | ||
1520 | ause+=countint(key2tval(n),nums); | ||
1521 | totaluse++; | ||
1522 | } | ||
1523 | } | ||
1524 | *pnasize+=ause; | ||
1525 | return totaluse; | ||
1526 | } | ||
1527 | static void setarrayvector(lua_State*L,Table*t,int size){ | ||
1528 | int i; | ||
1529 | luaM_reallocvector(L,t->array,t->sizearray,size,TValue); | ||
1530 | for(i=t->sizearray;i<size;i++) | ||
1531 | setnilvalue(&t->array[i]); | ||
1532 | t->sizearray=size; | ||
1533 | } | ||
1534 | static void setnodevector(lua_State*L,Table*t,int size){ | ||
1535 | int lsize; | ||
1536 | if(size==0){ | ||
1537 | t->node=cast(Node*,(&dummynode_)); | ||
1538 | lsize=0; | ||
1539 | } | ||
1540 | else{ | ||
1541 | int i; | ||
1542 | lsize=ceillog2(size); | ||
1543 | if(lsize>(32-2)) | ||
1544 | luaG_runerror(L,"table overflow"); | ||
1545 | size=twoto(lsize); | ||
1546 | t->node=luaM_newvector(L,size,Node); | ||
1547 | for(i=0;i<size;i++){ | ||
1548 | Node*n=gnode(t,i); | ||
1549 | gnext(n)=NULL; | ||
1550 | setnilvalue(gkey(n)); | ||
1551 | setnilvalue(gval(n)); | ||
1552 | } | ||
1553 | } | ||
1554 | t->lsizenode=cast_byte(lsize); | ||
1555 | t->lastfree=gnode(t,size); | ||
1556 | } | ||
1557 | static void resize(lua_State*L,Table*t,int nasize,int nhsize){ | ||
1558 | int i; | ||
1559 | int oldasize=t->sizearray; | ||
1560 | int oldhsize=t->lsizenode; | ||
1561 | Node*nold=t->node; | ||
1562 | if(nasize>oldasize) | ||
1563 | setarrayvector(L,t,nasize); | ||
1564 | setnodevector(L,t,nhsize); | ||
1565 | if(nasize<oldasize){ | ||
1566 | t->sizearray=nasize; | ||
1567 | for(i=nasize;i<oldasize;i++){ | ||
1568 | if(!ttisnil(&t->array[i])) | ||
1569 | setobj(L,luaH_setnum(L,t,i+1),&t->array[i]); | ||
1570 | } | ||
1571 | luaM_reallocvector(L,t->array,oldasize,nasize,TValue); | ||
1572 | } | ||
1573 | for(i=twoto(oldhsize)-1;i>=0;i--){ | ||
1574 | Node*old=nold+i; | ||
1575 | if(!ttisnil(gval(old))) | ||
1576 | setobj(L,luaH_set(L,t,key2tval(old)),gval(old)); | ||
1577 | } | ||
1578 | if(nold!=(&dummynode_)) | ||
1579 | luaM_freearray(L,nold,twoto(oldhsize),Node); | ||
1580 | } | ||
1581 | static void luaH_resizearray(lua_State*L,Table*t,int nasize){ | ||
1582 | int nsize=(t->node==(&dummynode_))?0:sizenode(t); | ||
1583 | resize(L,t,nasize,nsize); | ||
1584 | } | ||
1585 | static void rehash(lua_State*L,Table*t,const TValue*ek){ | ||
1586 | int nasize,na; | ||
1587 | int nums[(32-2)+1]; | ||
1588 | int i; | ||
1589 | int totaluse; | ||
1590 | for(i=0;i<=(32-2);i++)nums[i]=0; | ||
1591 | nasize=numusearray(t,nums); | ||
1592 | totaluse=nasize; | ||
1593 | totaluse+=numusehash(t,nums,&nasize); | ||
1594 | nasize+=countint(ek,nums); | ||
1595 | totaluse++; | ||
1596 | na=computesizes(nums,&nasize); | ||
1597 | resize(L,t,nasize,totaluse-na); | ||
1598 | } | ||
1599 | static Table*luaH_new(lua_State*L,int narray,int nhash){ | ||
1600 | Table*t=luaM_new(L,Table); | ||
1601 | luaC_link(L,obj2gco(t),5); | ||
1602 | t->metatable=NULL; | ||
1603 | t->flags=cast_byte(~0); | ||
1604 | t->array=NULL; | ||
1605 | t->sizearray=0; | ||
1606 | t->lsizenode=0; | ||
1607 | t->node=cast(Node*,(&dummynode_)); | ||
1608 | setarrayvector(L,t,narray); | ||
1609 | setnodevector(L,t,nhash); | ||
1610 | return t; | ||
1611 | } | ||
1612 | static void luaH_free(lua_State*L,Table*t){ | ||
1613 | if(t->node!=(&dummynode_)) | ||
1614 | luaM_freearray(L,t->node,sizenode(t),Node); | ||
1615 | luaM_freearray(L,t->array,t->sizearray,TValue); | ||
1616 | luaM_free(L,t); | ||
1617 | } | ||
1618 | static Node*getfreepos(Table*t){ | ||
1619 | while(t->lastfree-->t->node){ | ||
1620 | if(ttisnil(gkey(t->lastfree))) | ||
1621 | return t->lastfree; | ||
1622 | } | ||
1623 | return NULL; | ||
1624 | } | ||
1625 | static TValue*newkey(lua_State*L,Table*t,const TValue*key){ | ||
1626 | Node*mp=mainposition(t,key); | ||
1627 | if(!ttisnil(gval(mp))||mp==(&dummynode_)){ | ||
1628 | Node*othern; | ||
1629 | Node*n=getfreepos(t); | ||
1630 | if(n==NULL){ | ||
1631 | rehash(L,t,key); | ||
1632 | return luaH_set(L,t,key); | ||
1633 | } | ||
1634 | othern=mainposition(t,key2tval(mp)); | ||
1635 | if(othern!=mp){ | ||
1636 | while(gnext(othern)!=mp)othern=gnext(othern); | ||
1637 | gnext(othern)=n; | ||
1638 | *n=*mp; | ||
1639 | gnext(mp)=NULL; | ||
1640 | setnilvalue(gval(mp)); | ||
1641 | } | ||
1642 | else{ | ||
1643 | gnext(n)=gnext(mp); | ||
1644 | gnext(mp)=n; | ||
1645 | mp=n; | ||
1646 | } | ||
1647 | } | ||
1648 | gkey(mp)->value=key->value;gkey(mp)->tt=key->tt; | ||
1649 | luaC_barriert(L,t,key); | ||
1650 | return gval(mp); | ||
1651 | } | ||
1652 | static const TValue*luaH_getnum(Table*t,int key){ | ||
1653 | if(cast(unsigned int,key-1)<cast(unsigned int,t->sizearray)) | ||
1654 | return&t->array[key-1]; | ||
1655 | else{ | ||
1656 | lua_Number nk=cast_num(key); | ||
1657 | Node*n=hashnum(t,nk); | ||
1658 | do{ | ||
1659 | if(ttisnumber(gkey(n))&&luai_numeq(nvalue(gkey(n)),nk)) | ||
1660 | return gval(n); | ||
1661 | else n=gnext(n); | ||
1662 | }while(n); | ||
1663 | return(&luaO_nilobject_); | ||
1664 | } | ||
1665 | } | ||
1666 | static const TValue*luaH_getstr(Table*t,TString*key){ | ||
1667 | Node*n=hashstr(t,key); | ||
1668 | do{ | ||
1669 | if(ttisstring(gkey(n))&&rawtsvalue(gkey(n))==key) | ||
1670 | return gval(n); | ||
1671 | else n=gnext(n); | ||
1672 | }while(n); | ||
1673 | return(&luaO_nilobject_); | ||
1674 | } | ||
1675 | static const TValue*luaH_get(Table*t,const TValue*key){ | ||
1676 | switch(ttype(key)){ | ||
1677 | case 0:return(&luaO_nilobject_); | ||
1678 | case 4:return luaH_getstr(t,rawtsvalue(key)); | ||
1679 | case 3:{ | ||
1680 | int k; | ||
1681 | lua_Number n=nvalue(key); | ||
1682 | lua_number2int(k,n); | ||
1683 | if(luai_numeq(cast_num(k),nvalue(key))) | ||
1684 | return luaH_getnum(t,k); | ||
1685 | } | ||
1686 | default:{ | ||
1687 | Node*n=mainposition(t,key); | ||
1688 | do{ | ||
1689 | if(luaO_rawequalObj(key2tval(n),key)) | ||
1690 | return gval(n); | ||
1691 | else n=gnext(n); | ||
1692 | }while(n); | ||
1693 | return(&luaO_nilobject_); | ||
1694 | } | ||
1695 | } | ||
1696 | } | ||
1697 | static TValue*luaH_set(lua_State*L,Table*t,const TValue*key){ | ||
1698 | const TValue*p=luaH_get(t,key); | ||
1699 | t->flags=0; | ||
1700 | if(p!=(&luaO_nilobject_)) | ||
1701 | return cast(TValue*,p); | ||
1702 | else{ | ||
1703 | if(ttisnil(key))luaG_runerror(L,"table index is nil"); | ||
1704 | else if(ttisnumber(key)&&luai_numisnan(nvalue(key))) | ||
1705 | luaG_runerror(L,"table index is NaN"); | ||
1706 | return newkey(L,t,key); | ||
1707 | } | ||
1708 | } | ||
1709 | static TValue*luaH_setnum(lua_State*L,Table*t,int key){ | ||
1710 | const TValue*p=luaH_getnum(t,key); | ||
1711 | if(p!=(&luaO_nilobject_)) | ||
1712 | return cast(TValue*,p); | ||
1713 | else{ | ||
1714 | TValue k; | ||
1715 | setnvalue(&k,cast_num(key)); | ||
1716 | return newkey(L,t,&k); | ||
1717 | } | ||
1718 | } | ||
1719 | static TValue*luaH_setstr(lua_State*L,Table*t,TString*key){ | ||
1720 | const TValue*p=luaH_getstr(t,key); | ||
1721 | if(p!=(&luaO_nilobject_)) | ||
1722 | return cast(TValue*,p); | ||
1723 | else{ | ||
1724 | TValue k; | ||
1725 | setsvalue(L,&k,key); | ||
1726 | return newkey(L,t,&k); | ||
1727 | } | ||
1728 | } | ||
1729 | static int unbound_search(Table*t,unsigned int j){ | ||
1730 | unsigned int i=j; | ||
1731 | j++; | ||
1732 | while(!ttisnil(luaH_getnum(t,j))){ | ||
1733 | i=j; | ||
1734 | j*=2; | ||
1735 | if(j>cast(unsigned int,(INT_MAX-2))){ | ||
1736 | i=1; | ||
1737 | while(!ttisnil(luaH_getnum(t,i)))i++; | ||
1738 | return i-1; | ||
1739 | } | ||
1740 | } | ||
1741 | while(j-i>1){ | ||
1742 | unsigned int m=(i+j)/2; | ||
1743 | if(ttisnil(luaH_getnum(t,m)))j=m; | ||
1744 | else i=m; | ||
1745 | } | ||
1746 | return i; | ||
1747 | } | ||
1748 | static int luaH_getn(Table*t){ | ||
1749 | unsigned int j=t->sizearray; | ||
1750 | if(j>0&&ttisnil(&t->array[j-1])){ | ||
1751 | unsigned int i=0; | ||
1752 | while(j-i>1){ | ||
1753 | unsigned int m=(i+j)/2; | ||
1754 | if(ttisnil(&t->array[m-1]))j=m; | ||
1755 | else i=m; | ||
1756 | } | ||
1757 | return i; | ||
1758 | } | ||
1759 | else if(t->node==(&dummynode_)) | ||
1760 | return j; | ||
1761 | else return unbound_search(t,j); | ||
1762 | } | ||
1763 | #define makewhite(g,x)((x)->gch.marked=cast_byte(((x)->gch.marked&cast_byte(~(bitmask(2)|bit2mask(0,1))))|luaC_white(g))) | ||
1764 | #define white2gray(x)reset2bits((x)->gch.marked,0,1) | ||
1765 | #define black2gray(x)resetbit((x)->gch.marked,2) | ||
1766 | #define stringmark(s)reset2bits((s)->tsv.marked,0,1) | ||
1767 | #define isfinalized(u)testbit((u)->marked,3) | ||
1768 | #define markfinalized(u)l_setbit((u)->marked,3) | ||
1769 | #define markvalue(g,o){checkconsistency(o);if(iscollectable(o)&&iswhite(gcvalue(o)))reallymarkobject(g,gcvalue(o));} | ||
1770 | #define markobject(g,t){if(iswhite(obj2gco(t)))reallymarkobject(g,obj2gco(t));} | ||
1771 | #define setthreshold(g)(g->GCthreshold=(g->estimate/100)*g->gcpause) | ||
1772 | static void removeentry(Node*n){ | ||
1773 | if(iscollectable(gkey(n))) | ||
1774 | setttype(gkey(n),(8+3)); | ||
1775 | } | ||
1776 | static void reallymarkobject(global_State*g,GCObject*o){ | ||
1777 | white2gray(o); | ||
1778 | switch(o->gch.tt){ | ||
1779 | case 4:{ | ||
1780 | return; | ||
1781 | } | ||
1782 | case 7:{ | ||
1783 | Table*mt=gco2u(o)->metatable; | ||
1784 | gray2black(o); | ||
1785 | if(mt)markobject(g,mt); | ||
1786 | markobject(g,gco2u(o)->env); | ||
1787 | return; | ||
1788 | } | ||
1789 | case(8+2):{ | ||
1790 | UpVal*uv=gco2uv(o); | ||
1791 | markvalue(g,uv->v); | ||
1792 | if(uv->v==&uv->u.value) | ||
1793 | gray2black(o); | ||
1794 | return; | ||
1795 | } | ||
1796 | case 6:{ | ||
1797 | gco2cl(o)->c.gclist=g->gray; | ||
1798 | g->gray=o; | ||
1799 | break; | ||
1800 | } | ||
1801 | case 5:{ | ||
1802 | gco2h(o)->gclist=g->gray; | ||
1803 | g->gray=o; | ||
1804 | break; | ||
1805 | } | ||
1806 | case 8:{ | ||
1807 | gco2th(o)->gclist=g->gray; | ||
1808 | g->gray=o; | ||
1809 | break; | ||
1810 | } | ||
1811 | case(8+1):{ | ||
1812 | gco2p(o)->gclist=g->gray; | ||
1813 | g->gray=o; | ||
1814 | break; | ||
1815 | } | ||
1816 | default:; | ||
1817 | } | ||
1818 | } | ||
1819 | static void marktmu(global_State*g){ | ||
1820 | GCObject*u=g->tmudata; | ||
1821 | if(u){ | ||
1822 | do{ | ||
1823 | u=u->gch.next; | ||
1824 | makewhite(g,u); | ||
1825 | reallymarkobject(g,u); | ||
1826 | }while(u!=g->tmudata); | ||
1827 | } | ||
1828 | } | ||
1829 | static size_t luaC_separateudata(lua_State*L,int all){ | ||
1830 | global_State*g=G(L); | ||
1831 | size_t deadmem=0; | ||
1832 | GCObject**p=&g->mainthread->next; | ||
1833 | GCObject*curr; | ||
1834 | while((curr=*p)!=NULL){ | ||
1835 | if(!(iswhite(curr)||all)||isfinalized(gco2u(curr))) | ||
1836 | p=&curr->gch.next; | ||
1837 | else if(fasttm(L,gco2u(curr)->metatable,TM_GC)==NULL){ | ||
1838 | markfinalized(gco2u(curr)); | ||
1839 | p=&curr->gch.next; | ||
1840 | } | ||
1841 | else{ | ||
1842 | deadmem+=sizeudata(gco2u(curr)); | ||
1843 | markfinalized(gco2u(curr)); | ||
1844 | *p=curr->gch.next; | ||
1845 | if(g->tmudata==NULL) | ||
1846 | g->tmudata=curr->gch.next=curr; | ||
1847 | else{ | ||
1848 | curr->gch.next=g->tmudata->gch.next; | ||
1849 | g->tmudata->gch.next=curr; | ||
1850 | g->tmudata=curr; | ||
1851 | } | ||
1852 | } | ||
1853 | } | ||
1854 | return deadmem; | ||
1855 | } | ||
1856 | static int traversetable(global_State*g,Table*h){ | ||
1857 | int i; | ||
1858 | int weakkey=0; | ||
1859 | int weakvalue=0; | ||
1860 | const TValue*mode; | ||
1861 | if(h->metatable) | ||
1862 | markobject(g,h->metatable); | ||
1863 | mode=gfasttm(g,h->metatable,TM_MODE); | ||
1864 | if(mode&&ttisstring(mode)){ | ||
1865 | weakkey=(strchr(svalue(mode),'k')!=NULL); | ||
1866 | weakvalue=(strchr(svalue(mode),'v')!=NULL); | ||
1867 | if(weakkey||weakvalue){ | ||
1868 | h->marked&=~(bitmask(3)|bitmask(4)); | ||
1869 | h->marked|=cast_byte((weakkey<<3)| | ||
1870 | (weakvalue<<4)); | ||
1871 | h->gclist=g->weak; | ||
1872 | g->weak=obj2gco(h); | ||
1873 | } | ||
1874 | } | ||
1875 | if(weakkey&&weakvalue)return 1; | ||
1876 | if(!weakvalue){ | ||
1877 | i=h->sizearray; | ||
1878 | while(i--) | ||
1879 | markvalue(g,&h->array[i]); | ||
1880 | } | ||
1881 | i=sizenode(h); | ||
1882 | while(i--){ | ||
1883 | Node*n=gnode(h,i); | ||
1884 | if(ttisnil(gval(n))) | ||
1885 | removeentry(n); | ||
1886 | else{ | ||
1887 | if(!weakkey)markvalue(g,gkey(n)); | ||
1888 | if(!weakvalue)markvalue(g,gval(n)); | ||
1889 | } | ||
1890 | } | ||
1891 | return weakkey||weakvalue; | ||
1892 | } | ||
1893 | static void traverseproto(global_State*g,Proto*f){ | ||
1894 | int i; | ||
1895 | if(f->source)stringmark(f->source); | ||
1896 | for(i=0;i<f->sizek;i++) | ||
1897 | markvalue(g,&f->k[i]); | ||
1898 | for(i=0;i<f->sizeupvalues;i++){ | ||
1899 | if(f->upvalues[i]) | ||
1900 | stringmark(f->upvalues[i]); | ||
1901 | } | ||
1902 | for(i=0;i<f->sizep;i++){ | ||
1903 | if(f->p[i]) | ||
1904 | markobject(g,f->p[i]); | ||
1905 | } | ||
1906 | for(i=0;i<f->sizelocvars;i++){ | ||
1907 | if(f->locvars[i].varname) | ||
1908 | stringmark(f->locvars[i].varname); | ||
1909 | } | ||
1910 | } | ||
1911 | static void traverseclosure(global_State*g,Closure*cl){ | ||
1912 | markobject(g,cl->c.env); | ||
1913 | if(cl->c.isC){ | ||
1914 | int i; | ||
1915 | for(i=0;i<cl->c.nupvalues;i++) | ||
1916 | markvalue(g,&cl->c.upvalue[i]); | ||
1917 | } | ||
1918 | else{ | ||
1919 | int i; | ||
1920 | markobject(g,cl->l.p); | ||
1921 | for(i=0;i<cl->l.nupvalues;i++) | ||
1922 | markobject(g,cl->l.upvals[i]); | ||
1923 | } | ||
1924 | } | ||
1925 | static void checkstacksizes(lua_State*L,StkId max){ | ||
1926 | int ci_used=cast_int(L->ci-L->base_ci); | ||
1927 | int s_used=cast_int(max-L->stack); | ||
1928 | if(L->size_ci>20000) | ||
1929 | return; | ||
1930 | if(4*ci_used<L->size_ci&&2*8<L->size_ci) | ||
1931 | luaD_reallocCI(L,L->size_ci/2); | ||
1932 | condhardstacktests(luaD_reallocCI(L,ci_used+1)); | ||
1933 | if(4*s_used<L->stacksize&& | ||
1934 | 2*((2*20)+5)<L->stacksize) | ||
1935 | luaD_reallocstack(L,L->stacksize/2); | ||
1936 | condhardstacktests(luaD_reallocstack(L,s_used)); | ||
1937 | } | ||
1938 | static void traversestack(global_State*g,lua_State*l){ | ||
1939 | StkId o,lim; | ||
1940 | CallInfo*ci; | ||
1941 | markvalue(g,gt(l)); | ||
1942 | lim=l->top; | ||
1943 | for(ci=l->base_ci;ci<=l->ci;ci++){ | ||
1944 | if(lim<ci->top)lim=ci->top; | ||
1945 | } | ||
1946 | for(o=l->stack;o<l->top;o++) | ||
1947 | markvalue(g,o); | ||
1948 | for(;o<=lim;o++) | ||
1949 | setnilvalue(o); | ||
1950 | checkstacksizes(l,lim); | ||
1951 | } | ||
1952 | static l_mem propagatemark(global_State*g){ | ||
1953 | GCObject*o=g->gray; | ||
1954 | gray2black(o); | ||
1955 | switch(o->gch.tt){ | ||
1956 | case 5:{ | ||
1957 | Table*h=gco2h(o); | ||
1958 | g->gray=h->gclist; | ||
1959 | if(traversetable(g,h)) | ||
1960 | black2gray(o); | ||
1961 | return sizeof(Table)+sizeof(TValue)*h->sizearray+ | ||
1962 | sizeof(Node)*sizenode(h); | ||
1963 | } | ||
1964 | case 6:{ | ||
1965 | Closure*cl=gco2cl(o); | ||
1966 | g->gray=cl->c.gclist; | ||
1967 | traverseclosure(g,cl); | ||
1968 | return(cl->c.isC)?sizeCclosure(cl->c.nupvalues): | ||
1969 | sizeLclosure(cl->l.nupvalues); | ||
1970 | } | ||
1971 | case 8:{ | ||
1972 | lua_State*th=gco2th(o); | ||
1973 | g->gray=th->gclist; | ||
1974 | th->gclist=g->grayagain; | ||
1975 | g->grayagain=o; | ||
1976 | black2gray(o); | ||
1977 | traversestack(g,th); | ||
1978 | return sizeof(lua_State)+sizeof(TValue)*th->stacksize+ | ||
1979 | sizeof(CallInfo)*th->size_ci; | ||
1980 | } | ||
1981 | case(8+1):{ | ||
1982 | Proto*p=gco2p(o); | ||
1983 | g->gray=p->gclist; | ||
1984 | traverseproto(g,p); | ||
1985 | return sizeof(Proto)+sizeof(Instruction)*p->sizecode+ | ||
1986 | sizeof(Proto*)*p->sizep+ | ||
1987 | sizeof(TValue)*p->sizek+ | ||
1988 | sizeof(int)*p->sizelineinfo+ | ||
1989 | sizeof(LocVar)*p->sizelocvars+ | ||
1990 | sizeof(TString*)*p->sizeupvalues; | ||
1991 | } | ||
1992 | default:return 0; | ||
1993 | } | ||
1994 | } | ||
1995 | static size_t propagateall(global_State*g){ | ||
1996 | size_t m=0; | ||
1997 | while(g->gray)m+=propagatemark(g); | ||
1998 | return m; | ||
1999 | } | ||
2000 | static int iscleared(const TValue*o,int iskey){ | ||
2001 | if(!iscollectable(o))return 0; | ||
2002 | if(ttisstring(o)){ | ||
2003 | stringmark(rawtsvalue(o)); | ||
2004 | return 0; | ||
2005 | } | ||
2006 | return iswhite(gcvalue(o))|| | ||
2007 | (ttisuserdata(o)&&(!iskey&&isfinalized(uvalue(o)))); | ||
2008 | } | ||
2009 | static void cleartable(GCObject*l){ | ||
2010 | while(l){ | ||
2011 | Table*h=gco2h(l); | ||
2012 | int i=h->sizearray; | ||
2013 | if(testbit(h->marked,4)){ | ||
2014 | while(i--){ | ||
2015 | TValue*o=&h->array[i]; | ||
2016 | if(iscleared(o,0)) | ||
2017 | setnilvalue(o); | ||
2018 | } | ||
2019 | } | ||
2020 | i=sizenode(h); | ||
2021 | while(i--){ | ||
2022 | Node*n=gnode(h,i); | ||
2023 | if(!ttisnil(gval(n))&& | ||
2024 | (iscleared(key2tval(n),1)||iscleared(gval(n),0))){ | ||
2025 | setnilvalue(gval(n)); | ||
2026 | removeentry(n); | ||
2027 | } | ||
2028 | } | ||
2029 | l=h->gclist; | ||
2030 | } | ||
2031 | } | ||
2032 | static void freeobj(lua_State*L,GCObject*o){ | ||
2033 | switch(o->gch.tt){ | ||
2034 | case(8+1):luaF_freeproto(L,gco2p(o));break; | ||
2035 | case 6:luaF_freeclosure(L,gco2cl(o));break; | ||
2036 | case(8+2):luaF_freeupval(L,gco2uv(o));break; | ||
2037 | case 5:luaH_free(L,gco2h(o));break; | ||
2038 | case 8:{ | ||
2039 | luaE_freethread(L,gco2th(o)); | ||
2040 | break; | ||
2041 | } | ||
2042 | case 4:{ | ||
2043 | G(L)->strt.nuse--; | ||
2044 | luaM_freemem(L,o,sizestring(gco2ts(o))); | ||
2045 | break; | ||
2046 | } | ||
2047 | case 7:{ | ||
2048 | luaM_freemem(L,o,sizeudata(gco2u(o))); | ||
2049 | break; | ||
2050 | } | ||
2051 | default:; | ||
2052 | } | ||
2053 | } | ||
2054 | #define sweepwholelist(L,p)sweeplist(L,p,((lu_mem)(~(lu_mem)0)-2)) | ||
2055 | static GCObject**sweeplist(lua_State*L,GCObject**p,lu_mem count){ | ||
2056 | GCObject*curr; | ||
2057 | global_State*g=G(L); | ||
2058 | int deadmask=otherwhite(g); | ||
2059 | while((curr=*p)!=NULL&&count-->0){ | ||
2060 | if(curr->gch.tt==8) | ||
2061 | sweepwholelist(L,&gco2th(curr)->openupval); | ||
2062 | if((curr->gch.marked^bit2mask(0,1))&deadmask){ | ||
2063 | makewhite(g,curr); | ||
2064 | p=&curr->gch.next; | ||
2065 | } | ||
2066 | else{ | ||
2067 | *p=curr->gch.next; | ||
2068 | if(curr==g->rootgc) | ||
2069 | g->rootgc=curr->gch.next; | ||
2070 | freeobj(L,curr); | ||
2071 | } | ||
2072 | } | ||
2073 | return p; | ||
2074 | } | ||
2075 | static void checkSizes(lua_State*L){ | ||
2076 | global_State*g=G(L); | ||
2077 | if(g->strt.nuse<cast(lu_int32,g->strt.size/4)&& | ||
2078 | g->strt.size>32*2) | ||
2079 | luaS_resize(L,g->strt.size/2); | ||
2080 | if(luaZ_sizebuffer(&g->buff)>32*2){ | ||
2081 | size_t newsize=luaZ_sizebuffer(&g->buff)/2; | ||
2082 | luaZ_resizebuffer(L,&g->buff,newsize); | ||
2083 | } | ||
2084 | } | ||
2085 | static void GCTM(lua_State*L){ | ||
2086 | global_State*g=G(L); | ||
2087 | GCObject*o=g->tmudata->gch.next; | ||
2088 | Udata*udata=rawgco2u(o); | ||
2089 | const TValue*tm; | ||
2090 | if(o==g->tmudata) | ||
2091 | g->tmudata=NULL; | ||
2092 | else | ||
2093 | g->tmudata->gch.next=udata->uv.next; | ||
2094 | udata->uv.next=g->mainthread->next; | ||
2095 | g->mainthread->next=o; | ||
2096 | makewhite(g,o); | ||
2097 | tm=fasttm(L,udata->uv.metatable,TM_GC); | ||
2098 | if(tm!=NULL){ | ||
2099 | lu_byte oldah=L->allowhook; | ||
2100 | lu_mem oldt=g->GCthreshold; | ||
2101 | L->allowhook=0; | ||
2102 | g->GCthreshold=2*g->totalbytes; | ||
2103 | setobj(L,L->top,tm); | ||
2104 | setuvalue(L,L->top+1,udata); | ||
2105 | L->top+=2; | ||
2106 | luaD_call(L,L->top-2,0); | ||
2107 | L->allowhook=oldah; | ||
2108 | g->GCthreshold=oldt; | ||
2109 | } | ||
2110 | } | ||
2111 | static void luaC_callGCTM(lua_State*L){ | ||
2112 | while(G(L)->tmudata) | ||
2113 | GCTM(L); | ||
2114 | } | ||
2115 | static void luaC_freeall(lua_State*L){ | ||
2116 | global_State*g=G(L); | ||
2117 | int i; | ||
2118 | g->currentwhite=bit2mask(0,1)|bitmask(6); | ||
2119 | sweepwholelist(L,&g->rootgc); | ||
2120 | for(i=0;i<g->strt.size;i++) | ||
2121 | sweepwholelist(L,&g->strt.hash[i]); | ||
2122 | } | ||
2123 | static void markmt(global_State*g){ | ||
2124 | int i; | ||
2125 | for(i=0;i<(8+1);i++) | ||
2126 | if(g->mt[i])markobject(g,g->mt[i]); | ||
2127 | } | ||
2128 | static void markroot(lua_State*L){ | ||
2129 | global_State*g=G(L); | ||
2130 | g->gray=NULL; | ||
2131 | g->grayagain=NULL; | ||
2132 | g->weak=NULL; | ||
2133 | markobject(g,g->mainthread); | ||
2134 | markvalue(g,gt(g->mainthread)); | ||
2135 | markvalue(g,registry(L)); | ||
2136 | markmt(g); | ||
2137 | g->gcstate=1; | ||
2138 | } | ||
2139 | static void remarkupvals(global_State*g){ | ||
2140 | UpVal*uv; | ||
2141 | for(uv=g->uvhead.u.l.next;uv!=&g->uvhead;uv=uv->u.l.next){ | ||
2142 | if(isgray(obj2gco(uv))) | ||
2143 | markvalue(g,uv->v); | ||
2144 | } | ||
2145 | } | ||
2146 | static void atomic(lua_State*L){ | ||
2147 | global_State*g=G(L); | ||
2148 | size_t udsize; | ||
2149 | remarkupvals(g); | ||
2150 | propagateall(g); | ||
2151 | g->gray=g->weak; | ||
2152 | g->weak=NULL; | ||
2153 | markobject(g,L); | ||
2154 | markmt(g); | ||
2155 | propagateall(g); | ||
2156 | g->gray=g->grayagain; | ||
2157 | g->grayagain=NULL; | ||
2158 | propagateall(g); | ||
2159 | udsize=luaC_separateudata(L,0); | ||
2160 | marktmu(g); | ||
2161 | udsize+=propagateall(g); | ||
2162 | cleartable(g->weak); | ||
2163 | g->currentwhite=cast_byte(otherwhite(g)); | ||
2164 | g->sweepstrgc=0; | ||
2165 | g->sweepgc=&g->rootgc; | ||
2166 | g->gcstate=2; | ||
2167 | g->estimate=g->totalbytes-udsize; | ||
2168 | } | ||
2169 | static l_mem singlestep(lua_State*L){ | ||
2170 | global_State*g=G(L); | ||
2171 | switch(g->gcstate){ | ||
2172 | case 0:{ | ||
2173 | markroot(L); | ||
2174 | return 0; | ||
2175 | } | ||
2176 | case 1:{ | ||
2177 | if(g->gray) | ||
2178 | return propagatemark(g); | ||
2179 | else{ | ||
2180 | atomic(L); | ||
2181 | return 0; | ||
2182 | } | ||
2183 | } | ||
2184 | case 2:{ | ||
2185 | lu_mem old=g->totalbytes; | ||
2186 | sweepwholelist(L,&g->strt.hash[g->sweepstrgc++]); | ||
2187 | if(g->sweepstrgc>=g->strt.size) | ||
2188 | g->gcstate=3; | ||
2189 | g->estimate-=old-g->totalbytes; | ||
2190 | return 10; | ||
2191 | } | ||
2192 | case 3:{ | ||
2193 | lu_mem old=g->totalbytes; | ||
2194 | g->sweepgc=sweeplist(L,g->sweepgc,40); | ||
2195 | if(*g->sweepgc==NULL){ | ||
2196 | checkSizes(L); | ||
2197 | g->gcstate=4; | ||
2198 | } | ||
2199 | g->estimate-=old-g->totalbytes; | ||
2200 | return 40*10; | ||
2201 | } | ||
2202 | case 4:{ | ||
2203 | if(g->tmudata){ | ||
2204 | GCTM(L); | ||
2205 | if(g->estimate>100) | ||
2206 | g->estimate-=100; | ||
2207 | return 100; | ||
2208 | } | ||
2209 | else{ | ||
2210 | g->gcstate=0; | ||
2211 | g->gcdept=0; | ||
2212 | return 0; | ||
2213 | } | ||
2214 | } | ||
2215 | default:return 0; | ||
2216 | } | ||
2217 | } | ||
2218 | static void luaC_step(lua_State*L){ | ||
2219 | global_State*g=G(L); | ||
2220 | l_mem lim=(1024u/100)*g->gcstepmul; | ||
2221 | if(lim==0) | ||
2222 | lim=(((lu_mem)(~(lu_mem)0)-2)-1)/2; | ||
2223 | g->gcdept+=g->totalbytes-g->GCthreshold; | ||
2224 | do{ | ||
2225 | lim-=singlestep(L); | ||
2226 | if(g->gcstate==0) | ||
2227 | break; | ||
2228 | }while(lim>0); | ||
2229 | if(g->gcstate!=0){ | ||
2230 | if(g->gcdept<1024u) | ||
2231 | g->GCthreshold=g->totalbytes+1024u; | ||
2232 | else{ | ||
2233 | g->gcdept-=1024u; | ||
2234 | g->GCthreshold=g->totalbytes; | ||
2235 | } | ||
2236 | } | ||
2237 | else{ | ||
2238 | setthreshold(g); | ||
2239 | } | ||
2240 | } | ||
2241 | static void luaC_barrierf(lua_State*L,GCObject*o,GCObject*v){ | ||
2242 | global_State*g=G(L); | ||
2243 | if(g->gcstate==1) | ||
2244 | reallymarkobject(g,v); | ||
2245 | else | ||
2246 | makewhite(g,o); | ||
2247 | } | ||
2248 | static void luaC_barrierback(lua_State*L,Table*t){ | ||
2249 | global_State*g=G(L); | ||
2250 | GCObject*o=obj2gco(t); | ||
2251 | black2gray(o); | ||
2252 | t->gclist=g->grayagain; | ||
2253 | g->grayagain=o; | ||
2254 | } | ||
2255 | static void luaC_link(lua_State*L,GCObject*o,lu_byte tt){ | ||
2256 | global_State*g=G(L); | ||
2257 | o->gch.next=g->rootgc; | ||
2258 | g->rootgc=o; | ||
2259 | o->gch.marked=luaC_white(g); | ||
2260 | o->gch.tt=tt; | ||
2261 | } | ||
2262 | static void luaC_linkupval(lua_State*L,UpVal*uv){ | ||
2263 | global_State*g=G(L); | ||
2264 | GCObject*o=obj2gco(uv); | ||
2265 | o->gch.next=g->rootgc; | ||
2266 | g->rootgc=o; | ||
2267 | if(isgray(o)){ | ||
2268 | if(g->gcstate==1){ | ||
2269 | gray2black(o); | ||
2270 | luaC_barrier(L,uv,uv->v); | ||
2271 | } | ||
2272 | else{ | ||
2273 | makewhite(g,o); | ||
2274 | } | ||
2275 | } | ||
2276 | } | ||
2277 | typedef union{ | ||
2278 | lua_Number r; | ||
2279 | TString*ts; | ||
2280 | }SemInfo; | ||
2281 | typedef struct Token{ | ||
2282 | int token; | ||
2283 | SemInfo seminfo; | ||
2284 | }Token; | ||
2285 | typedef struct LexState{ | ||
2286 | int current; | ||
2287 | int linenumber; | ||
2288 | int lastline; | ||
2289 | Token t; | ||
2290 | Token lookahead; | ||
2291 | struct FuncState*fs; | ||
2292 | struct lua_State*L; | ||
2293 | ZIO*z; | ||
2294 | Mbuffer*buff; | ||
2295 | TString*source; | ||
2296 | char decpoint; | ||
2297 | }LexState; | ||
2298 | static void luaX_init(lua_State*L); | ||
2299 | static void luaX_lexerror(LexState*ls,const char*msg,int token); | ||
2300 | #define state_size(x)(sizeof(x)+0) | ||
2301 | #define fromstate(l)(cast(lu_byte*,(l))-0) | ||
2302 | #define tostate(l)(cast(lua_State*,cast(lu_byte*,l)+0)) | ||
2303 | typedef struct LG{ | ||
2304 | lua_State l; | ||
2305 | global_State g; | ||
2306 | }LG; | ||
2307 | static void stack_init(lua_State*L1,lua_State*L){ | ||
2308 | L1->base_ci=luaM_newvector(L,8,CallInfo); | ||
2309 | L1->ci=L1->base_ci; | ||
2310 | L1->size_ci=8; | ||
2311 | L1->end_ci=L1->base_ci+L1->size_ci-1; | ||
2312 | L1->stack=luaM_newvector(L,(2*20)+5,TValue); | ||
2313 | L1->stacksize=(2*20)+5; | ||
2314 | L1->top=L1->stack; | ||
2315 | L1->stack_last=L1->stack+(L1->stacksize-5)-1; | ||
2316 | L1->ci->func=L1->top; | ||
2317 | setnilvalue(L1->top++); | ||
2318 | L1->base=L1->ci->base=L1->top; | ||
2319 | L1->ci->top=L1->top+20; | ||
2320 | } | ||
2321 | static void freestack(lua_State*L,lua_State*L1){ | ||
2322 | luaM_freearray(L,L1->base_ci,L1->size_ci,CallInfo); | ||
2323 | luaM_freearray(L,L1->stack,L1->stacksize,TValue); | ||
2324 | } | ||
2325 | static void f_luaopen(lua_State*L,void*ud){ | ||
2326 | global_State*g=G(L); | ||
2327 | UNUSED(ud); | ||
2328 | stack_init(L,L); | ||
2329 | sethvalue(L,gt(L),luaH_new(L,0,2)); | ||
2330 | sethvalue(L,registry(L),luaH_new(L,0,2)); | ||
2331 | luaS_resize(L,32); | ||
2332 | luaT_init(L); | ||
2333 | luaX_init(L); | ||
2334 | luaS_fix(luaS_newliteral(L,"not enough memory")); | ||
2335 | g->GCthreshold=4*g->totalbytes; | ||
2336 | } | ||
2337 | static void preinit_state(lua_State*L,global_State*g){ | ||
2338 | G(L)=g; | ||
2339 | L->stack=NULL; | ||
2340 | L->stacksize=0; | ||
2341 | L->errorJmp=NULL; | ||
2342 | L->hook=NULL; | ||
2343 | L->hookmask=0; | ||
2344 | L->basehookcount=0; | ||
2345 | L->allowhook=1; | ||
2346 | resethookcount(L); | ||
2347 | L->openupval=NULL; | ||
2348 | L->size_ci=0; | ||
2349 | L->nCcalls=L->baseCcalls=0; | ||
2350 | L->status=0; | ||
2351 | L->base_ci=L->ci=NULL; | ||
2352 | L->savedpc=NULL; | ||
2353 | L->errfunc=0; | ||
2354 | setnilvalue(gt(L)); | ||
2355 | } | ||
2356 | static void close_state(lua_State*L){ | ||
2357 | global_State*g=G(L); | ||
2358 | luaF_close(L,L->stack); | ||
2359 | luaC_freeall(L); | ||
2360 | luaM_freearray(L,G(L)->strt.hash,G(L)->strt.size,TString*); | ||
2361 | luaZ_freebuffer(L,&g->buff); | ||
2362 | freestack(L,L); | ||
2363 | (*g->frealloc)(g->ud,fromstate(L),state_size(LG),0); | ||
2364 | } | ||
2365 | static lua_State*luaE_newthread(lua_State*L){ | ||
2366 | lua_State*L1=tostate(luaM_malloc(L,state_size(lua_State))); | ||
2367 | luaC_link(L,obj2gco(L1),8); | ||
2368 | preinit_state(L1,G(L)); | ||
2369 | stack_init(L1,L); | ||
2370 | setobj(L,gt(L1),gt(L)); | ||
2371 | L1->hookmask=L->hookmask; | ||
2372 | L1->basehookcount=L->basehookcount; | ||
2373 | L1->hook=L->hook; | ||
2374 | resethookcount(L1); | ||
2375 | return L1; | ||
2376 | } | ||
2377 | static void luaE_freethread(lua_State*L,lua_State*L1){ | ||
2378 | luaF_close(L1,L1->stack); | ||
2379 | freestack(L,L1); | ||
2380 | luaM_freemem(L,fromstate(L1),state_size(lua_State)); | ||
2381 | } | ||
2382 | static lua_State*lua_newstate(lua_Alloc f,void*ud){ | ||
2383 | int i; | ||
2384 | lua_State*L; | ||
2385 | global_State*g; | ||
2386 | void*l=(*f)(ud,NULL,0,state_size(LG)); | ||
2387 | if(l==NULL)return NULL; | ||
2388 | L=tostate(l); | ||
2389 | g=&((LG*)L)->g; | ||
2390 | L->next=NULL; | ||
2391 | L->tt=8; | ||
2392 | g->currentwhite=bit2mask(0,5); | ||
2393 | L->marked=luaC_white(g); | ||
2394 | set2bits(L->marked,5,6); | ||
2395 | preinit_state(L,g); | ||
2396 | g->frealloc=f; | ||
2397 | g->ud=ud; | ||
2398 | g->mainthread=L; | ||
2399 | g->uvhead.u.l.prev=&g->uvhead; | ||
2400 | g->uvhead.u.l.next=&g->uvhead; | ||
2401 | g->GCthreshold=0; | ||
2402 | g->strt.size=0; | ||
2403 | g->strt.nuse=0; | ||
2404 | g->strt.hash=NULL; | ||
2405 | setnilvalue(registry(L)); | ||
2406 | luaZ_initbuffer(L,&g->buff); | ||
2407 | g->panic=NULL; | ||
2408 | g->gcstate=0; | ||
2409 | g->rootgc=obj2gco(L); | ||
2410 | g->sweepstrgc=0; | ||
2411 | g->sweepgc=&g->rootgc; | ||
2412 | g->gray=NULL; | ||
2413 | g->grayagain=NULL; | ||
2414 | g->weak=NULL; | ||
2415 | g->tmudata=NULL; | ||
2416 | g->totalbytes=sizeof(LG); | ||
2417 | g->gcpause=200; | ||
2418 | g->gcstepmul=200; | ||
2419 | g->gcdept=0; | ||
2420 | for(i=0;i<(8+1);i++)g->mt[i]=NULL; | ||
2421 | if(luaD_rawrunprotected(L,f_luaopen,NULL)!=0){ | ||
2422 | close_state(L); | ||
2423 | L=NULL; | ||
2424 | } | ||
2425 | else | ||
2426 | {} | ||
2427 | return L; | ||
2428 | } | ||
2429 | static void callallgcTM(lua_State*L,void*ud){ | ||
2430 | UNUSED(ud); | ||
2431 | luaC_callGCTM(L); | ||
2432 | } | ||
2433 | static void lua_close(lua_State*L){ | ||
2434 | L=G(L)->mainthread; | ||
2435 | luaF_close(L,L->stack); | ||
2436 | luaC_separateudata(L,1); | ||
2437 | L->errfunc=0; | ||
2438 | do{ | ||
2439 | L->ci=L->base_ci; | ||
2440 | L->base=L->top=L->ci->base; | ||
2441 | L->nCcalls=L->baseCcalls=0; | ||
2442 | }while(luaD_rawrunprotected(L,callallgcTM,NULL)!=0); | ||
2443 | close_state(L); | ||
2444 | } | ||
2445 | #define getcode(fs,e)((fs)->f->code[(e)->u.s.info]) | ||
2446 | #define luaK_codeAsBx(fs,o,A,sBx)luaK_codeABx(fs,o,A,(sBx)+(((1<<(9+9))-1)>>1)) | ||
2447 | #define luaK_setmultret(fs,e)luaK_setreturns(fs,e,(-1)) | ||
2448 | static int luaK_codeABx(FuncState*fs,OpCode o,int A,unsigned int Bx); | ||
2449 | static int luaK_codeABC(FuncState*fs,OpCode o,int A,int B,int C); | ||
2450 | static void luaK_setreturns(FuncState*fs,expdesc*e,int nresults); | ||
2451 | static void luaK_patchtohere(FuncState*fs,int list); | ||
2452 | static void luaK_concat(FuncState*fs,int*l1,int l2); | ||
2453 | static int currentpc(lua_State*L,CallInfo*ci){ | ||
2454 | if(!isLua(ci))return-1; | ||
2455 | if(ci==L->ci) | ||
2456 | ci->savedpc=L->savedpc; | ||
2457 | return pcRel(ci->savedpc,ci_func(ci)->l.p); | ||
2458 | } | ||
2459 | static int currentline(lua_State*L,CallInfo*ci){ | ||
2460 | int pc=currentpc(L,ci); | ||
2461 | if(pc<0) | ||
2462 | return-1; | ||
2463 | else | ||
2464 | return getline_(ci_func(ci)->l.p,pc); | ||
2465 | } | ||
2466 | static int lua_getstack(lua_State*L,int level,lua_Debug*ar){ | ||
2467 | int status; | ||
2468 | CallInfo*ci; | ||
2469 | for(ci=L->ci;level>0&&ci>L->base_ci;ci--){ | ||
2470 | level--; | ||
2471 | if(f_isLua(ci)) | ||
2472 | level-=ci->tailcalls; | ||
2473 | } | ||
2474 | if(level==0&&ci>L->base_ci){ | ||
2475 | status=1; | ||
2476 | ar->i_ci=cast_int(ci-L->base_ci); | ||
2477 | } | ||
2478 | else if(level<0){ | ||
2479 | status=1; | ||
2480 | ar->i_ci=0; | ||
2481 | } | ||
2482 | else status=0; | ||
2483 | return status; | ||
2484 | } | ||
2485 | static Proto*getluaproto(CallInfo*ci){ | ||
2486 | return(isLua(ci)?ci_func(ci)->l.p:NULL); | ||
2487 | } | ||
2488 | static void funcinfo(lua_Debug*ar,Closure*cl){ | ||
2489 | if(cl->c.isC){ | ||
2490 | ar->source="=[C]"; | ||
2491 | ar->linedefined=-1; | ||
2492 | ar->lastlinedefined=-1; | ||
2493 | ar->what="C"; | ||
2494 | } | ||
2495 | else{ | ||
2496 | ar->source=getstr(cl->l.p->source); | ||
2497 | ar->linedefined=cl->l.p->linedefined; | ||
2498 | ar->lastlinedefined=cl->l.p->lastlinedefined; | ||
2499 | ar->what=(ar->linedefined==0)?"main":"Lua"; | ||
2500 | } | ||
2501 | luaO_chunkid(ar->short_src,ar->source,60); | ||
2502 | } | ||
2503 | static void info_tailcall(lua_Debug*ar){ | ||
2504 | ar->name=ar->namewhat=""; | ||
2505 | ar->what="tail"; | ||
2506 | ar->lastlinedefined=ar->linedefined=ar->currentline=-1; | ||
2507 | ar->source="=(tail call)"; | ||
2508 | luaO_chunkid(ar->short_src,ar->source,60); | ||
2509 | ar->nups=0; | ||
2510 | } | ||
2511 | static void collectvalidlines(lua_State*L,Closure*f){ | ||
2512 | if(f==NULL||f->c.isC){ | ||
2513 | setnilvalue(L->top); | ||
2514 | } | ||
2515 | else{ | ||
2516 | Table*t=luaH_new(L,0,0); | ||
2517 | int*lineinfo=f->l.p->lineinfo; | ||
2518 | int i; | ||
2519 | for(i=0;i<f->l.p->sizelineinfo;i++) | ||
2520 | setbvalue(luaH_setnum(L,t,lineinfo[i]),1); | ||
2521 | sethvalue(L,L->top,t); | ||
2522 | } | ||
2523 | incr_top(L); | ||
2524 | } | ||
2525 | static int auxgetinfo(lua_State*L,const char*what,lua_Debug*ar, | ||
2526 | Closure*f,CallInfo*ci){ | ||
2527 | int status=1; | ||
2528 | if(f==NULL){ | ||
2529 | info_tailcall(ar); | ||
2530 | return status; | ||
2531 | } | ||
2532 | for(;*what;what++){ | ||
2533 | switch(*what){ | ||
2534 | case'S':{ | ||
2535 | funcinfo(ar,f); | ||
2536 | break; | ||
2537 | } | ||
2538 | case'l':{ | ||
2539 | ar->currentline=(ci)?currentline(L,ci):-1; | ||
2540 | break; | ||
2541 | } | ||
2542 | case'u':{ | ||
2543 | ar->nups=f->c.nupvalues; | ||
2544 | break; | ||
2545 | } | ||
2546 | case'n':{ | ||
2547 | ar->namewhat=(ci)?NULL:NULL; | ||
2548 | if(ar->namewhat==NULL){ | ||
2549 | ar->namewhat=""; | ||
2550 | ar->name=NULL; | ||
2551 | } | ||
2552 | break; | ||
2553 | } | ||
2554 | case'L': | ||
2555 | case'f': | ||
2556 | break; | ||
2557 | default:status=0; | ||
2558 | } | ||
2559 | } | ||
2560 | return status; | ||
2561 | } | ||
2562 | static int lua_getinfo(lua_State*L,const char*what,lua_Debug*ar){ | ||
2563 | int status; | ||
2564 | Closure*f=NULL; | ||
2565 | CallInfo*ci=NULL; | ||
2566 | if(*what=='>'){ | ||
2567 | StkId func=L->top-1; | ||
2568 | luai_apicheck(L,ttisfunction(func)); | ||
2569 | what++; | ||
2570 | f=clvalue(func); | ||
2571 | L->top--; | ||
2572 | } | ||
2573 | else if(ar->i_ci!=0){ | ||
2574 | ci=L->base_ci+ar->i_ci; | ||
2575 | f=clvalue(ci->func); | ||
2576 | } | ||
2577 | status=auxgetinfo(L,what,ar,f,ci); | ||
2578 | if(strchr(what,'f')){ | ||
2579 | if(f==NULL)setnilvalue(L->top); | ||
2580 | else setclvalue(L,L->top,f); | ||
2581 | incr_top(L); | ||
2582 | } | ||
2583 | if(strchr(what,'L')) | ||
2584 | collectvalidlines(L,f); | ||
2585 | return status; | ||
2586 | } | ||
2587 | static int isinstack(CallInfo*ci,const TValue*o){ | ||
2588 | StkId p; | ||
2589 | for(p=ci->base;p<ci->top;p++) | ||
2590 | if(o==p)return 1; | ||
2591 | return 0; | ||
2592 | } | ||
2593 | static void luaG_typeerror(lua_State*L,const TValue*o,const char*op){ | ||
2594 | const char*name=NULL; | ||
2595 | const char*t=luaT_typenames[ttype(o)]; | ||
2596 | const char*kind=(isinstack(L->ci,o))? | ||
2597 | NULL: | ||
2598 | NULL; | ||
2599 | if(kind) | ||
2600 | luaG_runerror(L,"attempt to %s %s "LUA_QL("%s")" (a %s value)", | ||
2601 | op,kind,name,t); | ||
2602 | else | ||
2603 | luaG_runerror(L,"attempt to %s a %s value",op,t); | ||
2604 | } | ||
2605 | static void luaG_concaterror(lua_State*L,StkId p1,StkId p2){ | ||
2606 | if(ttisstring(p1)||ttisnumber(p1))p1=p2; | ||
2607 | luaG_typeerror(L,p1,"concatenate"); | ||
2608 | } | ||
2609 | static void luaG_aritherror(lua_State*L,const TValue*p1,const TValue*p2){ | ||
2610 | TValue temp; | ||
2611 | if(luaV_tonumber(p1,&temp)==NULL) | ||
2612 | p2=p1; | ||
2613 | luaG_typeerror(L,p2,"perform arithmetic on"); | ||
2614 | } | ||
2615 | static int luaG_ordererror(lua_State*L,const TValue*p1,const TValue*p2){ | ||
2616 | const char*t1=luaT_typenames[ttype(p1)]; | ||
2617 | const char*t2=luaT_typenames[ttype(p2)]; | ||
2618 | if(t1[2]==t2[2]) | ||
2619 | luaG_runerror(L,"attempt to compare two %s values",t1); | ||
2620 | else | ||
2621 | luaG_runerror(L,"attempt to compare %s with %s",t1,t2); | ||
2622 | return 0; | ||
2623 | } | ||
2624 | static void addinfo(lua_State*L,const char*msg){ | ||
2625 | CallInfo*ci=L->ci; | ||
2626 | if(isLua(ci)){ | ||
2627 | char buff[60]; | ||
2628 | int line=currentline(L,ci); | ||
2629 | luaO_chunkid(buff,getstr(getluaproto(ci)->source),60); | ||
2630 | luaO_pushfstring(L,"%s:%d: %s",buff,line,msg); | ||
2631 | } | ||
2632 | } | ||
2633 | static void luaG_errormsg(lua_State*L){ | ||
2634 | if(L->errfunc!=0){ | ||
2635 | StkId errfunc=restorestack(L,L->errfunc); | ||
2636 | if(!ttisfunction(errfunc))luaD_throw(L,5); | ||
2637 | setobj(L,L->top,L->top-1); | ||
2638 | setobj(L,L->top-1,errfunc); | ||
2639 | incr_top(L); | ||
2640 | luaD_call(L,L->top-2,1); | ||
2641 | } | ||
2642 | luaD_throw(L,2); | ||
2643 | } | ||
2644 | static void luaG_runerror(lua_State*L,const char*fmt,...){ | ||
2645 | va_list argp; | ||
2646 | va_start(argp,fmt); | ||
2647 | addinfo(L,luaO_pushvfstring(L,fmt,argp)); | ||
2648 | va_end(argp); | ||
2649 | luaG_errormsg(L); | ||
2650 | } | ||
2651 | static int luaZ_fill(ZIO*z){ | ||
2652 | size_t size; | ||
2653 | lua_State*L=z->L; | ||
2654 | const char*buff; | ||
2655 | buff=z->reader(L,z->data,&size); | ||
2656 | if(buff==NULL||size==0)return(-1); | ||
2657 | z->n=size-1; | ||
2658 | z->p=buff; | ||
2659 | return char2int(*(z->p++)); | ||
2660 | } | ||
2661 | static void luaZ_init(lua_State*L,ZIO*z,lua_Reader reader,void*data){ | ||
2662 | z->L=L; | ||
2663 | z->reader=reader; | ||
2664 | z->data=data; | ||
2665 | z->n=0; | ||
2666 | z->p=NULL; | ||
2667 | } | ||
2668 | static char*luaZ_openspace(lua_State*L,Mbuffer*buff,size_t n){ | ||
2669 | if(n>buff->buffsize){ | ||
2670 | if(n<32)n=32; | ||
2671 | luaZ_resizebuffer(L,buff,n); | ||
2672 | } | ||
2673 | return buff->buffer; | ||
2674 | } | ||
2675 | #define opmode(t,a,b,c,m)(((t)<<7)|((a)<<6)|((b)<<4)|((c)<<2)|(m)) | ||
2676 | static const lu_byte luaP_opmodes[(cast(int,OP_VARARG)+1)]={ | ||
2677 | opmode(0,1,OpArgR,OpArgN,iABC) | ||
2678 | ,opmode(0,1,OpArgK,OpArgN,iABx) | ||
2679 | ,opmode(0,1,OpArgU,OpArgU,iABC) | ||
2680 | ,opmode(0,1,OpArgR,OpArgN,iABC) | ||
2681 | ,opmode(0,1,OpArgU,OpArgN,iABC) | ||
2682 | ,opmode(0,1,OpArgK,OpArgN,iABx) | ||
2683 | ,opmode(0,1,OpArgR,OpArgK,iABC) | ||
2684 | ,opmode(0,0,OpArgK,OpArgN,iABx) | ||
2685 | ,opmode(0,0,OpArgU,OpArgN,iABC) | ||
2686 | ,opmode(0,0,OpArgK,OpArgK,iABC) | ||
2687 | ,opmode(0,1,OpArgU,OpArgU,iABC) | ||
2688 | ,opmode(0,1,OpArgR,OpArgK,iABC) | ||
2689 | ,opmode(0,1,OpArgK,OpArgK,iABC) | ||
2690 | ,opmode(0,1,OpArgK,OpArgK,iABC) | ||
2691 | ,opmode(0,1,OpArgK,OpArgK,iABC) | ||
2692 | ,opmode(0,1,OpArgK,OpArgK,iABC) | ||
2693 | ,opmode(0,1,OpArgK,OpArgK,iABC) | ||
2694 | ,opmode(0,1,OpArgK,OpArgK,iABC) | ||
2695 | ,opmode(0,1,OpArgR,OpArgN,iABC) | ||
2696 | ,opmode(0,1,OpArgR,OpArgN,iABC) | ||
2697 | ,opmode(0,1,OpArgR,OpArgN,iABC) | ||
2698 | ,opmode(0,1,OpArgR,OpArgR,iABC) | ||
2699 | ,opmode(0,0,OpArgR,OpArgN,iAsBx) | ||
2700 | ,opmode(1,0,OpArgK,OpArgK,iABC) | ||
2701 | ,opmode(1,0,OpArgK,OpArgK,iABC) | ||
2702 | ,opmode(1,0,OpArgK,OpArgK,iABC) | ||
2703 | ,opmode(1,1,OpArgR,OpArgU,iABC) | ||
2704 | ,opmode(1,1,OpArgR,OpArgU,iABC) | ||
2705 | ,opmode(0,1,OpArgU,OpArgU,iABC) | ||
2706 | ,opmode(0,1,OpArgU,OpArgU,iABC) | ||
2707 | ,opmode(0,0,OpArgU,OpArgN,iABC) | ||
2708 | ,opmode(0,1,OpArgR,OpArgN,iAsBx) | ||
2709 | ,opmode(0,1,OpArgR,OpArgN,iAsBx) | ||
2710 | ,opmode(1,0,OpArgN,OpArgU,iABC) | ||
2711 | ,opmode(0,0,OpArgU,OpArgU,iABC) | ||
2712 | ,opmode(0,0,OpArgN,OpArgN,iABC) | ||
2713 | ,opmode(0,1,OpArgU,OpArgN,iABx) | ||
2714 | ,opmode(0,1,OpArgU,OpArgN,iABC) | ||
2715 | }; | ||
2716 | #define next(ls)(ls->current=zgetc(ls->z)) | ||
2717 | #define currIsNewline(ls)(ls->current=='\n'||ls->current=='\r') | ||
2718 | static const char*const luaX_tokens[]={ | ||
2719 | "and","break","do","else","elseif", | ||
2720 | "end","false","for","function","if", | ||
2721 | "in","local","nil","not","or","repeat", | ||
2722 | "return","then","true","until","while", | ||
2723 | "..","...","==",">=","<=","~=", | ||
2724 | "<number>","<name>","<string>","<eof>", | ||
2725 | NULL | ||
2726 | }; | ||
2727 | #define save_and_next(ls)(save(ls,ls->current),next(ls)) | ||
2728 | static void save(LexState*ls,int c){ | ||
2729 | Mbuffer*b=ls->buff; | ||
2730 | if(b->n+1>b->buffsize){ | ||
2731 | size_t newsize; | ||
2732 | if(b->buffsize>=((size_t)(~(size_t)0)-2)/2) | ||
2733 | luaX_lexerror(ls,"lexical element too long",0); | ||
2734 | newsize=b->buffsize*2; | ||
2735 | luaZ_resizebuffer(ls->L,b,newsize); | ||
2736 | } | ||
2737 | b->buffer[b->n++]=cast(char,c); | ||
2738 | } | ||
2739 | static void luaX_init(lua_State*L){ | ||
2740 | int i; | ||
2741 | for(i=0;i<(cast(int,TK_WHILE-257+1));i++){ | ||
2742 | TString*ts=luaS_new(L,luaX_tokens[i]); | ||
2743 | luaS_fix(ts); | ||
2744 | ts->tsv.reserved=cast_byte(i+1); | ||
2745 | } | ||
2746 | } | ||
2747 | static const char*luaX_token2str(LexState*ls,int token){ | ||
2748 | if(token<257){ | ||
2749 | return(iscntrl(token))?luaO_pushfstring(ls->L,"char(%d)",token): | ||
2750 | luaO_pushfstring(ls->L,"%c",token); | ||
2751 | } | ||
2752 | else | ||
2753 | return luaX_tokens[token-257]; | ||
2754 | } | ||
2755 | static const char*txtToken(LexState*ls,int token){ | ||
2756 | switch(token){ | ||
2757 | case TK_NAME: | ||
2758 | case TK_STRING: | ||
2759 | case TK_NUMBER: | ||
2760 | save(ls,'\0'); | ||
2761 | return luaZ_buffer(ls->buff); | ||
2762 | default: | ||
2763 | return luaX_token2str(ls,token); | ||
2764 | } | ||
2765 | } | ||
2766 | static void luaX_lexerror(LexState*ls,const char*msg,int token){ | ||
2767 | char buff[80]; | ||
2768 | luaO_chunkid(buff,getstr(ls->source),80); | ||
2769 | msg=luaO_pushfstring(ls->L,"%s:%d: %s",buff,ls->linenumber,msg); | ||
2770 | if(token) | ||
2771 | luaO_pushfstring(ls->L,"%s near "LUA_QL("%s"),msg,txtToken(ls,token)); | ||
2772 | luaD_throw(ls->L,3); | ||
2773 | } | ||
2774 | static void luaX_syntaxerror(LexState*ls,const char*msg){ | ||
2775 | luaX_lexerror(ls,msg,ls->t.token); | ||
2776 | } | ||
2777 | static TString*luaX_newstring(LexState*ls,const char*str,size_t l){ | ||
2778 | lua_State*L=ls->L; | ||
2779 | TString*ts=luaS_newlstr(L,str,l); | ||
2780 | TValue*o=luaH_setstr(L,ls->fs->h,ts); | ||
2781 | if(ttisnil(o)){ | ||
2782 | setbvalue(o,1); | ||
2783 | luaC_checkGC(L); | ||
2784 | } | ||
2785 | return ts; | ||
2786 | } | ||
2787 | static void inclinenumber(LexState*ls){ | ||
2788 | int old=ls->current; | ||
2789 | next(ls); | ||
2790 | if(currIsNewline(ls)&&ls->current!=old) | ||
2791 | next(ls); | ||
2792 | if(++ls->linenumber>=(INT_MAX-2)) | ||
2793 | luaX_syntaxerror(ls,"chunk has too many lines"); | ||
2794 | } | ||
2795 | static void luaX_setinput(lua_State*L,LexState*ls,ZIO*z,TString*source){ | ||
2796 | ls->decpoint='.'; | ||
2797 | ls->L=L; | ||
2798 | ls->lookahead.token=TK_EOS; | ||
2799 | ls->z=z; | ||
2800 | ls->fs=NULL; | ||
2801 | ls->linenumber=1; | ||
2802 | ls->lastline=1; | ||
2803 | ls->source=source; | ||
2804 | luaZ_resizebuffer(ls->L,ls->buff,32); | ||
2805 | next(ls); | ||
2806 | } | ||
2807 | static int check_next(LexState*ls,const char*set){ | ||
2808 | if(!strchr(set,ls->current)) | ||
2809 | return 0; | ||
2810 | save_and_next(ls); | ||
2811 | return 1; | ||
2812 | } | ||
2813 | static void buffreplace(LexState*ls,char from,char to){ | ||
2814 | size_t n=luaZ_bufflen(ls->buff); | ||
2815 | char*p=luaZ_buffer(ls->buff); | ||
2816 | while(n--) | ||
2817 | if(p[n]==from)p[n]=to; | ||
2818 | } | ||
2819 | static void read_numeral(LexState*ls,SemInfo*seminfo){ | ||
2820 | do{ | ||
2821 | save_and_next(ls); | ||
2822 | }while(isdigit(ls->current)||ls->current=='.'); | ||
2823 | if(check_next(ls,"Ee")) | ||
2824 | check_next(ls,"+-"); | ||
2825 | while(isalnum(ls->current)||ls->current=='_') | ||
2826 | save_and_next(ls); | ||
2827 | save(ls,'\0'); | ||
2828 | buffreplace(ls,'.',ls->decpoint); | ||
2829 | if(!luaO_str2d(luaZ_buffer(ls->buff),&seminfo->r)) | ||
2830 | luaX_lexerror(ls,"malformed number",TK_NUMBER); | ||
2831 | } | ||
2832 | static int skip_sep(LexState*ls){ | ||
2833 | int count=0; | ||
2834 | int s=ls->current; | ||
2835 | save_and_next(ls); | ||
2836 | while(ls->current=='='){ | ||
2837 | save_and_next(ls); | ||
2838 | count++; | ||
2839 | } | ||
2840 | return(ls->current==s)?count:(-count)-1; | ||
2841 | } | ||
2842 | static void read_long_string(LexState*ls,SemInfo*seminfo,int sep){ | ||
2843 | int cont=0; | ||
2844 | (void)(cont); | ||
2845 | save_and_next(ls); | ||
2846 | if(currIsNewline(ls)) | ||
2847 | inclinenumber(ls); | ||
2848 | for(;;){ | ||
2849 | switch(ls->current){ | ||
2850 | case(-1): | ||
2851 | luaX_lexerror(ls,(seminfo)?"unfinished long string": | ||
2852 | "unfinished long comment",TK_EOS); | ||
2853 | break; | ||
2854 | case']':{ | ||
2855 | if(skip_sep(ls)==sep){ | ||
2856 | save_and_next(ls); | ||
2857 | goto endloop; | ||
2858 | } | ||
2859 | break; | ||
2860 | } | ||
2861 | case'\n': | ||
2862 | case'\r':{ | ||
2863 | save(ls,'\n'); | ||
2864 | inclinenumber(ls); | ||
2865 | if(!seminfo)luaZ_resetbuffer(ls->buff); | ||
2866 | break; | ||
2867 | } | ||
2868 | default:{ | ||
2869 | if(seminfo)save_and_next(ls); | ||
2870 | else next(ls); | ||
2871 | } | ||
2872 | } | ||
2873 | }endloop: | ||
2874 | if(seminfo) | ||
2875 | seminfo->ts=luaX_newstring(ls,luaZ_buffer(ls->buff)+(2+sep), | ||
2876 | luaZ_bufflen(ls->buff)-2*(2+sep)); | ||
2877 | } | ||
2878 | static void read_string(LexState*ls,int del,SemInfo*seminfo){ | ||
2879 | save_and_next(ls); | ||
2880 | while(ls->current!=del){ | ||
2881 | switch(ls->current){ | ||
2882 | case(-1): | ||
2883 | luaX_lexerror(ls,"unfinished string",TK_EOS); | ||
2884 | continue; | ||
2885 | case'\n': | ||
2886 | case'\r': | ||
2887 | luaX_lexerror(ls,"unfinished string",TK_STRING); | ||
2888 | continue; | ||
2889 | case'\\':{ | ||
2890 | int c; | ||
2891 | next(ls); | ||
2892 | switch(ls->current){ | ||
2893 | case'a':c='\a';break; | ||
2894 | case'b':c='\b';break; | ||
2895 | case'f':c='\f';break; | ||
2896 | case'n':c='\n';break; | ||
2897 | case'r':c='\r';break; | ||
2898 | case't':c='\t';break; | ||
2899 | case'v':c='\v';break; | ||
2900 | case'\n': | ||
2901 | case'\r':save(ls,'\n');inclinenumber(ls);continue; | ||
2902 | case(-1):continue; | ||
2903 | default:{ | ||
2904 | if(!isdigit(ls->current)) | ||
2905 | save_and_next(ls); | ||
2906 | else{ | ||
2907 | int i=0; | ||
2908 | c=0; | ||
2909 | do{ | ||
2910 | c=10*c+(ls->current-'0'); | ||
2911 | next(ls); | ||
2912 | }while(++i<3&&isdigit(ls->current)); | ||
2913 | if(c>UCHAR_MAX) | ||
2914 | luaX_lexerror(ls,"escape sequence too large",TK_STRING); | ||
2915 | save(ls,c); | ||
2916 | } | ||
2917 | continue; | ||
2918 | } | ||
2919 | } | ||
2920 | save(ls,c); | ||
2921 | next(ls); | ||
2922 | continue; | ||
2923 | } | ||
2924 | default: | ||
2925 | save_and_next(ls); | ||
2926 | } | ||
2927 | } | ||
2928 | save_and_next(ls); | ||
2929 | seminfo->ts=luaX_newstring(ls,luaZ_buffer(ls->buff)+1, | ||
2930 | luaZ_bufflen(ls->buff)-2); | ||
2931 | } | ||
2932 | static int llex(LexState*ls,SemInfo*seminfo){ | ||
2933 | luaZ_resetbuffer(ls->buff); | ||
2934 | for(;;){ | ||
2935 | switch(ls->current){ | ||
2936 | case'\n': | ||
2937 | case'\r':{ | ||
2938 | inclinenumber(ls); | ||
2939 | continue; | ||
2940 | } | ||
2941 | case'-':{ | ||
2942 | next(ls); | ||
2943 | if(ls->current!='-')return'-'; | ||
2944 | next(ls); | ||
2945 | if(ls->current=='['){ | ||
2946 | int sep=skip_sep(ls); | ||
2947 | luaZ_resetbuffer(ls->buff); | ||
2948 | if(sep>=0){ | ||
2949 | read_long_string(ls,NULL,sep); | ||
2950 | luaZ_resetbuffer(ls->buff); | ||
2951 | continue; | ||
2952 | } | ||
2953 | } | ||
2954 | while(!currIsNewline(ls)&&ls->current!=(-1)) | ||
2955 | next(ls); | ||
2956 | continue; | ||
2957 | } | ||
2958 | case'[':{ | ||
2959 | int sep=skip_sep(ls); | ||
2960 | if(sep>=0){ | ||
2961 | read_long_string(ls,seminfo,sep); | ||
2962 | return TK_STRING; | ||
2963 | } | ||
2964 | else if(sep==-1)return'['; | ||
2965 | else luaX_lexerror(ls,"invalid long string delimiter",TK_STRING); | ||
2966 | } | ||
2967 | case'=':{ | ||
2968 | next(ls); | ||
2969 | if(ls->current!='=')return'='; | ||
2970 | else{next(ls);return TK_EQ;} | ||
2971 | } | ||
2972 | case'<':{ | ||
2973 | next(ls); | ||
2974 | if(ls->current!='=')return'<'; | ||
2975 | else{next(ls);return TK_LE;} | ||
2976 | } | ||
2977 | case'>':{ | ||
2978 | next(ls); | ||
2979 | if(ls->current!='=')return'>'; | ||
2980 | else{next(ls);return TK_GE;} | ||
2981 | } | ||
2982 | case'~':{ | ||
2983 | next(ls); | ||
2984 | if(ls->current!='=')return'~'; | ||
2985 | else{next(ls);return TK_NE;} | ||
2986 | } | ||
2987 | case'"': | ||
2988 | case'\'':{ | ||
2989 | read_string(ls,ls->current,seminfo); | ||
2990 | return TK_STRING; | ||
2991 | } | ||
2992 | case'.':{ | ||
2993 | save_and_next(ls); | ||
2994 | if(check_next(ls,".")){ | ||
2995 | if(check_next(ls,".")) | ||
2996 | return TK_DOTS; | ||
2997 | else return TK_CONCAT; | ||
2998 | } | ||
2999 | else if(!isdigit(ls->current))return'.'; | ||
3000 | else{ | ||
3001 | read_numeral(ls,seminfo); | ||
3002 | return TK_NUMBER; | ||
3003 | } | ||
3004 | } | ||
3005 | case(-1):{ | ||
3006 | return TK_EOS; | ||
3007 | } | ||
3008 | default:{ | ||
3009 | if(isspace(ls->current)){ | ||
3010 | next(ls); | ||
3011 | continue; | ||
3012 | } | ||
3013 | else if(isdigit(ls->current)){ | ||
3014 | read_numeral(ls,seminfo); | ||
3015 | return TK_NUMBER; | ||
3016 | } | ||
3017 | else if(isalpha(ls->current)||ls->current=='_'){ | ||
3018 | TString*ts; | ||
3019 | do{ | ||
3020 | save_and_next(ls); | ||
3021 | }while(isalnum(ls->current)||ls->current=='_'); | ||
3022 | ts=luaX_newstring(ls,luaZ_buffer(ls->buff), | ||
3023 | luaZ_bufflen(ls->buff)); | ||
3024 | if(ts->tsv.reserved>0) | ||
3025 | return ts->tsv.reserved-1+257; | ||
3026 | else{ | ||
3027 | seminfo->ts=ts; | ||
3028 | return TK_NAME; | ||
3029 | } | ||
3030 | } | ||
3031 | else{ | ||
3032 | int c=ls->current; | ||
3033 | next(ls); | ||
3034 | return c; | ||
3035 | } | ||
3036 | } | ||
3037 | } | ||
3038 | } | ||
3039 | } | ||
3040 | static void luaX_next(LexState*ls){ | ||
3041 | ls->lastline=ls->linenumber; | ||
3042 | if(ls->lookahead.token!=TK_EOS){ | ||
3043 | ls->t=ls->lookahead; | ||
3044 | ls->lookahead.token=TK_EOS; | ||
3045 | } | ||
3046 | else | ||
3047 | ls->t.token=llex(ls,&ls->t.seminfo); | ||
3048 | } | ||
3049 | static void luaX_lookahead(LexState*ls){ | ||
3050 | ls->lookahead.token=llex(ls,&ls->lookahead.seminfo); | ||
3051 | } | ||
3052 | #define hasjumps(e)((e)->t!=(e)->f) | ||
3053 | static int isnumeral(expdesc*e){ | ||
3054 | return(e->k==VKNUM&&e->t==(-1)&&e->f==(-1)); | ||
3055 | } | ||
3056 | static void luaK_nil(FuncState*fs,int from,int n){ | ||
3057 | Instruction*previous; | ||
3058 | if(fs->pc>fs->lasttarget){ | ||
3059 | if(fs->pc==0){ | ||
3060 | if(from>=fs->nactvar) | ||
3061 | return; | ||
3062 | } | ||
3063 | else{ | ||
3064 | previous=&fs->f->code[fs->pc-1]; | ||
3065 | if(GET_OPCODE(*previous)==OP_LOADNIL){ | ||
3066 | int pfrom=GETARG_A(*previous); | ||
3067 | int pto=GETARG_B(*previous); | ||
3068 | if(pfrom<=from&&from<=pto+1){ | ||
3069 | if(from+n-1>pto) | ||
3070 | SETARG_B(*previous,from+n-1); | ||
3071 | return; | ||
3072 | } | ||
3073 | } | ||
3074 | } | ||
3075 | } | ||
3076 | luaK_codeABC(fs,OP_LOADNIL,from,from+n-1,0); | ||
3077 | } | ||
3078 | static int luaK_jump(FuncState*fs){ | ||
3079 | int jpc=fs->jpc; | ||
3080 | int j; | ||
3081 | fs->jpc=(-1); | ||
3082 | j=luaK_codeAsBx(fs,OP_JMP,0,(-1)); | ||
3083 | luaK_concat(fs,&j,jpc); | ||
3084 | return j; | ||
3085 | } | ||
3086 | static void luaK_ret(FuncState*fs,int first,int nret){ | ||
3087 | luaK_codeABC(fs,OP_RETURN,first,nret+1,0); | ||
3088 | } | ||
3089 | static int condjump(FuncState*fs,OpCode op,int A,int B,int C){ | ||
3090 | luaK_codeABC(fs,op,A,B,C); | ||
3091 | return luaK_jump(fs); | ||
3092 | } | ||
3093 | static void fixjump(FuncState*fs,int pc,int dest){ | ||
3094 | Instruction*jmp=&fs->f->code[pc]; | ||
3095 | int offset=dest-(pc+1); | ||
3096 | if(abs(offset)>(((1<<(9+9))-1)>>1)) | ||
3097 | luaX_syntaxerror(fs->ls,"control structure too long"); | ||
3098 | SETARG_sBx(*jmp,offset); | ||
3099 | } | ||
3100 | static int luaK_getlabel(FuncState*fs){ | ||
3101 | fs->lasttarget=fs->pc; | ||
3102 | return fs->pc; | ||
3103 | } | ||
3104 | static int getjump(FuncState*fs,int pc){ | ||
3105 | int offset=GETARG_sBx(fs->f->code[pc]); | ||
3106 | if(offset==(-1)) | ||
3107 | return(-1); | ||
3108 | else | ||
3109 | return(pc+1)+offset; | ||
3110 | } | ||
3111 | static Instruction*getjumpcontrol(FuncState*fs,int pc){ | ||
3112 | Instruction*pi=&fs->f->code[pc]; | ||
3113 | if(pc>=1&&testTMode(GET_OPCODE(*(pi-1)))) | ||
3114 | return pi-1; | ||
3115 | else | ||
3116 | return pi; | ||
3117 | } | ||
3118 | static int need_value(FuncState*fs,int list){ | ||
3119 | for(;list!=(-1);list=getjump(fs,list)){ | ||
3120 | Instruction i=*getjumpcontrol(fs,list); | ||
3121 | if(GET_OPCODE(i)!=OP_TESTSET)return 1; | ||
3122 | } | ||
3123 | return 0; | ||
3124 | } | ||
3125 | static int patchtestreg(FuncState*fs,int node,int reg){ | ||
3126 | Instruction*i=getjumpcontrol(fs,node); | ||
3127 | if(GET_OPCODE(*i)!=OP_TESTSET) | ||
3128 | return 0; | ||
3129 | if(reg!=((1<<8)-1)&®!=GETARG_B(*i)) | ||
3130 | SETARG_A(*i,reg); | ||
3131 | else | ||
3132 | *i=CREATE_ABC(OP_TEST,GETARG_B(*i),0,GETARG_C(*i)); | ||
3133 | return 1; | ||
3134 | } | ||
3135 | static void removevalues(FuncState*fs,int list){ | ||
3136 | for(;list!=(-1);list=getjump(fs,list)) | ||
3137 | patchtestreg(fs,list,((1<<8)-1)); | ||
3138 | } | ||
3139 | static void patchlistaux(FuncState*fs,int list,int vtarget,int reg, | ||
3140 | int dtarget){ | ||
3141 | while(list!=(-1)){ | ||
3142 | int next=getjump(fs,list); | ||
3143 | if(patchtestreg(fs,list,reg)) | ||
3144 | fixjump(fs,list,vtarget); | ||
3145 | else | ||
3146 | fixjump(fs,list,dtarget); | ||
3147 | list=next; | ||
3148 | } | ||
3149 | } | ||
3150 | static void dischargejpc(FuncState*fs){ | ||
3151 | patchlistaux(fs,fs->jpc,fs->pc,((1<<8)-1),fs->pc); | ||
3152 | fs->jpc=(-1); | ||
3153 | } | ||
3154 | static void luaK_patchlist(FuncState*fs,int list,int target){ | ||
3155 | if(target==fs->pc) | ||
3156 | luaK_patchtohere(fs,list); | ||
3157 | else{ | ||
3158 | patchlistaux(fs,list,target,((1<<8)-1),target); | ||
3159 | } | ||
3160 | } | ||
3161 | static void luaK_patchtohere(FuncState*fs,int list){ | ||
3162 | luaK_getlabel(fs); | ||
3163 | luaK_concat(fs,&fs->jpc,list); | ||
3164 | } | ||
3165 | static void luaK_concat(FuncState*fs,int*l1,int l2){ | ||
3166 | if(l2==(-1))return; | ||
3167 | else if(*l1==(-1)) | ||
3168 | *l1=l2; | ||
3169 | else{ | ||
3170 | int list=*l1; | ||
3171 | int next; | ||
3172 | while((next=getjump(fs,list))!=(-1)) | ||
3173 | list=next; | ||
3174 | fixjump(fs,list,l2); | ||
3175 | } | ||
3176 | } | ||
3177 | static void luaK_checkstack(FuncState*fs,int n){ | ||
3178 | int newstack=fs->freereg+n; | ||
3179 | if(newstack>fs->f->maxstacksize){ | ||
3180 | if(newstack>=250) | ||
3181 | luaX_syntaxerror(fs->ls,"function or expression too complex"); | ||
3182 | fs->f->maxstacksize=cast_byte(newstack); | ||
3183 | } | ||
3184 | } | ||
3185 | static void luaK_reserveregs(FuncState*fs,int n){ | ||
3186 | luaK_checkstack(fs,n); | ||
3187 | fs->freereg+=n; | ||
3188 | } | ||
3189 | static void freereg(FuncState*fs,int reg){ | ||
3190 | if(!ISK(reg)&®>=fs->nactvar){ | ||
3191 | fs->freereg--; | ||
3192 | } | ||
3193 | } | ||
3194 | static void freeexp(FuncState*fs,expdesc*e){ | ||
3195 | if(e->k==VNONRELOC) | ||
3196 | freereg(fs,e->u.s.info); | ||
3197 | } | ||
3198 | static int addk(FuncState*fs,TValue*k,TValue*v){ | ||
3199 | lua_State*L=fs->L; | ||
3200 | TValue*idx=luaH_set(L,fs->h,k); | ||
3201 | Proto*f=fs->f; | ||
3202 | int oldsize=f->sizek; | ||
3203 | if(ttisnumber(idx)){ | ||
3204 | return cast_int(nvalue(idx)); | ||
3205 | } | ||
3206 | else{ | ||
3207 | setnvalue(idx,cast_num(fs->nk)); | ||
3208 | luaM_growvector(L,f->k,fs->nk,f->sizek,TValue, | ||
3209 | ((1<<(9+9))-1),"constant table overflow"); | ||
3210 | while(oldsize<f->sizek)setnilvalue(&f->k[oldsize++]); | ||
3211 | setobj(L,&f->k[fs->nk],v); | ||
3212 | luaC_barrier(L,f,v); | ||
3213 | return fs->nk++; | ||
3214 | } | ||
3215 | } | ||
3216 | static int luaK_stringK(FuncState*fs,TString*s){ | ||
3217 | TValue o; | ||
3218 | setsvalue(fs->L,&o,s); | ||
3219 | return addk(fs,&o,&o); | ||
3220 | } | ||
3221 | static int luaK_numberK(FuncState*fs,lua_Number r){ | ||
3222 | TValue o; | ||
3223 | setnvalue(&o,r); | ||
3224 | return addk(fs,&o,&o); | ||
3225 | } | ||
3226 | static int boolK(FuncState*fs,int b){ | ||
3227 | TValue o; | ||
3228 | setbvalue(&o,b); | ||
3229 | return addk(fs,&o,&o); | ||
3230 | } | ||
3231 | static int nilK(FuncState*fs){ | ||
3232 | TValue k,v; | ||
3233 | setnilvalue(&v); | ||
3234 | sethvalue(fs->L,&k,fs->h); | ||
3235 | return addk(fs,&k,&v); | ||
3236 | } | ||
3237 | static void luaK_setreturns(FuncState*fs,expdesc*e,int nresults){ | ||
3238 | if(e->k==VCALL){ | ||
3239 | SETARG_C(getcode(fs,e),nresults+1); | ||
3240 | } | ||
3241 | else if(e->k==VVARARG){ | ||
3242 | SETARG_B(getcode(fs,e),nresults+1); | ||
3243 | SETARG_A(getcode(fs,e),fs->freereg); | ||
3244 | luaK_reserveregs(fs,1); | ||
3245 | } | ||
3246 | } | ||
3247 | static void luaK_setoneret(FuncState*fs,expdesc*e){ | ||
3248 | if(e->k==VCALL){ | ||
3249 | e->k=VNONRELOC; | ||
3250 | e->u.s.info=GETARG_A(getcode(fs,e)); | ||
3251 | } | ||
3252 | else if(e->k==VVARARG){ | ||
3253 | SETARG_B(getcode(fs,e),2); | ||
3254 | e->k=VRELOCABLE; | ||
3255 | } | ||
3256 | } | ||
3257 | static void luaK_dischargevars(FuncState*fs,expdesc*e){ | ||
3258 | switch(e->k){ | ||
3259 | case VLOCAL:{ | ||
3260 | e->k=VNONRELOC; | ||
3261 | break; | ||
3262 | } | ||
3263 | case VUPVAL:{ | ||
3264 | e->u.s.info=luaK_codeABC(fs,OP_GETUPVAL,0,e->u.s.info,0); | ||
3265 | e->k=VRELOCABLE; | ||
3266 | break; | ||
3267 | } | ||
3268 | case VGLOBAL:{ | ||
3269 | e->u.s.info=luaK_codeABx(fs,OP_GETGLOBAL,0,e->u.s.info); | ||
3270 | e->k=VRELOCABLE; | ||
3271 | break; | ||
3272 | } | ||
3273 | case VINDEXED:{ | ||
3274 | freereg(fs,e->u.s.aux); | ||
3275 | freereg(fs,e->u.s.info); | ||
3276 | e->u.s.info=luaK_codeABC(fs,OP_GETTABLE,0,e->u.s.info,e->u.s.aux); | ||
3277 | e->k=VRELOCABLE; | ||
3278 | break; | ||
3279 | } | ||
3280 | case VVARARG: | ||
3281 | case VCALL:{ | ||
3282 | luaK_setoneret(fs,e); | ||
3283 | break; | ||
3284 | } | ||
3285 | default:break; | ||
3286 | } | ||
3287 | } | ||
3288 | static int code_label(FuncState*fs,int A,int b,int jump){ | ||
3289 | luaK_getlabel(fs); | ||
3290 | return luaK_codeABC(fs,OP_LOADBOOL,A,b,jump); | ||
3291 | } | ||
3292 | static void discharge2reg(FuncState*fs,expdesc*e,int reg){ | ||
3293 | luaK_dischargevars(fs,e); | ||
3294 | switch(e->k){ | ||
3295 | case VNIL:{ | ||
3296 | luaK_nil(fs,reg,1); | ||
3297 | break; | ||
3298 | } | ||
3299 | case VFALSE:case VTRUE:{ | ||
3300 | luaK_codeABC(fs,OP_LOADBOOL,reg,e->k==VTRUE,0); | ||
3301 | break; | ||
3302 | } | ||
3303 | case VK:{ | ||
3304 | luaK_codeABx(fs,OP_LOADK,reg,e->u.s.info); | ||
3305 | break; | ||
3306 | } | ||
3307 | case VKNUM:{ | ||
3308 | luaK_codeABx(fs,OP_LOADK,reg,luaK_numberK(fs,e->u.nval)); | ||
3309 | break; | ||
3310 | } | ||
3311 | case VRELOCABLE:{ | ||
3312 | Instruction*pc=&getcode(fs,e); | ||
3313 | SETARG_A(*pc,reg); | ||
3314 | break; | ||
3315 | } | ||
3316 | case VNONRELOC:{ | ||
3317 | if(reg!=e->u.s.info) | ||
3318 | luaK_codeABC(fs,OP_MOVE,reg,e->u.s.info,0); | ||
3319 | break; | ||
3320 | } | ||
3321 | default:{ | ||
3322 | return; | ||
3323 | } | ||
3324 | } | ||
3325 | e->u.s.info=reg; | ||
3326 | e->k=VNONRELOC; | ||
3327 | } | ||
3328 | static void discharge2anyreg(FuncState*fs,expdesc*e){ | ||
3329 | if(e->k!=VNONRELOC){ | ||
3330 | luaK_reserveregs(fs,1); | ||
3331 | discharge2reg(fs,e,fs->freereg-1); | ||
3332 | } | ||
3333 | } | ||
3334 | static void exp2reg(FuncState*fs,expdesc*e,int reg){ | ||
3335 | discharge2reg(fs,e,reg); | ||
3336 | if(e->k==VJMP) | ||
3337 | luaK_concat(fs,&e->t,e->u.s.info); | ||
3338 | if(hasjumps(e)){ | ||
3339 | int final; | ||
3340 | int p_f=(-1); | ||
3341 | int p_t=(-1); | ||
3342 | if(need_value(fs,e->t)||need_value(fs,e->f)){ | ||
3343 | int fj=(e->k==VJMP)?(-1):luaK_jump(fs); | ||
3344 | p_f=code_label(fs,reg,0,1); | ||
3345 | p_t=code_label(fs,reg,1,0); | ||
3346 | luaK_patchtohere(fs,fj); | ||
3347 | } | ||
3348 | final=luaK_getlabel(fs); | ||
3349 | patchlistaux(fs,e->f,final,reg,p_f); | ||
3350 | patchlistaux(fs,e->t,final,reg,p_t); | ||
3351 | } | ||
3352 | e->f=e->t=(-1); | ||
3353 | e->u.s.info=reg; | ||
3354 | e->k=VNONRELOC; | ||
3355 | } | ||
3356 | static void luaK_exp2nextreg(FuncState*fs,expdesc*e){ | ||
3357 | luaK_dischargevars(fs,e); | ||
3358 | freeexp(fs,e); | ||
3359 | luaK_reserveregs(fs,1); | ||
3360 | exp2reg(fs,e,fs->freereg-1); | ||
3361 | } | ||
3362 | static int luaK_exp2anyreg(FuncState*fs,expdesc*e){ | ||
3363 | luaK_dischargevars(fs,e); | ||
3364 | if(e->k==VNONRELOC){ | ||
3365 | if(!hasjumps(e))return e->u.s.info; | ||
3366 | if(e->u.s.info>=fs->nactvar){ | ||
3367 | exp2reg(fs,e,e->u.s.info); | ||
3368 | return e->u.s.info; | ||
3369 | } | ||
3370 | } | ||
3371 | luaK_exp2nextreg(fs,e); | ||
3372 | return e->u.s.info; | ||
3373 | } | ||
3374 | static void luaK_exp2val(FuncState*fs,expdesc*e){ | ||
3375 | if(hasjumps(e)) | ||
3376 | luaK_exp2anyreg(fs,e); | ||
3377 | else | ||
3378 | luaK_dischargevars(fs,e); | ||
3379 | } | ||
3380 | static int luaK_exp2RK(FuncState*fs,expdesc*e){ | ||
3381 | luaK_exp2val(fs,e); | ||
3382 | switch(e->k){ | ||
3383 | case VKNUM: | ||
3384 | case VTRUE: | ||
3385 | case VFALSE: | ||
3386 | case VNIL:{ | ||
3387 | if(fs->nk<=((1<<(9-1))-1)){ | ||
3388 | e->u.s.info=(e->k==VNIL)?nilK(fs): | ||
3389 | (e->k==VKNUM)?luaK_numberK(fs,e->u.nval): | ||
3390 | boolK(fs,(e->k==VTRUE)); | ||
3391 | e->k=VK; | ||
3392 | return RKASK(e->u.s.info); | ||
3393 | } | ||
3394 | else break; | ||
3395 | } | ||
3396 | case VK:{ | ||
3397 | if(e->u.s.info<=((1<<(9-1))-1)) | ||
3398 | return RKASK(e->u.s.info); | ||
3399 | else break; | ||
3400 | } | ||
3401 | default:break; | ||
3402 | } | ||
3403 | return luaK_exp2anyreg(fs,e); | ||
3404 | } | ||
3405 | static void luaK_storevar(FuncState*fs,expdesc*var,expdesc*ex){ | ||
3406 | switch(var->k){ | ||
3407 | case VLOCAL:{ | ||
3408 | freeexp(fs,ex); | ||
3409 | exp2reg(fs,ex,var->u.s.info); | ||
3410 | return; | ||
3411 | } | ||
3412 | case VUPVAL:{ | ||
3413 | int e=luaK_exp2anyreg(fs,ex); | ||
3414 | luaK_codeABC(fs,OP_SETUPVAL,e,var->u.s.info,0); | ||
3415 | break; | ||
3416 | } | ||
3417 | case VGLOBAL:{ | ||
3418 | int e=luaK_exp2anyreg(fs,ex); | ||
3419 | luaK_codeABx(fs,OP_SETGLOBAL,e,var->u.s.info); | ||
3420 | break; | ||
3421 | } | ||
3422 | case VINDEXED:{ | ||
3423 | int e=luaK_exp2RK(fs,ex); | ||
3424 | luaK_codeABC(fs,OP_SETTABLE,var->u.s.info,var->u.s.aux,e); | ||
3425 | break; | ||
3426 | } | ||
3427 | default:{ | ||
3428 | break; | ||
3429 | } | ||
3430 | } | ||
3431 | freeexp(fs,ex); | ||
3432 | } | ||
3433 | static void luaK_self(FuncState*fs,expdesc*e,expdesc*key){ | ||
3434 | int func; | ||
3435 | luaK_exp2anyreg(fs,e); | ||
3436 | freeexp(fs,e); | ||
3437 | func=fs->freereg; | ||
3438 | luaK_reserveregs(fs,2); | ||
3439 | luaK_codeABC(fs,OP_SELF,func,e->u.s.info,luaK_exp2RK(fs,key)); | ||
3440 | freeexp(fs,key); | ||
3441 | e->u.s.info=func; | ||
3442 | e->k=VNONRELOC; | ||
3443 | } | ||
3444 | static void invertjump(FuncState*fs,expdesc*e){ | ||
3445 | Instruction*pc=getjumpcontrol(fs,e->u.s.info); | ||
3446 | SETARG_A(*pc,!(GETARG_A(*pc))); | ||
3447 | } | ||
3448 | static int jumponcond(FuncState*fs,expdesc*e,int cond){ | ||
3449 | if(e->k==VRELOCABLE){ | ||
3450 | Instruction ie=getcode(fs,e); | ||
3451 | if(GET_OPCODE(ie)==OP_NOT){ | ||
3452 | fs->pc--; | ||
3453 | return condjump(fs,OP_TEST,GETARG_B(ie),0,!cond); | ||
3454 | } | ||
3455 | } | ||
3456 | discharge2anyreg(fs,e); | ||
3457 | freeexp(fs,e); | ||
3458 | return condjump(fs,OP_TESTSET,((1<<8)-1),e->u.s.info,cond); | ||
3459 | } | ||
3460 | static void luaK_goiftrue(FuncState*fs,expdesc*e){ | ||
3461 | int pc; | ||
3462 | luaK_dischargevars(fs,e); | ||
3463 | switch(e->k){ | ||
3464 | case VK:case VKNUM:case VTRUE:{ | ||
3465 | pc=(-1); | ||
3466 | break; | ||
3467 | } | ||
3468 | case VJMP:{ | ||
3469 | invertjump(fs,e); | ||
3470 | pc=e->u.s.info; | ||
3471 | break; | ||
3472 | } | ||
3473 | default:{ | ||
3474 | pc=jumponcond(fs,e,0); | ||
3475 | break; | ||
3476 | } | ||
3477 | } | ||
3478 | luaK_concat(fs,&e->f,pc); | ||
3479 | luaK_patchtohere(fs,e->t); | ||
3480 | e->t=(-1); | ||
3481 | } | ||
3482 | static void luaK_goiffalse(FuncState*fs,expdesc*e){ | ||
3483 | int pc; | ||
3484 | luaK_dischargevars(fs,e); | ||
3485 | switch(e->k){ | ||
3486 | case VNIL:case VFALSE:{ | ||
3487 | pc=(-1); | ||
3488 | break; | ||
3489 | } | ||
3490 | case VJMP:{ | ||
3491 | pc=e->u.s.info; | ||
3492 | break; | ||
3493 | } | ||
3494 | default:{ | ||
3495 | pc=jumponcond(fs,e,1); | ||
3496 | break; | ||
3497 | } | ||
3498 | } | ||
3499 | luaK_concat(fs,&e->t,pc); | ||
3500 | luaK_patchtohere(fs,e->f); | ||
3501 | e->f=(-1); | ||
3502 | } | ||
3503 | static void codenot(FuncState*fs,expdesc*e){ | ||
3504 | luaK_dischargevars(fs,e); | ||
3505 | switch(e->k){ | ||
3506 | case VNIL:case VFALSE:{ | ||
3507 | e->k=VTRUE; | ||
3508 | break; | ||
3509 | } | ||
3510 | case VK:case VKNUM:case VTRUE:{ | ||
3511 | e->k=VFALSE; | ||
3512 | break; | ||
3513 | } | ||
3514 | case VJMP:{ | ||
3515 | invertjump(fs,e); | ||
3516 | break; | ||
3517 | } | ||
3518 | case VRELOCABLE: | ||
3519 | case VNONRELOC:{ | ||
3520 | discharge2anyreg(fs,e); | ||
3521 | freeexp(fs,e); | ||
3522 | e->u.s.info=luaK_codeABC(fs,OP_NOT,0,e->u.s.info,0); | ||
3523 | e->k=VRELOCABLE; | ||
3524 | break; | ||
3525 | } | ||
3526 | default:{ | ||
3527 | break; | ||
3528 | } | ||
3529 | } | ||
3530 | {int temp=e->f;e->f=e->t;e->t=temp;} | ||
3531 | removevalues(fs,e->f); | ||
3532 | removevalues(fs,e->t); | ||
3533 | } | ||
3534 | static void luaK_indexed(FuncState*fs,expdesc*t,expdesc*k){ | ||
3535 | t->u.s.aux=luaK_exp2RK(fs,k); | ||
3536 | t->k=VINDEXED; | ||
3537 | } | ||
3538 | static int constfolding(OpCode op,expdesc*e1,expdesc*e2){ | ||
3539 | lua_Number v1,v2,r; | ||
3540 | if(!isnumeral(e1)||!isnumeral(e2))return 0; | ||
3541 | v1=e1->u.nval; | ||
3542 | v2=e2->u.nval; | ||
3543 | switch(op){ | ||
3544 | case OP_ADD:r=luai_numadd(v1,v2);break; | ||
3545 | case OP_SUB:r=luai_numsub(v1,v2);break; | ||
3546 | case OP_MUL:r=luai_nummul(v1,v2);break; | ||
3547 | case OP_DIV: | ||
3548 | if(v2==0)return 0; | ||
3549 | r=luai_numdiv(v1,v2);break; | ||
3550 | case OP_MOD: | ||
3551 | if(v2==0)return 0; | ||
3552 | r=luai_nummod(v1,v2);break; | ||
3553 | case OP_POW:r=luai_numpow(v1,v2);break; | ||
3554 | case OP_UNM:r=luai_numunm(v1);break; | ||
3555 | case OP_LEN:return 0; | ||
3556 | default:r=0;break; | ||
3557 | } | ||
3558 | if(luai_numisnan(r))return 0; | ||
3559 | e1->u.nval=r; | ||
3560 | return 1; | ||
3561 | } | ||
3562 | static void codearith(FuncState*fs,OpCode op,expdesc*e1,expdesc*e2){ | ||
3563 | if(constfolding(op,e1,e2)) | ||
3564 | return; | ||
3565 | else{ | ||
3566 | int o2=(op!=OP_UNM&&op!=OP_LEN)?luaK_exp2RK(fs,e2):0; | ||
3567 | int o1=luaK_exp2RK(fs,e1); | ||
3568 | if(o1>o2){ | ||
3569 | freeexp(fs,e1); | ||
3570 | freeexp(fs,e2); | ||
3571 | } | ||
3572 | else{ | ||
3573 | freeexp(fs,e2); | ||
3574 | freeexp(fs,e1); | ||
3575 | } | ||
3576 | e1->u.s.info=luaK_codeABC(fs,op,0,o1,o2); | ||
3577 | e1->k=VRELOCABLE; | ||
3578 | } | ||
3579 | } | ||
3580 | static void codecomp(FuncState*fs,OpCode op,int cond,expdesc*e1, | ||
3581 | expdesc*e2){ | ||
3582 | int o1=luaK_exp2RK(fs,e1); | ||
3583 | int o2=luaK_exp2RK(fs,e2); | ||
3584 | freeexp(fs,e2); | ||
3585 | freeexp(fs,e1); | ||
3586 | if(cond==0&&op!=OP_EQ){ | ||
3587 | int temp; | ||
3588 | temp=o1;o1=o2;o2=temp; | ||
3589 | cond=1; | ||
3590 | } | ||
3591 | e1->u.s.info=condjump(fs,op,cond,o1,o2); | ||
3592 | e1->k=VJMP; | ||
3593 | } | ||
3594 | static void luaK_prefix(FuncState*fs,UnOpr op,expdesc*e){ | ||
3595 | expdesc e2; | ||
3596 | e2.t=e2.f=(-1);e2.k=VKNUM;e2.u.nval=0; | ||
3597 | switch(op){ | ||
3598 | case OPR_MINUS:{ | ||
3599 | if(!isnumeral(e)) | ||
3600 | luaK_exp2anyreg(fs,e); | ||
3601 | codearith(fs,OP_UNM,e,&e2); | ||
3602 | break; | ||
3603 | } | ||
3604 | case OPR_NOT:codenot(fs,e);break; | ||
3605 | case OPR_LEN:{ | ||
3606 | luaK_exp2anyreg(fs,e); | ||
3607 | codearith(fs,OP_LEN,e,&e2); | ||
3608 | break; | ||
3609 | } | ||
3610 | default:; | ||
3611 | } | ||
3612 | } | ||
3613 | static void luaK_infix(FuncState*fs,BinOpr op,expdesc*v){ | ||
3614 | switch(op){ | ||
3615 | case OPR_AND:{ | ||
3616 | luaK_goiftrue(fs,v); | ||
3617 | break; | ||
3618 | } | ||
3619 | case OPR_OR:{ | ||
3620 | luaK_goiffalse(fs,v); | ||
3621 | break; | ||
3622 | } | ||
3623 | case OPR_CONCAT:{ | ||
3624 | luaK_exp2nextreg(fs,v); | ||
3625 | break; | ||
3626 | } | ||
3627 | case OPR_ADD:case OPR_SUB:case OPR_MUL:case OPR_DIV: | ||
3628 | case OPR_MOD:case OPR_POW:{ | ||
3629 | if(!isnumeral(v))luaK_exp2RK(fs,v); | ||
3630 | break; | ||
3631 | } | ||
3632 | default:{ | ||
3633 | luaK_exp2RK(fs,v); | ||
3634 | break; | ||
3635 | } | ||
3636 | } | ||
3637 | } | ||
3638 | static void luaK_posfix(FuncState*fs,BinOpr op,expdesc*e1,expdesc*e2){ | ||
3639 | switch(op){ | ||
3640 | case OPR_AND:{ | ||
3641 | luaK_dischargevars(fs,e2); | ||
3642 | luaK_concat(fs,&e2->f,e1->f); | ||
3643 | *e1=*e2; | ||
3644 | break; | ||
3645 | } | ||
3646 | case OPR_OR:{ | ||
3647 | luaK_dischargevars(fs,e2); | ||
3648 | luaK_concat(fs,&e2->t,e1->t); | ||
3649 | *e1=*e2; | ||
3650 | break; | ||
3651 | } | ||
3652 | case OPR_CONCAT:{ | ||
3653 | luaK_exp2val(fs,e2); | ||
3654 | if(e2->k==VRELOCABLE&&GET_OPCODE(getcode(fs,e2))==OP_CONCAT){ | ||
3655 | freeexp(fs,e1); | ||
3656 | SETARG_B(getcode(fs,e2),e1->u.s.info); | ||
3657 | e1->k=VRELOCABLE;e1->u.s.info=e2->u.s.info; | ||
3658 | } | ||
3659 | else{ | ||
3660 | luaK_exp2nextreg(fs,e2); | ||
3661 | codearith(fs,OP_CONCAT,e1,e2); | ||
3662 | } | ||
3663 | break; | ||
3664 | } | ||
3665 | case OPR_ADD:codearith(fs,OP_ADD,e1,e2);break; | ||
3666 | case OPR_SUB:codearith(fs,OP_SUB,e1,e2);break; | ||
3667 | case OPR_MUL:codearith(fs,OP_MUL,e1,e2);break; | ||
3668 | case OPR_DIV:codearith(fs,OP_DIV,e1,e2);break; | ||
3669 | case OPR_MOD:codearith(fs,OP_MOD,e1,e2);break; | ||
3670 | case OPR_POW:codearith(fs,OP_POW,e1,e2);break; | ||
3671 | case OPR_EQ:codecomp(fs,OP_EQ,1,e1,e2);break; | ||
3672 | case OPR_NE:codecomp(fs,OP_EQ,0,e1,e2);break; | ||
3673 | case OPR_LT:codecomp(fs,OP_LT,1,e1,e2);break; | ||
3674 | case OPR_LE:codecomp(fs,OP_LE,1,e1,e2);break; | ||
3675 | case OPR_GT:codecomp(fs,OP_LT,0,e1,e2);break; | ||
3676 | case OPR_GE:codecomp(fs,OP_LE,0,e1,e2);break; | ||
3677 | default:; | ||
3678 | } | ||
3679 | } | ||
3680 | static void luaK_fixline(FuncState*fs,int line){ | ||
3681 | fs->f->lineinfo[fs->pc-1]=line; | ||
3682 | } | ||
3683 | static int luaK_code(FuncState*fs,Instruction i,int line){ | ||
3684 | Proto*f=fs->f; | ||
3685 | dischargejpc(fs); | ||
3686 | luaM_growvector(fs->L,f->code,fs->pc,f->sizecode,Instruction, | ||
3687 | (INT_MAX-2),"code size overflow"); | ||
3688 | f->code[fs->pc]=i; | ||
3689 | luaM_growvector(fs->L,f->lineinfo,fs->pc,f->sizelineinfo,int, | ||
3690 | (INT_MAX-2),"code size overflow"); | ||
3691 | f->lineinfo[fs->pc]=line; | ||
3692 | return fs->pc++; | ||
3693 | } | ||
3694 | static int luaK_codeABC(FuncState*fs,OpCode o,int a,int b,int c){ | ||
3695 | return luaK_code(fs,CREATE_ABC(o,a,b,c),fs->ls->lastline); | ||
3696 | } | ||
3697 | static int luaK_codeABx(FuncState*fs,OpCode o,int a,unsigned int bc){ | ||
3698 | return luaK_code(fs,CREATE_ABx(o,a,bc),fs->ls->lastline); | ||
3699 | } | ||
3700 | static void luaK_setlist(FuncState*fs,int base,int nelems,int tostore){ | ||
3701 | int c=(nelems-1)/50+1; | ||
3702 | int b=(tostore==(-1))?0:tostore; | ||
3703 | if(c<=((1<<9)-1)) | ||
3704 | luaK_codeABC(fs,OP_SETLIST,base,b,c); | ||
3705 | else{ | ||
3706 | luaK_codeABC(fs,OP_SETLIST,base,b,0); | ||
3707 | luaK_code(fs,cast(Instruction,c),fs->ls->lastline); | ||
3708 | } | ||
3709 | fs->freereg=base+1; | ||
3710 | } | ||
3711 | #define hasmultret(k)((k)==VCALL||(k)==VVARARG) | ||
3712 | #define getlocvar(fs,i)((fs)->f->locvars[(fs)->actvar[i]]) | ||
3713 | #define luaY_checklimit(fs,v,l,m)if((v)>(l))errorlimit(fs,l,m) | ||
3714 | typedef struct BlockCnt{ | ||
3715 | struct BlockCnt*previous; | ||
3716 | int breaklist; | ||
3717 | lu_byte nactvar; | ||
3718 | lu_byte upval; | ||
3719 | lu_byte isbreakable; | ||
3720 | }BlockCnt; | ||
3721 | static void chunk(LexState*ls); | ||
3722 | static void expr(LexState*ls,expdesc*v); | ||
3723 | static void anchor_token(LexState*ls){ | ||
3724 | if(ls->t.token==TK_NAME||ls->t.token==TK_STRING){ | ||
3725 | TString*ts=ls->t.seminfo.ts; | ||
3726 | luaX_newstring(ls,getstr(ts),ts->tsv.len); | ||
3727 | } | ||
3728 | } | ||
3729 | static void error_expected(LexState*ls,int token){ | ||
3730 | luaX_syntaxerror(ls, | ||
3731 | luaO_pushfstring(ls->L,LUA_QL("%s")" expected",luaX_token2str(ls,token))); | ||
3732 | } | ||
3733 | static void errorlimit(FuncState*fs,int limit,const char*what){ | ||
3734 | const char*msg=(fs->f->linedefined==0)? | ||
3735 | luaO_pushfstring(fs->L,"main function has more than %d %s",limit,what): | ||
3736 | luaO_pushfstring(fs->L,"function at line %d has more than %d %s", | ||
3737 | fs->f->linedefined,limit,what); | ||
3738 | luaX_lexerror(fs->ls,msg,0); | ||
3739 | } | ||
3740 | static int testnext(LexState*ls,int c){ | ||
3741 | if(ls->t.token==c){ | ||
3742 | luaX_next(ls); | ||
3743 | return 1; | ||
3744 | } | ||
3745 | else return 0; | ||
3746 | } | ||
3747 | static void check(LexState*ls,int c){ | ||
3748 | if(ls->t.token!=c) | ||
3749 | error_expected(ls,c); | ||
3750 | } | ||
3751 | static void checknext(LexState*ls,int c){ | ||
3752 | check(ls,c); | ||
3753 | luaX_next(ls); | ||
3754 | } | ||
3755 | #define check_condition(ls,c,msg){if(!(c))luaX_syntaxerror(ls,msg);} | ||
3756 | static void check_match(LexState*ls,int what,int who,int where){ | ||
3757 | if(!testnext(ls,what)){ | ||
3758 | if(where==ls->linenumber) | ||
3759 | error_expected(ls,what); | ||
3760 | else{ | ||
3761 | luaX_syntaxerror(ls,luaO_pushfstring(ls->L, | ||
3762 | LUA_QL("%s")" expected (to close "LUA_QL("%s")" at line %d)", | ||
3763 | luaX_token2str(ls,what),luaX_token2str(ls,who),where)); | ||
3764 | } | ||
3765 | } | ||
3766 | } | ||
3767 | static TString*str_checkname(LexState*ls){ | ||
3768 | TString*ts; | ||
3769 | check(ls,TK_NAME); | ||
3770 | ts=ls->t.seminfo.ts; | ||
3771 | luaX_next(ls); | ||
3772 | return ts; | ||
3773 | } | ||
3774 | static void init_exp(expdesc*e,expkind k,int i){ | ||
3775 | e->f=e->t=(-1); | ||
3776 | e->k=k; | ||
3777 | e->u.s.info=i; | ||
3778 | } | ||
3779 | static void codestring(LexState*ls,expdesc*e,TString*s){ | ||
3780 | init_exp(e,VK,luaK_stringK(ls->fs,s)); | ||
3781 | } | ||
3782 | static void checkname(LexState*ls,expdesc*e){ | ||
3783 | codestring(ls,e,str_checkname(ls)); | ||
3784 | } | ||
3785 | static int registerlocalvar(LexState*ls,TString*varname){ | ||
3786 | FuncState*fs=ls->fs; | ||
3787 | Proto*f=fs->f; | ||
3788 | int oldsize=f->sizelocvars; | ||
3789 | luaM_growvector(ls->L,f->locvars,fs->nlocvars,f->sizelocvars, | ||
3790 | LocVar,SHRT_MAX,"too many local variables"); | ||
3791 | while(oldsize<f->sizelocvars)f->locvars[oldsize++].varname=NULL; | ||
3792 | f->locvars[fs->nlocvars].varname=varname; | ||
3793 | luaC_objbarrier(ls->L,f,varname); | ||
3794 | return fs->nlocvars++; | ||
3795 | } | ||
3796 | #define new_localvarliteral(ls,v,n)new_localvar(ls,luaX_newstring(ls,""v,(sizeof(v)/sizeof(char))-1),n) | ||
3797 | static void new_localvar(LexState*ls,TString*name,int n){ | ||
3798 | FuncState*fs=ls->fs; | ||
3799 | luaY_checklimit(fs,fs->nactvar+n+1,200,"local variables"); | ||
3800 | fs->actvar[fs->nactvar+n]=cast(unsigned short,registerlocalvar(ls,name)); | ||
3801 | } | ||
3802 | static void adjustlocalvars(LexState*ls,int nvars){ | ||
3803 | FuncState*fs=ls->fs; | ||
3804 | fs->nactvar=cast_byte(fs->nactvar+nvars); | ||
3805 | for(;nvars;nvars--){ | ||
3806 | getlocvar(fs,fs->nactvar-nvars).startpc=fs->pc; | ||
3807 | } | ||
3808 | } | ||
3809 | static void removevars(LexState*ls,int tolevel){ | ||
3810 | FuncState*fs=ls->fs; | ||
3811 | while(fs->nactvar>tolevel) | ||
3812 | getlocvar(fs,--fs->nactvar).endpc=fs->pc; | ||
3813 | } | ||
3814 | static int indexupvalue(FuncState*fs,TString*name,expdesc*v){ | ||
3815 | int i; | ||
3816 | Proto*f=fs->f; | ||
3817 | int oldsize=f->sizeupvalues; | ||
3818 | for(i=0;i<f->nups;i++){ | ||
3819 | if(fs->upvalues[i].k==v->k&&fs->upvalues[i].info==v->u.s.info){ | ||
3820 | return i; | ||
3821 | } | ||
3822 | } | ||
3823 | luaY_checklimit(fs,f->nups+1,60,"upvalues"); | ||
3824 | luaM_growvector(fs->L,f->upvalues,f->nups,f->sizeupvalues, | ||
3825 | TString*,(INT_MAX-2),""); | ||
3826 | while(oldsize<f->sizeupvalues)f->upvalues[oldsize++]=NULL; | ||
3827 | f->upvalues[f->nups]=name; | ||
3828 | luaC_objbarrier(fs->L,f,name); | ||
3829 | fs->upvalues[f->nups].k=cast_byte(v->k); | ||
3830 | fs->upvalues[f->nups].info=cast_byte(v->u.s.info); | ||
3831 | return f->nups++; | ||
3832 | } | ||
3833 | static int searchvar(FuncState*fs,TString*n){ | ||
3834 | int i; | ||
3835 | for(i=fs->nactvar-1;i>=0;i--){ | ||
3836 | if(n==getlocvar(fs,i).varname) | ||
3837 | return i; | ||
3838 | } | ||
3839 | return-1; | ||
3840 | } | ||
3841 | static void markupval(FuncState*fs,int level){ | ||
3842 | BlockCnt*bl=fs->bl; | ||
3843 | while(bl&&bl->nactvar>level)bl=bl->previous; | ||
3844 | if(bl)bl->upval=1; | ||
3845 | } | ||
3846 | static int singlevaraux(FuncState*fs,TString*n,expdesc*var,int base){ | ||
3847 | if(fs==NULL){ | ||
3848 | init_exp(var,VGLOBAL,((1<<8)-1)); | ||
3849 | return VGLOBAL; | ||
3850 | } | ||
3851 | else{ | ||
3852 | int v=searchvar(fs,n); | ||
3853 | if(v>=0){ | ||
3854 | init_exp(var,VLOCAL,v); | ||
3855 | if(!base) | ||
3856 | markupval(fs,v); | ||
3857 | return VLOCAL; | ||
3858 | } | ||
3859 | else{ | ||
3860 | if(singlevaraux(fs->prev,n,var,0)==VGLOBAL) | ||
3861 | return VGLOBAL; | ||
3862 | var->u.s.info=indexupvalue(fs,n,var); | ||
3863 | var->k=VUPVAL; | ||
3864 | return VUPVAL; | ||
3865 | } | ||
3866 | } | ||
3867 | } | ||
3868 | static void singlevar(LexState*ls,expdesc*var){ | ||
3869 | TString*varname=str_checkname(ls); | ||
3870 | FuncState*fs=ls->fs; | ||
3871 | if(singlevaraux(fs,varname,var,1)==VGLOBAL) | ||
3872 | var->u.s.info=luaK_stringK(fs,varname); | ||
3873 | } | ||
3874 | static void adjust_assign(LexState*ls,int nvars,int nexps,expdesc*e){ | ||
3875 | FuncState*fs=ls->fs; | ||
3876 | int extra=nvars-nexps; | ||
3877 | if(hasmultret(e->k)){ | ||
3878 | extra++; | ||
3879 | if(extra<0)extra=0; | ||
3880 | luaK_setreturns(fs,e,extra); | ||
3881 | if(extra>1)luaK_reserveregs(fs,extra-1); | ||
3882 | } | ||
3883 | else{ | ||
3884 | if(e->k!=VVOID)luaK_exp2nextreg(fs,e); | ||
3885 | if(extra>0){ | ||
3886 | int reg=fs->freereg; | ||
3887 | luaK_reserveregs(fs,extra); | ||
3888 | luaK_nil(fs,reg,extra); | ||
3889 | } | ||
3890 | } | ||
3891 | } | ||
3892 | static void enterlevel(LexState*ls){ | ||
3893 | if(++ls->L->nCcalls>200) | ||
3894 | luaX_lexerror(ls,"chunk has too many syntax levels",0); | ||
3895 | } | ||
3896 | #define leavelevel(ls)((ls)->L->nCcalls--) | ||
3897 | static void enterblock(FuncState*fs,BlockCnt*bl,lu_byte isbreakable){ | ||
3898 | bl->breaklist=(-1); | ||
3899 | bl->isbreakable=isbreakable; | ||
3900 | bl->nactvar=fs->nactvar; | ||
3901 | bl->upval=0; | ||
3902 | bl->previous=fs->bl; | ||
3903 | fs->bl=bl; | ||
3904 | } | ||
3905 | static void leaveblock(FuncState*fs){ | ||
3906 | BlockCnt*bl=fs->bl; | ||
3907 | fs->bl=bl->previous; | ||
3908 | removevars(fs->ls,bl->nactvar); | ||
3909 | if(bl->upval) | ||
3910 | luaK_codeABC(fs,OP_CLOSE,bl->nactvar,0,0); | ||
3911 | fs->freereg=fs->nactvar; | ||
3912 | luaK_patchtohere(fs,bl->breaklist); | ||
3913 | } | ||
3914 | static void pushclosure(LexState*ls,FuncState*func,expdesc*v){ | ||
3915 | FuncState*fs=ls->fs; | ||
3916 | Proto*f=fs->f; | ||
3917 | int oldsize=f->sizep; | ||
3918 | int i; | ||
3919 | luaM_growvector(ls->L,f->p,fs->np,f->sizep,Proto*, | ||
3920 | ((1<<(9+9))-1),"constant table overflow"); | ||
3921 | while(oldsize<f->sizep)f->p[oldsize++]=NULL; | ||
3922 | f->p[fs->np++]=func->f; | ||
3923 | luaC_objbarrier(ls->L,f,func->f); | ||
3924 | init_exp(v,VRELOCABLE,luaK_codeABx(fs,OP_CLOSURE,0,fs->np-1)); | ||
3925 | for(i=0;i<func->f->nups;i++){ | ||
3926 | OpCode o=(func->upvalues[i].k==VLOCAL)?OP_MOVE:OP_GETUPVAL; | ||
3927 | luaK_codeABC(fs,o,0,func->upvalues[i].info,0); | ||
3928 | } | ||
3929 | } | ||
3930 | static void open_func(LexState*ls,FuncState*fs){ | ||
3931 | lua_State*L=ls->L; | ||
3932 | Proto*f=luaF_newproto(L); | ||
3933 | fs->f=f; | ||
3934 | fs->prev=ls->fs; | ||
3935 | fs->ls=ls; | ||
3936 | fs->L=L; | ||
3937 | ls->fs=fs; | ||
3938 | fs->pc=0; | ||
3939 | fs->lasttarget=-1; | ||
3940 | fs->jpc=(-1); | ||
3941 | fs->freereg=0; | ||
3942 | fs->nk=0; | ||
3943 | fs->np=0; | ||
3944 | fs->nlocvars=0; | ||
3945 | fs->nactvar=0; | ||
3946 | fs->bl=NULL; | ||
3947 | f->source=ls->source; | ||
3948 | f->maxstacksize=2; | ||
3949 | fs->h=luaH_new(L,0,0); | ||
3950 | sethvalue(L,L->top,fs->h); | ||
3951 | incr_top(L); | ||
3952 | setptvalue(L,L->top,f); | ||
3953 | incr_top(L); | ||
3954 | } | ||
3955 | static void close_func(LexState*ls){ | ||
3956 | lua_State*L=ls->L; | ||
3957 | FuncState*fs=ls->fs; | ||
3958 | Proto*f=fs->f; | ||
3959 | removevars(ls,0); | ||
3960 | luaK_ret(fs,0,0); | ||
3961 | luaM_reallocvector(L,f->code,f->sizecode,fs->pc,Instruction); | ||
3962 | f->sizecode=fs->pc; | ||
3963 | luaM_reallocvector(L,f->lineinfo,f->sizelineinfo,fs->pc,int); | ||
3964 | f->sizelineinfo=fs->pc; | ||
3965 | luaM_reallocvector(L,f->k,f->sizek,fs->nk,TValue); | ||
3966 | f->sizek=fs->nk; | ||
3967 | luaM_reallocvector(L,f->p,f->sizep,fs->np,Proto*); | ||
3968 | f->sizep=fs->np; | ||
3969 | luaM_reallocvector(L,f->locvars,f->sizelocvars,fs->nlocvars,LocVar); | ||
3970 | f->sizelocvars=fs->nlocvars; | ||
3971 | luaM_reallocvector(L,f->upvalues,f->sizeupvalues,f->nups,TString*); | ||
3972 | f->sizeupvalues=f->nups; | ||
3973 | ls->fs=fs->prev; | ||
3974 | if(fs)anchor_token(ls); | ||
3975 | L->top-=2; | ||
3976 | } | ||
3977 | static Proto*luaY_parser(lua_State*L,ZIO*z,Mbuffer*buff,const char*name){ | ||
3978 | struct LexState lexstate; | ||
3979 | struct FuncState funcstate; | ||
3980 | lexstate.buff=buff; | ||
3981 | luaX_setinput(L,&lexstate,z,luaS_new(L,name)); | ||
3982 | open_func(&lexstate,&funcstate); | ||
3983 | funcstate.f->is_vararg=2; | ||
3984 | luaX_next(&lexstate); | ||
3985 | chunk(&lexstate); | ||
3986 | check(&lexstate,TK_EOS); | ||
3987 | close_func(&lexstate); | ||
3988 | return funcstate.f; | ||
3989 | } | ||
3990 | static void field(LexState*ls,expdesc*v){ | ||
3991 | FuncState*fs=ls->fs; | ||
3992 | expdesc key; | ||
3993 | luaK_exp2anyreg(fs,v); | ||
3994 | luaX_next(ls); | ||
3995 | checkname(ls,&key); | ||
3996 | luaK_indexed(fs,v,&key); | ||
3997 | } | ||
3998 | static void yindex(LexState*ls,expdesc*v){ | ||
3999 | luaX_next(ls); | ||
4000 | expr(ls,v); | ||
4001 | luaK_exp2val(ls->fs,v); | ||
4002 | checknext(ls,']'); | ||
4003 | } | ||
4004 | struct ConsControl{ | ||
4005 | expdesc v; | ||
4006 | expdesc*t; | ||
4007 | int nh; | ||
4008 | int na; | ||
4009 | int tostore; | ||
4010 | }; | ||
4011 | static void recfield(LexState*ls,struct ConsControl*cc){ | ||
4012 | FuncState*fs=ls->fs; | ||
4013 | int reg=ls->fs->freereg; | ||
4014 | expdesc key,val; | ||
4015 | int rkkey; | ||
4016 | if(ls->t.token==TK_NAME){ | ||
4017 | luaY_checklimit(fs,cc->nh,(INT_MAX-2),"items in a constructor"); | ||
4018 | checkname(ls,&key); | ||
4019 | } | ||
4020 | else | ||
4021 | yindex(ls,&key); | ||
4022 | cc->nh++; | ||
4023 | checknext(ls,'='); | ||
4024 | rkkey=luaK_exp2RK(fs,&key); | ||
4025 | expr(ls,&val); | ||
4026 | luaK_codeABC(fs,OP_SETTABLE,cc->t->u.s.info,rkkey,luaK_exp2RK(fs,&val)); | ||
4027 | fs->freereg=reg; | ||
4028 | } | ||
4029 | static void closelistfield(FuncState*fs,struct ConsControl*cc){ | ||
4030 | if(cc->v.k==VVOID)return; | ||
4031 | luaK_exp2nextreg(fs,&cc->v); | ||
4032 | cc->v.k=VVOID; | ||
4033 | if(cc->tostore==50){ | ||
4034 | luaK_setlist(fs,cc->t->u.s.info,cc->na,cc->tostore); | ||
4035 | cc->tostore=0; | ||
4036 | } | ||
4037 | } | ||
4038 | static void lastlistfield(FuncState*fs,struct ConsControl*cc){ | ||
4039 | if(cc->tostore==0)return; | ||
4040 | if(hasmultret(cc->v.k)){ | ||
4041 | luaK_setmultret(fs,&cc->v); | ||
4042 | luaK_setlist(fs,cc->t->u.s.info,cc->na,(-1)); | ||
4043 | cc->na--; | ||
4044 | } | ||
4045 | else{ | ||
4046 | if(cc->v.k!=VVOID) | ||
4047 | luaK_exp2nextreg(fs,&cc->v); | ||
4048 | luaK_setlist(fs,cc->t->u.s.info,cc->na,cc->tostore); | ||
4049 | } | ||
4050 | } | ||
4051 | static void listfield(LexState*ls,struct ConsControl*cc){ | ||
4052 | expr(ls,&cc->v); | ||
4053 | luaY_checklimit(ls->fs,cc->na,(INT_MAX-2),"items in a constructor"); | ||
4054 | cc->na++; | ||
4055 | cc->tostore++; | ||
4056 | } | ||
4057 | static void constructor(LexState*ls,expdesc*t){ | ||
4058 | FuncState*fs=ls->fs; | ||
4059 | int line=ls->linenumber; | ||
4060 | int pc=luaK_codeABC(fs,OP_NEWTABLE,0,0,0); | ||
4061 | struct ConsControl cc; | ||
4062 | cc.na=cc.nh=cc.tostore=0; | ||
4063 | cc.t=t; | ||
4064 | init_exp(t,VRELOCABLE,pc); | ||
4065 | init_exp(&cc.v,VVOID,0); | ||
4066 | luaK_exp2nextreg(ls->fs,t); | ||
4067 | checknext(ls,'{'); | ||
4068 | do{ | ||
4069 | if(ls->t.token=='}')break; | ||
4070 | closelistfield(fs,&cc); | ||
4071 | switch(ls->t.token){ | ||
4072 | case TK_NAME:{ | ||
4073 | luaX_lookahead(ls); | ||
4074 | if(ls->lookahead.token!='=') | ||
4075 | listfield(ls,&cc); | ||
4076 | else | ||
4077 | recfield(ls,&cc); | ||
4078 | break; | ||
4079 | } | ||
4080 | case'[':{ | ||
4081 | recfield(ls,&cc); | ||
4082 | break; | ||
4083 | } | ||
4084 | default:{ | ||
4085 | listfield(ls,&cc); | ||
4086 | break; | ||
4087 | } | ||
4088 | } | ||
4089 | }while(testnext(ls,',')||testnext(ls,';')); | ||
4090 | check_match(ls,'}','{',line); | ||
4091 | lastlistfield(fs,&cc); | ||
4092 | SETARG_B(fs->f->code[pc],luaO_int2fb(cc.na)); | ||
4093 | SETARG_C(fs->f->code[pc],luaO_int2fb(cc.nh)); | ||
4094 | } | ||
4095 | static void parlist(LexState*ls){ | ||
4096 | FuncState*fs=ls->fs; | ||
4097 | Proto*f=fs->f; | ||
4098 | int nparams=0; | ||
4099 | f->is_vararg=0; | ||
4100 | if(ls->t.token!=')'){ | ||
4101 | do{ | ||
4102 | switch(ls->t.token){ | ||
4103 | case TK_NAME:{ | ||
4104 | new_localvar(ls,str_checkname(ls),nparams++); | ||
4105 | break; | ||
4106 | } | ||
4107 | case TK_DOTS:{ | ||
4108 | luaX_next(ls); | ||
4109 | f->is_vararg|=2; | ||
4110 | break; | ||
4111 | } | ||
4112 | default:luaX_syntaxerror(ls,"<name> or "LUA_QL("...")" expected"); | ||
4113 | } | ||
4114 | }while(!f->is_vararg&&testnext(ls,',')); | ||
4115 | } | ||
4116 | adjustlocalvars(ls,nparams); | ||
4117 | f->numparams=cast_byte(fs->nactvar-(f->is_vararg&1)); | ||
4118 | luaK_reserveregs(fs,fs->nactvar); | ||
4119 | } | ||
4120 | static void body(LexState*ls,expdesc*e,int needself,int line){ | ||
4121 | FuncState new_fs; | ||
4122 | open_func(ls,&new_fs); | ||
4123 | new_fs.f->linedefined=line; | ||
4124 | checknext(ls,'('); | ||
4125 | if(needself){ | ||
4126 | new_localvarliteral(ls,"self",0); | ||
4127 | adjustlocalvars(ls,1); | ||
4128 | } | ||
4129 | parlist(ls); | ||
4130 | checknext(ls,')'); | ||
4131 | chunk(ls); | ||
4132 | new_fs.f->lastlinedefined=ls->linenumber; | ||
4133 | check_match(ls,TK_END,TK_FUNCTION,line); | ||
4134 | close_func(ls); | ||
4135 | pushclosure(ls,&new_fs,e); | ||
4136 | } | ||
4137 | static int explist1(LexState*ls,expdesc*v){ | ||
4138 | int n=1; | ||
4139 | expr(ls,v); | ||
4140 | while(testnext(ls,',')){ | ||
4141 | luaK_exp2nextreg(ls->fs,v); | ||
4142 | expr(ls,v); | ||
4143 | n++; | ||
4144 | } | ||
4145 | return n; | ||
4146 | } | ||
4147 | static void funcargs(LexState*ls,expdesc*f){ | ||
4148 | FuncState*fs=ls->fs; | ||
4149 | expdesc args; | ||
4150 | int base,nparams; | ||
4151 | int line=ls->linenumber; | ||
4152 | switch(ls->t.token){ | ||
4153 | case'(':{ | ||
4154 | if(line!=ls->lastline) | ||
4155 | luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); | ||
4156 | luaX_next(ls); | ||
4157 | if(ls->t.token==')') | ||
4158 | args.k=VVOID; | ||
4159 | else{ | ||
4160 | explist1(ls,&args); | ||
4161 | luaK_setmultret(fs,&args); | ||
4162 | } | ||
4163 | check_match(ls,')','(',line); | ||
4164 | break; | ||
4165 | } | ||
4166 | case'{':{ | ||
4167 | constructor(ls,&args); | ||
4168 | break; | ||
4169 | } | ||
4170 | case TK_STRING:{ | ||
4171 | codestring(ls,&args,ls->t.seminfo.ts); | ||
4172 | luaX_next(ls); | ||
4173 | break; | ||
4174 | } | ||
4175 | default:{ | ||
4176 | luaX_syntaxerror(ls,"function arguments expected"); | ||
4177 | return; | ||
4178 | } | ||
4179 | } | ||
4180 | base=f->u.s.info; | ||
4181 | if(hasmultret(args.k)) | ||
4182 | nparams=(-1); | ||
4183 | else{ | ||
4184 | if(args.k!=VVOID) | ||
4185 | luaK_exp2nextreg(fs,&args); | ||
4186 | nparams=fs->freereg-(base+1); | ||
4187 | } | ||
4188 | init_exp(f,VCALL,luaK_codeABC(fs,OP_CALL,base,nparams+1,2)); | ||
4189 | luaK_fixline(fs,line); | ||
4190 | fs->freereg=base+1; | ||
4191 | } | ||
4192 | static void prefixexp(LexState*ls,expdesc*v){ | ||
4193 | switch(ls->t.token){ | ||
4194 | case'(':{ | ||
4195 | int line=ls->linenumber; | ||
4196 | luaX_next(ls); | ||
4197 | expr(ls,v); | ||
4198 | check_match(ls,')','(',line); | ||
4199 | luaK_dischargevars(ls->fs,v); | ||
4200 | return; | ||
4201 | } | ||
4202 | case TK_NAME:{ | ||
4203 | singlevar(ls,v); | ||
4204 | return; | ||
4205 | } | ||
4206 | default:{ | ||
4207 | luaX_syntaxerror(ls,"unexpected symbol"); | ||
4208 | return; | ||
4209 | } | ||
4210 | } | ||
4211 | } | ||
4212 | static void primaryexp(LexState*ls,expdesc*v){ | ||
4213 | FuncState*fs=ls->fs; | ||
4214 | prefixexp(ls,v); | ||
4215 | for(;;){ | ||
4216 | switch(ls->t.token){ | ||
4217 | case'.':{ | ||
4218 | field(ls,v); | ||
4219 | break; | ||
4220 | } | ||
4221 | case'[':{ | ||
4222 | expdesc key; | ||
4223 | luaK_exp2anyreg(fs,v); | ||
4224 | yindex(ls,&key); | ||
4225 | luaK_indexed(fs,v,&key); | ||
4226 | break; | ||
4227 | } | ||
4228 | case':':{ | ||
4229 | expdesc key; | ||
4230 | luaX_next(ls); | ||
4231 | checkname(ls,&key); | ||
4232 | luaK_self(fs,v,&key); | ||
4233 | funcargs(ls,v); | ||
4234 | break; | ||
4235 | } | ||
4236 | case'(':case TK_STRING:case'{':{ | ||
4237 | luaK_exp2nextreg(fs,v); | ||
4238 | funcargs(ls,v); | ||
4239 | break; | ||
4240 | } | ||
4241 | default:return; | ||
4242 | } | ||
4243 | } | ||
4244 | } | ||
4245 | static void simpleexp(LexState*ls,expdesc*v){ | ||
4246 | switch(ls->t.token){ | ||
4247 | case TK_NUMBER:{ | ||
4248 | init_exp(v,VKNUM,0); | ||
4249 | v->u.nval=ls->t.seminfo.r; | ||
4250 | break; | ||
4251 | } | ||
4252 | case TK_STRING:{ | ||
4253 | codestring(ls,v,ls->t.seminfo.ts); | ||
4254 | break; | ||
4255 | } | ||
4256 | case TK_NIL:{ | ||
4257 | init_exp(v,VNIL,0); | ||
4258 | break; | ||
4259 | } | ||
4260 | case TK_TRUE:{ | ||
4261 | init_exp(v,VTRUE,0); | ||
4262 | break; | ||
4263 | } | ||
4264 | case TK_FALSE:{ | ||
4265 | init_exp(v,VFALSE,0); | ||
4266 | break; | ||
4267 | } | ||
4268 | case TK_DOTS:{ | ||
4269 | FuncState*fs=ls->fs; | ||
4270 | check_condition(ls,fs->f->is_vararg, | ||
4271 | "cannot use "LUA_QL("...")" outside a vararg function"); | ||
4272 | fs->f->is_vararg&=~4; | ||
4273 | init_exp(v,VVARARG,luaK_codeABC(fs,OP_VARARG,0,1,0)); | ||
4274 | break; | ||
4275 | } | ||
4276 | case'{':{ | ||
4277 | constructor(ls,v); | ||
4278 | return; | ||
4279 | } | ||
4280 | case TK_FUNCTION:{ | ||
4281 | luaX_next(ls); | ||
4282 | body(ls,v,0,ls->linenumber); | ||
4283 | return; | ||
4284 | } | ||
4285 | default:{ | ||
4286 | primaryexp(ls,v); | ||
4287 | return; | ||
4288 | } | ||
4289 | } | ||
4290 | luaX_next(ls); | ||
4291 | } | ||
4292 | static UnOpr getunopr(int op){ | ||
4293 | switch(op){ | ||
4294 | case TK_NOT:return OPR_NOT; | ||
4295 | case'-':return OPR_MINUS; | ||
4296 | case'#':return OPR_LEN; | ||
4297 | default:return OPR_NOUNOPR; | ||
4298 | } | ||
4299 | } | ||
4300 | static BinOpr getbinopr(int op){ | ||
4301 | switch(op){ | ||
4302 | case'+':return OPR_ADD; | ||
4303 | case'-':return OPR_SUB; | ||
4304 | case'*':return OPR_MUL; | ||
4305 | case'/':return OPR_DIV; | ||
4306 | case'%':return OPR_MOD; | ||
4307 | case'^':return OPR_POW; | ||
4308 | case TK_CONCAT:return OPR_CONCAT; | ||
4309 | case TK_NE:return OPR_NE; | ||
4310 | case TK_EQ:return OPR_EQ; | ||
4311 | case'<':return OPR_LT; | ||
4312 | case TK_LE:return OPR_LE; | ||
4313 | case'>':return OPR_GT; | ||
4314 | case TK_GE:return OPR_GE; | ||
4315 | case TK_AND:return OPR_AND; | ||
4316 | case TK_OR:return OPR_OR; | ||
4317 | default:return OPR_NOBINOPR; | ||
4318 | } | ||
4319 | } | ||
4320 | static const struct{ | ||
4321 | lu_byte left; | ||
4322 | lu_byte right; | ||
4323 | }priority[]={ | ||
4324 | {6,6},{6,6},{7,7},{7,7},{7,7}, | ||
4325 | {10,9},{5,4}, | ||
4326 | {3,3},{3,3}, | ||
4327 | {3,3},{3,3},{3,3},{3,3}, | ||
4328 | {2,2},{1,1} | ||
4329 | }; | ||
4330 | static BinOpr subexpr(LexState*ls,expdesc*v,unsigned int limit){ | ||
4331 | BinOpr op; | ||
4332 | UnOpr uop; | ||
4333 | enterlevel(ls); | ||
4334 | uop=getunopr(ls->t.token); | ||
4335 | if(uop!=OPR_NOUNOPR){ | ||
4336 | luaX_next(ls); | ||
4337 | subexpr(ls,v,8); | ||
4338 | luaK_prefix(ls->fs,uop,v); | ||
4339 | } | ||
4340 | else simpleexp(ls,v); | ||
4341 | op=getbinopr(ls->t.token); | ||
4342 | while(op!=OPR_NOBINOPR&&priority[op].left>limit){ | ||
4343 | expdesc v2; | ||
4344 | BinOpr nextop; | ||
4345 | luaX_next(ls); | ||
4346 | luaK_infix(ls->fs,op,v); | ||
4347 | nextop=subexpr(ls,&v2,priority[op].right); | ||
4348 | luaK_posfix(ls->fs,op,v,&v2); | ||
4349 | op=nextop; | ||
4350 | } | ||
4351 | leavelevel(ls); | ||
4352 | return op; | ||
4353 | } | ||
4354 | static void expr(LexState*ls,expdesc*v){ | ||
4355 | subexpr(ls,v,0); | ||
4356 | } | ||
4357 | static int block_follow(int token){ | ||
4358 | switch(token){ | ||
4359 | case TK_ELSE:case TK_ELSEIF:case TK_END: | ||
4360 | case TK_UNTIL:case TK_EOS: | ||
4361 | return 1; | ||
4362 | default:return 0; | ||
4363 | } | ||
4364 | } | ||
4365 | static void block(LexState*ls){ | ||
4366 | FuncState*fs=ls->fs; | ||
4367 | BlockCnt bl; | ||
4368 | enterblock(fs,&bl,0); | ||
4369 | chunk(ls); | ||
4370 | leaveblock(fs); | ||
4371 | } | ||
4372 | struct LHS_assign{ | ||
4373 | struct LHS_assign*prev; | ||
4374 | expdesc v; | ||
4375 | }; | ||
4376 | static void check_conflict(LexState*ls,struct LHS_assign*lh,expdesc*v){ | ||
4377 | FuncState*fs=ls->fs; | ||
4378 | int extra=fs->freereg; | ||
4379 | int conflict=0; | ||
4380 | for(;lh;lh=lh->prev){ | ||
4381 | if(lh->v.k==VINDEXED){ | ||
4382 | if(lh->v.u.s.info==v->u.s.info){ | ||
4383 | conflict=1; | ||
4384 | lh->v.u.s.info=extra; | ||
4385 | } | ||
4386 | if(lh->v.u.s.aux==v->u.s.info){ | ||
4387 | conflict=1; | ||
4388 | lh->v.u.s.aux=extra; | ||
4389 | } | ||
4390 | } | ||
4391 | } | ||
4392 | if(conflict){ | ||
4393 | luaK_codeABC(fs,OP_MOVE,fs->freereg,v->u.s.info,0); | ||
4394 | luaK_reserveregs(fs,1); | ||
4395 | } | ||
4396 | } | ||
4397 | static void assignment(LexState*ls,struct LHS_assign*lh,int nvars){ | ||
4398 | expdesc e; | ||
4399 | check_condition(ls,VLOCAL<=lh->v.k&&lh->v.k<=VINDEXED, | ||
4400 | "syntax error"); | ||
4401 | if(testnext(ls,',')){ | ||
4402 | struct LHS_assign nv; | ||
4403 | nv.prev=lh; | ||
4404 | primaryexp(ls,&nv.v); | ||
4405 | if(nv.v.k==VLOCAL) | ||
4406 | check_conflict(ls,lh,&nv.v); | ||
4407 | luaY_checklimit(ls->fs,nvars,200-ls->L->nCcalls, | ||
4408 | "variables in assignment"); | ||
4409 | assignment(ls,&nv,nvars+1); | ||
4410 | } | ||
4411 | else{ | ||
4412 | int nexps; | ||
4413 | checknext(ls,'='); | ||
4414 | nexps=explist1(ls,&e); | ||
4415 | if(nexps!=nvars){ | ||
4416 | adjust_assign(ls,nvars,nexps,&e); | ||
4417 | if(nexps>nvars) | ||
4418 | ls->fs->freereg-=nexps-nvars; | ||
4419 | } | ||
4420 | else{ | ||
4421 | luaK_setoneret(ls->fs,&e); | ||
4422 | luaK_storevar(ls->fs,&lh->v,&e); | ||
4423 | return; | ||
4424 | } | ||
4425 | } | ||
4426 | init_exp(&e,VNONRELOC,ls->fs->freereg-1); | ||
4427 | luaK_storevar(ls->fs,&lh->v,&e); | ||
4428 | } | ||
4429 | static int cond(LexState*ls){ | ||
4430 | expdesc v; | ||
4431 | expr(ls,&v); | ||
4432 | if(v.k==VNIL)v.k=VFALSE; | ||
4433 | luaK_goiftrue(ls->fs,&v); | ||
4434 | return v.f; | ||
4435 | } | ||
4436 | static void breakstat(LexState*ls){ | ||
4437 | FuncState*fs=ls->fs; | ||
4438 | BlockCnt*bl=fs->bl; | ||
4439 | int upval=0; | ||
4440 | while(bl&&!bl->isbreakable){ | ||
4441 | upval|=bl->upval; | ||
4442 | bl=bl->previous; | ||
4443 | } | ||
4444 | if(!bl) | ||
4445 | luaX_syntaxerror(ls,"no loop to break"); | ||
4446 | if(upval) | ||
4447 | luaK_codeABC(fs,OP_CLOSE,bl->nactvar,0,0); | ||
4448 | luaK_concat(fs,&bl->breaklist,luaK_jump(fs)); | ||
4449 | } | ||
4450 | static void whilestat(LexState*ls,int line){ | ||
4451 | FuncState*fs=ls->fs; | ||
4452 | int whileinit; | ||
4453 | int condexit; | ||
4454 | BlockCnt bl; | ||
4455 | luaX_next(ls); | ||
4456 | whileinit=luaK_getlabel(fs); | ||
4457 | condexit=cond(ls); | ||
4458 | enterblock(fs,&bl,1); | ||
4459 | checknext(ls,TK_DO); | ||
4460 | block(ls); | ||
4461 | luaK_patchlist(fs,luaK_jump(fs),whileinit); | ||
4462 | check_match(ls,TK_END,TK_WHILE,line); | ||
4463 | leaveblock(fs); | ||
4464 | luaK_patchtohere(fs,condexit); | ||
4465 | } | ||
4466 | static void repeatstat(LexState*ls,int line){ | ||
4467 | int condexit; | ||
4468 | FuncState*fs=ls->fs; | ||
4469 | int repeat_init=luaK_getlabel(fs); | ||
4470 | BlockCnt bl1,bl2; | ||
4471 | enterblock(fs,&bl1,1); | ||
4472 | enterblock(fs,&bl2,0); | ||
4473 | luaX_next(ls); | ||
4474 | chunk(ls); | ||
4475 | check_match(ls,TK_UNTIL,TK_REPEAT,line); | ||
4476 | condexit=cond(ls); | ||
4477 | if(!bl2.upval){ | ||
4478 | leaveblock(fs); | ||
4479 | luaK_patchlist(ls->fs,condexit,repeat_init); | ||
4480 | } | ||
4481 | else{ | ||
4482 | breakstat(ls); | ||
4483 | luaK_patchtohere(ls->fs,condexit); | ||
4484 | leaveblock(fs); | ||
4485 | luaK_patchlist(ls->fs,luaK_jump(fs),repeat_init); | ||
4486 | } | ||
4487 | leaveblock(fs); | ||
4488 | } | ||
4489 | static int exp1(LexState*ls){ | ||
4490 | expdesc e; | ||
4491 | int k; | ||
4492 | expr(ls,&e); | ||
4493 | k=e.k; | ||
4494 | luaK_exp2nextreg(ls->fs,&e); | ||
4495 | return k; | ||
4496 | } | ||
4497 | static void forbody(LexState*ls,int base,int line,int nvars,int isnum){ | ||
4498 | BlockCnt bl; | ||
4499 | FuncState*fs=ls->fs; | ||
4500 | int prep,endfor; | ||
4501 | adjustlocalvars(ls,3); | ||
4502 | checknext(ls,TK_DO); | ||
4503 | prep=isnum?luaK_codeAsBx(fs,OP_FORPREP,base,(-1)):luaK_jump(fs); | ||
4504 | enterblock(fs,&bl,0); | ||
4505 | adjustlocalvars(ls,nvars); | ||
4506 | luaK_reserveregs(fs,nvars); | ||
4507 | block(ls); | ||
4508 | leaveblock(fs); | ||
4509 | luaK_patchtohere(fs,prep); | ||
4510 | endfor=(isnum)?luaK_codeAsBx(fs,OP_FORLOOP,base,(-1)): | ||
4511 | luaK_codeABC(fs,OP_TFORLOOP,base,0,nvars); | ||
4512 | luaK_fixline(fs,line); | ||
4513 | luaK_patchlist(fs,(isnum?endfor:luaK_jump(fs)),prep+1); | ||
4514 | } | ||
4515 | static void fornum(LexState*ls,TString*varname,int line){ | ||
4516 | FuncState*fs=ls->fs; | ||
4517 | int base=fs->freereg; | ||
4518 | new_localvarliteral(ls,"(for index)",0); | ||
4519 | new_localvarliteral(ls,"(for limit)",1); | ||
4520 | new_localvarliteral(ls,"(for step)",2); | ||
4521 | new_localvar(ls,varname,3); | ||
4522 | checknext(ls,'='); | ||
4523 | exp1(ls); | ||
4524 | checknext(ls,','); | ||
4525 | exp1(ls); | ||
4526 | if(testnext(ls,',')) | ||
4527 | exp1(ls); | ||
4528 | else{ | ||
4529 | luaK_codeABx(fs,OP_LOADK,fs->freereg,luaK_numberK(fs,1)); | ||
4530 | luaK_reserveregs(fs,1); | ||
4531 | } | ||
4532 | forbody(ls,base,line,1,1); | ||
4533 | } | ||
4534 | static void forlist(LexState*ls,TString*indexname){ | ||
4535 | FuncState*fs=ls->fs; | ||
4536 | expdesc e; | ||
4537 | int nvars=0; | ||
4538 | int line; | ||
4539 | int base=fs->freereg; | ||
4540 | new_localvarliteral(ls,"(for generator)",nvars++); | ||
4541 | new_localvarliteral(ls,"(for state)",nvars++); | ||
4542 | new_localvarliteral(ls,"(for control)",nvars++); | ||
4543 | new_localvar(ls,indexname,nvars++); | ||
4544 | while(testnext(ls,',')) | ||
4545 | new_localvar(ls,str_checkname(ls),nvars++); | ||
4546 | checknext(ls,TK_IN); | ||
4547 | line=ls->linenumber; | ||
4548 | adjust_assign(ls,3,explist1(ls,&e),&e); | ||
4549 | luaK_checkstack(fs,3); | ||
4550 | forbody(ls,base,line,nvars-3,0); | ||
4551 | } | ||
4552 | static void forstat(LexState*ls,int line){ | ||
4553 | FuncState*fs=ls->fs; | ||
4554 | TString*varname; | ||
4555 | BlockCnt bl; | ||
4556 | enterblock(fs,&bl,1); | ||
4557 | luaX_next(ls); | ||
4558 | varname=str_checkname(ls); | ||
4559 | switch(ls->t.token){ | ||
4560 | case'=':fornum(ls,varname,line);break; | ||
4561 | case',':case TK_IN:forlist(ls,varname);break; | ||
4562 | default:luaX_syntaxerror(ls,LUA_QL("=")" or "LUA_QL("in")" expected"); | ||
4563 | } | ||
4564 | check_match(ls,TK_END,TK_FOR,line); | ||
4565 | leaveblock(fs); | ||
4566 | } | ||
4567 | static int test_then_block(LexState*ls){ | ||
4568 | int condexit; | ||
4569 | luaX_next(ls); | ||
4570 | condexit=cond(ls); | ||
4571 | checknext(ls,TK_THEN); | ||
4572 | block(ls); | ||
4573 | return condexit; | ||
4574 | } | ||
4575 | static void ifstat(LexState*ls,int line){ | ||
4576 | FuncState*fs=ls->fs; | ||
4577 | int flist; | ||
4578 | int escapelist=(-1); | ||
4579 | flist=test_then_block(ls); | ||
4580 | while(ls->t.token==TK_ELSEIF){ | ||
4581 | luaK_concat(fs,&escapelist,luaK_jump(fs)); | ||
4582 | luaK_patchtohere(fs,flist); | ||
4583 | flist=test_then_block(ls); | ||
4584 | } | ||
4585 | if(ls->t.token==TK_ELSE){ | ||
4586 | luaK_concat(fs,&escapelist,luaK_jump(fs)); | ||
4587 | luaK_patchtohere(fs,flist); | ||
4588 | luaX_next(ls); | ||
4589 | block(ls); | ||
4590 | } | ||
4591 | else | ||
4592 | luaK_concat(fs,&escapelist,flist); | ||
4593 | luaK_patchtohere(fs,escapelist); | ||
4594 | check_match(ls,TK_END,TK_IF,line); | ||
4595 | } | ||
4596 | static void localfunc(LexState*ls){ | ||
4597 | expdesc v,b; | ||
4598 | FuncState*fs=ls->fs; | ||
4599 | new_localvar(ls,str_checkname(ls),0); | ||
4600 | init_exp(&v,VLOCAL,fs->freereg); | ||
4601 | luaK_reserveregs(fs,1); | ||
4602 | adjustlocalvars(ls,1); | ||
4603 | body(ls,&b,0,ls->linenumber); | ||
4604 | luaK_storevar(fs,&v,&b); | ||
4605 | getlocvar(fs,fs->nactvar-1).startpc=fs->pc; | ||
4606 | } | ||
4607 | static void localstat(LexState*ls){ | ||
4608 | int nvars=0; | ||
4609 | int nexps; | ||
4610 | expdesc e; | ||
4611 | do{ | ||
4612 | new_localvar(ls,str_checkname(ls),nvars++); | ||
4613 | }while(testnext(ls,',')); | ||
4614 | if(testnext(ls,'=')) | ||
4615 | nexps=explist1(ls,&e); | ||
4616 | else{ | ||
4617 | e.k=VVOID; | ||
4618 | nexps=0; | ||
4619 | } | ||
4620 | adjust_assign(ls,nvars,nexps,&e); | ||
4621 | adjustlocalvars(ls,nvars); | ||
4622 | } | ||
4623 | static int funcname(LexState*ls,expdesc*v){ | ||
4624 | int needself=0; | ||
4625 | singlevar(ls,v); | ||
4626 | while(ls->t.token=='.') | ||
4627 | field(ls,v); | ||
4628 | if(ls->t.token==':'){ | ||
4629 | needself=1; | ||
4630 | field(ls,v); | ||
4631 | } | ||
4632 | return needself; | ||
4633 | } | ||
4634 | static void funcstat(LexState*ls,int line){ | ||
4635 | int needself; | ||
4636 | expdesc v,b; | ||
4637 | luaX_next(ls); | ||
4638 | needself=funcname(ls,&v); | ||
4639 | body(ls,&b,needself,line); | ||
4640 | luaK_storevar(ls->fs,&v,&b); | ||
4641 | luaK_fixline(ls->fs,line); | ||
4642 | } | ||
4643 | static void exprstat(LexState*ls){ | ||
4644 | FuncState*fs=ls->fs; | ||
4645 | struct LHS_assign v; | ||
4646 | primaryexp(ls,&v.v); | ||
4647 | if(v.v.k==VCALL) | ||
4648 | SETARG_C(getcode(fs,&v.v),1); | ||
4649 | else{ | ||
4650 | v.prev=NULL; | ||
4651 | assignment(ls,&v,1); | ||
4652 | } | ||
4653 | } | ||
4654 | static void retstat(LexState*ls){ | ||
4655 | FuncState*fs=ls->fs; | ||
4656 | expdesc e; | ||
4657 | int first,nret; | ||
4658 | luaX_next(ls); | ||
4659 | if(block_follow(ls->t.token)||ls->t.token==';') | ||
4660 | first=nret=0; | ||
4661 | else{ | ||
4662 | nret=explist1(ls,&e); | ||
4663 | if(hasmultret(e.k)){ | ||
4664 | luaK_setmultret(fs,&e); | ||
4665 | if(e.k==VCALL&&nret==1){ | ||
4666 | SET_OPCODE(getcode(fs,&e),OP_TAILCALL); | ||
4667 | } | ||
4668 | first=fs->nactvar; | ||
4669 | nret=(-1); | ||
4670 | } | ||
4671 | else{ | ||
4672 | if(nret==1) | ||
4673 | first=luaK_exp2anyreg(fs,&e); | ||
4674 | else{ | ||
4675 | luaK_exp2nextreg(fs,&e); | ||
4676 | first=fs->nactvar; | ||
4677 | } | ||
4678 | } | ||
4679 | } | ||
4680 | luaK_ret(fs,first,nret); | ||
4681 | } | ||
4682 | static int statement(LexState*ls){ | ||
4683 | int line=ls->linenumber; | ||
4684 | switch(ls->t.token){ | ||
4685 | case TK_IF:{ | ||
4686 | ifstat(ls,line); | ||
4687 | return 0; | ||
4688 | } | ||
4689 | case TK_WHILE:{ | ||
4690 | whilestat(ls,line); | ||
4691 | return 0; | ||
4692 | } | ||
4693 | case TK_DO:{ | ||
4694 | luaX_next(ls); | ||
4695 | block(ls); | ||
4696 | check_match(ls,TK_END,TK_DO,line); | ||
4697 | return 0; | ||
4698 | } | ||
4699 | case TK_FOR:{ | ||
4700 | forstat(ls,line); | ||
4701 | return 0; | ||
4702 | } | ||
4703 | case TK_REPEAT:{ | ||
4704 | repeatstat(ls,line); | ||
4705 | return 0; | ||
4706 | } | ||
4707 | case TK_FUNCTION:{ | ||
4708 | funcstat(ls,line); | ||
4709 | return 0; | ||
4710 | } | ||
4711 | case TK_LOCAL:{ | ||
4712 | luaX_next(ls); | ||
4713 | if(testnext(ls,TK_FUNCTION)) | ||
4714 | localfunc(ls); | ||
4715 | else | ||
4716 | localstat(ls); | ||
4717 | return 0; | ||
4718 | } | ||
4719 | case TK_RETURN:{ | ||
4720 | retstat(ls); | ||
4721 | return 1; | ||
4722 | } | ||
4723 | case TK_BREAK:{ | ||
4724 | luaX_next(ls); | ||
4725 | breakstat(ls); | ||
4726 | return 1; | ||
4727 | } | ||
4728 | default:{ | ||
4729 | exprstat(ls); | ||
4730 | return 0; | ||
4731 | } | ||
4732 | } | ||
4733 | } | ||
4734 | static void chunk(LexState*ls){ | ||
4735 | int islast=0; | ||
4736 | enterlevel(ls); | ||
4737 | while(!islast&&!block_follow(ls->t.token)){ | ||
4738 | islast=statement(ls); | ||
4739 | testnext(ls,';'); | ||
4740 | ls->fs->freereg=ls->fs->nactvar; | ||
4741 | } | ||
4742 | leavelevel(ls); | ||
4743 | } | ||
4744 | static const TValue*luaV_tonumber(const TValue*obj,TValue*n){ | ||
4745 | lua_Number num; | ||
4746 | if(ttisnumber(obj))return obj; | ||
4747 | if(ttisstring(obj)&&luaO_str2d(svalue(obj),&num)){ | ||
4748 | setnvalue(n,num); | ||
4749 | return n; | ||
4750 | } | ||
4751 | else | ||
4752 | return NULL; | ||
4753 | } | ||
4754 | static int luaV_tostring(lua_State*L,StkId obj){ | ||
4755 | if(!ttisnumber(obj)) | ||
4756 | return 0; | ||
4757 | else{ | ||
4758 | char s[32]; | ||
4759 | lua_Number n=nvalue(obj); | ||
4760 | lua_number2str(s,n); | ||
4761 | setsvalue(L,obj,luaS_new(L,s)); | ||
4762 | return 1; | ||
4763 | } | ||
4764 | } | ||
4765 | static void callTMres(lua_State*L,StkId res,const TValue*f, | ||
4766 | const TValue*p1,const TValue*p2){ | ||
4767 | ptrdiff_t result=savestack(L,res); | ||
4768 | setobj(L,L->top,f); | ||
4769 | setobj(L,L->top+1,p1); | ||
4770 | setobj(L,L->top+2,p2); | ||
4771 | luaD_checkstack(L,3); | ||
4772 | L->top+=3; | ||
4773 | luaD_call(L,L->top-3,1); | ||
4774 | res=restorestack(L,result); | ||
4775 | L->top--; | ||
4776 | setobj(L,res,L->top); | ||
4777 | } | ||
4778 | static void callTM(lua_State*L,const TValue*f,const TValue*p1, | ||
4779 | const TValue*p2,const TValue*p3){ | ||
4780 | setobj(L,L->top,f); | ||
4781 | setobj(L,L->top+1,p1); | ||
4782 | setobj(L,L->top+2,p2); | ||
4783 | setobj(L,L->top+3,p3); | ||
4784 | luaD_checkstack(L,4); | ||
4785 | L->top+=4; | ||
4786 | luaD_call(L,L->top-4,0); | ||
4787 | } | ||
4788 | static void luaV_gettable(lua_State*L,const TValue*t,TValue*key,StkId val){ | ||
4789 | int loop; | ||
4790 | for(loop=0;loop<100;loop++){ | ||
4791 | const TValue*tm; | ||
4792 | if(ttistable(t)){ | ||
4793 | Table*h=hvalue(t); | ||
4794 | const TValue*res=luaH_get(h,key); | ||
4795 | if(!ttisnil(res)|| | ||
4796 | (tm=fasttm(L,h->metatable,TM_INDEX))==NULL){ | ||
4797 | setobj(L,val,res); | ||
4798 | return; | ||
4799 | } | ||
4800 | } | ||
4801 | else if(ttisnil(tm=luaT_gettmbyobj(L,t,TM_INDEX))) | ||
4802 | luaG_typeerror(L,t,"index"); | ||
4803 | if(ttisfunction(tm)){ | ||
4804 | callTMres(L,val,tm,t,key); | ||
4805 | return; | ||
4806 | } | ||
4807 | t=tm; | ||
4808 | } | ||
4809 | luaG_runerror(L,"loop in gettable"); | ||
4810 | } | ||
4811 | static void luaV_settable(lua_State*L,const TValue*t,TValue*key,StkId val){ | ||
4812 | int loop; | ||
4813 | TValue temp; | ||
4814 | for(loop=0;loop<100;loop++){ | ||
4815 | const TValue*tm; | ||
4816 | if(ttistable(t)){ | ||
4817 | Table*h=hvalue(t); | ||
4818 | TValue*oldval=luaH_set(L,h,key); | ||
4819 | if(!ttisnil(oldval)|| | ||
4820 | (tm=fasttm(L,h->metatable,TM_NEWINDEX))==NULL){ | ||
4821 | setobj(L,oldval,val); | ||
4822 | h->flags=0; | ||
4823 | luaC_barriert(L,h,val); | ||
4824 | return; | ||
4825 | } | ||
4826 | } | ||
4827 | else if(ttisnil(tm=luaT_gettmbyobj(L,t,TM_NEWINDEX))) | ||
4828 | luaG_typeerror(L,t,"index"); | ||
4829 | if(ttisfunction(tm)){ | ||
4830 | callTM(L,tm,t,key,val); | ||
4831 | return; | ||
4832 | } | ||
4833 | setobj(L,&temp,tm); | ||
4834 | t=&temp; | ||
4835 | } | ||
4836 | luaG_runerror(L,"loop in settable"); | ||
4837 | } | ||
4838 | static int call_binTM(lua_State*L,const TValue*p1,const TValue*p2, | ||
4839 | StkId res,TMS event){ | ||
4840 | const TValue*tm=luaT_gettmbyobj(L,p1,event); | ||
4841 | if(ttisnil(tm)) | ||
4842 | tm=luaT_gettmbyobj(L,p2,event); | ||
4843 | if(ttisnil(tm))return 0; | ||
4844 | callTMres(L,res,tm,p1,p2); | ||
4845 | return 1; | ||
4846 | } | ||
4847 | static const TValue*get_compTM(lua_State*L,Table*mt1,Table*mt2, | ||
4848 | TMS event){ | ||
4849 | const TValue*tm1=fasttm(L,mt1,event); | ||
4850 | const TValue*tm2; | ||
4851 | if(tm1==NULL)return NULL; | ||
4852 | if(mt1==mt2)return tm1; | ||
4853 | tm2=fasttm(L,mt2,event); | ||
4854 | if(tm2==NULL)return NULL; | ||
4855 | if(luaO_rawequalObj(tm1,tm2)) | ||
4856 | return tm1; | ||
4857 | return NULL; | ||
4858 | } | ||
4859 | static int call_orderTM(lua_State*L,const TValue*p1,const TValue*p2, | ||
4860 | TMS event){ | ||
4861 | const TValue*tm1=luaT_gettmbyobj(L,p1,event); | ||
4862 | const TValue*tm2; | ||
4863 | if(ttisnil(tm1))return-1; | ||
4864 | tm2=luaT_gettmbyobj(L,p2,event); | ||
4865 | if(!luaO_rawequalObj(tm1,tm2)) | ||
4866 | return-1; | ||
4867 | callTMres(L,L->top,tm1,p1,p2); | ||
4868 | return!l_isfalse(L->top); | ||
4869 | } | ||
4870 | static int l_strcmp(const TString*ls,const TString*rs){ | ||
4871 | const char*l=getstr(ls); | ||
4872 | size_t ll=ls->tsv.len; | ||
4873 | const char*r=getstr(rs); | ||
4874 | size_t lr=rs->tsv.len; | ||
4875 | for(;;){ | ||
4876 | int temp=strcoll(l,r); | ||
4877 | if(temp!=0)return temp; | ||
4878 | else{ | ||
4879 | size_t len=strlen(l); | ||
4880 | if(len==lr) | ||
4881 | return(len==ll)?0:1; | ||
4882 | else if(len==ll) | ||
4883 | return-1; | ||
4884 | len++; | ||
4885 | l+=len;ll-=len;r+=len;lr-=len; | ||
4886 | } | ||
4887 | } | ||
4888 | } | ||
4889 | static int luaV_lessthan(lua_State*L,const TValue*l,const TValue*r){ | ||
4890 | int res; | ||
4891 | if(ttype(l)!=ttype(r)) | ||
4892 | return luaG_ordererror(L,l,r); | ||
4893 | else if(ttisnumber(l)) | ||
4894 | return luai_numlt(nvalue(l),nvalue(r)); | ||
4895 | else if(ttisstring(l)) | ||
4896 | return l_strcmp(rawtsvalue(l),rawtsvalue(r))<0; | ||
4897 | else if((res=call_orderTM(L,l,r,TM_LT))!=-1) | ||
4898 | return res; | ||
4899 | return luaG_ordererror(L,l,r); | ||
4900 | } | ||
4901 | static int lessequal(lua_State*L,const TValue*l,const TValue*r){ | ||
4902 | int res; | ||
4903 | if(ttype(l)!=ttype(r)) | ||
4904 | return luaG_ordererror(L,l,r); | ||
4905 | else if(ttisnumber(l)) | ||
4906 | return luai_numle(nvalue(l),nvalue(r)); | ||
4907 | else if(ttisstring(l)) | ||
4908 | return l_strcmp(rawtsvalue(l),rawtsvalue(r))<=0; | ||
4909 | else if((res=call_orderTM(L,l,r,TM_LE))!=-1) | ||
4910 | return res; | ||
4911 | else if((res=call_orderTM(L,r,l,TM_LT))!=-1) | ||
4912 | return!res; | ||
4913 | return luaG_ordererror(L,l,r); | ||
4914 | } | ||
4915 | static int luaV_equalval(lua_State*L,const TValue*t1,const TValue*t2){ | ||
4916 | const TValue*tm; | ||
4917 | switch(ttype(t1)){ | ||
4918 | case 0:return 1; | ||
4919 | case 3:return luai_numeq(nvalue(t1),nvalue(t2)); | ||
4920 | case 1:return bvalue(t1)==bvalue(t2); | ||
4921 | case 2:return pvalue(t1)==pvalue(t2); | ||
4922 | case 7:{ | ||
4923 | if(uvalue(t1)==uvalue(t2))return 1; | ||
4924 | tm=get_compTM(L,uvalue(t1)->metatable,uvalue(t2)->metatable, | ||
4925 | TM_EQ); | ||
4926 | break; | ||
4927 | } | ||
4928 | case 5:{ | ||
4929 | if(hvalue(t1)==hvalue(t2))return 1; | ||
4930 | tm=get_compTM(L,hvalue(t1)->metatable,hvalue(t2)->metatable,TM_EQ); | ||
4931 | break; | ||
4932 | } | ||
4933 | default:return gcvalue(t1)==gcvalue(t2); | ||
4934 | } | ||
4935 | if(tm==NULL)return 0; | ||
4936 | callTMres(L,L->top,tm,t1,t2); | ||
4937 | return!l_isfalse(L->top); | ||
4938 | } | ||
4939 | static void luaV_concat(lua_State*L,int total,int last){ | ||
4940 | do{ | ||
4941 | StkId top=L->base+last+1; | ||
4942 | int n=2; | ||
4943 | if(!(ttisstring(top-2)||ttisnumber(top-2))||!tostring(L,top-1)){ | ||
4944 | if(!call_binTM(L,top-2,top-1,top-2,TM_CONCAT)) | ||
4945 | luaG_concaterror(L,top-2,top-1); | ||
4946 | }else if(tsvalue(top-1)->len==0) | ||
4947 | (void)tostring(L,top-2); | ||
4948 | else{ | ||
4949 | size_t tl=tsvalue(top-1)->len; | ||
4950 | char*buffer; | ||
4951 | int i; | ||
4952 | for(n=1;n<total&&tostring(L,top-n-1);n++){ | ||
4953 | size_t l=tsvalue(top-n-1)->len; | ||
4954 | if(l>=((size_t)(~(size_t)0)-2)-tl)luaG_runerror(L,"string length overflow"); | ||
4955 | tl+=l; | ||
4956 | } | ||
4957 | buffer=luaZ_openspace(L,&G(L)->buff,tl); | ||
4958 | tl=0; | ||
4959 | for(i=n;i>0;i--){ | ||
4960 | size_t l=tsvalue(top-i)->len; | ||
4961 | memcpy(buffer+tl,svalue(top-i),l); | ||
4962 | tl+=l; | ||
4963 | } | ||
4964 | setsvalue(L,top-n,luaS_newlstr(L,buffer,tl)); | ||
4965 | } | ||
4966 | total-=n-1; | ||
4967 | last-=n-1; | ||
4968 | }while(total>1); | ||
4969 | } | ||
4970 | static void Arith(lua_State*L,StkId ra,const TValue*rb, | ||
4971 | const TValue*rc,TMS op){ | ||
4972 | TValue tempb,tempc; | ||
4973 | const TValue*b,*c; | ||
4974 | if((b=luaV_tonumber(rb,&tempb))!=NULL&& | ||
4975 | (c=luaV_tonumber(rc,&tempc))!=NULL){ | ||
4976 | lua_Number nb=nvalue(b),nc=nvalue(c); | ||
4977 | switch(op){ | ||
4978 | case TM_ADD:setnvalue(ra,luai_numadd(nb,nc));break; | ||
4979 | case TM_SUB:setnvalue(ra,luai_numsub(nb,nc));break; | ||
4980 | case TM_MUL:setnvalue(ra,luai_nummul(nb,nc));break; | ||
4981 | case TM_DIV:setnvalue(ra,luai_numdiv(nb,nc));break; | ||
4982 | case TM_MOD:setnvalue(ra,luai_nummod(nb,nc));break; | ||
4983 | case TM_POW:setnvalue(ra,luai_numpow(nb,nc));break; | ||
4984 | case TM_UNM:setnvalue(ra,luai_numunm(nb));break; | ||
4985 | default:break; | ||
4986 | } | ||
4987 | } | ||
4988 | else if(!call_binTM(L,rb,rc,ra,op)) | ||
4989 | luaG_aritherror(L,rb,rc); | ||
4990 | } | ||
4991 | #define runtime_check(L,c){if(!(c))break;} | ||
4992 | #define RA(i)(base+GETARG_A(i)) | ||
4993 | #define RB(i)check_exp(getBMode(GET_OPCODE(i))==OpArgR,base+GETARG_B(i)) | ||
4994 | #define RKB(i)check_exp(getBMode(GET_OPCODE(i))==OpArgK,ISK(GETARG_B(i))?k+INDEXK(GETARG_B(i)):base+GETARG_B(i)) | ||
4995 | #define RKC(i)check_exp(getCMode(GET_OPCODE(i))==OpArgK,ISK(GETARG_C(i))?k+INDEXK(GETARG_C(i)):base+GETARG_C(i)) | ||
4996 | #define KBx(i)check_exp(getBMode(GET_OPCODE(i))==OpArgK,k+GETARG_Bx(i)) | ||
4997 | #define dojump(L,pc,i){(pc)+=(i);} | ||
4998 | #define Protect(x){L->savedpc=pc;{x;};base=L->base;} | ||
4999 | #define arith_op(op,tm){TValue*rb=RKB(i);TValue*rc=RKC(i);if(ttisnumber(rb)&&ttisnumber(rc)){lua_Number nb=nvalue(rb),nc=nvalue(rc);setnvalue(ra,op(nb,nc));}else Protect(Arith(L,ra,rb,rc,tm));} | ||
5000 | static void luaV_execute(lua_State*L,int nexeccalls){ | ||
5001 | LClosure*cl; | ||
5002 | StkId base; | ||
5003 | TValue*k; | ||
5004 | const Instruction*pc; | ||
5005 | reentry: | ||
5006 | pc=L->savedpc; | ||
5007 | cl=&clvalue(L->ci->func)->l; | ||
5008 | base=L->base; | ||
5009 | k=cl->p->k; | ||
5010 | for(;;){ | ||
5011 | const Instruction i=*pc++; | ||
5012 | StkId ra; | ||
5013 | ra=RA(i); | ||
5014 | switch(GET_OPCODE(i)){ | ||
5015 | case OP_MOVE:{ | ||
5016 | setobj(L,ra,RB(i)); | ||
5017 | continue; | ||
5018 | } | ||
5019 | case OP_LOADK:{ | ||
5020 | setobj(L,ra,KBx(i)); | ||
5021 | continue; | ||
5022 | } | ||
5023 | case OP_LOADBOOL:{ | ||
5024 | setbvalue(ra,GETARG_B(i)); | ||
5025 | if(GETARG_C(i))pc++; | ||
5026 | continue; | ||
5027 | } | ||
5028 | case OP_LOADNIL:{ | ||
5029 | TValue*rb=RB(i); | ||
5030 | do{ | ||
5031 | setnilvalue(rb--); | ||
5032 | }while(rb>=ra); | ||
5033 | continue; | ||
5034 | } | ||
5035 | case OP_GETUPVAL:{ | ||
5036 | int b=GETARG_B(i); | ||
5037 | setobj(L,ra,cl->upvals[b]->v); | ||
5038 | continue; | ||
5039 | } | ||
5040 | case OP_GETGLOBAL:{ | ||
5041 | TValue g; | ||
5042 | TValue*rb=KBx(i); | ||
5043 | sethvalue(L,&g,cl->env); | ||
5044 | Protect(luaV_gettable(L,&g,rb,ra)); | ||
5045 | continue; | ||
5046 | } | ||
5047 | case OP_GETTABLE:{ | ||
5048 | Protect(luaV_gettable(L,RB(i),RKC(i),ra)); | ||
5049 | continue; | ||
5050 | } | ||
5051 | case OP_SETGLOBAL:{ | ||
5052 | TValue g; | ||
5053 | sethvalue(L,&g,cl->env); | ||
5054 | Protect(luaV_settable(L,&g,KBx(i),ra)); | ||
5055 | continue; | ||
5056 | } | ||
5057 | case OP_SETUPVAL:{ | ||
5058 | UpVal*uv=cl->upvals[GETARG_B(i)]; | ||
5059 | setobj(L,uv->v,ra); | ||
5060 | luaC_barrier(L,uv,ra); | ||
5061 | continue; | ||
5062 | } | ||
5063 | case OP_SETTABLE:{ | ||
5064 | Protect(luaV_settable(L,ra,RKB(i),RKC(i))); | ||
5065 | continue; | ||
5066 | } | ||
5067 | case OP_NEWTABLE:{ | ||
5068 | int b=GETARG_B(i); | ||
5069 | int c=GETARG_C(i); | ||
5070 | sethvalue(L,ra,luaH_new(L,luaO_fb2int(b),luaO_fb2int(c))); | ||
5071 | Protect(luaC_checkGC(L)); | ||
5072 | continue; | ||
5073 | } | ||
5074 | case OP_SELF:{ | ||
5075 | StkId rb=RB(i); | ||
5076 | setobj(L,ra+1,rb); | ||
5077 | Protect(luaV_gettable(L,rb,RKC(i),ra)); | ||
5078 | continue; | ||
5079 | } | ||
5080 | case OP_ADD:{ | ||
5081 | arith_op(luai_numadd,TM_ADD); | ||
5082 | continue; | ||
5083 | } | ||
5084 | case OP_SUB:{ | ||
5085 | arith_op(luai_numsub,TM_SUB); | ||
5086 | continue; | ||
5087 | } | ||
5088 | case OP_MUL:{ | ||
5089 | arith_op(luai_nummul,TM_MUL); | ||
5090 | continue; | ||
5091 | } | ||
5092 | case OP_DIV:{ | ||
5093 | arith_op(luai_numdiv,TM_DIV); | ||
5094 | continue; | ||
5095 | } | ||
5096 | case OP_MOD:{ | ||
5097 | arith_op(luai_nummod,TM_MOD); | ||
5098 | continue; | ||
5099 | } | ||
5100 | case OP_POW:{ | ||
5101 | arith_op(luai_numpow,TM_POW); | ||
5102 | continue; | ||
5103 | } | ||
5104 | case OP_UNM:{ | ||
5105 | TValue*rb=RB(i); | ||
5106 | if(ttisnumber(rb)){ | ||
5107 | lua_Number nb=nvalue(rb); | ||
5108 | setnvalue(ra,luai_numunm(nb)); | ||
5109 | } | ||
5110 | else{ | ||
5111 | Protect(Arith(L,ra,rb,rb,TM_UNM)); | ||
5112 | } | ||
5113 | continue; | ||
5114 | } | ||
5115 | case OP_NOT:{ | ||
5116 | int res=l_isfalse(RB(i)); | ||
5117 | setbvalue(ra,res); | ||
5118 | continue; | ||
5119 | } | ||
5120 | case OP_LEN:{ | ||
5121 | const TValue*rb=RB(i); | ||
5122 | switch(ttype(rb)){ | ||
5123 | case 5:{ | ||
5124 | setnvalue(ra,cast_num(luaH_getn(hvalue(rb)))); | ||
5125 | break; | ||
5126 | } | ||
5127 | case 4:{ | ||
5128 | setnvalue(ra,cast_num(tsvalue(rb)->len)); | ||
5129 | break; | ||
5130 | } | ||
5131 | default:{ | ||
5132 | Protect( | ||
5133 | if(!call_binTM(L,rb,(&luaO_nilobject_),ra,TM_LEN)) | ||
5134 | luaG_typeerror(L,rb,"get length of"); | ||
5135 | ) | ||
5136 | } | ||
5137 | } | ||
5138 | continue; | ||
5139 | } | ||
5140 | case OP_CONCAT:{ | ||
5141 | int b=GETARG_B(i); | ||
5142 | int c=GETARG_C(i); | ||
5143 | Protect(luaV_concat(L,c-b+1,c);luaC_checkGC(L)); | ||
5144 | setobj(L,RA(i),base+b); | ||
5145 | continue; | ||
5146 | } | ||
5147 | case OP_JMP:{ | ||
5148 | dojump(L,pc,GETARG_sBx(i)); | ||
5149 | continue; | ||
5150 | } | ||
5151 | case OP_EQ:{ | ||
5152 | TValue*rb=RKB(i); | ||
5153 | TValue*rc=RKC(i); | ||
5154 | Protect( | ||
5155 | if(equalobj(L,rb,rc)==GETARG_A(i)) | ||
5156 | dojump(L,pc,GETARG_sBx(*pc)); | ||
5157 | ) | ||
5158 | pc++; | ||
5159 | continue; | ||
5160 | } | ||
5161 | case OP_LT:{ | ||
5162 | Protect( | ||
5163 | if(luaV_lessthan(L,RKB(i),RKC(i))==GETARG_A(i)) | ||
5164 | dojump(L,pc,GETARG_sBx(*pc)); | ||
5165 | ) | ||
5166 | pc++; | ||
5167 | continue; | ||
5168 | } | ||
5169 | case OP_LE:{ | ||
5170 | Protect( | ||
5171 | if(lessequal(L,RKB(i),RKC(i))==GETARG_A(i)) | ||
5172 | dojump(L,pc,GETARG_sBx(*pc)); | ||
5173 | ) | ||
5174 | pc++; | ||
5175 | continue; | ||
5176 | } | ||
5177 | case OP_TEST:{ | ||
5178 | if(l_isfalse(ra)!=GETARG_C(i)) | ||
5179 | dojump(L,pc,GETARG_sBx(*pc)); | ||
5180 | pc++; | ||
5181 | continue; | ||
5182 | } | ||
5183 | case OP_TESTSET:{ | ||
5184 | TValue*rb=RB(i); | ||
5185 | if(l_isfalse(rb)!=GETARG_C(i)){ | ||
5186 | setobj(L,ra,rb); | ||
5187 | dojump(L,pc,GETARG_sBx(*pc)); | ||
5188 | } | ||
5189 | pc++; | ||
5190 | continue; | ||
5191 | } | ||
5192 | case OP_CALL:{ | ||
5193 | int b=GETARG_B(i); | ||
5194 | int nresults=GETARG_C(i)-1; | ||
5195 | if(b!=0)L->top=ra+b; | ||
5196 | L->savedpc=pc; | ||
5197 | switch(luaD_precall(L,ra,nresults)){ | ||
5198 | case 0:{ | ||
5199 | nexeccalls++; | ||
5200 | goto reentry; | ||
5201 | } | ||
5202 | case 1:{ | ||
5203 | if(nresults>=0)L->top=L->ci->top; | ||
5204 | base=L->base; | ||
5205 | continue; | ||
5206 | } | ||
5207 | default:{ | ||
5208 | return; | ||
5209 | } | ||
5210 | } | ||
5211 | } | ||
5212 | case OP_TAILCALL:{ | ||
5213 | int b=GETARG_B(i); | ||
5214 | if(b!=0)L->top=ra+b; | ||
5215 | L->savedpc=pc; | ||
5216 | switch(luaD_precall(L,ra,(-1))){ | ||
5217 | case 0:{ | ||
5218 | CallInfo*ci=L->ci-1; | ||
5219 | int aux; | ||
5220 | StkId func=ci->func; | ||
5221 | StkId pfunc=(ci+1)->func; | ||
5222 | if(L->openupval)luaF_close(L,ci->base); | ||
5223 | L->base=ci->base=ci->func+((ci+1)->base-pfunc); | ||
5224 | for(aux=0;pfunc+aux<L->top;aux++) | ||
5225 | setobj(L,func+aux,pfunc+aux); | ||
5226 | ci->top=L->top=func+aux; | ||
5227 | ci->savedpc=L->savedpc; | ||
5228 | ci->tailcalls++; | ||
5229 | L->ci--; | ||
5230 | goto reentry; | ||
5231 | } | ||
5232 | case 1:{ | ||
5233 | base=L->base; | ||
5234 | continue; | ||
5235 | } | ||
5236 | default:{ | ||
5237 | return; | ||
5238 | } | ||
5239 | } | ||
5240 | } | ||
5241 | case OP_RETURN:{ | ||
5242 | int b=GETARG_B(i); | ||
5243 | if(b!=0)L->top=ra+b-1; | ||
5244 | if(L->openupval)luaF_close(L,base); | ||
5245 | L->savedpc=pc; | ||
5246 | b=luaD_poscall(L,ra); | ||
5247 | if(--nexeccalls==0) | ||
5248 | return; | ||
5249 | else{ | ||
5250 | if(b)L->top=L->ci->top; | ||
5251 | goto reentry; | ||
5252 | } | ||
5253 | } | ||
5254 | case OP_FORLOOP:{ | ||
5255 | lua_Number step=nvalue(ra+2); | ||
5256 | lua_Number idx=luai_numadd(nvalue(ra),step); | ||
5257 | lua_Number limit=nvalue(ra+1); | ||
5258 | if(luai_numlt(0,step)?luai_numle(idx,limit) | ||
5259 | :luai_numle(limit,idx)){ | ||
5260 | dojump(L,pc,GETARG_sBx(i)); | ||
5261 | setnvalue(ra,idx); | ||
5262 | setnvalue(ra+3,idx); | ||
5263 | } | ||
5264 | continue; | ||
5265 | } | ||
5266 | case OP_FORPREP:{ | ||
5267 | const TValue*init=ra; | ||
5268 | const TValue*plimit=ra+1; | ||
5269 | const TValue*pstep=ra+2; | ||
5270 | L->savedpc=pc; | ||
5271 | if(!tonumber(init,ra)) | ||
5272 | luaG_runerror(L,LUA_QL("for")" initial value must be a number"); | ||
5273 | else if(!tonumber(plimit,ra+1)) | ||
5274 | luaG_runerror(L,LUA_QL("for")" limit must be a number"); | ||
5275 | else if(!tonumber(pstep,ra+2)) | ||
5276 | luaG_runerror(L,LUA_QL("for")" step must be a number"); | ||
5277 | setnvalue(ra,luai_numsub(nvalue(ra),nvalue(pstep))); | ||
5278 | dojump(L,pc,GETARG_sBx(i)); | ||
5279 | continue; | ||
5280 | } | ||
5281 | case OP_TFORLOOP:{ | ||
5282 | StkId cb=ra+3; | ||
5283 | setobj(L,cb+2,ra+2); | ||
5284 | setobj(L,cb+1,ra+1); | ||
5285 | setobj(L,cb,ra); | ||
5286 | L->top=cb+3; | ||
5287 | Protect(luaD_call(L,cb,GETARG_C(i))); | ||
5288 | L->top=L->ci->top; | ||
5289 | cb=RA(i)+3; | ||
5290 | if(!ttisnil(cb)){ | ||
5291 | setobj(L,cb-1,cb); | ||
5292 | dojump(L,pc,GETARG_sBx(*pc)); | ||
5293 | } | ||
5294 | pc++; | ||
5295 | continue; | ||
5296 | } | ||
5297 | case OP_SETLIST:{ | ||
5298 | int n=GETARG_B(i); | ||
5299 | int c=GETARG_C(i); | ||
5300 | int last; | ||
5301 | Table*h; | ||
5302 | if(n==0){ | ||
5303 | n=cast_int(L->top-ra)-1; | ||
5304 | L->top=L->ci->top; | ||
5305 | } | ||
5306 | if(c==0)c=cast_int(*pc++); | ||
5307 | runtime_check(L,ttistable(ra)); | ||
5308 | h=hvalue(ra); | ||
5309 | last=((c-1)*50)+n; | ||
5310 | if(last>h->sizearray) | ||
5311 | luaH_resizearray(L,h,last); | ||
5312 | for(;n>0;n--){ | ||
5313 | TValue*val=ra+n; | ||
5314 | setobj(L,luaH_setnum(L,h,last--),val); | ||
5315 | luaC_barriert(L,h,val); | ||
5316 | } | ||
5317 | continue; | ||
5318 | } | ||
5319 | case OP_CLOSE:{ | ||
5320 | luaF_close(L,ra); | ||
5321 | continue; | ||
5322 | } | ||
5323 | case OP_CLOSURE:{ | ||
5324 | Proto*p; | ||
5325 | Closure*ncl; | ||
5326 | int nup,j; | ||
5327 | p=cl->p->p[GETARG_Bx(i)]; | ||
5328 | nup=p->nups; | ||
5329 | ncl=luaF_newLclosure(L,nup,cl->env); | ||
5330 | ncl->l.p=p; | ||
5331 | for(j=0;j<nup;j++,pc++){ | ||
5332 | if(GET_OPCODE(*pc)==OP_GETUPVAL) | ||
5333 | ncl->l.upvals[j]=cl->upvals[GETARG_B(*pc)]; | ||
5334 | else{ | ||
5335 | ncl->l.upvals[j]=luaF_findupval(L,base+GETARG_B(*pc)); | ||
5336 | } | ||
5337 | } | ||
5338 | setclvalue(L,ra,ncl); | ||
5339 | Protect(luaC_checkGC(L)); | ||
5340 | continue; | ||
5341 | } | ||
5342 | case OP_VARARG:{ | ||
5343 | int b=GETARG_B(i)-1; | ||
5344 | int j; | ||
5345 | CallInfo*ci=L->ci; | ||
5346 | int n=cast_int(ci->base-ci->func)-cl->p->numparams-1; | ||
5347 | if(b==(-1)){ | ||
5348 | Protect(luaD_checkstack(L,n)); | ||
5349 | ra=RA(i); | ||
5350 | b=n; | ||
5351 | L->top=ra+n; | ||
5352 | } | ||
5353 | for(j=0;j<b;j++){ | ||
5354 | if(j<n){ | ||
5355 | setobj(L,ra+j,ci->base-n+j); | ||
5356 | } | ||
5357 | else{ | ||
5358 | setnilvalue(ra+j); | ||
5359 | } | ||
5360 | } | ||
5361 | continue; | ||
5362 | } | ||
5363 | } | ||
5364 | } | ||
5365 | } | ||
5366 | #define api_checknelems(L,n)luai_apicheck(L,(n)<=(L->top-L->base)) | ||
5367 | #define api_checkvalidindex(L,i)luai_apicheck(L,(i)!=(&luaO_nilobject_)) | ||
5368 | #define api_incr_top(L){luai_apicheck(L,L->top<L->ci->top);L->top++;} | ||
5369 | static TValue*index2adr(lua_State*L,int idx){ | ||
5370 | if(idx>0){ | ||
5371 | TValue*o=L->base+(idx-1); | ||
5372 | luai_apicheck(L,idx<=L->ci->top-L->base); | ||
5373 | if(o>=L->top)return cast(TValue*,(&luaO_nilobject_)); | ||
5374 | else return o; | ||
5375 | } | ||
5376 | else if(idx>(-10000)){ | ||
5377 | luai_apicheck(L,idx!=0&&-idx<=L->top-L->base); | ||
5378 | return L->top+idx; | ||
5379 | } | ||
5380 | else switch(idx){ | ||
5381 | case(-10000):return registry(L); | ||
5382 | case(-10001):{ | ||
5383 | Closure*func=curr_func(L); | ||
5384 | sethvalue(L,&L->env,func->c.env); | ||
5385 | return&L->env; | ||
5386 | } | ||
5387 | case(-10002):return gt(L); | ||
5388 | default:{ | ||
5389 | Closure*func=curr_func(L); | ||
5390 | idx=(-10002)-idx; | ||
5391 | return(idx<=func->c.nupvalues) | ||
5392 | ?&func->c.upvalue[idx-1] | ||
5393 | :cast(TValue*,(&luaO_nilobject_)); | ||
5394 | } | ||
5395 | } | ||
5396 | } | ||
5397 | static Table*getcurrenv(lua_State*L){ | ||
5398 | if(L->ci==L->base_ci) | ||
5399 | return hvalue(gt(L)); | ||
5400 | else{ | ||
5401 | Closure*func=curr_func(L); | ||
5402 | return func->c.env; | ||
5403 | } | ||
5404 | } | ||
5405 | static int lua_checkstack(lua_State*L,int size){ | ||
5406 | int res=1; | ||
5407 | if(size>8000||(L->top-L->base+size)>8000) | ||
5408 | res=0; | ||
5409 | else if(size>0){ | ||
5410 | luaD_checkstack(L,size); | ||
5411 | if(L->ci->top<L->top+size) | ||
5412 | L->ci->top=L->top+size; | ||
5413 | } | ||
5414 | return res; | ||
5415 | } | ||
5416 | static void lua_xmove(lua_State*from,lua_State*to,int n){ | ||
5417 | int i; | ||
5418 | if(from==to)return; | ||
5419 | api_checknelems(from,n); | ||
5420 | luai_apicheck(from,G(from)==G(to)); | ||
5421 | luai_apicheck(from,to->ci->top-to->top>=n); | ||
5422 | from->top-=n; | ||
5423 | for(i=0;i<n;i++){ | ||
5424 | setobj(to,to->top++,from->top+i); | ||
5425 | } | ||
5426 | } | ||
5427 | static void lua_setlevel(lua_State*from,lua_State*to){ | ||
5428 | to->nCcalls=from->nCcalls; | ||
5429 | } | ||
5430 | static lua_CFunction lua_atpanic(lua_State*L,lua_CFunction panicf){ | ||
5431 | lua_CFunction old; | ||
5432 | old=G(L)->panic; | ||
5433 | G(L)->panic=panicf; | ||
5434 | return old; | ||
5435 | } | ||
5436 | static lua_State*lua_newthread(lua_State*L){ | ||
5437 | lua_State*L1; | ||
5438 | luaC_checkGC(L); | ||
5439 | L1=luaE_newthread(L); | ||
5440 | setthvalue(L,L->top,L1); | ||
5441 | api_incr_top(L); | ||
5442 | return L1; | ||
5443 | } | ||
5444 | static int lua_gettop(lua_State*L){ | ||
5445 | return cast_int(L->top-L->base); | ||
5446 | } | ||
5447 | static void lua_settop(lua_State*L,int idx){ | ||
5448 | if(idx>=0){ | ||
5449 | luai_apicheck(L,idx<=L->stack_last-L->base); | ||
5450 | while(L->top<L->base+idx) | ||
5451 | setnilvalue(L->top++); | ||
5452 | L->top=L->base+idx; | ||
5453 | } | ||
5454 | else{ | ||
5455 | luai_apicheck(L,-(idx+1)<=(L->top-L->base)); | ||
5456 | L->top+=idx+1; | ||
5457 | } | ||
5458 | } | ||
5459 | static void lua_remove(lua_State*L,int idx){ | ||
5460 | StkId p; | ||
5461 | p=index2adr(L,idx); | ||
5462 | api_checkvalidindex(L,p); | ||
5463 | while(++p<L->top)setobj(L,p-1,p); | ||
5464 | L->top--; | ||
5465 | } | ||
5466 | static void lua_insert(lua_State*L,int idx){ | ||
5467 | StkId p; | ||
5468 | StkId q; | ||
5469 | p=index2adr(L,idx); | ||
5470 | api_checkvalidindex(L,p); | ||
5471 | for(q=L->top;q>p;q--)setobj(L,q,q-1); | ||
5472 | setobj(L,p,L->top); | ||
5473 | } | ||
5474 | static void lua_replace(lua_State*L,int idx){ | ||
5475 | StkId o; | ||
5476 | if(idx==(-10001)&&L->ci==L->base_ci) | ||
5477 | luaG_runerror(L,"no calling environment"); | ||
5478 | api_checknelems(L,1); | ||
5479 | o=index2adr(L,idx); | ||
5480 | api_checkvalidindex(L,o); | ||
5481 | if(idx==(-10001)){ | ||
5482 | Closure*func=curr_func(L); | ||
5483 | luai_apicheck(L,ttistable(L->top-1)); | ||
5484 | func->c.env=hvalue(L->top-1); | ||
5485 | luaC_barrier(L,func,L->top-1); | ||
5486 | } | ||
5487 | else{ | ||
5488 | setobj(L,o,L->top-1); | ||
5489 | if(idx<(-10002)) | ||
5490 | luaC_barrier(L,curr_func(L),L->top-1); | ||
5491 | } | ||
5492 | L->top--; | ||
5493 | } | ||
5494 | static void lua_pushvalue(lua_State*L,int idx){ | ||
5495 | setobj(L,L->top,index2adr(L,idx)); | ||
5496 | api_incr_top(L); | ||
5497 | } | ||
5498 | static int lua_type(lua_State*L,int idx){ | ||
5499 | StkId o=index2adr(L,idx); | ||
5500 | return(o==(&luaO_nilobject_))?(-1):ttype(o); | ||
5501 | } | ||
5502 | static const char*lua_typename(lua_State*L,int t){ | ||
5503 | UNUSED(L); | ||
5504 | return(t==(-1))?"no value":luaT_typenames[t]; | ||
5505 | } | ||
5506 | static int lua_iscfunction(lua_State*L,int idx){ | ||
5507 | StkId o=index2adr(L,idx); | ||
5508 | return iscfunction(o); | ||
5509 | } | ||
5510 | static int lua_isnumber(lua_State*L,int idx){ | ||
5511 | TValue n; | ||
5512 | const TValue*o=index2adr(L,idx); | ||
5513 | return tonumber(o,&n); | ||
5514 | } | ||
5515 | static int lua_isstring(lua_State*L,int idx){ | ||
5516 | int t=lua_type(L,idx); | ||
5517 | return(t==4||t==3); | ||
5518 | } | ||
5519 | static int lua_rawequal(lua_State*L,int index1,int index2){ | ||
5520 | StkId o1=index2adr(L,index1); | ||
5521 | StkId o2=index2adr(L,index2); | ||
5522 | return(o1==(&luaO_nilobject_)||o2==(&luaO_nilobject_))?0 | ||
5523 | :luaO_rawequalObj(o1,o2); | ||
5524 | } | ||
5525 | static int lua_lessthan(lua_State*L,int index1,int index2){ | ||
5526 | StkId o1,o2; | ||
5527 | int i; | ||
5528 | o1=index2adr(L,index1); | ||
5529 | o2=index2adr(L,index2); | ||
5530 | i=(o1==(&luaO_nilobject_)||o2==(&luaO_nilobject_))?0 | ||
5531 | :luaV_lessthan(L,o1,o2); | ||
5532 | return i; | ||
5533 | } | ||
5534 | static lua_Number lua_tonumber(lua_State*L,int idx){ | ||
5535 | TValue n; | ||
5536 | const TValue*o=index2adr(L,idx); | ||
5537 | if(tonumber(o,&n)) | ||
5538 | return nvalue(o); | ||
5539 | else | ||
5540 | return 0; | ||
5541 | } | ||
5542 | static lua_Integer lua_tointeger(lua_State*L,int idx){ | ||
5543 | TValue n; | ||
5544 | const TValue*o=index2adr(L,idx); | ||
5545 | if(tonumber(o,&n)){ | ||
5546 | lua_Integer res; | ||
5547 | lua_Number num=nvalue(o); | ||
5548 | lua_number2integer(res,num); | ||
5549 | return res; | ||
5550 | } | ||
5551 | else | ||
5552 | return 0; | ||
5553 | } | ||
5554 | static int lua_toboolean(lua_State*L,int idx){ | ||
5555 | const TValue*o=index2adr(L,idx); | ||
5556 | return!l_isfalse(o); | ||
5557 | } | ||
5558 | static const char*lua_tolstring(lua_State*L,int idx,size_t*len){ | ||
5559 | StkId o=index2adr(L,idx); | ||
5560 | if(!ttisstring(o)){ | ||
5561 | if(!luaV_tostring(L,o)){ | ||
5562 | if(len!=NULL)*len=0; | ||
5563 | return NULL; | ||
5564 | } | ||
5565 | luaC_checkGC(L); | ||
5566 | o=index2adr(L,idx); | ||
5567 | } | ||
5568 | if(len!=NULL)*len=tsvalue(o)->len; | ||
5569 | return svalue(o); | ||
5570 | } | ||
5571 | static size_t lua_objlen(lua_State*L,int idx){ | ||
5572 | StkId o=index2adr(L,idx); | ||
5573 | switch(ttype(o)){ | ||
5574 | case 4:return tsvalue(o)->len; | ||
5575 | case 7:return uvalue(o)->len; | ||
5576 | case 5:return luaH_getn(hvalue(o)); | ||
5577 | case 3:{ | ||
5578 | size_t l; | ||
5579 | l=(luaV_tostring(L,o)?tsvalue(o)->len:0); | ||
5580 | return l; | ||
5581 | } | ||
5582 | default:return 0; | ||
5583 | } | ||
5584 | } | ||
5585 | static lua_CFunction lua_tocfunction(lua_State*L,int idx){ | ||
5586 | StkId o=index2adr(L,idx); | ||
5587 | return(!iscfunction(o))?NULL:clvalue(o)->c.f; | ||
5588 | } | ||
5589 | static void*lua_touserdata(lua_State*L,int idx){ | ||
5590 | StkId o=index2adr(L,idx); | ||
5591 | switch(ttype(o)){ | ||
5592 | case 7:return(rawuvalue(o)+1); | ||
5593 | case 2:return pvalue(o); | ||
5594 | default:return NULL; | ||
5595 | } | ||
5596 | } | ||
5597 | static lua_State*lua_tothread(lua_State*L,int idx){ | ||
5598 | StkId o=index2adr(L,idx); | ||
5599 | return(!ttisthread(o))?NULL:thvalue(o); | ||
5600 | } | ||
5601 | static void lua_pushnil(lua_State*L){ | ||
5602 | setnilvalue(L->top); | ||
5603 | api_incr_top(L); | ||
5604 | } | ||
5605 | static void lua_pushnumber(lua_State*L,lua_Number n){ | ||
5606 | setnvalue(L->top,n); | ||
5607 | api_incr_top(L); | ||
5608 | } | ||
5609 | static void lua_pushinteger(lua_State*L,lua_Integer n){ | ||
5610 | setnvalue(L->top,cast_num(n)); | ||
5611 | api_incr_top(L); | ||
5612 | } | ||
5613 | static void lua_pushlstring(lua_State*L,const char*s,size_t len){ | ||
5614 | luaC_checkGC(L); | ||
5615 | setsvalue(L,L->top,luaS_newlstr(L,s,len)); | ||
5616 | api_incr_top(L); | ||
5617 | } | ||
5618 | static void lua_pushstring(lua_State*L,const char*s){ | ||
5619 | if(s==NULL) | ||
5620 | lua_pushnil(L); | ||
5621 | else | ||
5622 | lua_pushlstring(L,s,strlen(s)); | ||
5623 | } | ||
5624 | static const char*lua_pushvfstring(lua_State*L,const char*fmt, | ||
5625 | va_list argp){ | ||
5626 | const char*ret; | ||
5627 | luaC_checkGC(L); | ||
5628 | ret=luaO_pushvfstring(L,fmt,argp); | ||
5629 | return ret; | ||
5630 | } | ||
5631 | static const char*lua_pushfstring(lua_State*L,const char*fmt,...){ | ||
5632 | const char*ret; | ||
5633 | va_list argp; | ||
5634 | luaC_checkGC(L); | ||
5635 | va_start(argp,fmt); | ||
5636 | ret=luaO_pushvfstring(L,fmt,argp); | ||
5637 | va_end(argp); | ||
5638 | return ret; | ||
5639 | } | ||
5640 | static void lua_pushcclosure(lua_State*L,lua_CFunction fn,int n){ | ||
5641 | Closure*cl; | ||
5642 | luaC_checkGC(L); | ||
5643 | api_checknelems(L,n); | ||
5644 | cl=luaF_newCclosure(L,n,getcurrenv(L)); | ||
5645 | cl->c.f=fn; | ||
5646 | L->top-=n; | ||
5647 | while(n--) | ||
5648 | setobj(L,&cl->c.upvalue[n],L->top+n); | ||
5649 | setclvalue(L,L->top,cl); | ||
5650 | api_incr_top(L); | ||
5651 | } | ||
5652 | static void lua_pushboolean(lua_State*L,int b){ | ||
5653 | setbvalue(L->top,(b!=0)); | ||
5654 | api_incr_top(L); | ||
5655 | } | ||
5656 | static int lua_pushthread(lua_State*L){ | ||
5657 | setthvalue(L,L->top,L); | ||
5658 | api_incr_top(L); | ||
5659 | return(G(L)->mainthread==L); | ||
5660 | } | ||
5661 | static void lua_gettable(lua_State*L,int idx){ | ||
5662 | StkId t; | ||
5663 | t=index2adr(L,idx); | ||
5664 | api_checkvalidindex(L,t); | ||
5665 | luaV_gettable(L,t,L->top-1,L->top-1); | ||
5666 | } | ||
5667 | static void lua_getfield(lua_State*L,int idx,const char*k){ | ||
5668 | StkId t; | ||
5669 | TValue key; | ||
5670 | t=index2adr(L,idx); | ||
5671 | api_checkvalidindex(L,t); | ||
5672 | setsvalue(L,&key,luaS_new(L,k)); | ||
5673 | luaV_gettable(L,t,&key,L->top); | ||
5674 | api_incr_top(L); | ||
5675 | } | ||
5676 | static void lua_rawget(lua_State*L,int idx){ | ||
5677 | StkId t; | ||
5678 | t=index2adr(L,idx); | ||
5679 | luai_apicheck(L,ttistable(t)); | ||
5680 | setobj(L,L->top-1,luaH_get(hvalue(t),L->top-1)); | ||
5681 | } | ||
5682 | static void lua_rawgeti(lua_State*L,int idx,int n){ | ||
5683 | StkId o; | ||
5684 | o=index2adr(L,idx); | ||
5685 | luai_apicheck(L,ttistable(o)); | ||
5686 | setobj(L,L->top,luaH_getnum(hvalue(o),n)); | ||
5687 | api_incr_top(L); | ||
5688 | } | ||
5689 | static void lua_createtable(lua_State*L,int narray,int nrec){ | ||
5690 | luaC_checkGC(L); | ||
5691 | sethvalue(L,L->top,luaH_new(L,narray,nrec)); | ||
5692 | api_incr_top(L); | ||
5693 | } | ||
5694 | static int lua_getmetatable(lua_State*L,int objindex){ | ||
5695 | const TValue*obj; | ||
5696 | Table*mt=NULL; | ||
5697 | int res; | ||
5698 | obj=index2adr(L,objindex); | ||
5699 | switch(ttype(obj)){ | ||
5700 | case 5: | ||
5701 | mt=hvalue(obj)->metatable; | ||
5702 | break; | ||
5703 | case 7: | ||
5704 | mt=uvalue(obj)->metatable; | ||
5705 | break; | ||
5706 | default: | ||
5707 | mt=G(L)->mt[ttype(obj)]; | ||
5708 | break; | ||
5709 | } | ||
5710 | if(mt==NULL) | ||
5711 | res=0; | ||
5712 | else{ | ||
5713 | sethvalue(L,L->top,mt); | ||
5714 | api_incr_top(L); | ||
5715 | res=1; | ||
5716 | } | ||
5717 | return res; | ||
5718 | } | ||
5719 | static void lua_getfenv(lua_State*L,int idx){ | ||
5720 | StkId o; | ||
5721 | o=index2adr(L,idx); | ||
5722 | api_checkvalidindex(L,o); | ||
5723 | switch(ttype(o)){ | ||
5724 | case 6: | ||
5725 | sethvalue(L,L->top,clvalue(o)->c.env); | ||
5726 | break; | ||
5727 | case 7: | ||
5728 | sethvalue(L,L->top,uvalue(o)->env); | ||
5729 | break; | ||
5730 | case 8: | ||
5731 | setobj(L,L->top,gt(thvalue(o))); | ||
5732 | break; | ||
5733 | default: | ||
5734 | setnilvalue(L->top); | ||
5735 | break; | ||
5736 | } | ||
5737 | api_incr_top(L); | ||
5738 | } | ||
5739 | static void lua_settable(lua_State*L,int idx){ | ||
5740 | StkId t; | ||
5741 | api_checknelems(L,2); | ||
5742 | t=index2adr(L,idx); | ||
5743 | api_checkvalidindex(L,t); | ||
5744 | luaV_settable(L,t,L->top-2,L->top-1); | ||
5745 | L->top-=2; | ||
5746 | } | ||
5747 | static void lua_setfield(lua_State*L,int idx,const char*k){ | ||
5748 | StkId t; | ||
5749 | TValue key; | ||
5750 | api_checknelems(L,1); | ||
5751 | t=index2adr(L,idx); | ||
5752 | api_checkvalidindex(L,t); | ||
5753 | setsvalue(L,&key,luaS_new(L,k)); | ||
5754 | luaV_settable(L,t,&key,L->top-1); | ||
5755 | L->top--; | ||
5756 | } | ||
5757 | static void lua_rawset(lua_State*L,int idx){ | ||
5758 | StkId t; | ||
5759 | api_checknelems(L,2); | ||
5760 | t=index2adr(L,idx); | ||
5761 | luai_apicheck(L,ttistable(t)); | ||
5762 | setobj(L,luaH_set(L,hvalue(t),L->top-2),L->top-1); | ||
5763 | luaC_barriert(L,hvalue(t),L->top-1); | ||
5764 | L->top-=2; | ||
5765 | } | ||
5766 | static void lua_rawseti(lua_State*L,int idx,int n){ | ||
5767 | StkId o; | ||
5768 | api_checknelems(L,1); | ||
5769 | o=index2adr(L,idx); | ||
5770 | luai_apicheck(L,ttistable(o)); | ||
5771 | setobj(L,luaH_setnum(L,hvalue(o),n),L->top-1); | ||
5772 | luaC_barriert(L,hvalue(o),L->top-1); | ||
5773 | L->top--; | ||
5774 | } | ||
5775 | static int lua_setmetatable(lua_State*L,int objindex){ | ||
5776 | TValue*obj; | ||
5777 | Table*mt; | ||
5778 | api_checknelems(L,1); | ||
5779 | obj=index2adr(L,objindex); | ||
5780 | api_checkvalidindex(L,obj); | ||
5781 | if(ttisnil(L->top-1)) | ||
5782 | mt=NULL; | ||
5783 | else{ | ||
5784 | luai_apicheck(L,ttistable(L->top-1)); | ||
5785 | mt=hvalue(L->top-1); | ||
5786 | } | ||
5787 | switch(ttype(obj)){ | ||
5788 | case 5:{ | ||
5789 | hvalue(obj)->metatable=mt; | ||
5790 | if(mt) | ||
5791 | luaC_objbarriert(L,hvalue(obj),mt); | ||
5792 | break; | ||
5793 | } | ||
5794 | case 7:{ | ||
5795 | uvalue(obj)->metatable=mt; | ||
5796 | if(mt) | ||
5797 | luaC_objbarrier(L,rawuvalue(obj),mt); | ||
5798 | break; | ||
5799 | } | ||
5800 | default:{ | ||
5801 | G(L)->mt[ttype(obj)]=mt; | ||
5802 | break; | ||
5803 | } | ||
5804 | } | ||
5805 | L->top--; | ||
5806 | return 1; | ||
5807 | } | ||
5808 | static int lua_setfenv(lua_State*L,int idx){ | ||
5809 | StkId o; | ||
5810 | int res=1; | ||
5811 | api_checknelems(L,1); | ||
5812 | o=index2adr(L,idx); | ||
5813 | api_checkvalidindex(L,o); | ||
5814 | luai_apicheck(L,ttistable(L->top-1)); | ||
5815 | switch(ttype(o)){ | ||
5816 | case 6: | ||
5817 | clvalue(o)->c.env=hvalue(L->top-1); | ||
5818 | break; | ||
5819 | case 7: | ||
5820 | uvalue(o)->env=hvalue(L->top-1); | ||
5821 | break; | ||
5822 | case 8: | ||
5823 | sethvalue(L,gt(thvalue(o)),hvalue(L->top-1)); | ||
5824 | break; | ||
5825 | default: | ||
5826 | res=0; | ||
5827 | break; | ||
5828 | } | ||
5829 | if(res)luaC_objbarrier(L,gcvalue(o),hvalue(L->top-1)); | ||
5830 | L->top--; | ||
5831 | return res; | ||
5832 | } | ||
5833 | #define adjustresults(L,nres){if(nres==(-1)&&L->top>=L->ci->top)L->ci->top=L->top;} | ||
5834 | #define checkresults(L,na,nr)luai_apicheck(L,(nr)==(-1)||(L->ci->top-L->top>=(nr)-(na))) | ||
5835 | static void lua_call(lua_State*L,int nargs,int nresults){ | ||
5836 | StkId func; | ||
5837 | api_checknelems(L,nargs+1); | ||
5838 | checkresults(L,nargs,nresults); | ||
5839 | func=L->top-(nargs+1); | ||
5840 | luaD_call(L,func,nresults); | ||
5841 | adjustresults(L,nresults); | ||
5842 | } | ||
5843 | struct CallS{ | ||
5844 | StkId func; | ||
5845 | int nresults; | ||
5846 | }; | ||
5847 | static void f_call(lua_State*L,void*ud){ | ||
5848 | struct CallS*c=cast(struct CallS*,ud); | ||
5849 | luaD_call(L,c->func,c->nresults); | ||
5850 | } | ||
5851 | static int lua_pcall(lua_State*L,int nargs,int nresults,int errfunc){ | ||
5852 | struct CallS c; | ||
5853 | int status; | ||
5854 | ptrdiff_t func; | ||
5855 | api_checknelems(L,nargs+1); | ||
5856 | checkresults(L,nargs,nresults); | ||
5857 | if(errfunc==0) | ||
5858 | func=0; | ||
5859 | else{ | ||
5860 | StkId o=index2adr(L,errfunc); | ||
5861 | api_checkvalidindex(L,o); | ||
5862 | func=savestack(L,o); | ||
5863 | } | ||
5864 | c.func=L->top-(nargs+1); | ||
5865 | c.nresults=nresults; | ||
5866 | status=luaD_pcall(L,f_call,&c,savestack(L,c.func),func); | ||
5867 | adjustresults(L,nresults); | ||
5868 | return status; | ||
5869 | } | ||
5870 | static int lua_load(lua_State*L,lua_Reader reader,void*data, | ||
5871 | const char*chunkname){ | ||
5872 | ZIO z; | ||
5873 | int status; | ||
5874 | if(!chunkname)chunkname="?"; | ||
5875 | luaZ_init(L,&z,reader,data); | ||
5876 | status=luaD_protectedparser(L,&z,chunkname); | ||
5877 | return status; | ||
5878 | } | ||
5879 | static int lua_status(lua_State*L){ | ||
5880 | return L->status; | ||
5881 | } | ||
5882 | static int lua_error(lua_State*L){ | ||
5883 | api_checknelems(L,1); | ||
5884 | luaG_errormsg(L); | ||
5885 | return 0; | ||
5886 | } | ||
5887 | static int lua_next(lua_State*L,int idx){ | ||
5888 | StkId t; | ||
5889 | int more; | ||
5890 | t=index2adr(L,idx); | ||
5891 | luai_apicheck(L,ttistable(t)); | ||
5892 | more=luaH_next(L,hvalue(t),L->top-1); | ||
5893 | if(more){ | ||
5894 | api_incr_top(L); | ||
5895 | } | ||
5896 | else | ||
5897 | L->top-=1; | ||
5898 | return more; | ||
5899 | } | ||
5900 | static void lua_concat(lua_State*L,int n){ | ||
5901 | api_checknelems(L,n); | ||
5902 | if(n>=2){ | ||
5903 | luaC_checkGC(L); | ||
5904 | luaV_concat(L,n,cast_int(L->top-L->base)-1); | ||
5905 | L->top-=(n-1); | ||
5906 | } | ||
5907 | else if(n==0){ | ||
5908 | setsvalue(L,L->top,luaS_newlstr(L,"",0)); | ||
5909 | api_incr_top(L); | ||
5910 | } | ||
5911 | } | ||
5912 | static void*lua_newuserdata(lua_State*L,size_t size){ | ||
5913 | Udata*u; | ||
5914 | luaC_checkGC(L); | ||
5915 | u=luaS_newudata(L,size,getcurrenv(L)); | ||
5916 | setuvalue(L,L->top,u); | ||
5917 | api_incr_top(L); | ||
5918 | return u+1; | ||
5919 | } | ||
5920 | #define luaL_getn(L,i)((int)lua_objlen(L,i)) | ||
5921 | #define luaL_setn(L,i,j)((void)0) | ||
5922 | typedef struct luaL_Reg{ | ||
5923 | const char*name; | ||
5924 | lua_CFunction func; | ||
5925 | }luaL_Reg; | ||
5926 | static void luaI_openlib(lua_State*L,const char*libname, | ||
5927 | const luaL_Reg*l,int nup); | ||
5928 | static int luaL_argerror(lua_State*L,int numarg,const char*extramsg); | ||
5929 | static const char* luaL_checklstring(lua_State*L,int numArg, | ||
5930 | size_t*l); | ||
5931 | static const char* luaL_optlstring(lua_State*L,int numArg, | ||
5932 | const char*def,size_t*l); | ||
5933 | static lua_Integer luaL_checkinteger(lua_State*L,int numArg); | ||
5934 | static lua_Integer luaL_optinteger(lua_State*L,int nArg, | ||
5935 | lua_Integer def); | ||
5936 | static int luaL_error(lua_State*L,const char*fmt,...); | ||
5937 | static const char* luaL_findtable(lua_State*L,int idx, | ||
5938 | const char*fname,int szhint); | ||
5939 | #define luaL_argcheck(L,cond,numarg,extramsg)((void)((cond)||luaL_argerror(L,(numarg),(extramsg)))) | ||
5940 | #define luaL_checkstring(L,n)(luaL_checklstring(L,(n),NULL)) | ||
5941 | #define luaL_optstring(L,n,d)(luaL_optlstring(L,(n),(d),NULL)) | ||
5942 | #define luaL_checkint(L,n)((int)luaL_checkinteger(L,(n))) | ||
5943 | #define luaL_optint(L,n,d)((int)luaL_optinteger(L,(n),(d))) | ||
5944 | #define luaL_typename(L,i)lua_typename(L,lua_type(L,(i))) | ||
5945 | #define luaL_getmetatable(L,n)(lua_getfield(L,(-10000),(n))) | ||
5946 | #define luaL_opt(L,f,n,d)(lua_isnoneornil(L,(n))?(d):f(L,(n))) | ||
5947 | typedef struct luaL_Buffer{ | ||
5948 | char*p; | ||
5949 | int lvl; | ||
5950 | lua_State*L; | ||
5951 | char buffer[BUFSIZ]; | ||
5952 | }luaL_Buffer; | ||
5953 | #define luaL_addchar(B,c)((void)((B)->p<((B)->buffer+BUFSIZ)||luaL_prepbuffer(B)),(*(B)->p++=(char)(c))) | ||
5954 | #define luaL_addsize(B,n)((B)->p+=(n)) | ||
5955 | static char* luaL_prepbuffer(luaL_Buffer*B); | ||
5956 | static int luaL_argerror(lua_State*L,int narg,const char*extramsg){ | ||
5957 | lua_Debug ar; | ||
5958 | if(!lua_getstack(L,0,&ar)) | ||
5959 | return luaL_error(L,"bad argument #%d (%s)",narg,extramsg); | ||
5960 | lua_getinfo(L,"n",&ar); | ||
5961 | if(strcmp(ar.namewhat,"method")==0){ | ||
5962 | narg--; | ||
5963 | if(narg==0) | ||
5964 | return luaL_error(L,"calling "LUA_QL("%s")" on bad self (%s)", | ||
5965 | ar.name,extramsg); | ||
5966 | } | ||
5967 | if(ar.name==NULL) | ||
5968 | ar.name="?"; | ||
5969 | return luaL_error(L,"bad argument #%d to "LUA_QL("%s")" (%s)", | ||
5970 | narg,ar.name,extramsg); | ||
5971 | } | ||
5972 | static int luaL_typerror(lua_State*L,int narg,const char*tname){ | ||
5973 | const char*msg=lua_pushfstring(L,"%s expected, got %s", | ||
5974 | tname,luaL_typename(L,narg)); | ||
5975 | return luaL_argerror(L,narg,msg); | ||
5976 | } | ||
5977 | static void tag_error(lua_State*L,int narg,int tag){ | ||
5978 | luaL_typerror(L,narg,lua_typename(L,tag)); | ||
5979 | } | ||
5980 | static void luaL_where(lua_State*L,int level){ | ||
5981 | lua_Debug ar; | ||
5982 | if(lua_getstack(L,level,&ar)){ | ||
5983 | lua_getinfo(L,"Sl",&ar); | ||
5984 | if(ar.currentline>0){ | ||
5985 | lua_pushfstring(L,"%s:%d: ",ar.short_src,ar.currentline); | ||
5986 | return; | ||
5987 | } | ||
5988 | } | ||
5989 | lua_pushliteral(L,""); | ||
5990 | } | ||
5991 | static int luaL_error(lua_State*L,const char*fmt,...){ | ||
5992 | va_list argp; | ||
5993 | va_start(argp,fmt); | ||
5994 | luaL_where(L,1); | ||
5995 | lua_pushvfstring(L,fmt,argp); | ||
5996 | va_end(argp); | ||
5997 | lua_concat(L,2); | ||
5998 | return lua_error(L); | ||
5999 | } | ||
6000 | static int luaL_newmetatable(lua_State*L,const char*tname){ | ||
6001 | lua_getfield(L,(-10000),tname); | ||
6002 | if(!lua_isnil(L,-1)) | ||
6003 | return 0; | ||
6004 | lua_pop(L,1); | ||
6005 | lua_newtable(L); | ||
6006 | lua_pushvalue(L,-1); | ||
6007 | lua_setfield(L,(-10000),tname); | ||
6008 | return 1; | ||
6009 | } | ||
6010 | static void*luaL_checkudata(lua_State*L,int ud,const char*tname){ | ||
6011 | void*p=lua_touserdata(L,ud); | ||
6012 | if(p!=NULL){ | ||
6013 | if(lua_getmetatable(L,ud)){ | ||
6014 | lua_getfield(L,(-10000),tname); | ||
6015 | if(lua_rawequal(L,-1,-2)){ | ||
6016 | lua_pop(L,2); | ||
6017 | return p; | ||
6018 | } | ||
6019 | } | ||
6020 | } | ||
6021 | luaL_typerror(L,ud,tname); | ||
6022 | return NULL; | ||
6023 | } | ||
6024 | static void luaL_checkstack(lua_State*L,int space,const char*mes){ | ||
6025 | if(!lua_checkstack(L,space)) | ||
6026 | luaL_error(L,"stack overflow (%s)",mes); | ||
6027 | } | ||
6028 | static void luaL_checktype(lua_State*L,int narg,int t){ | ||
6029 | if(lua_type(L,narg)!=t) | ||
6030 | tag_error(L,narg,t); | ||
6031 | } | ||
6032 | static void luaL_checkany(lua_State*L,int narg){ | ||
6033 | if(lua_type(L,narg)==(-1)) | ||
6034 | luaL_argerror(L,narg,"value expected"); | ||
6035 | } | ||
6036 | static const char*luaL_checklstring(lua_State*L,int narg,size_t*len){ | ||
6037 | const char*s=lua_tolstring(L,narg,len); | ||
6038 | if(!s)tag_error(L,narg,4); | ||
6039 | return s; | ||
6040 | } | ||
6041 | static const char*luaL_optlstring(lua_State*L,int narg, | ||
6042 | const char*def,size_t*len){ | ||
6043 | if(lua_isnoneornil(L,narg)){ | ||
6044 | if(len) | ||
6045 | *len=(def?strlen(def):0); | ||
6046 | return def; | ||
6047 | } | ||
6048 | else return luaL_checklstring(L,narg,len); | ||
6049 | } | ||
6050 | static lua_Number luaL_checknumber(lua_State*L,int narg){ | ||
6051 | lua_Number d=lua_tonumber(L,narg); | ||
6052 | if(d==0&&!lua_isnumber(L,narg)) | ||
6053 | tag_error(L,narg,3); | ||
6054 | return d; | ||
6055 | } | ||
6056 | static lua_Integer luaL_checkinteger(lua_State*L,int narg){ | ||
6057 | lua_Integer d=lua_tointeger(L,narg); | ||
6058 | if(d==0&&!lua_isnumber(L,narg)) | ||
6059 | tag_error(L,narg,3); | ||
6060 | return d; | ||
6061 | } | ||
6062 | static lua_Integer luaL_optinteger(lua_State*L,int narg, | ||
6063 | lua_Integer def){ | ||
6064 | return luaL_opt(L,luaL_checkinteger,narg,def); | ||
6065 | } | ||
6066 | static int luaL_getmetafield(lua_State*L,int obj,const char*event){ | ||
6067 | if(!lua_getmetatable(L,obj)) | ||
6068 | return 0; | ||
6069 | lua_pushstring(L,event); | ||
6070 | lua_rawget(L,-2); | ||
6071 | if(lua_isnil(L,-1)){ | ||
6072 | lua_pop(L,2); | ||
6073 | return 0; | ||
6074 | } | ||
6075 | else{ | ||
6076 | lua_remove(L,-2); | ||
6077 | return 1; | ||
6078 | } | ||
6079 | } | ||
6080 | static void luaL_register(lua_State*L,const char*libname, | ||
6081 | const luaL_Reg*l){ | ||
6082 | luaI_openlib(L,libname,l,0); | ||
6083 | } | ||
6084 | static int libsize(const luaL_Reg*l){ | ||
6085 | int size=0; | ||
6086 | for(;l->name;l++)size++; | ||
6087 | return size; | ||
6088 | } | ||
6089 | static void luaI_openlib(lua_State*L,const char*libname, | ||
6090 | const luaL_Reg*l,int nup){ | ||
6091 | if(libname){ | ||
6092 | int size=libsize(l); | ||
6093 | luaL_findtable(L,(-10000),"_LOADED",1); | ||
6094 | lua_getfield(L,-1,libname); | ||
6095 | if(!lua_istable(L,-1)){ | ||
6096 | lua_pop(L,1); | ||
6097 | if(luaL_findtable(L,(-10002),libname,size)!=NULL) | ||
6098 | luaL_error(L,"name conflict for module "LUA_QL("%s"),libname); | ||
6099 | lua_pushvalue(L,-1); | ||
6100 | lua_setfield(L,-3,libname); | ||
6101 | } | ||
6102 | lua_remove(L,-2); | ||
6103 | lua_insert(L,-(nup+1)); | ||
6104 | } | ||
6105 | for(;l->name;l++){ | ||
6106 | int i; | ||
6107 | for(i=0;i<nup;i++) | ||
6108 | lua_pushvalue(L,-nup); | ||
6109 | lua_pushcclosure(L,l->func,nup); | ||
6110 | lua_setfield(L,-(nup+2),l->name); | ||
6111 | } | ||
6112 | lua_pop(L,nup); | ||
6113 | } | ||
6114 | static const char*luaL_findtable(lua_State*L,int idx, | ||
6115 | const char*fname,int szhint){ | ||
6116 | const char*e; | ||
6117 | lua_pushvalue(L,idx); | ||
6118 | do{ | ||
6119 | e=strchr(fname,'.'); | ||
6120 | if(e==NULL)e=fname+strlen(fname); | ||
6121 | lua_pushlstring(L,fname,e-fname); | ||
6122 | lua_rawget(L,-2); | ||
6123 | if(lua_isnil(L,-1)){ | ||
6124 | lua_pop(L,1); | ||
6125 | lua_createtable(L,0,(*e=='.'?1:szhint)); | ||
6126 | lua_pushlstring(L,fname,e-fname); | ||
6127 | lua_pushvalue(L,-2); | ||
6128 | lua_settable(L,-4); | ||
6129 | } | ||
6130 | else if(!lua_istable(L,-1)){ | ||
6131 | lua_pop(L,2); | ||
6132 | return fname; | ||
6133 | } | ||
6134 | lua_remove(L,-2); | ||
6135 | fname=e+1; | ||
6136 | }while(*e=='.'); | ||
6137 | return NULL; | ||
6138 | } | ||
6139 | #define bufflen(B)((B)->p-(B)->buffer) | ||
6140 | #define bufffree(B)((size_t)(BUFSIZ-bufflen(B))) | ||
6141 | static int emptybuffer(luaL_Buffer*B){ | ||
6142 | size_t l=bufflen(B); | ||
6143 | if(l==0)return 0; | ||
6144 | else{ | ||
6145 | lua_pushlstring(B->L,B->buffer,l); | ||
6146 | B->p=B->buffer; | ||
6147 | B->lvl++; | ||
6148 | return 1; | ||
6149 | } | ||
6150 | } | ||
6151 | static void adjuststack(luaL_Buffer*B){ | ||
6152 | if(B->lvl>1){ | ||
6153 | lua_State*L=B->L; | ||
6154 | int toget=1; | ||
6155 | size_t toplen=lua_strlen(L,-1); | ||
6156 | do{ | ||
6157 | size_t l=lua_strlen(L,-(toget+1)); | ||
6158 | if(B->lvl-toget+1>=(20/2)||toplen>l){ | ||
6159 | toplen+=l; | ||
6160 | toget++; | ||
6161 | } | ||
6162 | else break; | ||
6163 | }while(toget<B->lvl); | ||
6164 | lua_concat(L,toget); | ||
6165 | B->lvl=B->lvl-toget+1; | ||
6166 | } | ||
6167 | } | ||
6168 | static char*luaL_prepbuffer(luaL_Buffer*B){ | ||
6169 | if(emptybuffer(B)) | ||
6170 | adjuststack(B); | ||
6171 | return B->buffer; | ||
6172 | } | ||
6173 | static void luaL_addlstring(luaL_Buffer*B,const char*s,size_t l){ | ||
6174 | while(l--) | ||
6175 | luaL_addchar(B,*s++); | ||
6176 | } | ||
6177 | static void luaL_pushresult(luaL_Buffer*B){ | ||
6178 | emptybuffer(B); | ||
6179 | lua_concat(B->L,B->lvl); | ||
6180 | B->lvl=1; | ||
6181 | } | ||
6182 | static void luaL_addvalue(luaL_Buffer*B){ | ||
6183 | lua_State*L=B->L; | ||
6184 | size_t vl; | ||
6185 | const char*s=lua_tolstring(L,-1,&vl); | ||
6186 | if(vl<=bufffree(B)){ | ||
6187 | memcpy(B->p,s,vl); | ||
6188 | B->p+=vl; | ||
6189 | lua_pop(L,1); | ||
6190 | } | ||
6191 | else{ | ||
6192 | if(emptybuffer(B)) | ||
6193 | lua_insert(L,-2); | ||
6194 | B->lvl++; | ||
6195 | adjuststack(B); | ||
6196 | } | ||
6197 | } | ||
6198 | static void luaL_buffinit(lua_State*L,luaL_Buffer*B){ | ||
6199 | B->L=L; | ||
6200 | B->p=B->buffer; | ||
6201 | B->lvl=0; | ||
6202 | } | ||
6203 | typedef struct LoadF{ | ||
6204 | int extraline; | ||
6205 | FILE*f; | ||
6206 | char buff[BUFSIZ]; | ||
6207 | }LoadF; | ||
6208 | static const char*getF(lua_State*L,void*ud,size_t*size){ | ||
6209 | LoadF*lf=(LoadF*)ud; | ||
6210 | (void)L; | ||
6211 | if(lf->extraline){ | ||
6212 | lf->extraline=0; | ||
6213 | *size=1; | ||
6214 | return"\n"; | ||
6215 | } | ||
6216 | if(feof(lf->f))return NULL; | ||
6217 | *size=fread(lf->buff,1,sizeof(lf->buff),lf->f); | ||
6218 | return(*size>0)?lf->buff:NULL; | ||
6219 | } | ||
6220 | static int errfile(lua_State*L,const char*what,int fnameindex){ | ||
6221 | const char*serr=strerror(errno); | ||
6222 | const char*filename=lua_tostring(L,fnameindex)+1; | ||
6223 | lua_pushfstring(L,"cannot %s %s: %s",what,filename,serr); | ||
6224 | lua_remove(L,fnameindex); | ||
6225 | return(5+1); | ||
6226 | } | ||
6227 | static int luaL_loadfile(lua_State*L,const char*filename){ | ||
6228 | LoadF lf; | ||
6229 | int status,readstatus; | ||
6230 | int c; | ||
6231 | int fnameindex=lua_gettop(L)+1; | ||
6232 | lf.extraline=0; | ||
6233 | if(filename==NULL){ | ||
6234 | lua_pushliteral(L,"=stdin"); | ||
6235 | lf.f=stdin; | ||
6236 | } | ||
6237 | else{ | ||
6238 | lua_pushfstring(L,"@%s",filename); | ||
6239 | lf.f=fopen(filename,"r"); | ||
6240 | if(lf.f==NULL)return errfile(L,"open",fnameindex); | ||
6241 | } | ||
6242 | c=getc(lf.f); | ||
6243 | if(c=='#'){ | ||
6244 | lf.extraline=1; | ||
6245 | while((c=getc(lf.f))!=EOF&&c!='\n'); | ||
6246 | if(c=='\n')c=getc(lf.f); | ||
6247 | } | ||
6248 | if(c=="\033Lua"[0]&&filename){ | ||
6249 | lf.f=freopen(filename,"rb",lf.f); | ||
6250 | if(lf.f==NULL)return errfile(L,"reopen",fnameindex); | ||
6251 | while((c=getc(lf.f))!=EOF&&c!="\033Lua"[0]); | ||
6252 | lf.extraline=0; | ||
6253 | } | ||
6254 | ungetc(c,lf.f); | ||
6255 | status=lua_load(L,getF,&lf,lua_tostring(L,-1)); | ||
6256 | readstatus=ferror(lf.f); | ||
6257 | if(filename)fclose(lf.f); | ||
6258 | if(readstatus){ | ||
6259 | lua_settop(L,fnameindex); | ||
6260 | return errfile(L,"read",fnameindex); | ||
6261 | } | ||
6262 | lua_remove(L,fnameindex); | ||
6263 | return status; | ||
6264 | } | ||
6265 | typedef struct LoadS{ | ||
6266 | const char*s; | ||
6267 | size_t size; | ||
6268 | }LoadS; | ||
6269 | static const char*getS(lua_State*L,void*ud,size_t*size){ | ||
6270 | LoadS*ls=(LoadS*)ud; | ||
6271 | (void)L; | ||
6272 | if(ls->size==0)return NULL; | ||
6273 | *size=ls->size; | ||
6274 | ls->size=0; | ||
6275 | return ls->s; | ||
6276 | } | ||
6277 | static int luaL_loadbuffer(lua_State*L,const char*buff,size_t size, | ||
6278 | const char*name){ | ||
6279 | LoadS ls; | ||
6280 | ls.s=buff; | ||
6281 | ls.size=size; | ||
6282 | return lua_load(L,getS,&ls,name); | ||
6283 | } | ||
6284 | static void*l_alloc(void*ud,void*ptr,size_t osize,size_t nsize){ | ||
6285 | (void)ud; | ||
6286 | (void)osize; | ||
6287 | if(nsize==0){ | ||
6288 | free(ptr); | ||
6289 | return NULL; | ||
6290 | } | ||
6291 | else | ||
6292 | return realloc(ptr,nsize); | ||
6293 | } | ||
6294 | static int panic(lua_State*L){ | ||
6295 | (void)L; | ||
6296 | fprintf(stderr,"PANIC: unprotected error in call to Lua API (%s)\n", | ||
6297 | lua_tostring(L,-1)); | ||
6298 | return 0; | ||
6299 | } | ||
6300 | static lua_State*luaL_newstate(void){ | ||
6301 | lua_State*L=lua_newstate(l_alloc,NULL); | ||
6302 | if(L)lua_atpanic(L,&panic); | ||
6303 | return L; | ||
6304 | } | ||
6305 | static int luaB_tonumber(lua_State*L){ | ||
6306 | int base=luaL_optint(L,2,10); | ||
6307 | if(base==10){ | ||
6308 | luaL_checkany(L,1); | ||
6309 | if(lua_isnumber(L,1)){ | ||
6310 | lua_pushnumber(L,lua_tonumber(L,1)); | ||
6311 | return 1; | ||
6312 | } | ||
6313 | } | ||
6314 | else{ | ||
6315 | const char*s1=luaL_checkstring(L,1); | ||
6316 | char*s2; | ||
6317 | unsigned long n; | ||
6318 | luaL_argcheck(L,2<=base&&base<=36,2,"base out of range"); | ||
6319 | n=strtoul(s1,&s2,base); | ||
6320 | if(s1!=s2){ | ||
6321 | while(isspace((unsigned char)(*s2)))s2++; | ||
6322 | if(*s2=='\0'){ | ||
6323 | lua_pushnumber(L,(lua_Number)n); | ||
6324 | return 1; | ||
6325 | } | ||
6326 | } | ||
6327 | } | ||
6328 | lua_pushnil(L); | ||
6329 | return 1; | ||
6330 | } | ||
6331 | static int luaB_error(lua_State*L){ | ||
6332 | int level=luaL_optint(L,2,1); | ||
6333 | lua_settop(L,1); | ||
6334 | if(lua_isstring(L,1)&&level>0){ | ||
6335 | luaL_where(L,level); | ||
6336 | lua_pushvalue(L,1); | ||
6337 | lua_concat(L,2); | ||
6338 | } | ||
6339 | return lua_error(L); | ||
6340 | } | ||
6341 | static int luaB_setmetatable(lua_State*L){ | ||
6342 | int t=lua_type(L,2); | ||
6343 | luaL_checktype(L,1,5); | ||
6344 | luaL_argcheck(L,t==0||t==5,2, | ||
6345 | "nil or table expected"); | ||
6346 | if(luaL_getmetafield(L,1,"__metatable")) | ||
6347 | luaL_error(L,"cannot change a protected metatable"); | ||
6348 | lua_settop(L,2); | ||
6349 | lua_setmetatable(L,1); | ||
6350 | return 1; | ||
6351 | } | ||
6352 | static void getfunc(lua_State*L,int opt){ | ||
6353 | if(lua_isfunction(L,1))lua_pushvalue(L,1); | ||
6354 | else{ | ||
6355 | lua_Debug ar; | ||
6356 | int level=opt?luaL_optint(L,1,1):luaL_checkint(L,1); | ||
6357 | luaL_argcheck(L,level>=0,1,"level must be non-negative"); | ||
6358 | if(lua_getstack(L,level,&ar)==0) | ||
6359 | luaL_argerror(L,1,"invalid level"); | ||
6360 | lua_getinfo(L,"f",&ar); | ||
6361 | if(lua_isnil(L,-1)) | ||
6362 | luaL_error(L,"no function environment for tail call at level %d", | ||
6363 | level); | ||
6364 | } | ||
6365 | } | ||
6366 | static int luaB_setfenv(lua_State*L){ | ||
6367 | luaL_checktype(L,2,5); | ||
6368 | getfunc(L,0); | ||
6369 | lua_pushvalue(L,2); | ||
6370 | if(lua_isnumber(L,1)&&lua_tonumber(L,1)==0){ | ||
6371 | lua_pushthread(L); | ||
6372 | lua_insert(L,-2); | ||
6373 | lua_setfenv(L,-2); | ||
6374 | return 0; | ||
6375 | } | ||
6376 | else if(lua_iscfunction(L,-2)||lua_setfenv(L,-2)==0) | ||
6377 | luaL_error(L, | ||
6378 | LUA_QL("setfenv")" cannot change environment of given object"); | ||
6379 | return 1; | ||
6380 | } | ||
6381 | static int luaB_rawget(lua_State*L){ | ||
6382 | luaL_checktype(L,1,5); | ||
6383 | luaL_checkany(L,2); | ||
6384 | lua_settop(L,2); | ||
6385 | lua_rawget(L,1); | ||
6386 | return 1; | ||
6387 | } | ||
6388 | static int luaB_type(lua_State*L){ | ||
6389 | luaL_checkany(L,1); | ||
6390 | lua_pushstring(L,luaL_typename(L,1)); | ||
6391 | return 1; | ||
6392 | } | ||
6393 | static int luaB_next(lua_State*L){ | ||
6394 | luaL_checktype(L,1,5); | ||
6395 | lua_settop(L,2); | ||
6396 | if(lua_next(L,1)) | ||
6397 | return 2; | ||
6398 | else{ | ||
6399 | lua_pushnil(L); | ||
6400 | return 1; | ||
6401 | } | ||
6402 | } | ||
6403 | static int luaB_pairs(lua_State*L){ | ||
6404 | luaL_checktype(L,1,5); | ||
6405 | lua_pushvalue(L,lua_upvalueindex(1)); | ||
6406 | lua_pushvalue(L,1); | ||
6407 | lua_pushnil(L); | ||
6408 | return 3; | ||
6409 | } | ||
6410 | static int ipairsaux(lua_State*L){ | ||
6411 | int i=luaL_checkint(L,2); | ||
6412 | luaL_checktype(L,1,5); | ||
6413 | i++; | ||
6414 | lua_pushinteger(L,i); | ||
6415 | lua_rawgeti(L,1,i); | ||
6416 | return(lua_isnil(L,-1))?0:2; | ||
6417 | } | ||
6418 | static int luaB_ipairs(lua_State*L){ | ||
6419 | luaL_checktype(L,1,5); | ||
6420 | lua_pushvalue(L,lua_upvalueindex(1)); | ||
6421 | lua_pushvalue(L,1); | ||
6422 | lua_pushinteger(L,0); | ||
6423 | return 3; | ||
6424 | } | ||
6425 | static int load_aux(lua_State*L,int status){ | ||
6426 | if(status==0) | ||
6427 | return 1; | ||
6428 | else{ | ||
6429 | lua_pushnil(L); | ||
6430 | lua_insert(L,-2); | ||
6431 | return 2; | ||
6432 | } | ||
6433 | } | ||
6434 | static int luaB_loadstring(lua_State*L){ | ||
6435 | size_t l; | ||
6436 | const char*s=luaL_checklstring(L,1,&l); | ||
6437 | const char*chunkname=luaL_optstring(L,2,s); | ||
6438 | return load_aux(L,luaL_loadbuffer(L,s,l,chunkname)); | ||
6439 | } | ||
6440 | static int luaB_loadfile(lua_State*L){ | ||
6441 | const char*fname=luaL_optstring(L,1,NULL); | ||
6442 | return load_aux(L,luaL_loadfile(L,fname)); | ||
6443 | } | ||
6444 | static int luaB_assert(lua_State*L){ | ||
6445 | luaL_checkany(L,1); | ||
6446 | if(!lua_toboolean(L,1)) | ||
6447 | return luaL_error(L,"%s",luaL_optstring(L,2,"assertion failed!")); | ||
6448 | return lua_gettop(L); | ||
6449 | } | ||
6450 | static int luaB_unpack(lua_State*L){ | ||
6451 | int i,e,n; | ||
6452 | luaL_checktype(L,1,5); | ||
6453 | i=luaL_optint(L,2,1); | ||
6454 | e=luaL_opt(L,luaL_checkint,3,luaL_getn(L,1)); | ||
6455 | if(i>e)return 0; | ||
6456 | n=e-i+1; | ||
6457 | if(n<=0||!lua_checkstack(L,n)) | ||
6458 | return luaL_error(L,"too many results to unpack"); | ||
6459 | lua_rawgeti(L,1,i); | ||
6460 | while(i++<e) | ||
6461 | lua_rawgeti(L,1,i); | ||
6462 | return n; | ||
6463 | } | ||
6464 | static int luaB_pcall(lua_State*L){ | ||
6465 | int status; | ||
6466 | luaL_checkany(L,1); | ||
6467 | status=lua_pcall(L,lua_gettop(L)-1,(-1),0); | ||
6468 | lua_pushboolean(L,(status==0)); | ||
6469 | lua_insert(L,1); | ||
6470 | return lua_gettop(L); | ||
6471 | } | ||
6472 | static int luaB_newproxy(lua_State*L){ | ||
6473 | lua_settop(L,1); | ||
6474 | lua_newuserdata(L,0); | ||
6475 | if(lua_toboolean(L,1)==0) | ||
6476 | return 1; | ||
6477 | else if(lua_isboolean(L,1)){ | ||
6478 | lua_newtable(L); | ||
6479 | lua_pushvalue(L,-1); | ||
6480 | lua_pushboolean(L,1); | ||
6481 | lua_rawset(L,lua_upvalueindex(1)); | ||
6482 | } | ||
6483 | else{ | ||
6484 | int validproxy=0; | ||
6485 | if(lua_getmetatable(L,1)){ | ||
6486 | lua_rawget(L,lua_upvalueindex(1)); | ||
6487 | validproxy=lua_toboolean(L,-1); | ||
6488 | lua_pop(L,1); | ||
6489 | } | ||
6490 | luaL_argcheck(L,validproxy,1,"boolean or proxy expected"); | ||
6491 | lua_getmetatable(L,1); | ||
6492 | } | ||
6493 | lua_setmetatable(L,2); | ||
6494 | return 1; | ||
6495 | } | ||
6496 | static const luaL_Reg base_funcs[]={ | ||
6497 | {"assert",luaB_assert}, | ||
6498 | {"error",luaB_error}, | ||
6499 | {"loadfile",luaB_loadfile}, | ||
6500 | {"loadstring",luaB_loadstring}, | ||
6501 | {"next",luaB_next}, | ||
6502 | {"pcall",luaB_pcall}, | ||
6503 | {"rawget",luaB_rawget}, | ||
6504 | {"setfenv",luaB_setfenv}, | ||
6505 | {"setmetatable",luaB_setmetatable}, | ||
6506 | {"tonumber",luaB_tonumber}, | ||
6507 | {"type",luaB_type}, | ||
6508 | {"unpack",luaB_unpack}, | ||
6509 | {NULL,NULL} | ||
6510 | }; | ||
6511 | static const char*const statnames[]= | ||
6512 | {"running","suspended","normal","dead"}; | ||
6513 | static int costatus(lua_State*L,lua_State*co){ | ||
6514 | if(L==co)return 0; | ||
6515 | switch(lua_status(co)){ | ||
6516 | case 1: | ||
6517 | return 1; | ||
6518 | case 0:{ | ||
6519 | lua_Debug ar; | ||
6520 | if(lua_getstack(co,0,&ar)>0) | ||
6521 | return 2; | ||
6522 | else if(lua_gettop(co)==0) | ||
6523 | return 3; | ||
6524 | else | ||
6525 | return 1; | ||
6526 | } | ||
6527 | default: | ||
6528 | return 3; | ||
6529 | } | ||
6530 | } | ||
6531 | static int luaB_costatus(lua_State*L){ | ||
6532 | lua_State*co=lua_tothread(L,1); | ||
6533 | luaL_argcheck(L,co,1,"coroutine expected"); | ||
6534 | lua_pushstring(L,statnames[costatus(L,co)]); | ||
6535 | return 1; | ||
6536 | } | ||
6537 | static int auxresume(lua_State*L,lua_State*co,int narg){ | ||
6538 | int status=costatus(L,co); | ||
6539 | if(!lua_checkstack(co,narg)) | ||
6540 | luaL_error(L,"too many arguments to resume"); | ||
6541 | if(status!=1){ | ||
6542 | lua_pushfstring(L,"cannot resume %s coroutine",statnames[status]); | ||
6543 | return-1; | ||
6544 | } | ||
6545 | lua_xmove(L,co,narg); | ||
6546 | lua_setlevel(L,co); | ||
6547 | status=lua_resume(co,narg); | ||
6548 | if(status==0||status==1){ | ||
6549 | int nres=lua_gettop(co); | ||
6550 | if(!lua_checkstack(L,nres+1)) | ||
6551 | luaL_error(L,"too many results to resume"); | ||
6552 | lua_xmove(co,L,nres); | ||
6553 | return nres; | ||
6554 | } | ||
6555 | else{ | ||
6556 | lua_xmove(co,L,1); | ||
6557 | return-1; | ||
6558 | } | ||
6559 | } | ||
6560 | static int luaB_coresume(lua_State*L){ | ||
6561 | lua_State*co=lua_tothread(L,1); | ||
6562 | int r; | ||
6563 | luaL_argcheck(L,co,1,"coroutine expected"); | ||
6564 | r=auxresume(L,co,lua_gettop(L)-1); | ||
6565 | if(r<0){ | ||
6566 | lua_pushboolean(L,0); | ||
6567 | lua_insert(L,-2); | ||
6568 | return 2; | ||
6569 | } | ||
6570 | else{ | ||
6571 | lua_pushboolean(L,1); | ||
6572 | lua_insert(L,-(r+1)); | ||
6573 | return r+1; | ||
6574 | } | ||
6575 | } | ||
6576 | static int luaB_auxwrap(lua_State*L){ | ||
6577 | lua_State*co=lua_tothread(L,lua_upvalueindex(1)); | ||
6578 | int r=auxresume(L,co,lua_gettop(L)); | ||
6579 | if(r<0){ | ||
6580 | if(lua_isstring(L,-1)){ | ||
6581 | luaL_where(L,1); | ||
6582 | lua_insert(L,-2); | ||
6583 | lua_concat(L,2); | ||
6584 | } | ||
6585 | lua_error(L); | ||
6586 | } | ||
6587 | return r; | ||
6588 | } | ||
6589 | static int luaB_cocreate(lua_State*L){ | ||
6590 | lua_State*NL=lua_newthread(L); | ||
6591 | luaL_argcheck(L,lua_isfunction(L,1)&&!lua_iscfunction(L,1),1, | ||
6592 | "Lua function expected"); | ||
6593 | lua_pushvalue(L,1); | ||
6594 | lua_xmove(L,NL,1); | ||
6595 | return 1; | ||
6596 | } | ||
6597 | static int luaB_cowrap(lua_State*L){ | ||
6598 | luaB_cocreate(L); | ||
6599 | lua_pushcclosure(L,luaB_auxwrap,1); | ||
6600 | return 1; | ||
6601 | } | ||
6602 | static int luaB_yield(lua_State*L){ | ||
6603 | return lua_yield(L,lua_gettop(L)); | ||
6604 | } | ||
6605 | static int luaB_corunning(lua_State*L){ | ||
6606 | if(lua_pushthread(L)) | ||
6607 | lua_pushnil(L); | ||
6608 | return 1; | ||
6609 | } | ||
6610 | static const luaL_Reg co_funcs[]={ | ||
6611 | {"create",luaB_cocreate}, | ||
6612 | {"resume",luaB_coresume}, | ||
6613 | {"running",luaB_corunning}, | ||
6614 | {"status",luaB_costatus}, | ||
6615 | {"wrap",luaB_cowrap}, | ||
6616 | {"yield",luaB_yield}, | ||
6617 | {NULL,NULL} | ||
6618 | }; | ||
6619 | static void auxopen(lua_State*L,const char*name, | ||
6620 | lua_CFunction f,lua_CFunction u){ | ||
6621 | lua_pushcfunction(L,u); | ||
6622 | lua_pushcclosure(L,f,1); | ||
6623 | lua_setfield(L,-2,name); | ||
6624 | } | ||
6625 | static void base_open(lua_State*L){ | ||
6626 | lua_pushvalue(L,(-10002)); | ||
6627 | lua_setglobal(L,"_G"); | ||
6628 | luaL_register(L,"_G",base_funcs); | ||
6629 | lua_pushliteral(L,"Lua 5.1"); | ||
6630 | lua_setglobal(L,"_VERSION"); | ||
6631 | auxopen(L,"ipairs",luaB_ipairs,ipairsaux); | ||
6632 | auxopen(L,"pairs",luaB_pairs,luaB_next); | ||
6633 | lua_createtable(L,0,1); | ||
6634 | lua_pushvalue(L,-1); | ||
6635 | lua_setmetatable(L,-2); | ||
6636 | lua_pushliteral(L,"kv"); | ||
6637 | lua_setfield(L,-2,"__mode"); | ||
6638 | lua_pushcclosure(L,luaB_newproxy,1); | ||
6639 | lua_setglobal(L,"newproxy"); | ||
6640 | } | ||
6641 | static int luaopen_base(lua_State*L){ | ||
6642 | base_open(L); | ||
6643 | luaL_register(L,"coroutine",co_funcs); | ||
6644 | return 2; | ||
6645 | } | ||
6646 | #define aux_getn(L,n)(luaL_checktype(L,n,5),luaL_getn(L,n)) | ||
6647 | static int tinsert(lua_State*L){ | ||
6648 | int e=aux_getn(L,1)+1; | ||
6649 | int pos; | ||
6650 | switch(lua_gettop(L)){ | ||
6651 | case 2:{ | ||
6652 | pos=e; | ||
6653 | break; | ||
6654 | } | ||
6655 | case 3:{ | ||
6656 | int i; | ||
6657 | pos=luaL_checkint(L,2); | ||
6658 | if(pos>e)e=pos; | ||
6659 | for(i=e;i>pos;i--){ | ||
6660 | lua_rawgeti(L,1,i-1); | ||
6661 | lua_rawseti(L,1,i); | ||
6662 | } | ||
6663 | break; | ||
6664 | } | ||
6665 | default:{ | ||
6666 | return luaL_error(L,"wrong number of arguments to "LUA_QL("insert")); | ||
6667 | } | ||
6668 | } | ||
6669 | luaL_setn(L,1,e); | ||
6670 | lua_rawseti(L,1,pos); | ||
6671 | return 0; | ||
6672 | } | ||
6673 | static int tremove(lua_State*L){ | ||
6674 | int e=aux_getn(L,1); | ||
6675 | int pos=luaL_optint(L,2,e); | ||
6676 | if(!(1<=pos&&pos<=e)) | ||
6677 | return 0; | ||
6678 | luaL_setn(L,1,e-1); | ||
6679 | lua_rawgeti(L,1,pos); | ||
6680 | for(;pos<e;pos++){ | ||
6681 | lua_rawgeti(L,1,pos+1); | ||
6682 | lua_rawseti(L,1,pos); | ||
6683 | } | ||
6684 | lua_pushnil(L); | ||
6685 | lua_rawseti(L,1,e); | ||
6686 | return 1; | ||
6687 | } | ||
6688 | static void addfield(lua_State*L,luaL_Buffer*b,int i){ | ||
6689 | lua_rawgeti(L,1,i); | ||
6690 | if(!lua_isstring(L,-1)) | ||
6691 | luaL_error(L,"invalid value (%s) at index %d in table for " | ||
6692 | LUA_QL("concat"),luaL_typename(L,-1),i); | ||
6693 | luaL_addvalue(b); | ||
6694 | } | ||
6695 | static int tconcat(lua_State*L){ | ||
6696 | luaL_Buffer b; | ||
6697 | size_t lsep; | ||
6698 | int i,last; | ||
6699 | const char*sep=luaL_optlstring(L,2,"",&lsep); | ||
6700 | luaL_checktype(L,1,5); | ||
6701 | i=luaL_optint(L,3,1); | ||
6702 | last=luaL_opt(L,luaL_checkint,4,luaL_getn(L,1)); | ||
6703 | luaL_buffinit(L,&b); | ||
6704 | for(;i<last;i++){ | ||
6705 | addfield(L,&b,i); | ||
6706 | luaL_addlstring(&b,sep,lsep); | ||
6707 | } | ||
6708 | if(i==last) | ||
6709 | addfield(L,&b,i); | ||
6710 | luaL_pushresult(&b); | ||
6711 | return 1; | ||
6712 | } | ||
6713 | static void set2(lua_State*L,int i,int j){ | ||
6714 | lua_rawseti(L,1,i); | ||
6715 | lua_rawseti(L,1,j); | ||
6716 | } | ||
6717 | static int sort_comp(lua_State*L,int a,int b){ | ||
6718 | if(!lua_isnil(L,2)){ | ||
6719 | int res; | ||
6720 | lua_pushvalue(L,2); | ||
6721 | lua_pushvalue(L,a-1); | ||
6722 | lua_pushvalue(L,b-2); | ||
6723 | lua_call(L,2,1); | ||
6724 | res=lua_toboolean(L,-1); | ||
6725 | lua_pop(L,1); | ||
6726 | return res; | ||
6727 | } | ||
6728 | else | ||
6729 | return lua_lessthan(L,a,b); | ||
6730 | } | ||
6731 | static void auxsort(lua_State*L,int l,int u){ | ||
6732 | while(l<u){ | ||
6733 | int i,j; | ||
6734 | lua_rawgeti(L,1,l); | ||
6735 | lua_rawgeti(L,1,u); | ||
6736 | if(sort_comp(L,-1,-2)) | ||
6737 | set2(L,l,u); | ||
6738 | else | ||
6739 | lua_pop(L,2); | ||
6740 | if(u-l==1)break; | ||
6741 | i=(l+u)/2; | ||
6742 | lua_rawgeti(L,1,i); | ||
6743 | lua_rawgeti(L,1,l); | ||
6744 | if(sort_comp(L,-2,-1)) | ||
6745 | set2(L,i,l); | ||
6746 | else{ | ||
6747 | lua_pop(L,1); | ||
6748 | lua_rawgeti(L,1,u); | ||
6749 | if(sort_comp(L,-1,-2)) | ||
6750 | set2(L,i,u); | ||
6751 | else | ||
6752 | lua_pop(L,2); | ||
6753 | } | ||
6754 | if(u-l==2)break; | ||
6755 | lua_rawgeti(L,1,i); | ||
6756 | lua_pushvalue(L,-1); | ||
6757 | lua_rawgeti(L,1,u-1); | ||
6758 | set2(L,i,u-1); | ||
6759 | i=l;j=u-1; | ||
6760 | for(;;){ | ||
6761 | while(lua_rawgeti(L,1,++i),sort_comp(L,-1,-2)){ | ||
6762 | if(i>u)luaL_error(L,"invalid order function for sorting"); | ||
6763 | lua_pop(L,1); | ||
6764 | } | ||
6765 | while(lua_rawgeti(L,1,--j),sort_comp(L,-3,-1)){ | ||
6766 | if(j<l)luaL_error(L,"invalid order function for sorting"); | ||
6767 | lua_pop(L,1); | ||
6768 | } | ||
6769 | if(j<i){ | ||
6770 | lua_pop(L,3); | ||
6771 | break; | ||
6772 | } | ||
6773 | set2(L,i,j); | ||
6774 | } | ||
6775 | lua_rawgeti(L,1,u-1); | ||
6776 | lua_rawgeti(L,1,i); | ||
6777 | set2(L,u-1,i); | ||
6778 | if(i-l<u-i){ | ||
6779 | j=l;i=i-1;l=i+2; | ||
6780 | } | ||
6781 | else{ | ||
6782 | j=i+1;i=u;u=j-2; | ||
6783 | } | ||
6784 | auxsort(L,j,i); | ||
6785 | } | ||
6786 | } | ||
6787 | static int sort(lua_State*L){ | ||
6788 | int n=aux_getn(L,1); | ||
6789 | luaL_checkstack(L,40,""); | ||
6790 | if(!lua_isnoneornil(L,2)) | ||
6791 | luaL_checktype(L,2,6); | ||
6792 | lua_settop(L,2); | ||
6793 | auxsort(L,1,n); | ||
6794 | return 0; | ||
6795 | } | ||
6796 | static const luaL_Reg tab_funcs[]={ | ||
6797 | {"concat",tconcat}, | ||
6798 | {"insert",tinsert}, | ||
6799 | {"remove",tremove}, | ||
6800 | {"sort",sort}, | ||
6801 | {NULL,NULL} | ||
6802 | }; | ||
6803 | static int luaopen_table(lua_State*L){ | ||
6804 | luaL_register(L,"table",tab_funcs); | ||
6805 | return 1; | ||
6806 | } | ||
6807 | static const char*const fnames[]={"input","output"}; | ||
6808 | static int pushresult(lua_State*L,int i,const char*filename){ | ||
6809 | int en=errno; | ||
6810 | if(i){ | ||
6811 | lua_pushboolean(L,1); | ||
6812 | return 1; | ||
6813 | } | ||
6814 | else{ | ||
6815 | lua_pushnil(L); | ||
6816 | if(filename) | ||
6817 | lua_pushfstring(L,"%s: %s",filename,strerror(en)); | ||
6818 | else | ||
6819 | lua_pushfstring(L,"%s",strerror(en)); | ||
6820 | lua_pushinteger(L,en); | ||
6821 | return 3; | ||
6822 | } | ||
6823 | } | ||
6824 | static void fileerror(lua_State*L,int arg,const char*filename){ | ||
6825 | lua_pushfstring(L,"%s: %s",filename,strerror(errno)); | ||
6826 | luaL_argerror(L,arg,lua_tostring(L,-1)); | ||
6827 | } | ||
6828 | #define tofilep(L)((FILE**)luaL_checkudata(L,1,"FILE*")) | ||
6829 | static int io_type(lua_State*L){ | ||
6830 | void*ud; | ||
6831 | luaL_checkany(L,1); | ||
6832 | ud=lua_touserdata(L,1); | ||
6833 | lua_getfield(L,(-10000),"FILE*"); | ||
6834 | if(ud==NULL||!lua_getmetatable(L,1)||!lua_rawequal(L,-2,-1)) | ||
6835 | lua_pushnil(L); | ||
6836 | else if(*((FILE**)ud)==NULL) | ||
6837 | lua_pushliteral(L,"closed file"); | ||
6838 | else | ||
6839 | lua_pushliteral(L,"file"); | ||
6840 | return 1; | ||
6841 | } | ||
6842 | static FILE*tofile(lua_State*L){ | ||
6843 | FILE**f=tofilep(L); | ||
6844 | if(*f==NULL) | ||
6845 | luaL_error(L,"attempt to use a closed file"); | ||
6846 | return*f; | ||
6847 | } | ||
6848 | static FILE**newfile(lua_State*L){ | ||
6849 | FILE**pf=(FILE**)lua_newuserdata(L,sizeof(FILE*)); | ||
6850 | *pf=NULL; | ||
6851 | luaL_getmetatable(L,"FILE*"); | ||
6852 | lua_setmetatable(L,-2); | ||
6853 | return pf; | ||
6854 | } | ||
6855 | static int io_noclose(lua_State*L){ | ||
6856 | lua_pushnil(L); | ||
6857 | lua_pushliteral(L,"cannot close standard file"); | ||
6858 | return 2; | ||
6859 | } | ||
6860 | static int io_pclose(lua_State*L){ | ||
6861 | FILE**p=tofilep(L); | ||
6862 | int ok=lua_pclose(L,*p); | ||
6863 | *p=NULL; | ||
6864 | return pushresult(L,ok,NULL); | ||
6865 | } | ||
6866 | static int io_fclose(lua_State*L){ | ||
6867 | FILE**p=tofilep(L); | ||
6868 | int ok=(fclose(*p)==0); | ||
6869 | *p=NULL; | ||
6870 | return pushresult(L,ok,NULL); | ||
6871 | } | ||
6872 | static int aux_close(lua_State*L){ | ||
6873 | lua_getfenv(L,1); | ||
6874 | lua_getfield(L,-1,"__close"); | ||
6875 | return(lua_tocfunction(L,-1))(L); | ||
6876 | } | ||
6877 | static int io_close(lua_State*L){ | ||
6878 | if(lua_isnone(L,1)) | ||
6879 | lua_rawgeti(L,(-10001),2); | ||
6880 | tofile(L); | ||
6881 | return aux_close(L); | ||
6882 | } | ||
6883 | static int io_gc(lua_State*L){ | ||
6884 | FILE*f=*tofilep(L); | ||
6885 | if(f!=NULL) | ||
6886 | aux_close(L); | ||
6887 | return 0; | ||
6888 | } | ||
6889 | static int io_open(lua_State*L){ | ||
6890 | const char*filename=luaL_checkstring(L,1); | ||
6891 | const char*mode=luaL_optstring(L,2,"r"); | ||
6892 | FILE**pf=newfile(L); | ||
6893 | *pf=fopen(filename,mode); | ||
6894 | return(*pf==NULL)?pushresult(L,0,filename):1; | ||
6895 | } | ||
6896 | static FILE*getiofile(lua_State*L,int findex){ | ||
6897 | FILE*f; | ||
6898 | lua_rawgeti(L,(-10001),findex); | ||
6899 | f=*(FILE**)lua_touserdata(L,-1); | ||
6900 | if(f==NULL) | ||
6901 | luaL_error(L,"standard %s file is closed",fnames[findex-1]); | ||
6902 | return f; | ||
6903 | } | ||
6904 | static int g_iofile(lua_State*L,int f,const char*mode){ | ||
6905 | if(!lua_isnoneornil(L,1)){ | ||
6906 | const char*filename=lua_tostring(L,1); | ||
6907 | if(filename){ | ||
6908 | FILE**pf=newfile(L); | ||
6909 | *pf=fopen(filename,mode); | ||
6910 | if(*pf==NULL) | ||
6911 | fileerror(L,1,filename); | ||
6912 | } | ||
6913 | else{ | ||
6914 | tofile(L); | ||
6915 | lua_pushvalue(L,1); | ||
6916 | } | ||
6917 | lua_rawseti(L,(-10001),f); | ||
6918 | } | ||
6919 | lua_rawgeti(L,(-10001),f); | ||
6920 | return 1; | ||
6921 | } | ||
6922 | static int io_input(lua_State*L){ | ||
6923 | return g_iofile(L,1,"r"); | ||
6924 | } | ||
6925 | static int io_output(lua_State*L){ | ||
6926 | return g_iofile(L,2,"w"); | ||
6927 | } | ||
6928 | static int io_readline(lua_State*L); | ||
6929 | static void aux_lines(lua_State*L,int idx,int toclose){ | ||
6930 | lua_pushvalue(L,idx); | ||
6931 | lua_pushboolean(L,toclose); | ||
6932 | lua_pushcclosure(L,io_readline,2); | ||
6933 | } | ||
6934 | static int f_lines(lua_State*L){ | ||
6935 | tofile(L); | ||
6936 | aux_lines(L,1,0); | ||
6937 | return 1; | ||
6938 | } | ||
6939 | static int io_lines(lua_State*L){ | ||
6940 | if(lua_isnoneornil(L,1)){ | ||
6941 | lua_rawgeti(L,(-10001),1); | ||
6942 | return f_lines(L); | ||
6943 | } | ||
6944 | else{ | ||
6945 | const char*filename=luaL_checkstring(L,1); | ||
6946 | FILE**pf=newfile(L); | ||
6947 | *pf=fopen(filename,"r"); | ||
6948 | if(*pf==NULL) | ||
6949 | fileerror(L,1,filename); | ||
6950 | aux_lines(L,lua_gettop(L),1); | ||
6951 | return 1; | ||
6952 | } | ||
6953 | } | ||
6954 | static int read_number(lua_State*L,FILE*f){ | ||
6955 | lua_Number d; | ||
6956 | if(fscanf(f,"%lf",&d)==1){ | ||
6957 | lua_pushnumber(L,d); | ||
6958 | return 1; | ||
6959 | } | ||
6960 | else{ | ||
6961 | lua_pushnil(L); | ||
6962 | return 0; | ||
6963 | } | ||
6964 | } | ||
6965 | static int test_eof(lua_State*L,FILE*f){ | ||
6966 | int c=getc(f); | ||
6967 | ungetc(c,f); | ||
6968 | lua_pushlstring(L,NULL,0); | ||
6969 | return(c!=EOF); | ||
6970 | } | ||
6971 | static int read_line(lua_State*L,FILE*f){ | ||
6972 | luaL_Buffer b; | ||
6973 | luaL_buffinit(L,&b); | ||
6974 | for(;;){ | ||
6975 | size_t l; | ||
6976 | char*p=luaL_prepbuffer(&b); | ||
6977 | if(fgets(p,BUFSIZ,f)==NULL){ | ||
6978 | luaL_pushresult(&b); | ||
6979 | return(lua_objlen(L,-1)>0); | ||
6980 | } | ||
6981 | l=strlen(p); | ||
6982 | if(l==0||p[l-1]!='\n') | ||
6983 | luaL_addsize(&b,l); | ||
6984 | else{ | ||
6985 | luaL_addsize(&b,l-1); | ||
6986 | luaL_pushresult(&b); | ||
6987 | return 1; | ||
6988 | } | ||
6989 | } | ||
6990 | } | ||
6991 | static int read_chars(lua_State*L,FILE*f,size_t n){ | ||
6992 | size_t rlen; | ||
6993 | size_t nr; | ||
6994 | luaL_Buffer b; | ||
6995 | luaL_buffinit(L,&b); | ||
6996 | rlen=BUFSIZ; | ||
6997 | do{ | ||
6998 | char*p=luaL_prepbuffer(&b); | ||
6999 | if(rlen>n)rlen=n; | ||
7000 | nr=fread(p,sizeof(char),rlen,f); | ||
7001 | luaL_addsize(&b,nr); | ||
7002 | n-=nr; | ||
7003 | }while(n>0&&nr==rlen); | ||
7004 | luaL_pushresult(&b); | ||
7005 | return(n==0||lua_objlen(L,-1)>0); | ||
7006 | } | ||
7007 | static int g_read(lua_State*L,FILE*f,int first){ | ||
7008 | int nargs=lua_gettop(L)-1; | ||
7009 | int success; | ||
7010 | int n; | ||
7011 | clearerr(f); | ||
7012 | if(nargs==0){ | ||
7013 | success=read_line(L,f); | ||
7014 | n=first+1; | ||
7015 | } | ||
7016 | else{ | ||
7017 | luaL_checkstack(L,nargs+20,"too many arguments"); | ||
7018 | success=1; | ||
7019 | for(n=first;nargs--&&success;n++){ | ||
7020 | if(lua_type(L,n)==3){ | ||
7021 | size_t l=(size_t)lua_tointeger(L,n); | ||
7022 | success=(l==0)?test_eof(L,f):read_chars(L,f,l); | ||
7023 | } | ||
7024 | else{ | ||
7025 | const char*p=lua_tostring(L,n); | ||
7026 | luaL_argcheck(L,p&&p[0]=='*',n,"invalid option"); | ||
7027 | switch(p[1]){ | ||
7028 | case'n': | ||
7029 | success=read_number(L,f); | ||
7030 | break; | ||
7031 | case'l': | ||
7032 | success=read_line(L,f); | ||
7033 | break; | ||
7034 | case'a': | ||
7035 | read_chars(L,f,~((size_t)0)); | ||
7036 | success=1; | ||
7037 | break; | ||
7038 | default: | ||
7039 | return luaL_argerror(L,n,"invalid format"); | ||
7040 | } | ||
7041 | } | ||
7042 | } | ||
7043 | } | ||
7044 | if(ferror(f)) | ||
7045 | return pushresult(L,0,NULL); | ||
7046 | if(!success){ | ||
7047 | lua_pop(L,1); | ||
7048 | lua_pushnil(L); | ||
7049 | } | ||
7050 | return n-first; | ||
7051 | } | ||
7052 | static int io_read(lua_State*L){ | ||
7053 | return g_read(L,getiofile(L,1),1); | ||
7054 | } | ||
7055 | static int f_read(lua_State*L){ | ||
7056 | return g_read(L,tofile(L),2); | ||
7057 | } | ||
7058 | static int io_readline(lua_State*L){ | ||
7059 | FILE*f=*(FILE**)lua_touserdata(L,lua_upvalueindex(1)); | ||
7060 | int sucess; | ||
7061 | if(f==NULL) | ||
7062 | luaL_error(L,"file is already closed"); | ||
7063 | sucess=read_line(L,f); | ||
7064 | if(ferror(f)) | ||
7065 | return luaL_error(L,"%s",strerror(errno)); | ||
7066 | if(sucess)return 1; | ||
7067 | else{ | ||
7068 | if(lua_toboolean(L,lua_upvalueindex(2))){ | ||
7069 | lua_settop(L,0); | ||
7070 | lua_pushvalue(L,lua_upvalueindex(1)); | ||
7071 | aux_close(L); | ||
7072 | } | ||
7073 | return 0; | ||
7074 | } | ||
7075 | } | ||
7076 | static int g_write(lua_State*L,FILE*f,int arg){ | ||
7077 | int nargs=lua_gettop(L)-1; | ||
7078 | int status=1; | ||
7079 | for(;nargs--;arg++){ | ||
7080 | if(lua_type(L,arg)==3){ | ||
7081 | status=status&& | ||
7082 | fprintf(f,"%.14g",lua_tonumber(L,arg))>0; | ||
7083 | } | ||
7084 | else{ | ||
7085 | size_t l; | ||
7086 | const char*s=luaL_checklstring(L,arg,&l); | ||
7087 | status=status&&(fwrite(s,sizeof(char),l,f)==l); | ||
7088 | } | ||
7089 | } | ||
7090 | return pushresult(L,status,NULL); | ||
7091 | } | ||
7092 | static int io_write(lua_State*L){ | ||
7093 | return g_write(L,getiofile(L,2),1); | ||
7094 | } | ||
7095 | static int f_write(lua_State*L){ | ||
7096 | return g_write(L,tofile(L),2); | ||
7097 | } | ||
7098 | static int io_flush(lua_State*L){ | ||
7099 | return pushresult(L,fflush(getiofile(L,2))==0,NULL); | ||
7100 | } | ||
7101 | static int f_flush(lua_State*L){ | ||
7102 | return pushresult(L,fflush(tofile(L))==0,NULL); | ||
7103 | } | ||
7104 | static const luaL_Reg iolib[]={ | ||
7105 | {"close",io_close}, | ||
7106 | {"flush",io_flush}, | ||
7107 | {"input",io_input}, | ||
7108 | {"lines",io_lines}, | ||
7109 | {"open",io_open}, | ||
7110 | {"output",io_output}, | ||
7111 | {"read",io_read}, | ||
7112 | {"type",io_type}, | ||
7113 | {"write",io_write}, | ||
7114 | {NULL,NULL} | ||
7115 | }; | ||
7116 | static const luaL_Reg flib[]={ | ||
7117 | {"close",io_close}, | ||
7118 | {"flush",f_flush}, | ||
7119 | {"lines",f_lines}, | ||
7120 | {"read",f_read}, | ||
7121 | {"write",f_write}, | ||
7122 | {"__gc",io_gc}, | ||
7123 | {NULL,NULL} | ||
7124 | }; | ||
7125 | static void createmeta(lua_State*L){ | ||
7126 | luaL_newmetatable(L,"FILE*"); | ||
7127 | lua_pushvalue(L,-1); | ||
7128 | lua_setfield(L,-2,"__index"); | ||
7129 | luaL_register(L,NULL,flib); | ||
7130 | } | ||
7131 | static void createstdfile(lua_State*L,FILE*f,int k,const char*fname){ | ||
7132 | *newfile(L)=f; | ||
7133 | if(k>0){ | ||
7134 | lua_pushvalue(L,-1); | ||
7135 | lua_rawseti(L,(-10001),k); | ||
7136 | } | ||
7137 | lua_pushvalue(L,-2); | ||
7138 | lua_setfenv(L,-2); | ||
7139 | lua_setfield(L,-3,fname); | ||
7140 | } | ||
7141 | static void newfenv(lua_State*L,lua_CFunction cls){ | ||
7142 | lua_createtable(L,0,1); | ||
7143 | lua_pushcfunction(L,cls); | ||
7144 | lua_setfield(L,-2,"__close"); | ||
7145 | } | ||
7146 | static int luaopen_io(lua_State*L){ | ||
7147 | createmeta(L); | ||
7148 | newfenv(L,io_fclose); | ||
7149 | lua_replace(L,(-10001)); | ||
7150 | luaL_register(L,"io",iolib); | ||
7151 | newfenv(L,io_noclose); | ||
7152 | createstdfile(L,stdin,1,"stdin"); | ||
7153 | createstdfile(L,stdout,2,"stdout"); | ||
7154 | createstdfile(L,stderr,0,"stderr"); | ||
7155 | lua_pop(L,1); | ||
7156 | lua_getfield(L,-1,"popen"); | ||
7157 | newfenv(L,io_pclose); | ||
7158 | lua_setfenv(L,-2); | ||
7159 | lua_pop(L,1); | ||
7160 | return 1; | ||
7161 | } | ||
7162 | static int os_pushresult(lua_State*L,int i,const char*filename){ | ||
7163 | int en=errno; | ||
7164 | if(i){ | ||
7165 | lua_pushboolean(L,1); | ||
7166 | return 1; | ||
7167 | } | ||
7168 | else{ | ||
7169 | lua_pushnil(L); | ||
7170 | lua_pushfstring(L,"%s: %s",filename,strerror(en)); | ||
7171 | lua_pushinteger(L,en); | ||
7172 | return 3; | ||
7173 | } | ||
7174 | } | ||
7175 | static int os_remove(lua_State*L){ | ||
7176 | const char*filename=luaL_checkstring(L,1); | ||
7177 | return os_pushresult(L,remove(filename)==0,filename); | ||
7178 | } | ||
7179 | static int os_exit(lua_State*L){ | ||
7180 | exit(luaL_optint(L,1,EXIT_SUCCESS)); | ||
7181 | } | ||
7182 | static const luaL_Reg syslib[]={ | ||
7183 | {"exit",os_exit}, | ||
7184 | {"remove",os_remove}, | ||
7185 | {NULL,NULL} | ||
7186 | }; | ||
7187 | static int luaopen_os(lua_State*L){ | ||
7188 | luaL_register(L,"os",syslib); | ||
7189 | return 1; | ||
7190 | } | ||
7191 | #define uchar(c)((unsigned char)(c)) | ||
7192 | static ptrdiff_t posrelat(ptrdiff_t pos,size_t len){ | ||
7193 | if(pos<0)pos+=(ptrdiff_t)len+1; | ||
7194 | return(pos>=0)?pos:0; | ||
7195 | } | ||
7196 | static int str_sub(lua_State*L){ | ||
7197 | size_t l; | ||
7198 | const char*s=luaL_checklstring(L,1,&l); | ||
7199 | ptrdiff_t start=posrelat(luaL_checkinteger(L,2),l); | ||
7200 | ptrdiff_t end=posrelat(luaL_optinteger(L,3,-1),l); | ||
7201 | if(start<1)start=1; | ||
7202 | if(end>(ptrdiff_t)l)end=(ptrdiff_t)l; | ||
7203 | if(start<=end) | ||
7204 | lua_pushlstring(L,s+start-1,end-start+1); | ||
7205 | else lua_pushliteral(L,""); | ||
7206 | return 1; | ||
7207 | } | ||
7208 | static int str_lower(lua_State*L){ | ||
7209 | size_t l; | ||
7210 | size_t i; | ||
7211 | luaL_Buffer b; | ||
7212 | const char*s=luaL_checklstring(L,1,&l); | ||
7213 | luaL_buffinit(L,&b); | ||
7214 | for(i=0;i<l;i++) | ||
7215 | luaL_addchar(&b,tolower(uchar(s[i]))); | ||
7216 | luaL_pushresult(&b); | ||
7217 | return 1; | ||
7218 | } | ||
7219 | static int str_upper(lua_State*L){ | ||
7220 | size_t l; | ||
7221 | size_t i; | ||
7222 | luaL_Buffer b; | ||
7223 | const char*s=luaL_checklstring(L,1,&l); | ||
7224 | luaL_buffinit(L,&b); | ||
7225 | for(i=0;i<l;i++) | ||
7226 | luaL_addchar(&b,toupper(uchar(s[i]))); | ||
7227 | luaL_pushresult(&b); | ||
7228 | return 1; | ||
7229 | } | ||
7230 | static int str_rep(lua_State*L){ | ||
7231 | size_t l; | ||
7232 | luaL_Buffer b; | ||
7233 | const char*s=luaL_checklstring(L,1,&l); | ||
7234 | int n=luaL_checkint(L,2); | ||
7235 | luaL_buffinit(L,&b); | ||
7236 | while(n-->0) | ||
7237 | luaL_addlstring(&b,s,l); | ||
7238 | luaL_pushresult(&b); | ||
7239 | return 1; | ||
7240 | } | ||
7241 | static int str_byte(lua_State*L){ | ||
7242 | size_t l; | ||
7243 | const char*s=luaL_checklstring(L,1,&l); | ||
7244 | ptrdiff_t posi=posrelat(luaL_optinteger(L,2,1),l); | ||
7245 | ptrdiff_t pose=posrelat(luaL_optinteger(L,3,posi),l); | ||
7246 | int n,i; | ||
7247 | if(posi<=0)posi=1; | ||
7248 | if((size_t)pose>l)pose=l; | ||
7249 | if(posi>pose)return 0; | ||
7250 | n=(int)(pose-posi+1); | ||
7251 | if(posi+n<=pose) | ||
7252 | luaL_error(L,"string slice too long"); | ||
7253 | luaL_checkstack(L,n,"string slice too long"); | ||
7254 | for(i=0;i<n;i++) | ||
7255 | lua_pushinteger(L,uchar(s[posi+i-1])); | ||
7256 | return n; | ||
7257 | } | ||
7258 | static int str_char(lua_State*L){ | ||
7259 | int n=lua_gettop(L); | ||
7260 | int i; | ||
7261 | luaL_Buffer b; | ||
7262 | luaL_buffinit(L,&b); | ||
7263 | for(i=1;i<=n;i++){ | ||
7264 | int c=luaL_checkint(L,i); | ||
7265 | luaL_argcheck(L,uchar(c)==c,i,"invalid value"); | ||
7266 | luaL_addchar(&b,uchar(c)); | ||
7267 | } | ||
7268 | luaL_pushresult(&b); | ||
7269 | return 1; | ||
7270 | } | ||
7271 | typedef struct MatchState{ | ||
7272 | const char*src_init; | ||
7273 | const char*src_end; | ||
7274 | lua_State*L; | ||
7275 | int level; | ||
7276 | struct{ | ||
7277 | const char*init; | ||
7278 | ptrdiff_t len; | ||
7279 | }capture[32]; | ||
7280 | }MatchState; | ||
7281 | static int check_capture(MatchState*ms,int l){ | ||
7282 | l-='1'; | ||
7283 | if(l<0||l>=ms->level||ms->capture[l].len==(-1)) | ||
7284 | return luaL_error(ms->L,"invalid capture index"); | ||
7285 | return l; | ||
7286 | } | ||
7287 | static int capture_to_close(MatchState*ms){ | ||
7288 | int level=ms->level; | ||
7289 | for(level--;level>=0;level--) | ||
7290 | if(ms->capture[level].len==(-1))return level; | ||
7291 | return luaL_error(ms->L,"invalid pattern capture"); | ||
7292 | } | ||
7293 | static const char*classend(MatchState*ms,const char*p){ | ||
7294 | switch(*p++){ | ||
7295 | case'%':{ | ||
7296 | if(*p=='\0') | ||
7297 | luaL_error(ms->L,"malformed pattern (ends with "LUA_QL("%%")")"); | ||
7298 | return p+1; | ||
7299 | } | ||
7300 | case'[':{ | ||
7301 | if(*p=='^')p++; | ||
7302 | do{ | ||
7303 | if(*p=='\0') | ||
7304 | luaL_error(ms->L,"malformed pattern (missing "LUA_QL("]")")"); | ||
7305 | if(*(p++)=='%'&&*p!='\0') | ||
7306 | p++; | ||
7307 | }while(*p!=']'); | ||
7308 | return p+1; | ||
7309 | } | ||
7310 | default:{ | ||
7311 | return p; | ||
7312 | } | ||
7313 | } | ||
7314 | } | ||
7315 | static int match_class(int c,int cl){ | ||
7316 | int res; | ||
7317 | switch(tolower(cl)){ | ||
7318 | case'a':res=isalpha(c);break; | ||
7319 | case'c':res=iscntrl(c);break; | ||
7320 | case'd':res=isdigit(c);break; | ||
7321 | case'l':res=islower(c);break; | ||
7322 | case'p':res=ispunct(c);break; | ||
7323 | case's':res=isspace(c);break; | ||
7324 | case'u':res=isupper(c);break; | ||
7325 | case'w':res=isalnum(c);break; | ||
7326 | case'x':res=isxdigit(c);break; | ||
7327 | case'z':res=(c==0);break; | ||
7328 | default:return(cl==c); | ||
7329 | } | ||
7330 | return(islower(cl)?res:!res); | ||
7331 | } | ||
7332 | static int matchbracketclass(int c,const char*p,const char*ec){ | ||
7333 | int sig=1; | ||
7334 | if(*(p+1)=='^'){ | ||
7335 | sig=0; | ||
7336 | p++; | ||
7337 | } | ||
7338 | while(++p<ec){ | ||
7339 | if(*p=='%'){ | ||
7340 | p++; | ||
7341 | if(match_class(c,uchar(*p))) | ||
7342 | return sig; | ||
7343 | } | ||
7344 | else if((*(p+1)=='-')&&(p+2<ec)){ | ||
7345 | p+=2; | ||
7346 | if(uchar(*(p-2))<=c&&c<=uchar(*p)) | ||
7347 | return sig; | ||
7348 | } | ||
7349 | else if(uchar(*p)==c)return sig; | ||
7350 | } | ||
7351 | return!sig; | ||
7352 | } | ||
7353 | static int singlematch(int c,const char*p,const char*ep){ | ||
7354 | switch(*p){ | ||
7355 | case'.':return 1; | ||
7356 | case'%':return match_class(c,uchar(*(p+1))); | ||
7357 | case'[':return matchbracketclass(c,p,ep-1); | ||
7358 | default:return(uchar(*p)==c); | ||
7359 | } | ||
7360 | } | ||
7361 | static const char*match(MatchState*ms,const char*s,const char*p); | ||
7362 | static const char*matchbalance(MatchState*ms,const char*s, | ||
7363 | const char*p){ | ||
7364 | if(*p==0||*(p+1)==0) | ||
7365 | luaL_error(ms->L,"unbalanced pattern"); | ||
7366 | if(*s!=*p)return NULL; | ||
7367 | else{ | ||
7368 | int b=*p; | ||
7369 | int e=*(p+1); | ||
7370 | int cont=1; | ||
7371 | while(++s<ms->src_end){ | ||
7372 | if(*s==e){ | ||
7373 | if(--cont==0)return s+1; | ||
7374 | } | ||
7375 | else if(*s==b)cont++; | ||
7376 | } | ||
7377 | } | ||
7378 | return NULL; | ||
7379 | } | ||
7380 | static const char*max_expand(MatchState*ms,const char*s, | ||
7381 | const char*p,const char*ep){ | ||
7382 | ptrdiff_t i=0; | ||
7383 | while((s+i)<ms->src_end&&singlematch(uchar(*(s+i)),p,ep)) | ||
7384 | i++; | ||
7385 | while(i>=0){ | ||
7386 | const char*res=match(ms,(s+i),ep+1); | ||
7387 | if(res)return res; | ||
7388 | i--; | ||
7389 | } | ||
7390 | return NULL; | ||
7391 | } | ||
7392 | static const char*min_expand(MatchState*ms,const char*s, | ||
7393 | const char*p,const char*ep){ | ||
7394 | for(;;){ | ||
7395 | const char*res=match(ms,s,ep+1); | ||
7396 | if(res!=NULL) | ||
7397 | return res; | ||
7398 | else if(s<ms->src_end&&singlematch(uchar(*s),p,ep)) | ||
7399 | s++; | ||
7400 | else return NULL; | ||
7401 | } | ||
7402 | } | ||
7403 | static const char*start_capture(MatchState*ms,const char*s, | ||
7404 | const char*p,int what){ | ||
7405 | const char*res; | ||
7406 | int level=ms->level; | ||
7407 | if(level>=32)luaL_error(ms->L,"too many captures"); | ||
7408 | ms->capture[level].init=s; | ||
7409 | ms->capture[level].len=what; | ||
7410 | ms->level=level+1; | ||
7411 | if((res=match(ms,s,p))==NULL) | ||
7412 | ms->level--; | ||
7413 | return res; | ||
7414 | } | ||
7415 | static const char*end_capture(MatchState*ms,const char*s, | ||
7416 | const char*p){ | ||
7417 | int l=capture_to_close(ms); | ||
7418 | const char*res; | ||
7419 | ms->capture[l].len=s-ms->capture[l].init; | ||
7420 | if((res=match(ms,s,p))==NULL) | ||
7421 | ms->capture[l].len=(-1); | ||
7422 | return res; | ||
7423 | } | ||
7424 | static const char*match_capture(MatchState*ms,const char*s,int l){ | ||
7425 | size_t len; | ||
7426 | l=check_capture(ms,l); | ||
7427 | len=ms->capture[l].len; | ||
7428 | if((size_t)(ms->src_end-s)>=len&& | ||
7429 | memcmp(ms->capture[l].init,s,len)==0) | ||
7430 | return s+len; | ||
7431 | else return NULL; | ||
7432 | } | ||
7433 | static const char*match(MatchState*ms,const char*s,const char*p){ | ||
7434 | init: | ||
7435 | switch(*p){ | ||
7436 | case'(':{ | ||
7437 | if(*(p+1)==')') | ||
7438 | return start_capture(ms,s,p+2,(-2)); | ||
7439 | else | ||
7440 | return start_capture(ms,s,p+1,(-1)); | ||
7441 | } | ||
7442 | case')':{ | ||
7443 | return end_capture(ms,s,p+1); | ||
7444 | } | ||
7445 | case'%':{ | ||
7446 | switch(*(p+1)){ | ||
7447 | case'b':{ | ||
7448 | s=matchbalance(ms,s,p+2); | ||
7449 | if(s==NULL)return NULL; | ||
7450 | p+=4;goto init; | ||
7451 | } | ||
7452 | case'f':{ | ||
7453 | const char*ep;char previous; | ||
7454 | p+=2; | ||
7455 | if(*p!='[') | ||
7456 | luaL_error(ms->L,"missing "LUA_QL("[")" after " | ||
7457 | LUA_QL("%%f")" in pattern"); | ||
7458 | ep=classend(ms,p); | ||
7459 | previous=(s==ms->src_init)?'\0':*(s-1); | ||
7460 | if(matchbracketclass(uchar(previous),p,ep-1)|| | ||
7461 | !matchbracketclass(uchar(*s),p,ep-1))return NULL; | ||
7462 | p=ep;goto init; | ||
7463 | } | ||
7464 | default:{ | ||
7465 | if(isdigit(uchar(*(p+1)))){ | ||
7466 | s=match_capture(ms,s,uchar(*(p+1))); | ||
7467 | if(s==NULL)return NULL; | ||
7468 | p+=2;goto init; | ||
7469 | } | ||
7470 | goto dflt; | ||
7471 | } | ||
7472 | } | ||
7473 | } | ||
7474 | case'\0':{ | ||
7475 | return s; | ||
7476 | } | ||
7477 | case'$':{ | ||
7478 | if(*(p+1)=='\0') | ||
7479 | return(s==ms->src_end)?s:NULL; | ||
7480 | else goto dflt; | ||
7481 | } | ||
7482 | default:dflt:{ | ||
7483 | const char*ep=classend(ms,p); | ||
7484 | int m=s<ms->src_end&&singlematch(uchar(*s),p,ep); | ||
7485 | switch(*ep){ | ||
7486 | case'?':{ | ||
7487 | const char*res; | ||
7488 | if(m&&((res=match(ms,s+1,ep+1))!=NULL)) | ||
7489 | return res; | ||
7490 | p=ep+1;goto init; | ||
7491 | } | ||
7492 | case'*':{ | ||
7493 | return max_expand(ms,s,p,ep); | ||
7494 | } | ||
7495 | case'+':{ | ||
7496 | return(m?max_expand(ms,s+1,p,ep):NULL); | ||
7497 | } | ||
7498 | case'-':{ | ||
7499 | return min_expand(ms,s,p,ep); | ||
7500 | } | ||
7501 | default:{ | ||
7502 | if(!m)return NULL; | ||
7503 | s++;p=ep;goto init; | ||
7504 | } | ||
7505 | } | ||
7506 | } | ||
7507 | } | ||
7508 | } | ||
7509 | static const char*lmemfind(const char*s1,size_t l1, | ||
7510 | const char*s2,size_t l2){ | ||
7511 | if(l2==0)return s1; | ||
7512 | else if(l2>l1)return NULL; | ||
7513 | else{ | ||
7514 | const char*init; | ||
7515 | l2--; | ||
7516 | l1=l1-l2; | ||
7517 | while(l1>0&&(init=(const char*)memchr(s1,*s2,l1))!=NULL){ | ||
7518 | init++; | ||
7519 | if(memcmp(init,s2+1,l2)==0) | ||
7520 | return init-1; | ||
7521 | else{ | ||
7522 | l1-=init-s1; | ||
7523 | s1=init; | ||
7524 | } | ||
7525 | } | ||
7526 | return NULL; | ||
7527 | } | ||
7528 | } | ||
7529 | static void push_onecapture(MatchState*ms,int i,const char*s, | ||
7530 | const char*e){ | ||
7531 | if(i>=ms->level){ | ||
7532 | if(i==0) | ||
7533 | lua_pushlstring(ms->L,s,e-s); | ||
7534 | else | ||
7535 | luaL_error(ms->L,"invalid capture index"); | ||
7536 | } | ||
7537 | else{ | ||
7538 | ptrdiff_t l=ms->capture[i].len; | ||
7539 | if(l==(-1))luaL_error(ms->L,"unfinished capture"); | ||
7540 | if(l==(-2)) | ||
7541 | lua_pushinteger(ms->L,ms->capture[i].init-ms->src_init+1); | ||
7542 | else | ||
7543 | lua_pushlstring(ms->L,ms->capture[i].init,l); | ||
7544 | } | ||
7545 | } | ||
7546 | static int push_captures(MatchState*ms,const char*s,const char*e){ | ||
7547 | int i; | ||
7548 | int nlevels=(ms->level==0&&s)?1:ms->level; | ||
7549 | luaL_checkstack(ms->L,nlevels,"too many captures"); | ||
7550 | for(i=0;i<nlevels;i++) | ||
7551 | push_onecapture(ms,i,s,e); | ||
7552 | return nlevels; | ||
7553 | } | ||
7554 | static int str_find_aux(lua_State*L,int find){ | ||
7555 | size_t l1,l2; | ||
7556 | const char*s=luaL_checklstring(L,1,&l1); | ||
7557 | const char*p=luaL_checklstring(L,2,&l2); | ||
7558 | ptrdiff_t init=posrelat(luaL_optinteger(L,3,1),l1)-1; | ||
7559 | if(init<0)init=0; | ||
7560 | else if((size_t)(init)>l1)init=(ptrdiff_t)l1; | ||
7561 | if(find&&(lua_toboolean(L,4)|| | ||
7562 | strpbrk(p,"^$*+?.([%-")==NULL)){ | ||
7563 | const char*s2=lmemfind(s+init,l1-init,p,l2); | ||
7564 | if(s2){ | ||
7565 | lua_pushinteger(L,s2-s+1); | ||
7566 | lua_pushinteger(L,s2-s+l2); | ||
7567 | return 2; | ||
7568 | } | ||
7569 | } | ||
7570 | else{ | ||
7571 | MatchState ms; | ||
7572 | int anchor=(*p=='^')?(p++,1):0; | ||
7573 | const char*s1=s+init; | ||
7574 | ms.L=L; | ||
7575 | ms.src_init=s; | ||
7576 | ms.src_end=s+l1; | ||
7577 | do{ | ||
7578 | const char*res; | ||
7579 | ms.level=0; | ||
7580 | if((res=match(&ms,s1,p))!=NULL){ | ||
7581 | if(find){ | ||
7582 | lua_pushinteger(L,s1-s+1); | ||
7583 | lua_pushinteger(L,res-s); | ||
7584 | return push_captures(&ms,NULL,0)+2; | ||
7585 | } | ||
7586 | else | ||
7587 | return push_captures(&ms,s1,res); | ||
7588 | } | ||
7589 | }while(s1++<ms.src_end&&!anchor); | ||
7590 | } | ||
7591 | lua_pushnil(L); | ||
7592 | return 1; | ||
7593 | } | ||
7594 | static int str_find(lua_State*L){ | ||
7595 | return str_find_aux(L,1); | ||
7596 | } | ||
7597 | static int str_match(lua_State*L){ | ||
7598 | return str_find_aux(L,0); | ||
7599 | } | ||
7600 | static int gmatch_aux(lua_State*L){ | ||
7601 | MatchState ms; | ||
7602 | size_t ls; | ||
7603 | const char*s=lua_tolstring(L,lua_upvalueindex(1),&ls); | ||
7604 | const char*p=lua_tostring(L,lua_upvalueindex(2)); | ||
7605 | const char*src; | ||
7606 | ms.L=L; | ||
7607 | ms.src_init=s; | ||
7608 | ms.src_end=s+ls; | ||
7609 | for(src=s+(size_t)lua_tointeger(L,lua_upvalueindex(3)); | ||
7610 | src<=ms.src_end; | ||
7611 | src++){ | ||
7612 | const char*e; | ||
7613 | ms.level=0; | ||
7614 | if((e=match(&ms,src,p))!=NULL){ | ||
7615 | lua_Integer newstart=e-s; | ||
7616 | if(e==src)newstart++; | ||
7617 | lua_pushinteger(L,newstart); | ||
7618 | lua_replace(L,lua_upvalueindex(3)); | ||
7619 | return push_captures(&ms,src,e); | ||
7620 | } | ||
7621 | } | ||
7622 | return 0; | ||
7623 | } | ||
7624 | static int gmatch(lua_State*L){ | ||
7625 | luaL_checkstring(L,1); | ||
7626 | luaL_checkstring(L,2); | ||
7627 | lua_settop(L,2); | ||
7628 | lua_pushinteger(L,0); | ||
7629 | lua_pushcclosure(L,gmatch_aux,3); | ||
7630 | return 1; | ||
7631 | } | ||
7632 | static void add_s(MatchState*ms,luaL_Buffer*b,const char*s, | ||
7633 | const char*e){ | ||
7634 | size_t l,i; | ||
7635 | const char*news=lua_tolstring(ms->L,3,&l); | ||
7636 | for(i=0;i<l;i++){ | ||
7637 | if(news[i]!='%') | ||
7638 | luaL_addchar(b,news[i]); | ||
7639 | else{ | ||
7640 | i++; | ||
7641 | if(!isdigit(uchar(news[i]))) | ||
7642 | luaL_addchar(b,news[i]); | ||
7643 | else if(news[i]=='0') | ||
7644 | luaL_addlstring(b,s,e-s); | ||
7645 | else{ | ||
7646 | push_onecapture(ms,news[i]-'1',s,e); | ||
7647 | luaL_addvalue(b); | ||
7648 | } | ||
7649 | } | ||
7650 | } | ||
7651 | } | ||
7652 | static void add_value(MatchState*ms,luaL_Buffer*b,const char*s, | ||
7653 | const char*e){ | ||
7654 | lua_State*L=ms->L; | ||
7655 | switch(lua_type(L,3)){ | ||
7656 | case 3: | ||
7657 | case 4:{ | ||
7658 | add_s(ms,b,s,e); | ||
7659 | return; | ||
7660 | } | ||
7661 | case 6:{ | ||
7662 | int n; | ||
7663 | lua_pushvalue(L,3); | ||
7664 | n=push_captures(ms,s,e); | ||
7665 | lua_call(L,n,1); | ||
7666 | break; | ||
7667 | } | ||
7668 | case 5:{ | ||
7669 | push_onecapture(ms,0,s,e); | ||
7670 | lua_gettable(L,3); | ||
7671 | break; | ||
7672 | } | ||
7673 | } | ||
7674 | if(!lua_toboolean(L,-1)){ | ||
7675 | lua_pop(L,1); | ||
7676 | lua_pushlstring(L,s,e-s); | ||
7677 | } | ||
7678 | else if(!lua_isstring(L,-1)) | ||
7679 | luaL_error(L,"invalid replacement value (a %s)",luaL_typename(L,-1)); | ||
7680 | luaL_addvalue(b); | ||
7681 | } | ||
7682 | static int str_gsub(lua_State*L){ | ||
7683 | size_t srcl; | ||
7684 | const char*src=luaL_checklstring(L,1,&srcl); | ||
7685 | const char*p=luaL_checkstring(L,2); | ||
7686 | int tr=lua_type(L,3); | ||
7687 | int max_s=luaL_optint(L,4,srcl+1); | ||
7688 | int anchor=(*p=='^')?(p++,1):0; | ||
7689 | int n=0; | ||
7690 | MatchState ms; | ||
7691 | luaL_Buffer b; | ||
7692 | luaL_argcheck(L,tr==3||tr==4|| | ||
7693 | tr==6||tr==5,3, | ||
7694 | "string/function/table expected"); | ||
7695 | luaL_buffinit(L,&b); | ||
7696 | ms.L=L; | ||
7697 | ms.src_init=src; | ||
7698 | ms.src_end=src+srcl; | ||
7699 | while(n<max_s){ | ||
7700 | const char*e; | ||
7701 | ms.level=0; | ||
7702 | e=match(&ms,src,p); | ||
7703 | if(e){ | ||
7704 | n++; | ||
7705 | add_value(&ms,&b,src,e); | ||
7706 | } | ||
7707 | if(e&&e>src) | ||
7708 | src=e; | ||
7709 | else if(src<ms.src_end) | ||
7710 | luaL_addchar(&b,*src++); | ||
7711 | else break; | ||
7712 | if(anchor)break; | ||
7713 | } | ||
7714 | luaL_addlstring(&b,src,ms.src_end-src); | ||
7715 | luaL_pushresult(&b); | ||
7716 | lua_pushinteger(L,n); | ||
7717 | return 2; | ||
7718 | } | ||
7719 | static void addquoted(lua_State*L,luaL_Buffer*b,int arg){ | ||
7720 | size_t l; | ||
7721 | const char*s=luaL_checklstring(L,arg,&l); | ||
7722 | luaL_addchar(b,'"'); | ||
7723 | while(l--){ | ||
7724 | switch(*s){ | ||
7725 | case'"':case'\\':case'\n':{ | ||
7726 | luaL_addchar(b,'\\'); | ||
7727 | luaL_addchar(b,*s); | ||
7728 | break; | ||
7729 | } | ||
7730 | case'\r':{ | ||
7731 | luaL_addlstring(b,"\\r",2); | ||
7732 | break; | ||
7733 | } | ||
7734 | case'\0':{ | ||
7735 | luaL_addlstring(b,"\\000",4); | ||
7736 | break; | ||
7737 | } | ||
7738 | default:{ | ||
7739 | luaL_addchar(b,*s); | ||
7740 | break; | ||
7741 | } | ||
7742 | } | ||
7743 | s++; | ||
7744 | } | ||
7745 | luaL_addchar(b,'"'); | ||
7746 | } | ||
7747 | static const char*scanformat(lua_State*L,const char*strfrmt,char*form){ | ||
7748 | const char*p=strfrmt; | ||
7749 | while(*p!='\0'&&strchr("-+ #0",*p)!=NULL)p++; | ||
7750 | if((size_t)(p-strfrmt)>=sizeof("-+ #0")) | ||
7751 | luaL_error(L,"invalid format (repeated flags)"); | ||
7752 | if(isdigit(uchar(*p)))p++; | ||
7753 | if(isdigit(uchar(*p)))p++; | ||
7754 | if(*p=='.'){ | ||
7755 | p++; | ||
7756 | if(isdigit(uchar(*p)))p++; | ||
7757 | if(isdigit(uchar(*p)))p++; | ||
7758 | } | ||
7759 | if(isdigit(uchar(*p))) | ||
7760 | luaL_error(L,"invalid format (width or precision too long)"); | ||
7761 | *(form++)='%'; | ||
7762 | strncpy(form,strfrmt,p-strfrmt+1); | ||
7763 | form+=p-strfrmt+1; | ||
7764 | *form='\0'; | ||
7765 | return p; | ||
7766 | } | ||
7767 | static void addintlen(char*form){ | ||
7768 | size_t l=strlen(form); | ||
7769 | char spec=form[l-1]; | ||
7770 | strcpy(form+l-1,"l"); | ||
7771 | form[l+sizeof("l")-2]=spec; | ||
7772 | form[l+sizeof("l")-1]='\0'; | ||
7773 | } | ||
7774 | static int str_format(lua_State*L){ | ||
7775 | int top=lua_gettop(L); | ||
7776 | int arg=1; | ||
7777 | size_t sfl; | ||
7778 | const char*strfrmt=luaL_checklstring(L,arg,&sfl); | ||
7779 | const char*strfrmt_end=strfrmt+sfl; | ||
7780 | luaL_Buffer b; | ||
7781 | luaL_buffinit(L,&b); | ||
7782 | while(strfrmt<strfrmt_end){ | ||
7783 | if(*strfrmt!='%') | ||
7784 | luaL_addchar(&b,*strfrmt++); | ||
7785 | else if(*++strfrmt=='%') | ||
7786 | luaL_addchar(&b,*strfrmt++); | ||
7787 | else{ | ||
7788 | char form[(sizeof("-+ #0")+sizeof("l")+10)]; | ||
7789 | char buff[512]; | ||
7790 | if(++arg>top) | ||
7791 | luaL_argerror(L,arg,"no value"); | ||
7792 | strfrmt=scanformat(L,strfrmt,form); | ||
7793 | switch(*strfrmt++){ | ||
7794 | case'c':{ | ||
7795 | sprintf(buff,form,(int)luaL_checknumber(L,arg)); | ||
7796 | break; | ||
7797 | } | ||
7798 | case'd':case'i':{ | ||
7799 | addintlen(form); | ||
7800 | sprintf(buff,form,(long)luaL_checknumber(L,arg)); | ||
7801 | break; | ||
7802 | } | ||
7803 | case'o':case'u':case'x':case'X':{ | ||
7804 | addintlen(form); | ||
7805 | sprintf(buff,form,(unsigned long)luaL_checknumber(L,arg)); | ||
7806 | break; | ||
7807 | } | ||
7808 | case'e':case'E':case'f': | ||
7809 | case'g':case'G':{ | ||
7810 | sprintf(buff,form,(double)luaL_checknumber(L,arg)); | ||
7811 | break; | ||
7812 | } | ||
7813 | case'q':{ | ||
7814 | addquoted(L,&b,arg); | ||
7815 | continue; | ||
7816 | } | ||
7817 | case's':{ | ||
7818 | size_t l; | ||
7819 | const char*s=luaL_checklstring(L,arg,&l); | ||
7820 | if(!strchr(form,'.')&&l>=100){ | ||
7821 | lua_pushvalue(L,arg); | ||
7822 | luaL_addvalue(&b); | ||
7823 | continue; | ||
7824 | } | ||
7825 | else{ | ||
7826 | sprintf(buff,form,s); | ||
7827 | break; | ||
7828 | } | ||
7829 | } | ||
7830 | default:{ | ||
7831 | return luaL_error(L,"invalid option "LUA_QL("%%%c")" to " | ||
7832 | LUA_QL("format"),*(strfrmt-1)); | ||
7833 | } | ||
7834 | } | ||
7835 | luaL_addlstring(&b,buff,strlen(buff)); | ||
7836 | } | ||
7837 | } | ||
7838 | luaL_pushresult(&b); | ||
7839 | return 1; | ||
7840 | } | ||
7841 | static const luaL_Reg strlib[]={ | ||
7842 | {"byte",str_byte}, | ||
7843 | {"char",str_char}, | ||
7844 | {"find",str_find}, | ||
7845 | {"format",str_format}, | ||
7846 | {"gmatch",gmatch}, | ||
7847 | {"gsub",str_gsub}, | ||
7848 | {"lower",str_lower}, | ||
7849 | {"match",str_match}, | ||
7850 | {"rep",str_rep}, | ||
7851 | {"sub",str_sub}, | ||
7852 | {"upper",str_upper}, | ||
7853 | {NULL,NULL} | ||
7854 | }; | ||
7855 | static void createmetatable(lua_State*L){ | ||
7856 | lua_createtable(L,0,1); | ||
7857 | lua_pushliteral(L,""); | ||
7858 | lua_pushvalue(L,-2); | ||
7859 | lua_setmetatable(L,-2); | ||
7860 | lua_pop(L,1); | ||
7861 | lua_pushvalue(L,-2); | ||
7862 | lua_setfield(L,-2,"__index"); | ||
7863 | lua_pop(L,1); | ||
7864 | } | ||
7865 | static int luaopen_string(lua_State*L){ | ||
7866 | luaL_register(L,"string",strlib); | ||
7867 | createmetatable(L); | ||
7868 | return 1; | ||
7869 | } | ||
7870 | static const luaL_Reg lualibs[]={ | ||
7871 | {"",luaopen_base}, | ||
7872 | {"table",luaopen_table}, | ||
7873 | {"io",luaopen_io}, | ||
7874 | {"os",luaopen_os}, | ||
7875 | {"string",luaopen_string}, | ||
7876 | {NULL,NULL} | ||
7877 | }; | ||
7878 | static void luaL_openlibs(lua_State*L){ | ||
7879 | const luaL_Reg*lib=lualibs; | ||
7880 | for(;lib->func;lib++){ | ||
7881 | lua_pushcfunction(L,lib->func); | ||
7882 | lua_pushstring(L,lib->name); | ||
7883 | lua_call(L,1,0); | ||
7884 | } | ||
7885 | } | ||
7886 | int main(int argc,char**argv){ | ||
7887 | lua_State*L=luaL_newstate(); | ||
7888 | int i; | ||
7889 | luaL_openlibs(L); | ||
7890 | if(argc<2)return 1; | ||
7891 | lua_createtable(L,0,1); | ||
7892 | lua_pushstring(L,argv[1]); | ||
7893 | lua_rawseti(L,-2,0); | ||
7894 | lua_setglobal(L,"arg"); | ||
7895 | if(luaL_loadfile(L,argv[1])) | ||
7896 | goto err; | ||
7897 | for(i=2;i<argc;i++) | ||
7898 | lua_pushstring(L,argv[i]); | ||
7899 | if(lua_pcall(L,argc-2,0,0)){ | ||
7900 | err: | ||
7901 | fprintf(stderr,"Error: %s\n",lua_tostring(L,-1)); | ||
7902 | return 1; | ||
7903 | } | ||
7904 | lua_close(L); | ||
7905 | return 0; | ||
7906 | } | ||