diff options
author | Richard Quirk <richard.quirk@gmail.com> | 2014-03-19 19:31:31 +0100 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2014-04-02 20:31:54 +0200 |
commit | 36378988ad4059982742f05f5eb50580b456840a (patch) | |
tree | ee70be810d894566c5e351f21a1ebb79be742a85 /apps/plugins/lua/lvm.c | |
parent | 020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff) | |
download | rockbox-36378988ad4059982742f05f5eb50580b456840a.tar.gz rockbox-36378988ad4059982742f05f5eb50580b456840a.zip |
Update lua plugin to 5.2.3
Prior to this patch the Lua plugin used version 5.1.4. This change
reduces the number of modifications in the Lua source using some new
defines and because the upstream source is now more flexible.
Unless otherwise stated, l*.[ch] files are taken unmodified from the
upstream lua-5.2.3.
fscanf.c:
file descriptors in rockbox are just ints, they are hidden behind a
void* now so liolib requires less modifications. fscanf is updated to
use void* too.
getc.c: this is a new file required for getc implementation in lauxlib.c
lauxlib.c: LoadF replaced FILE* with int, the rockbox file
descriptor int are cast to FILE* (actually void* due to typedef).
getc uses the PREFIX version. stdin is not used, as per 5.1.4.
lbaselib.c: now uses strspn in the number parsing. print uses DEBUGF now
rather than being commented out.
lbitlib.c: use the built-in version from 5.2.3 rather than Reuben
Thomas's external library. Backwards compatible and adds some new bit
operations.
ldo.c: the LUAI_THROW/TRY defines are now in the core lua code, so have
been removed from rockconf.h
liolib.c: here the implementation has changed to use the LStream from
the original source, and cast the FILE* pointers to int. This has
reduced the number of modifications from the upstream version.
llex.c: the only change from upstream is to remove the locale include.
lmathlib.c: updated from the 5.2.3 version and re-applied the changes
that were made vs 5.1.4 for random numbers and to remove unsupported
float functions.
loadlib.c: upstream version, with the 5.1.4 changes for missing
functions.
lobject.c: upstream version, with ctype.h added and sprintf changed to
snprintf.
loslib.c: upstream version with locale.h removed and 5.1.4 changes for
unsupportable functions.
lstrlib.c: sprintf changed to snprintf.
ltable.c: upstream with the hashnum function from 5.1.4 to avoid frexp
in luai_hashnum.
luaconf.h: updated to 5.2.3 version, restored relevant parts from the
original 5.1.4 configuration. The COMPAT defines that are no longer
available are not included.
lundump.c: VERSION macro conflicts with the core Rockbox equivalent.
rocklib.c: luaL_reg is no longer available, replaced by luaL_Reg
equivalent. Moved checkboolean/optboolean functions to this file and out
of core lua files. luaL_getn is no longer available, replaced by
luaL_rawlen. luaL_register is deprecated, use the newlib/setfuncs
replacements. rli_init has to be called before setting up the newlib to
avoid overwriting the rb table.
rocklib_aux.pl: use rli_checkboolean from rocklib.c.
rocklua.c: new default bits library used, update the library loading
code with idiomatic 5.2 code.
strcspn.c: no longer needed, but strspn.c is required for strspn in
lbaselib.c
Change-Id: I0c7945c755f79083afe98ec117e1e8cf13de2651
Reviewed-on: http://gerrit.rockbox.org/774
Tested: Richard Quirk <richard.quirk@gmail.com>
Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
Diffstat (limited to 'apps/plugins/lua/lvm.c')
-rw-r--r-- | apps/plugins/lua/lvm.c | 914 |
1 files changed, 509 insertions, 405 deletions
diff --git a/apps/plugins/lua/lvm.c b/apps/plugins/lua/lvm.c index ee3256ab94..141b9fd19c 100644 --- a/apps/plugins/lua/lvm.c +++ b/apps/plugins/lua/lvm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ | 2 | ** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -35,7 +35,7 @@ | |||
35 | const TValue *luaV_tonumber (const TValue *obj, TValue *n) { | 35 | const TValue *luaV_tonumber (const TValue *obj, TValue *n) { |
36 | lua_Number num; | 36 | lua_Number num; |
37 | if (ttisnumber(obj)) return obj; | 37 | if (ttisnumber(obj)) return obj; |
38 | if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { | 38 | if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { |
39 | setnvalue(n, num); | 39 | setnvalue(n, num); |
40 | return n; | 40 | return n; |
41 | } | 41 | } |
@@ -50,58 +50,60 @@ int luaV_tostring (lua_State *L, StkId obj) { | |||
50 | else { | 50 | else { |
51 | char s[LUAI_MAXNUMBER2STR]; | 51 | char s[LUAI_MAXNUMBER2STR]; |
52 | lua_Number n = nvalue(obj); | 52 | lua_Number n = nvalue(obj); |
53 | lua_number2str(s, n); | 53 | int l = lua_number2str(s, n); |
54 | setsvalue2s(L, obj, luaS_new(L, s)); | 54 | setsvalue2s(L, obj, luaS_newlstr(L, s, l)); |
55 | return 1; | 55 | return 1; |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | 59 | ||
60 | static void traceexec (lua_State *L, const Instruction *pc) { | 60 | static void traceexec (lua_State *L) { |
61 | CallInfo *ci = L->ci; | ||
61 | lu_byte mask = L->hookmask; | 62 | lu_byte mask = L->hookmask; |
62 | const Instruction *oldpc = L->savedpc; | 63 | int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); |
63 | L->savedpc = pc; | 64 | if (counthook) |
64 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { | 65 | resethookcount(L); /* reset count */ |
65 | resethookcount(L); | 66 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ |
66 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | 67 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ |
68 | return; /* do not call hook again (VM yielded, so it did not move) */ | ||
67 | } | 69 | } |
70 | if (counthook) | ||
71 | luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ | ||
68 | if (mask & LUA_MASKLINE) { | 72 | if (mask & LUA_MASKLINE) { |
69 | Proto *p = ci_func(L->ci)->l.p; | 73 | Proto *p = ci_func(ci)->p; |
70 | int npc = pcRel(pc, p); | 74 | int npc = pcRel(ci->u.l.savedpc, p); |
71 | int newline = getline(p, npc); | 75 | int newline = getfuncline(p, npc); |
72 | /* call linehook when enter a new function, when jump back (loop), | 76 | if (npc == 0 || /* call linehook when enter a new function, */ |
73 | or when enter a new line */ | 77 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ |
74 | if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) | 78 | newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ |
75 | luaD_callhook(L, LUA_HOOKLINE, newline); | 79 | luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ |
80 | } | ||
81 | L->oldpc = ci->u.l.savedpc; | ||
82 | if (L->status == LUA_YIELD) { /* did hook yield? */ | ||
83 | if (counthook) | ||
84 | L->hookcount = 1; /* undo decrement to zero */ | ||
85 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ | ||
86 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ | ||
87 | ci->func = L->top - 1; /* protect stack below results */ | ||
88 | luaD_throw(L, LUA_YIELD); | ||
76 | } | 89 | } |
77 | } | 90 | } |
78 | 91 | ||
79 | 92 | ||
80 | static void callTMres (lua_State *L, StkId res, const TValue *f, | ||
81 | const TValue *p1, const TValue *p2) { | ||
82 | ptrdiff_t result = savestack(L, res); | ||
83 | setobj2s(L, L->top, f); /* push function */ | ||
84 | setobj2s(L, L->top+1, p1); /* 1st argument */ | ||
85 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | ||
86 | luaD_checkstack(L, 3); | ||
87 | L->top += 3; | ||
88 | luaD_call(L, L->top - 3, 1); | ||
89 | res = restorestack(L, result); | ||
90 | L->top--; | ||
91 | setobjs2s(L, res, L->top); | ||
92 | } | ||
93 | |||
94 | |||
95 | |||
96 | static void callTM (lua_State *L, const TValue *f, const TValue *p1, | 93 | static void callTM (lua_State *L, const TValue *f, const TValue *p1, |
97 | const TValue *p2, const TValue *p3) { | 94 | const TValue *p2, TValue *p3, int hasres) { |
98 | setobj2s(L, L->top, f); /* push function */ | 95 | ptrdiff_t result = savestack(L, p3); |
99 | setobj2s(L, L->top+1, p1); /* 1st argument */ | 96 | setobj2s(L, L->top++, f); /* push function */ |
100 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | 97 | setobj2s(L, L->top++, p1); /* 1st argument */ |
101 | setobj2s(L, L->top+3, p3); /* 3th argument */ | 98 | setobj2s(L, L->top++, p2); /* 2nd argument */ |
102 | luaD_checkstack(L, 4); | 99 | if (!hasres) /* no result? 'p3' is third argument */ |
103 | L->top += 4; | 100 | setobj2s(L, L->top++, p3); /* 3rd argument */ |
104 | luaD_call(L, L->top - 4, 0); | 101 | /* metamethod may yield only when called from Lua code */ |
102 | luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); | ||
103 | if (hasres) { /* if has result, move it to its place */ | ||
104 | p3 = restorestack(L, result); | ||
105 | setobjs2s(L, p3, --L->top); | ||
106 | } | ||
105 | } | 107 | } |
106 | 108 | ||
107 | 109 | ||
@@ -112,7 +114,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
112 | if (ttistable(t)) { /* `t' is a table? */ | 114 | if (ttistable(t)) { /* `t' is a table? */ |
113 | Table *h = hvalue(t); | 115 | Table *h = hvalue(t); |
114 | const TValue *res = luaH_get(h, key); /* do a primitive get */ | 116 | const TValue *res = luaH_get(h, key); /* do a primitive get */ |
115 | if (!ttisnil(res) || /* result is no nil? */ | 117 | if (!ttisnil(res) || /* result is not nil? */ |
116 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ | 118 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ |
117 | setobj2s(L, val, res); | 119 | setobj2s(L, val, res); |
118 | return; | 120 | return; |
@@ -122,10 +124,10 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
122 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) | 124 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) |
123 | luaG_typeerror(L, t, "index"); | 125 | luaG_typeerror(L, t, "index"); |
124 | if (ttisfunction(tm)) { | 126 | if (ttisfunction(tm)) { |
125 | callTMres(L, val, tm, t, key); | 127 | callTM(L, tm, t, key, val, 1); |
126 | return; | 128 | return; |
127 | } | 129 | } |
128 | t = tm; /* else repeat with `tm' */ | 130 | t = tm; /* else repeat with 'tm' */ |
129 | } | 131 | } |
130 | luaG_runerror(L, "loop in gettable"); | 132 | luaG_runerror(L, "loop in gettable"); |
131 | } | 133 | } |
@@ -137,22 +139,34 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
137 | const TValue *tm; | 139 | const TValue *tm; |
138 | if (ttistable(t)) { /* `t' is a table? */ | 140 | if (ttistable(t)) { /* `t' is a table? */ |
139 | Table *h = hvalue(t); | 141 | Table *h = hvalue(t); |
140 | TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ | 142 | TValue *oldval = cast(TValue *, luaH_get(h, key)); |
141 | if (!ttisnil(oldval) || /* result is no nil? */ | 143 | /* if previous value is not nil, there must be a previous entry |
142 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ | 144 | in the table; moreover, a metamethod has no relevance */ |
143 | setobj2t(L, oldval, val); | 145 | if (!ttisnil(oldval) || |
144 | luaC_barriert(L, h, val); | 146 | /* previous value is nil; must check the metamethod */ |
147 | ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && | ||
148 | /* no metamethod; is there a previous entry in the table? */ | ||
149 | (oldval != luaO_nilobject || | ||
150 | /* no previous entry; must create one. (The next test is | ||
151 | always true; we only need the assignment.) */ | ||
152 | (oldval = luaH_newkey(L, h, key), 1)))) { | ||
153 | /* no metamethod and (now) there is an entry with given key */ | ||
154 | setobj2t(L, oldval, val); /* assign new value to that entry */ | ||
155 | invalidateTMcache(h); | ||
156 | luaC_barrierback(L, obj2gco(h), val); | ||
145 | return; | 157 | return; |
146 | } | 158 | } |
147 | /* else will try the tag method */ | 159 | /* else will try the metamethod */ |
148 | } | 160 | } |
149 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) | 161 | else /* not a table; check metamethod */ |
150 | luaG_typeerror(L, t, "index"); | 162 | if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) |
163 | luaG_typeerror(L, t, "index"); | ||
164 | /* there is a metamethod */ | ||
151 | if (ttisfunction(tm)) { | 165 | if (ttisfunction(tm)) { |
152 | callTM(L, tm, t, key, val); | 166 | callTM(L, tm, t, key, val, 0); |
153 | return; | 167 | return; |
154 | } | 168 | } |
155 | t = tm; /* else repeat with `tm' */ | 169 | t = tm; /* else repeat with 'tm' */ |
156 | } | 170 | } |
157 | luaG_runerror(L, "loop in settable"); | 171 | luaG_runerror(L, "loop in settable"); |
158 | } | 172 | } |
@@ -164,12 +178,12 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
164 | if (ttisnil(tm)) | 178 | if (ttisnil(tm)) |
165 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 179 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
166 | if (ttisnil(tm)) return 0; | 180 | if (ttisnil(tm)) return 0; |
167 | callTMres(L, res, tm, p1, p2); | 181 | callTM(L, tm, p1, p2, res, 1); |
168 | return 1; | 182 | return 1; |
169 | } | 183 | } |
170 | 184 | ||
171 | 185 | ||
172 | static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, | 186 | static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, |
173 | TMS event) { | 187 | TMS event) { |
174 | const TValue *tm1 = fasttm(L, mt1, event); | 188 | const TValue *tm1 = fasttm(L, mt1, event); |
175 | const TValue *tm2; | 189 | const TValue *tm2; |
@@ -177,7 +191,7 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, | |||
177 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ | 191 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ |
178 | tm2 = fasttm(L, mt2, event); | 192 | tm2 = fasttm(L, mt2, event); |
179 | if (tm2 == NULL) return NULL; /* no metamethod */ | 193 | if (tm2 == NULL) return NULL; /* no metamethod */ |
180 | if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ | 194 | if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ |
181 | return tm1; | 195 | return tm1; |
182 | return NULL; | 196 | return NULL; |
183 | } | 197 | } |
@@ -185,14 +199,10 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, | |||
185 | 199 | ||
186 | static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, | 200 | static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, |
187 | TMS event) { | 201 | TMS event) { |
188 | const TValue *tm1 = luaT_gettmbyobj(L, p1, event); | 202 | if (!call_binTM(L, p1, p2, L->top, event)) |
189 | const TValue *tm2; | 203 | return -1; /* no metamethod */ |
190 | if (ttisnil(tm1)) return -1; /* no metamethod? */ | 204 | else |
191 | tm2 = luaT_gettmbyobj(L, p2, event); | 205 | return !l_isfalse(L->top); |
192 | if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ | ||
193 | return -1; | ||
194 | callTMres(L, L->top, tm1, p1, p2); | ||
195 | return !l_isfalse(L->top); | ||
196 | } | 206 | } |
197 | 207 | ||
198 | 208 | ||
@@ -220,125 +230,261 @@ static int l_strcmp (const TString *ls, const TString *rs) { | |||
220 | 230 | ||
221 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | 231 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
222 | int res; | 232 | int res; |
223 | if (ttype(l) != ttype(r)) | 233 | if (ttisnumber(l) && ttisnumber(r)) |
224 | return luaG_ordererror(L, l, r); | 234 | return luai_numlt(L, nvalue(l), nvalue(r)); |
225 | else if (ttisnumber(l)) | 235 | else if (ttisstring(l) && ttisstring(r)) |
226 | return luai_numlt(nvalue(l), nvalue(r)); | ||
227 | else if (ttisstring(l)) | ||
228 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; | 236 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; |
229 | else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) | 237 | else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) |
230 | return res; | 238 | luaG_ordererror(L, l, r); |
231 | return luaG_ordererror(L, l, r); | 239 | return res; |
232 | } | 240 | } |
233 | 241 | ||
234 | 242 | ||
235 | static int lessequal (lua_State *L, const TValue *l, const TValue *r) { | 243 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { |
236 | int res; | 244 | int res; |
237 | if (ttype(l) != ttype(r)) | 245 | if (ttisnumber(l) && ttisnumber(r)) |
238 | return luaG_ordererror(L, l, r); | 246 | return luai_numle(L, nvalue(l), nvalue(r)); |
239 | else if (ttisnumber(l)) | 247 | else if (ttisstring(l) && ttisstring(r)) |
240 | return luai_numle(nvalue(l), nvalue(r)); | ||
241 | else if (ttisstring(l)) | ||
242 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; | 248 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; |
243 | else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ | 249 | else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ |
244 | return res; | 250 | return res; |
245 | else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ | 251 | else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ |
246 | return !res; | 252 | luaG_ordererror(L, l, r); |
247 | return luaG_ordererror(L, l, r); | 253 | return !res; |
248 | } | 254 | } |
249 | 255 | ||
250 | 256 | ||
251 | int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { | 257 | /* |
258 | ** equality of Lua values. L == NULL means raw equality (no metamethods) | ||
259 | */ | ||
260 | int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { | ||
252 | const TValue *tm; | 261 | const TValue *tm; |
253 | lua_assert(ttype(t1) == ttype(t2)); | 262 | lua_assert(ttisequal(t1, t2)); |
254 | switch (ttype(t1)) { | 263 | switch (ttype(t1)) { |
255 | case LUA_TNIL: return 1; | 264 | case LUA_TNIL: return 1; |
256 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); | 265 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); |
257 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ | 266 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ |
258 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | 267 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); |
268 | case LUA_TLCF: return fvalue(t1) == fvalue(t2); | ||
269 | case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); | ||
270 | case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); | ||
259 | case LUA_TUSERDATA: { | 271 | case LUA_TUSERDATA: { |
260 | if (uvalue(t1) == uvalue(t2)) return 1; | 272 | if (uvalue(t1) == uvalue(t2)) return 1; |
261 | tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, | 273 | else if (L == NULL) return 0; |
262 | TM_EQ); | 274 | tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); |
263 | break; /* will try TM */ | 275 | break; /* will try TM */ |
264 | } | 276 | } |
265 | case LUA_TTABLE: { | 277 | case LUA_TTABLE: { |
266 | if (hvalue(t1) == hvalue(t2)) return 1; | 278 | if (hvalue(t1) == hvalue(t2)) return 1; |
267 | tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); | 279 | else if (L == NULL) return 0; |
280 | tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); | ||
268 | break; /* will try TM */ | 281 | break; /* will try TM */ |
269 | } | 282 | } |
270 | default: return gcvalue(t1) == gcvalue(t2); | 283 | default: |
284 | lua_assert(iscollectable(t1)); | ||
285 | return gcvalue(t1) == gcvalue(t2); | ||
271 | } | 286 | } |
272 | if (tm == NULL) return 0; /* no TM? */ | 287 | if (tm == NULL) return 0; /* no TM? */ |
273 | callTMres(L, L->top, tm, t1, t2); /* call TM */ | 288 | callTM(L, tm, t1, t2, L->top, 1); /* call TM */ |
274 | return !l_isfalse(L->top); | 289 | return !l_isfalse(L->top); |
275 | } | 290 | } |
276 | 291 | ||
277 | 292 | ||
278 | void luaV_concat (lua_State *L, int total, int last) { | 293 | void luaV_concat (lua_State *L, int total) { |
294 | lua_assert(total >= 2); | ||
279 | do { | 295 | do { |
280 | StkId top = L->base + last + 1; | 296 | StkId top = L->top; |
281 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 297 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
282 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { | 298 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { |
283 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) | 299 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
284 | luaG_concaterror(L, top-2, top-1); | 300 | luaG_concaterror(L, top-2, top-1); |
285 | } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ | 301 | } |
286 | (void)tostring(L, top - 2); /* result is first op (as string) */ | 302 | else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ |
303 | (void)tostring(L, top - 2); /* result is first operand */ | ||
304 | else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { | ||
305 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ | ||
306 | } | ||
287 | else { | 307 | else { |
288 | /* at least two string values; get as many as possible */ | 308 | /* at least two non-empty string values; get as many as possible */ |
289 | size_t tl = tsvalue(top-1)->len; | 309 | size_t tl = tsvalue(top-1)->len; |
290 | char *buffer; | 310 | char *buffer; |
291 | int i; | 311 | int i; |
292 | /* collect total length */ | 312 | /* collect total length */ |
293 | for (n = 1; n < total && tostring(L, top-n-1); n++) { | 313 | for (i = 1; i < total && tostring(L, top-i-1); i++) { |
294 | size_t l = tsvalue(top-n-1)->len; | 314 | size_t l = tsvalue(top-i-1)->len; |
295 | if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); | 315 | if (l >= (MAX_SIZET/sizeof(char)) - tl) |
316 | luaG_runerror(L, "string length overflow"); | ||
296 | tl += l; | 317 | tl += l; |
297 | } | 318 | } |
298 | buffer = luaZ_openspace(L, &G(L)->buff, tl); | 319 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
299 | tl = 0; | 320 | tl = 0; |
300 | for (i=n; i>0; i--) { /* concat all strings */ | 321 | n = i; |
322 | do { /* concat all strings */ | ||
301 | size_t l = tsvalue(top-i)->len; | 323 | size_t l = tsvalue(top-i)->len; |
302 | memcpy(buffer+tl, svalue(top-i), l); | 324 | memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); |
303 | tl += l; | 325 | tl += l; |
304 | } | 326 | } while (--i > 0); |
305 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); | 327 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); |
306 | } | 328 | } |
307 | total -= n-1; /* got `n' strings to create 1 new */ | 329 | total -= n-1; /* got 'n' strings to create 1 new */ |
308 | last -= n-1; | 330 | L->top -= n-1; /* popped 'n' strings and pushed one */ |
309 | } while (total > 1); /* repeat until only 1 result left */ | 331 | } while (total > 1); /* repeat until only 1 result left */ |
310 | } | 332 | } |
311 | 333 | ||
312 | 334 | ||
313 | static void Arith (lua_State *L, StkId ra, const TValue *rb, | 335 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { |
314 | const TValue *rc, TMS op) { | 336 | const TValue *tm; |
337 | switch (ttypenv(rb)) { | ||
338 | case LUA_TTABLE: { | ||
339 | Table *h = hvalue(rb); | ||
340 | tm = fasttm(L, h->metatable, TM_LEN); | ||
341 | if (tm) break; /* metamethod? break switch to call it */ | ||
342 | setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ | ||
343 | return; | ||
344 | } | ||
345 | case LUA_TSTRING: { | ||
346 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
347 | return; | ||
348 | } | ||
349 | default: { /* try metamethod */ | ||
350 | tm = luaT_gettmbyobj(L, rb, TM_LEN); | ||
351 | if (ttisnil(tm)) /* no metamethod? */ | ||
352 | luaG_typeerror(L, rb, "get length of"); | ||
353 | break; | ||
354 | } | ||
355 | } | ||
356 | callTM(L, tm, rb, rb, ra, 1); | ||
357 | } | ||
358 | |||
359 | |||
360 | void luaV_arith (lua_State *L, StkId ra, const TValue *rb, | ||
361 | const TValue *rc, TMS op) { | ||
315 | TValue tempb, tempc; | 362 | TValue tempb, tempc; |
316 | const TValue *b, *c; | 363 | const TValue *b, *c; |
317 | if ((b = luaV_tonumber(rb, &tempb)) != NULL && | 364 | if ((b = luaV_tonumber(rb, &tempb)) != NULL && |
318 | (c = luaV_tonumber(rc, &tempc)) != NULL) { | 365 | (c = luaV_tonumber(rc, &tempc)) != NULL) { |
319 | lua_Number nb = nvalue(b), nc = nvalue(c); | 366 | lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); |
320 | switch (op) { | 367 | setnvalue(ra, res); |
321 | case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; | ||
322 | case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; | ||
323 | case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; | ||
324 | case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; | ||
325 | case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; | ||
326 | case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; | ||
327 | case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; | ||
328 | default: lua_assert(0); break; | ||
329 | } | ||
330 | } | 368 | } |
331 | else if (!call_binTM(L, rb, rc, ra, op)) | 369 | else if (!call_binTM(L, rb, rc, ra, op)) |
332 | luaG_aritherror(L, rb, rc); | 370 | luaG_aritherror(L, rb, rc); |
333 | } | 371 | } |
334 | 372 | ||
335 | 373 | ||
374 | /* | ||
375 | ** check whether cached closure in prototype 'p' may be reused, that is, | ||
376 | ** whether there is a cached closure with the same upvalues needed by | ||
377 | ** new closure to be created. | ||
378 | */ | ||
379 | static Closure *getcached (Proto *p, UpVal **encup, StkId base) { | ||
380 | Closure *c = p->cache; | ||
381 | if (c != NULL) { /* is there a cached closure? */ | ||
382 | int nup = p->sizeupvalues; | ||
383 | Upvaldesc *uv = p->upvalues; | ||
384 | int i; | ||
385 | for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ | ||
386 | TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; | ||
387 | if (c->l.upvals[i]->v != v) | ||
388 | return NULL; /* wrong upvalue; cannot reuse closure */ | ||
389 | } | ||
390 | } | ||
391 | return c; /* return cached closure (or NULL if no cached closure) */ | ||
392 | } | ||
393 | |||
394 | |||
395 | /* | ||
396 | ** create a new Lua closure, push it in the stack, and initialize | ||
397 | ** its upvalues. Note that the call to 'luaC_barrierproto' must come | ||
398 | ** before the assignment to 'p->cache', as the function needs the | ||
399 | ** original value of that field. | ||
400 | */ | ||
401 | static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | ||
402 | StkId ra) { | ||
403 | int nup = p->sizeupvalues; | ||
404 | Upvaldesc *uv = p->upvalues; | ||
405 | int i; | ||
406 | Closure *ncl = luaF_newLclosure(L, nup); | ||
407 | ncl->l.p = p; | ||
408 | setclLvalue(L, ra, ncl); /* anchor new closure in stack */ | ||
409 | for (i = 0; i < nup; i++) { /* fill in its upvalues */ | ||
410 | if (uv[i].instack) /* upvalue refers to local variable? */ | ||
411 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); | ||
412 | else /* get upvalue from enclosing function */ | ||
413 | ncl->l.upvals[i] = encup[uv[i].idx]; | ||
414 | } | ||
415 | luaC_barrierproto(L, p, ncl); | ||
416 | p->cache = ncl; /* save it on cache for reuse */ | ||
417 | } | ||
418 | |||
419 | |||
420 | /* | ||
421 | ** finish execution of an opcode interrupted by an yield | ||
422 | */ | ||
423 | void luaV_finishOp (lua_State *L) { | ||
424 | CallInfo *ci = L->ci; | ||
425 | StkId base = ci->u.l.base; | ||
426 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | ||
427 | OpCode op = GET_OPCODE(inst); | ||
428 | switch (op) { /* finish its execution */ | ||
429 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: | ||
430 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | ||
431 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { | ||
432 | setobjs2s(L, base + GETARG_A(inst), --L->top); | ||
433 | break; | ||
434 | } | ||
435 | case OP_LE: case OP_LT: case OP_EQ: { | ||
436 | int res = !l_isfalse(L->top - 1); | ||
437 | L->top--; | ||
438 | /* metamethod should not be called when operand is K */ | ||
439 | lua_assert(!ISK(GETARG_B(inst))); | ||
440 | if (op == OP_LE && /* "<=" using "<" instead? */ | ||
441 | ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) | ||
442 | res = !res; /* invert result */ | ||
443 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); | ||
444 | if (res != GETARG_A(inst)) /* condition failed? */ | ||
445 | ci->u.l.savedpc++; /* skip jump instruction */ | ||
446 | break; | ||
447 | } | ||
448 | case OP_CONCAT: { | ||
449 | StkId top = L->top - 1; /* top when 'call_binTM' was called */ | ||
450 | int b = GETARG_B(inst); /* first element to concatenate */ | ||
451 | int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ | ||
452 | setobj2s(L, top - 2, top); /* put TM result in proper position */ | ||
453 | if (total > 1) { /* are there elements to concat? */ | ||
454 | L->top = top - 1; /* top is one after last element (at top-2) */ | ||
455 | luaV_concat(L, total); /* concat them (may yield again) */ | ||
456 | } | ||
457 | /* move final result to final position */ | ||
458 | setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); | ||
459 | L->top = ci->top; /* restore top */ | ||
460 | break; | ||
461 | } | ||
462 | case OP_TFORCALL: { | ||
463 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); | ||
464 | L->top = ci->top; /* correct top */ | ||
465 | break; | ||
466 | } | ||
467 | case OP_CALL: { | ||
468 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ | ||
469 | L->top = ci->top; /* adjust results */ | ||
470 | break; | ||
471 | } | ||
472 | case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: | ||
473 | break; | ||
474 | default: lua_assert(0); | ||
475 | } | ||
476 | } | ||
477 | |||
478 | |||
336 | 479 | ||
337 | /* | 480 | /* |
338 | ** some macros for common tasks in `luaV_execute' | 481 | ** some macros for common tasks in `luaV_execute' |
339 | */ | 482 | */ |
340 | 483 | ||
341 | #define runtime_check(L, c) { if (!(c)) break; } | 484 | #if !defined luai_runtimecheck |
485 | #define luai_runtimecheck(L, c) /* void */ | ||
486 | #endif | ||
487 | |||
342 | 488 | ||
343 | #define RA(i) (base+GETARG_A(i)) | 489 | #define RA(i) (base+GETARG_A(i)) |
344 | /* to be used after possible stack reallocation */ | 490 | /* to be used after possible stack reallocation */ |
@@ -348,13 +494,27 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, | |||
348 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) | 494 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) |
349 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ | 495 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ |
350 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) | 496 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) |
351 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) | 497 | #define KBx(i) \ |
498 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) | ||
499 | |||
352 | 500 | ||
501 | /* execute a jump instruction */ | ||
502 | #define dojump(ci,i,e) \ | ||
503 | { int a = GETARG_A(i); \ | ||
504 | if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ | ||
505 | ci->u.l.savedpc += GETARG_sBx(i) + e; } | ||
353 | 506 | ||
354 | #define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} | 507 | /* for test instructions, execute the jump instruction that follows it */ |
508 | #define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } | ||
355 | 509 | ||
356 | 510 | ||
357 | #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } | 511 | #define Protect(x) { {x;}; base = ci->u.l.base; } |
512 | |||
513 | #define checkGC(L,c) \ | ||
514 | Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \ | ||
515 | luaC_step(L); \ | ||
516 | L->top = ci->top;}) /* restore top */ \ | ||
517 | luai_threadyield(L); ) | ||
358 | 518 | ||
359 | 519 | ||
360 | #define arith_op(op,tm) { \ | 520 | #define arith_op(op,tm) { \ |
@@ -362,401 +522,345 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, | |||
362 | TValue *rc = RKC(i); \ | 522 | TValue *rc = RKC(i); \ |
363 | if (ttisnumber(rb) && ttisnumber(rc)) { \ | 523 | if (ttisnumber(rb) && ttisnumber(rc)) { \ |
364 | lua_Number nb = nvalue(rb), nc = nvalue(rc); \ | 524 | lua_Number nb = nvalue(rb), nc = nvalue(rc); \ |
365 | setnvalue(ra, op(nb, nc)); \ | 525 | setnvalue(ra, op(L, nb, nc)); \ |
366 | } \ | 526 | } \ |
367 | else \ | 527 | else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } |
368 | Protect(Arith(L, ra, rb, rc, tm)); \ | ||
369 | } | ||
370 | 528 | ||
371 | 529 | ||
530 | #define vmdispatch(o) switch(o) | ||
531 | #define vmcase(l,b) case l: {b} break; | ||
532 | #define vmcasenb(l,b) case l: {b} /* nb = no break */ | ||
372 | 533 | ||
373 | void luaV_execute (lua_State *L, int nexeccalls) { | 534 | void luaV_execute (lua_State *L) { |
535 | CallInfo *ci = L->ci; | ||
374 | LClosure *cl; | 536 | LClosure *cl; |
375 | StkId base; | ||
376 | TValue *k; | 537 | TValue *k; |
377 | const Instruction *pc; | 538 | StkId base; |
378 | reentry: /* entry point */ | 539 | newframe: /* reentry point when frame changes (call/return) */ |
379 | lua_assert(isLua(L->ci)); | 540 | lua_assert(ci == L->ci); |
380 | pc = L->savedpc; | 541 | cl = clLvalue(ci->func); |
381 | cl = &clvalue(L->ci->func)->l; | ||
382 | base = L->base; | ||
383 | k = cl->p->k; | 542 | k = cl->p->k; |
543 | base = ci->u.l.base; | ||
384 | /* main loop of interpreter */ | 544 | /* main loop of interpreter */ |
385 | for (;;) { | 545 | for (;;) { |
386 | const Instruction i = *pc++; | 546 | Instruction i = *(ci->u.l.savedpc++); |
387 | StkId ra; | 547 | StkId ra; |
388 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && | 548 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
389 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | 549 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
390 | traceexec(L, pc); | 550 | Protect(traceexec(L)); |
391 | if (L->status == LUA_YIELD) { /* did hook yield? */ | ||
392 | L->savedpc = pc - 1; | ||
393 | return; | ||
394 | } | ||
395 | base = L->base; | ||
396 | } | 551 | } |
397 | /* warning!! several calls may realloc the stack and invalidate `ra' */ | 552 | /* WARNING: several calls may realloc the stack and invalidate `ra' */ |
398 | ra = RA(i); | 553 | ra = RA(i); |
399 | lua_assert(base == L->base && L->base == L->ci->base); | 554 | lua_assert(base == ci->u.l.base); |
400 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); | 555 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); |
401 | lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); | 556 | vmdispatch (GET_OPCODE(i)) { |
402 | switch (GET_OPCODE(i)) { | 557 | vmcase(OP_MOVE, |
403 | case OP_MOVE: { | ||
404 | setobjs2s(L, ra, RB(i)); | 558 | setobjs2s(L, ra, RB(i)); |
405 | continue; | 559 | ) |
406 | } | 560 | vmcase(OP_LOADK, |
407 | case OP_LOADK: { | 561 | TValue *rb = k + GETARG_Bx(i); |
408 | setobj2s(L, ra, KBx(i)); | 562 | setobj2s(L, ra, rb); |
409 | continue; | 563 | ) |
410 | } | 564 | vmcase(OP_LOADKX, |
411 | case OP_LOADBOOL: { | 565 | TValue *rb; |
566 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); | ||
567 | rb = k + GETARG_Ax(*ci->u.l.savedpc++); | ||
568 | setobj2s(L, ra, rb); | ||
569 | ) | ||
570 | vmcase(OP_LOADBOOL, | ||
412 | setbvalue(ra, GETARG_B(i)); | 571 | setbvalue(ra, GETARG_B(i)); |
413 | if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ | 572 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
414 | continue; | 573 | ) |
415 | } | 574 | vmcase(OP_LOADNIL, |
416 | case OP_LOADNIL: { | 575 | int b = GETARG_B(i); |
417 | TValue *rb = RB(i); | ||
418 | do { | 576 | do { |
419 | setnilvalue(rb--); | 577 | setnilvalue(ra++); |
420 | } while (rb >= ra); | 578 | } while (b--); |
421 | continue; | 579 | ) |
422 | } | 580 | vmcase(OP_GETUPVAL, |
423 | case OP_GETUPVAL: { | ||
424 | int b = GETARG_B(i); | 581 | int b = GETARG_B(i); |
425 | setobj2s(L, ra, cl->upvals[b]->v); | 582 | setobj2s(L, ra, cl->upvals[b]->v); |
426 | continue; | 583 | ) |
427 | } | 584 | vmcase(OP_GETTABUP, |
428 | case OP_GETGLOBAL: { | 585 | int b = GETARG_B(i); |
429 | TValue g; | 586 | Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); |
430 | TValue *rb = KBx(i); | 587 | ) |
431 | sethvalue(L, &g, cl->env); | 588 | vmcase(OP_GETTABLE, |
432 | lua_assert(ttisstring(rb)); | ||
433 | Protect(luaV_gettable(L, &g, rb, ra)); | ||
434 | continue; | ||
435 | } | ||
436 | case OP_GETTABLE: { | ||
437 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); | 589 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); |
438 | continue; | 590 | ) |
439 | } | 591 | vmcase(OP_SETTABUP, |
440 | case OP_SETGLOBAL: { | 592 | int a = GETARG_A(i); |
441 | TValue g; | 593 | Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); |
442 | sethvalue(L, &g, cl->env); | 594 | ) |
443 | lua_assert(ttisstring(KBx(i))); | 595 | vmcase(OP_SETUPVAL, |
444 | Protect(luaV_settable(L, &g, KBx(i), ra)); | ||
445 | continue; | ||
446 | } | ||
447 | case OP_SETUPVAL: { | ||
448 | UpVal *uv = cl->upvals[GETARG_B(i)]; | 596 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
449 | setobj(L, uv->v, ra); | 597 | setobj(L, uv->v, ra); |
450 | luaC_barrier(L, uv, ra); | 598 | luaC_barrier(L, uv, ra); |
451 | continue; | 599 | ) |
452 | } | 600 | vmcase(OP_SETTABLE, |
453 | case OP_SETTABLE: { | ||
454 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); | 601 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); |
455 | continue; | 602 | ) |
456 | } | 603 | vmcase(OP_NEWTABLE, |
457 | case OP_NEWTABLE: { | ||
458 | int b = GETARG_B(i); | 604 | int b = GETARG_B(i); |
459 | int c = GETARG_C(i); | 605 | int c = GETARG_C(i); |
460 | sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); | 606 | Table *t = luaH_new(L); |
461 | Protect(luaC_checkGC(L)); | 607 | sethvalue(L, ra, t); |
462 | continue; | 608 | if (b != 0 || c != 0) |
463 | } | 609 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); |
464 | case OP_SELF: { | 610 | checkGC(L, ra + 1); |
611 | ) | ||
612 | vmcase(OP_SELF, | ||
465 | StkId rb = RB(i); | 613 | StkId rb = RB(i); |
466 | setobjs2s(L, ra+1, rb); | 614 | setobjs2s(L, ra+1, rb); |
467 | Protect(luaV_gettable(L, rb, RKC(i), ra)); | 615 | Protect(luaV_gettable(L, rb, RKC(i), ra)); |
468 | continue; | 616 | ) |
469 | } | 617 | vmcase(OP_ADD, |
470 | case OP_ADD: { | ||
471 | arith_op(luai_numadd, TM_ADD); | 618 | arith_op(luai_numadd, TM_ADD); |
472 | continue; | 619 | ) |
473 | } | 620 | vmcase(OP_SUB, |
474 | case OP_SUB: { | ||
475 | arith_op(luai_numsub, TM_SUB); | 621 | arith_op(luai_numsub, TM_SUB); |
476 | continue; | 622 | ) |
477 | } | 623 | vmcase(OP_MUL, |
478 | case OP_MUL: { | ||
479 | arith_op(luai_nummul, TM_MUL); | 624 | arith_op(luai_nummul, TM_MUL); |
480 | continue; | 625 | ) |
481 | } | 626 | vmcase(OP_DIV, |
482 | case OP_DIV: { | ||
483 | arith_op(luai_numdiv, TM_DIV); | 627 | arith_op(luai_numdiv, TM_DIV); |
484 | continue; | 628 | ) |
485 | } | 629 | vmcase(OP_MOD, |
486 | case OP_MOD: { | ||
487 | arith_op(luai_nummod, TM_MOD); | 630 | arith_op(luai_nummod, TM_MOD); |
488 | continue; | 631 | ) |
489 | } | 632 | vmcase(OP_POW, |
490 | case OP_POW: { | ||
491 | arith_op(luai_numpow, TM_POW); | 633 | arith_op(luai_numpow, TM_POW); |
492 | continue; | 634 | ) |
493 | } | 635 | vmcase(OP_UNM, |
494 | case OP_UNM: { | ||
495 | TValue *rb = RB(i); | 636 | TValue *rb = RB(i); |
496 | if (ttisnumber(rb)) { | 637 | if (ttisnumber(rb)) { |
497 | lua_Number nb = nvalue(rb); | 638 | lua_Number nb = nvalue(rb); |
498 | setnvalue(ra, luai_numunm(nb)); | 639 | setnvalue(ra, luai_numunm(L, nb)); |
499 | } | 640 | } |
500 | else { | 641 | else { |
501 | Protect(Arith(L, ra, rb, rb, TM_UNM)); | 642 | Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); |
502 | } | 643 | } |
503 | continue; | 644 | ) |
504 | } | 645 | vmcase(OP_NOT, |
505 | case OP_NOT: { | 646 | TValue *rb = RB(i); |
506 | int res = l_isfalse(RB(i)); /* next assignment may change this value */ | 647 | int res = l_isfalse(rb); /* next assignment may change this value */ |
507 | setbvalue(ra, res); | 648 | setbvalue(ra, res); |
508 | continue; | 649 | ) |
509 | } | 650 | vmcase(OP_LEN, |
510 | case OP_LEN: { | 651 | Protect(luaV_objlen(L, ra, RB(i))); |
511 | const TValue *rb = RB(i); | 652 | ) |
512 | switch (ttype(rb)) { | 653 | vmcase(OP_CONCAT, |
513 | case LUA_TTABLE: { | ||
514 | setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); | ||
515 | break; | ||
516 | } | ||
517 | case LUA_TSTRING: { | ||
518 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
519 | break; | ||
520 | } | ||
521 | default: { /* try metamethod */ | ||
522 | Protect( | ||
523 | if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) | ||
524 | luaG_typeerror(L, rb, "get length of"); | ||
525 | ) | ||
526 | } | ||
527 | } | ||
528 | continue; | ||
529 | } | ||
530 | case OP_CONCAT: { | ||
531 | int b = GETARG_B(i); | 654 | int b = GETARG_B(i); |
532 | int c = GETARG_C(i); | 655 | int c = GETARG_C(i); |
533 | Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); | 656 | StkId rb; |
534 | setobjs2s(L, RA(i), base+b); | 657 | L->top = base + c + 1; /* mark the end of concat operands */ |
535 | continue; | 658 | Protect(luaV_concat(L, c - b + 1)); |
536 | } | 659 | ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ |
537 | case OP_JMP: { | 660 | rb = b + base; |
538 | dojump(L, pc, GETARG_sBx(i)); | 661 | setobjs2s(L, ra, rb); |
539 | continue; | 662 | checkGC(L, (ra >= rb ? ra + 1 : rb)); |
540 | } | 663 | L->top = ci->top; /* restore top */ |
541 | case OP_EQ: { | 664 | ) |
665 | vmcase(OP_JMP, | ||
666 | dojump(ci, i, 0); | ||
667 | ) | ||
668 | vmcase(OP_EQ, | ||
542 | TValue *rb = RKB(i); | 669 | TValue *rb = RKB(i); |
543 | TValue *rc = RKC(i); | 670 | TValue *rc = RKC(i); |
544 | Protect( | 671 | Protect( |
545 | if (equalobj(L, rb, rc) == GETARG_A(i)) | 672 | if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) |
546 | dojump(L, pc, GETARG_sBx(*pc)); | 673 | ci->u.l.savedpc++; |
674 | else | ||
675 | donextjump(ci); | ||
547 | ) | 676 | ) |
548 | pc++; | 677 | ) |
549 | continue; | 678 | vmcase(OP_LT, |
550 | } | ||
551 | case OP_LT: { | ||
552 | Protect( | 679 | Protect( |
553 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | 680 | if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) |
554 | dojump(L, pc, GETARG_sBx(*pc)); | 681 | ci->u.l.savedpc++; |
682 | else | ||
683 | donextjump(ci); | ||
555 | ) | 684 | ) |
556 | pc++; | 685 | ) |
557 | continue; | 686 | vmcase(OP_LE, |
558 | } | ||
559 | case OP_LE: { | ||
560 | Protect( | 687 | Protect( |
561 | if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | 688 | if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) |
562 | dojump(L, pc, GETARG_sBx(*pc)); | 689 | ci->u.l.savedpc++; |
690 | else | ||
691 | donextjump(ci); | ||
563 | ) | 692 | ) |
564 | pc++; | 693 | ) |
565 | continue; | 694 | vmcase(OP_TEST, |
566 | } | 695 | if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) |
567 | case OP_TEST: { | 696 | ci->u.l.savedpc++; |
568 | if (l_isfalse(ra) != GETARG_C(i)) | 697 | else |
569 | dojump(L, pc, GETARG_sBx(*pc)); | 698 | donextjump(ci); |
570 | pc++; | 699 | ) |
571 | continue; | 700 | vmcase(OP_TESTSET, |
572 | } | ||
573 | case OP_TESTSET: { | ||
574 | TValue *rb = RB(i); | 701 | TValue *rb = RB(i); |
575 | if (l_isfalse(rb) != GETARG_C(i)) { | 702 | if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) |
703 | ci->u.l.savedpc++; | ||
704 | else { | ||
576 | setobjs2s(L, ra, rb); | 705 | setobjs2s(L, ra, rb); |
577 | dojump(L, pc, GETARG_sBx(*pc)); | 706 | donextjump(ci); |
578 | } | 707 | } |
579 | pc++; | 708 | ) |
580 | continue; | 709 | vmcase(OP_CALL, |
581 | } | ||
582 | case OP_CALL: { | ||
583 | int b = GETARG_B(i); | 710 | int b = GETARG_B(i); |
584 | int nresults = GETARG_C(i) - 1; | 711 | int nresults = GETARG_C(i) - 1; |
585 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 712 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
586 | L->savedpc = pc; | 713 | if (luaD_precall(L, ra, nresults)) { /* C function? */ |
587 | switch (luaD_precall(L, ra, nresults)) { | 714 | if (nresults >= 0) L->top = ci->top; /* adjust results */ |
588 | case PCRLUA: { | 715 | base = ci->u.l.base; |
589 | nexeccalls++; | ||
590 | goto reentry; /* restart luaV_execute over new Lua function */ | ||
591 | } | ||
592 | case PCRC: { | ||
593 | /* it was a C function (`precall' called it); adjust results */ | ||
594 | if (nresults >= 0) L->top = L->ci->top; | ||
595 | base = L->base; | ||
596 | continue; | ||
597 | } | ||
598 | default: { | ||
599 | return; /* yield */ | ||
600 | } | ||
601 | } | 716 | } |
602 | } | 717 | else { /* Lua function */ |
603 | case OP_TAILCALL: { | 718 | ci = L->ci; |
719 | ci->callstatus |= CIST_REENTRY; | ||
720 | goto newframe; /* restart luaV_execute over new Lua function */ | ||
721 | } | ||
722 | ) | ||
723 | vmcase(OP_TAILCALL, | ||
604 | int b = GETARG_B(i); | 724 | int b = GETARG_B(i); |
605 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 725 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
606 | L->savedpc = pc; | ||
607 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 726 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
608 | switch (luaD_precall(L, ra, LUA_MULTRET)) { | 727 | if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ |
609 | case PCRLUA: { | 728 | base = ci->u.l.base; |
610 | /* tail call: put new frame in place of previous one */ | 729 | else { |
611 | CallInfo *ci = L->ci - 1; /* previous frame */ | 730 | /* tail call: put called frame (n) in place of caller one (o) */ |
612 | int aux; | 731 | CallInfo *nci = L->ci; /* called frame */ |
613 | StkId func = ci->func; | 732 | CallInfo *oci = nci->previous; /* caller frame */ |
614 | StkId pfunc = (ci+1)->func; /* previous function index */ | 733 | StkId nfunc = nci->func; /* called function */ |
615 | if (L->openupval) luaF_close(L, ci->base); | 734 | StkId ofunc = oci->func; /* caller function */ |
616 | L->base = ci->base = ci->func + ((ci+1)->base - pfunc); | 735 | /* last stack slot filled by 'precall' */ |
617 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ | 736 | StkId lim = nci->u.l.base + getproto(nfunc)->numparams; |
618 | setobjs2s(L, func+aux, pfunc+aux); | 737 | int aux; |
619 | ci->top = L->top = func+aux; /* correct top */ | 738 | /* close all upvalues from previous call */ |
620 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); | 739 | if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); |
621 | ci->savedpc = L->savedpc; | 740 | /* move new frame into old one */ |
622 | ci->tailcalls++; /* one more call lost */ | 741 | for (aux = 0; nfunc + aux < lim; aux++) |
623 | L->ci--; /* remove new frame */ | 742 | setobjs2s(L, ofunc + aux, nfunc + aux); |
624 | goto reentry; | 743 | oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ |
625 | } | 744 | oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ |
626 | case PCRC: { /* it was a C function (`precall' called it) */ | 745 | oci->u.l.savedpc = nci->u.l.savedpc; |
627 | base = L->base; | 746 | oci->callstatus |= CIST_TAIL; /* function was tail called */ |
628 | continue; | 747 | ci = L->ci = oci; /* remove new frame */ |
629 | } | 748 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); |
630 | default: { | 749 | goto newframe; /* restart luaV_execute over new Lua function */ |
631 | return; /* yield */ | ||
632 | } | ||
633 | } | 750 | } |
634 | } | 751 | ) |
635 | case OP_RETURN: { | 752 | vmcasenb(OP_RETURN, |
636 | int b = GETARG_B(i); | 753 | int b = GETARG_B(i); |
637 | if (b != 0) L->top = ra+b-1; | 754 | if (b != 0) L->top = ra+b-1; |
638 | if (L->openupval) luaF_close(L, base); | 755 | if (cl->p->sizep > 0) luaF_close(L, base); |
639 | L->savedpc = pc; | ||
640 | b = luaD_poscall(L, ra); | 756 | b = luaD_poscall(L, ra); |
641 | if (--nexeccalls == 0) /* was previous function running `here'? */ | 757 | if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ |
642 | return; /* no: return */ | 758 | return; /* external invocation: return */ |
643 | else { /* yes: continue its execution */ | 759 | else { /* invocation via reentry: continue execution */ |
644 | if (b) L->top = L->ci->top; | 760 | ci = L->ci; |
645 | lua_assert(isLua(L->ci)); | 761 | if (b) L->top = ci->top; |
646 | lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); | 762 | lua_assert(isLua(ci)); |
647 | goto reentry; | 763 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); |
764 | goto newframe; /* restart luaV_execute over new Lua function */ | ||
648 | } | 765 | } |
649 | } | 766 | ) |
650 | case OP_FORLOOP: { | 767 | vmcase(OP_FORLOOP, |
651 | lua_Number step = nvalue(ra+2); | 768 | lua_Number step = nvalue(ra+2); |
652 | lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ | 769 | lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ |
653 | lua_Number limit = nvalue(ra+1); | 770 | lua_Number limit = nvalue(ra+1); |
654 | if (luai_numlt(0, step) ? luai_numle(idx, limit) | 771 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) |
655 | : luai_numle(limit, idx)) { | 772 | : luai_numle(L, limit, idx)) { |
656 | dojump(L, pc, GETARG_sBx(i)); /* jump back */ | 773 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
657 | setnvalue(ra, idx); /* update internal index... */ | 774 | setnvalue(ra, idx); /* update internal index... */ |
658 | setnvalue(ra+3, idx); /* ...and external index */ | 775 | setnvalue(ra+3, idx); /* ...and external index */ |
659 | } | 776 | } |
660 | continue; | 777 | ) |
661 | } | 778 | vmcase(OP_FORPREP, |
662 | case OP_FORPREP: { | ||
663 | const TValue *init = ra; | 779 | const TValue *init = ra; |
664 | const TValue *plimit = ra+1; | 780 | const TValue *plimit = ra+1; |
665 | const TValue *pstep = ra+2; | 781 | const TValue *pstep = ra+2; |
666 | L->savedpc = pc; /* next steps may throw errors */ | ||
667 | if (!tonumber(init, ra)) | 782 | if (!tonumber(init, ra)) |
668 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); | 783 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); |
669 | else if (!tonumber(plimit, ra+1)) | 784 | else if (!tonumber(plimit, ra+1)) |
670 | luaG_runerror(L, LUA_QL("for") " limit must be a number"); | 785 | luaG_runerror(L, LUA_QL("for") " limit must be a number"); |
671 | else if (!tonumber(pstep, ra+2)) | 786 | else if (!tonumber(pstep, ra+2)) |
672 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | 787 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
673 | setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); | 788 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); |
674 | dojump(L, pc, GETARG_sBx(i)); | 789 | ci->u.l.savedpc += GETARG_sBx(i); |
675 | continue; | 790 | ) |
676 | } | 791 | vmcasenb(OP_TFORCALL, |
677 | case OP_TFORLOOP: { | ||
678 | StkId cb = ra + 3; /* call base */ | 792 | StkId cb = ra + 3; /* call base */ |
679 | setobjs2s(L, cb+2, ra+2); | 793 | setobjs2s(L, cb+2, ra+2); |
680 | setobjs2s(L, cb+1, ra+1); | 794 | setobjs2s(L, cb+1, ra+1); |
681 | setobjs2s(L, cb, ra); | 795 | setobjs2s(L, cb, ra); |
682 | L->top = cb+3; /* func. + 2 args (state and index) */ | 796 | L->top = cb + 3; /* func. + 2 args (state and index) */ |
683 | Protect(luaD_call(L, cb, GETARG_C(i))); | 797 | Protect(luaD_call(L, cb, GETARG_C(i), 1)); |
684 | L->top = L->ci->top; | 798 | L->top = ci->top; |
685 | cb = RA(i) + 3; /* previous call may change the stack */ | 799 | i = *(ci->u.l.savedpc++); /* go to next instruction */ |
686 | if (!ttisnil(cb)) { /* continue loop? */ | 800 | ra = RA(i); |
687 | setobjs2s(L, cb-1, cb); /* save control variable */ | 801 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
688 | dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ | 802 | goto l_tforloop; |
803 | ) | ||
804 | vmcase(OP_TFORLOOP, | ||
805 | l_tforloop: | ||
806 | if (!ttisnil(ra + 1)) { /* continue loop? */ | ||
807 | setobjs2s(L, ra, ra + 1); /* save control variable */ | ||
808 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | ||
689 | } | 809 | } |
690 | pc++; | 810 | ) |
691 | continue; | 811 | vmcase(OP_SETLIST, |
692 | } | ||
693 | case OP_SETLIST: { | ||
694 | int n = GETARG_B(i); | 812 | int n = GETARG_B(i); |
695 | int c = GETARG_C(i); | 813 | int c = GETARG_C(i); |
696 | int last; | 814 | int last; |
697 | Table *h; | 815 | Table *h; |
698 | if (n == 0) { | 816 | if (n == 0) n = cast_int(L->top - ra) - 1; |
699 | n = cast_int(L->top - ra) - 1; | 817 | if (c == 0) { |
700 | L->top = L->ci->top; | 818 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); |
819 | c = GETARG_Ax(*ci->u.l.savedpc++); | ||
701 | } | 820 | } |
702 | if (c == 0) c = cast_int(*pc++); | 821 | luai_runtimecheck(L, ttistable(ra)); |
703 | runtime_check(L, ttistable(ra)); | ||
704 | h = hvalue(ra); | 822 | h = hvalue(ra); |
705 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 823 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
706 | if (last > h->sizearray) /* needs more space? */ | 824 | if (last > h->sizearray) /* needs more space? */ |
707 | luaH_resizearray(L, h, last); /* pre-alloc it at once */ | 825 | luaH_resizearray(L, h, last); /* pre-allocate it at once */ |
708 | for (; n > 0; n--) { | 826 | for (; n > 0; n--) { |
709 | TValue *val = ra+n; | 827 | TValue *val = ra+n; |
710 | setobj2t(L, luaH_setnum(L, h, last--), val); | 828 | luaH_setint(L, h, last--, val); |
711 | luaC_barriert(L, h, val); | 829 | luaC_barrierback(L, obj2gco(h), val); |
712 | } | 830 | } |
713 | continue; | 831 | L->top = ci->top; /* correct top (in case of previous open call) */ |
714 | } | 832 | ) |
715 | case OP_CLOSE: { | 833 | vmcase(OP_CLOSURE, |
716 | luaF_close(L, ra); | 834 | Proto *p = cl->p->p[GETARG_Bx(i)]; |
717 | continue; | 835 | Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ |
718 | } | 836 | if (ncl == NULL) /* no match? */ |
719 | case OP_CLOSURE: { | 837 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ |
720 | Proto *p; | 838 | else |
721 | Closure *ncl; | 839 | setclLvalue(L, ra, ncl); /* push cashed closure */ |
722 | int nup, j; | 840 | checkGC(L, ra + 1); |
723 | p = cl->p->p[GETARG_Bx(i)]; | 841 | ) |
724 | nup = p->nups; | 842 | vmcase(OP_VARARG, |
725 | ncl = luaF_newLclosure(L, nup, cl->env); | ||
726 | ncl->l.p = p; | ||
727 | for (j=0; j<nup; j++, pc++) { | ||
728 | if (GET_OPCODE(*pc) == OP_GETUPVAL) | ||
729 | ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; | ||
730 | else { | ||
731 | lua_assert(GET_OPCODE(*pc) == OP_MOVE); | ||
732 | ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); | ||
733 | } | ||
734 | } | ||
735 | setclvalue(L, ra, ncl); | ||
736 | Protect(luaC_checkGC(L)); | ||
737 | continue; | ||
738 | } | ||
739 | case OP_VARARG: { | ||
740 | int b = GETARG_B(i) - 1; | 843 | int b = GETARG_B(i) - 1; |
741 | int j; | 844 | int j; |
742 | CallInfo *ci = L->ci; | 845 | int n = cast_int(base - ci->func) - cl->p->numparams - 1; |
743 | int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; | 846 | if (b < 0) { /* B == 0? */ |
744 | if (b == LUA_MULTRET) { | 847 | b = n; /* get all var. arguments */ |
745 | Protect(luaD_checkstack(L, n)); | 848 | Protect(luaD_checkstack(L, n)); |
746 | ra = RA(i); /* previous call may change the stack */ | 849 | ra = RA(i); /* previous call may change the stack */ |
747 | b = n; | ||
748 | L->top = ra + n; | 850 | L->top = ra + n; |
749 | } | 851 | } |
750 | for (j = 0; j < b; j++) { | 852 | for (j = 0; j < b; j++) { |
751 | if (j < n) { | 853 | if (j < n) { |
752 | setobjs2s(L, ra + j, ci->base - n + j); | 854 | setobjs2s(L, ra + j, base - n + j); |
753 | } | 855 | } |
754 | else { | 856 | else { |
755 | setnilvalue(ra + j); | 857 | setnilvalue(ra + j); |
756 | } | 858 | } |
757 | } | 859 | } |
758 | continue; | 860 | ) |
759 | } | 861 | vmcase(OP_EXTRAARG, |
862 | lua_assert(0); | ||
863 | ) | ||
760 | } | 864 | } |
761 | } | 865 | } |
762 | } | 866 | } |