summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/lvm.c
diff options
context:
space:
mode:
authorRichard Quirk <richard.quirk@gmail.com>2014-03-19 19:31:31 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2014-04-02 20:31:54 +0200
commit36378988ad4059982742f05f5eb50580b456840a (patch)
treeee70be810d894566c5e351f21a1ebb79be742a85 /apps/plugins/lua/lvm.c
parent020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff)
downloadrockbox-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.c914
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 @@
35const TValue *luaV_tonumber (const TValue *obj, TValue *n) { 35const 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
60static void traceexec (lua_State *L, const Instruction *pc) { 60static 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
80static 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
96static void callTM (lua_State *L, const TValue *f, const TValue *p1, 93static 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
172static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, 186static 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
186static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, 200static 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
221int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { 231int 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
235static int lessequal (lua_State *L, const TValue *l, const TValue *r) { 243int 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
251int 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*/
260int 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
278void luaV_concat (lua_State *L, int total, int last) { 293void 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
313static void Arith (lua_State *L, StkId ra, const TValue *rb, 335void 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
360void 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*/
379static 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*/
401static 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*/
423void 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
373void luaV_execute (lua_State *L, int nexeccalls) { 534void 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}