Imported from ../lua-4.0.1.tar.gz.
[lua.git] / src / lvm.c
blob2a00b6a5324d9d18dda909fc2fba6a90747ce0d8
1 /*
2 ** $Id: lvm.c,v 1.146a 2000/10/26 12:47:05 roberto Exp $
3 ** Lua virtual machine
4 ** See Copyright Notice in lua.h
5 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include "lua.h"
14 #include "lapi.h"
15 #include "ldebug.h"
16 #include "ldo.h"
17 #include "lfunc.h"
18 #include "lgc.h"
19 #include "lobject.h"
20 #include "lopcodes.h"
21 #include "lstate.h"
22 #include "lstring.h"
23 #include "ltable.h"
24 #include "ltm.h"
25 #include "lvm.h"
28 #ifdef OLD_ANSI
29 #define strcoll(a,b) strcmp(a,b)
30 #endif
35 ** Extra stack size to run a function:
36 ** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
38 #define EXTRA_STACK 8
42 int luaV_tonumber (TObject *obj) {
43 if (ttype(obj) != LUA_TSTRING)
44 return 1;
45 else {
46 if (!luaO_str2d(svalue(obj), &nvalue(obj)))
47 return 2;
48 ttype(obj) = LUA_TNUMBER;
49 return 0;
54 int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
55 if (ttype(obj) != LUA_TNUMBER)
56 return 1;
57 else {
58 char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */
59 lua_number2str(s, nvalue(obj)); /* convert `s' to number */
60 tsvalue(obj) = luaS_new(L, s);
61 ttype(obj) = LUA_TSTRING;
62 return 0;
67 static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
68 CallInfo *ci = infovalue(base-1);
69 int *lineinfo = ci->func->f.l->lineinfo;
70 int pc = (*ci->pc - ci->func->f.l->code) - 1;
71 int newline;
72 if (pc == 0) { /* may be first time? */
73 ci->line = 1;
74 ci->refi = 0;
75 ci->lastpc = pc+1; /* make sure it will call linehook */
77 newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi);
78 /* calls linehook when enters a new line or jumps back (loop) */
79 if (newline != ci->line || pc <= ci->lastpc) {
80 ci->line = newline;
81 L->top = top;
82 luaD_lineHook(L, base-1, newline, linehook);
84 ci->lastpc = pc;
88 static Closure *luaV_closure (lua_State *L, int nelems) {
89 Closure *c = luaF_newclosure(L, nelems);
90 L->top -= nelems;
91 while (nelems--)
92 c->upvalue[nelems] = *(L->top+nelems);
93 clvalue(L->top) = c;
94 ttype(L->top) = LUA_TFUNCTION;
95 incr_top;
96 return c;
100 void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
101 Closure *cl = luaV_closure(L, nelems);
102 cl->f.c = c;
103 cl->isC = 1;
107 void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
108 Closure *cl = luaV_closure(L, nelems);
109 cl->f.l = l;
110 cl->isC = 0;
115 ** Function to index a table.
116 ** Receives the table at `t' and the key at top.
118 const TObject *luaV_gettable (lua_State *L, StkId t) {
119 Closure *tm;
120 int tg;
121 if (ttype(t) == LUA_TTABLE && /* `t' is a table? */
122 ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */
123 luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */
124 /* do a primitive get */
125 const TObject *h = luaH_get(L, hvalue(t), L->top-1);
126 /* result is no nil or there is no `index' tag method? */
127 if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL))
128 return h; /* return result */
129 /* else call `index' tag method */
131 else { /* try a `gettable' tag method */
132 tm = luaT_gettmbyObj(L, t, TM_GETTABLE);
134 if (tm != NULL) { /* is there a tag method? */
135 luaD_checkstack(L, 2);
136 *(L->top+1) = *(L->top-1); /* key */
137 *L->top = *t; /* table */
138 clvalue(L->top-1) = tm; /* tag method */
139 ttype(L->top-1) = LUA_TFUNCTION;
140 L->top += 2;
141 luaD_call(L, L->top - 3, 1);
142 return L->top - 1; /* call result */
144 else { /* no tag method */
145 luaG_typeerror(L, t, "index");
146 return NULL; /* to avoid warnings */
152 ** Receives table at `t', key at `key' and value at top.
154 void luaV_settable (lua_State *L, StkId t, StkId key) {
155 int tg;
156 if (ttype(t) == LUA_TTABLE && /* `t' is a table? */
157 ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */
158 luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */
159 *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */
160 else { /* try a `settable' tag method */
161 Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE);
162 if (tm != NULL) {
163 luaD_checkstack(L, 3);
164 *(L->top+2) = *(L->top-1);
165 *(L->top+1) = *key;
166 *(L->top) = *t;
167 clvalue(L->top-1) = tm;
168 ttype(L->top-1) = LUA_TFUNCTION;
169 L->top += 3;
170 luaD_call(L, L->top - 4, 0); /* call `settable' tag method */
172 else /* no tag method... */
173 luaG_typeerror(L, t, "index");
178 const TObject *luaV_getglobal (lua_State *L, TString *s) {
179 const TObject *value = luaH_getstr(L->gt, s);
180 Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL);
181 if (tm == NULL) /* is there a tag method? */
182 return value; /* default behavior */
183 else { /* tag method */
184 luaD_checkstack(L, 3);
185 clvalue(L->top) = tm;
186 ttype(L->top) = LUA_TFUNCTION;
187 tsvalue(L->top+1) = s; /* global name */
188 ttype(L->top+1) = LUA_TSTRING;
189 *(L->top+2) = *value;
190 L->top += 3;
191 luaD_call(L, L->top - 3, 1);
192 return L->top - 1;
197 void luaV_setglobal (lua_State *L, TString *s) {
198 const TObject *oldvalue = luaH_getstr(L->gt, s);
199 Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL);
200 if (tm == NULL) { /* is there a tag method? */
201 if (oldvalue != &luaO_nilobject) {
202 /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */
203 *(TObject *)oldvalue = *(L->top - 1);
205 else {
206 TObject key;
207 ttype(&key) = LUA_TSTRING;
208 tsvalue(&key) = s;
209 *luaH_set(L, L->gt, &key) = *(L->top - 1);
212 else {
213 luaD_checkstack(L, 3);
214 *(L->top+2) = *(L->top-1); /* new value */
215 *(L->top+1) = *oldvalue;
216 ttype(L->top) = LUA_TSTRING;
217 tsvalue(L->top) = s;
218 clvalue(L->top-1) = tm;
219 ttype(L->top-1) = LUA_TFUNCTION;
220 L->top += 3;
221 luaD_call(L, L->top - 4, 0);
226 static int call_binTM (lua_State *L, StkId top, TMS event) {
227 /* try first operand */
228 Closure *tm = luaT_gettmbyObj(L, top-2, event);
229 L->top = top;
230 if (tm == NULL) {
231 tm = luaT_gettmbyObj(L, top-1, event); /* try second operand */
232 if (tm == NULL) {
233 tm = luaT_gettm(L, 0, event); /* try a `global' method */
234 if (tm == NULL)
235 return 0; /* error */
238 lua_pushstring(L, luaT_eventname[event]);
239 luaD_callTM(L, tm, 3, 1);
240 return 1;
244 static void call_arith (lua_State *L, StkId top, TMS event) {
245 if (!call_binTM(L, top, event))
246 luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on");
250 static int luaV_strcomp (const TString *ls, const TString *rs) {
251 const char *l = ls->str;
252 size_t ll = ls->len;
253 const char *r = rs->str;
254 size_t lr = rs->len;
255 for (;;) {
256 int temp = strcoll(l, r);
257 if (temp != 0) return temp;
258 else { /* strings are equal up to a '\0' */
259 size_t len = strlen(l); /* index of first '\0' in both strings */
260 if (len == ll) /* l is finished? */
261 return (len == lr) ? 0 : -1; /* l is equal or smaller than r */
262 else if (len == lr) /* r is finished? */
263 return 1; /* l is greater than r (because l is not finished) */
264 /* both strings longer than `len'; go on comparing (after the '\0') */
265 len++;
266 l += len; ll -= len; r += len; lr -= len;
272 int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
273 if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER)
274 return (nvalue(l) < nvalue(r));
275 else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING)
276 return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0);
277 else { /* call TM */
278 luaD_checkstack(L, 2);
279 *top++ = *l;
280 *top++ = *r;
281 if (!call_binTM(L, top, TM_LT))
282 luaG_ordererror(L, top-2);
283 L->top--;
284 return (ttype(L->top) != LUA_TNIL);
289 void luaV_strconc (lua_State *L, int total, StkId top) {
290 do {
291 int n = 2; /* number of elements handled in this pass (at least 2) */
292 if (tostring(L, top-2) || tostring(L, top-1)) {
293 if (!call_binTM(L, top, TM_CONCAT))
294 luaG_binerror(L, top-2, LUA_TSTRING, "concat");
296 else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */
297 /* at least two string values; get as many as possible */
298 lint32 tl = (lint32)tsvalue(top-1)->len +
299 (lint32)tsvalue(top-2)->len;
300 char *buffer;
301 int i;
302 while (n < total && !tostring(L, top-n-1)) { /* collect total length */
303 tl += tsvalue(top-n-1)->len;
304 n++;
306 if (tl > MAX_SIZET) lua_error(L, "string size overflow");
307 buffer = luaO_openspace(L, tl);
308 tl = 0;
309 for (i=n; i>0; i--) { /* concat all strings */
310 size_t l = tsvalue(top-i)->len;
311 memcpy(buffer+tl, tsvalue(top-i)->str, l);
312 tl += l;
314 tsvalue(top-n) = luaS_newlstr(L, buffer, tl);
316 total -= n-1; /* got `n' strings to create 1 new */
317 top -= n-1;
318 } while (total > 1); /* repeat until only 1 result left */
322 static void luaV_pack (lua_State *L, StkId firstelem) {
323 int i;
324 Hash *htab = luaH_new(L, 0);
325 for (i=0; firstelem+i<L->top; i++)
326 *luaH_setint(L, htab, i+1) = *(firstelem+i);
327 /* store counter in field `n' */
328 luaH_setstrnum(L, htab, luaS_new(L, "n"), i);
329 L->top = firstelem; /* remove elements from the stack */
330 ttype(L->top) = LUA_TTABLE;
331 hvalue(L->top) = htab;
332 incr_top;
336 static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
337 int nvararg = (L->top-base) - nfixargs;
338 if (nvararg < 0)
339 luaD_adjusttop(L, base, nfixargs);
340 luaV_pack(L, base+nfixargs);
345 #define dojump(pc, i) { int d = GETARG_S(i); pc += d; }
348 ** Executes the given Lua function. Parameters are between [base,top).
349 ** Returns n such that the the results are between [n,top).
351 StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
352 const Proto *const tf = cl->f.l;
353 StkId top; /* keep top local, for performance */
354 const Instruction *pc = tf->code;
355 TString **const kstr = tf->kstr;
356 const lua_Hook linehook = L->linehook;
357 infovalue(base-1)->pc = &pc;
358 luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
359 if (tf->is_vararg) /* varargs? */
360 adjust_varargs(L, base, tf->numparams);
361 else
362 luaD_adjusttop(L, base, tf->numparams);
363 top = L->top;
364 /* main loop of interpreter */
365 for (;;) {
366 const Instruction i = *pc++;
367 if (linehook)
368 traceexec(L, base, top, linehook);
369 switch (GET_OPCODE(i)) {
370 case OP_END: {
371 L->top = top;
372 return top;
374 case OP_RETURN: {
375 L->top = top;
376 return base+GETARG_U(i);
378 case OP_CALL: {
379 int nres = GETARG_B(i);
380 if (nres == MULT_RET) nres = LUA_MULTRET;
381 L->top = top;
382 luaD_call(L, base+GETARG_A(i), nres);
383 top = L->top;
384 break;
386 case OP_TAILCALL: {
387 L->top = top;
388 luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
389 return base+GETARG_B(i);
391 case OP_PUSHNIL: {
392 int n = GETARG_U(i);
393 LUA_ASSERT(n>0, "invalid argument");
394 do {
395 ttype(top++) = LUA_TNIL;
396 } while (--n > 0);
397 break;
399 case OP_POP: {
400 top -= GETARG_U(i);
401 break;
403 case OP_PUSHINT: {
404 ttype(top) = LUA_TNUMBER;
405 nvalue(top) = (Number)GETARG_S(i);
406 top++;
407 break;
409 case OP_PUSHSTRING: {
410 ttype(top) = LUA_TSTRING;
411 tsvalue(top) = kstr[GETARG_U(i)];
412 top++;
413 break;
415 case OP_PUSHNUM: {
416 ttype(top) = LUA_TNUMBER;
417 nvalue(top) = tf->knum[GETARG_U(i)];
418 top++;
419 break;
421 case OP_PUSHNEGNUM: {
422 ttype(top) = LUA_TNUMBER;
423 nvalue(top) = -tf->knum[GETARG_U(i)];
424 top++;
425 break;
427 case OP_PUSHUPVALUE: {
428 *top++ = cl->upvalue[GETARG_U(i)];
429 break;
431 case OP_GETLOCAL: {
432 *top++ = *(base+GETARG_U(i));
433 break;
435 case OP_GETGLOBAL: {
436 L->top = top;
437 *top = *luaV_getglobal(L, kstr[GETARG_U(i)]);
438 top++;
439 break;
441 case OP_GETTABLE: {
442 L->top = top;
443 top--;
444 *(top-1) = *luaV_gettable(L, top-1);
445 break;
447 case OP_GETDOTTED: {
448 ttype(top) = LUA_TSTRING;
449 tsvalue(top) = kstr[GETARG_U(i)];
450 L->top = top+1;
451 *(top-1) = *luaV_gettable(L, top-1);
452 break;
454 case OP_GETINDEXED: {
455 *top = *(base+GETARG_U(i));
456 L->top = top+1;
457 *(top-1) = *luaV_gettable(L, top-1);
458 break;
460 case OP_PUSHSELF: {
461 TObject receiver;
462 receiver = *(top-1);
463 ttype(top) = LUA_TSTRING;
464 tsvalue(top++) = kstr[GETARG_U(i)];
465 L->top = top;
466 *(top-2) = *luaV_gettable(L, top-2);
467 *(top-1) = receiver;
468 break;
470 case OP_CREATETABLE: {
471 L->top = top;
472 luaC_checkGC(L);
473 hvalue(top) = luaH_new(L, GETARG_U(i));
474 ttype(top) = LUA_TTABLE;
475 top++;
476 break;
478 case OP_SETLOCAL: {
479 *(base+GETARG_U(i)) = *(--top);
480 break;
482 case OP_SETGLOBAL: {
483 L->top = top;
484 luaV_setglobal(L, kstr[GETARG_U(i)]);
485 top--;
486 break;
488 case OP_SETTABLE: {
489 StkId t = top-GETARG_A(i);
490 L->top = top;
491 luaV_settable(L, t, t+1);
492 top -= GETARG_B(i); /* pop values */
493 break;
495 case OP_SETLIST: {
496 int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
497 int n = GETARG_B(i);
498 Hash *arr = hvalue(top-n-1);
499 L->top = top-n; /* final value of `top' (in case of errors) */
500 for (; n; n--)
501 *luaH_setint(L, arr, n+aux) = *(--top);
502 break;
504 case OP_SETMAP: {
505 int n = GETARG_U(i);
506 StkId finaltop = top-2*n;
507 Hash *arr = hvalue(finaltop-1);
508 L->top = finaltop; /* final value of `top' (in case of errors) */
509 for (; n; n--) {
510 top-=2;
511 *luaH_set(L, arr, top) = *(top+1);
513 break;
515 case OP_ADD: {
516 if (tonumber(top-2) || tonumber(top-1))
517 call_arith(L, top, TM_ADD);
518 else
519 nvalue(top-2) += nvalue(top-1);
520 top--;
521 break;
523 case OP_ADDI: {
524 if (tonumber(top-1)) {
525 ttype(top) = LUA_TNUMBER;
526 nvalue(top) = (Number)GETARG_S(i);
527 call_arith(L, top+1, TM_ADD);
529 else
530 nvalue(top-1) += (Number)GETARG_S(i);
531 break;
533 case OP_SUB: {
534 if (tonumber(top-2) || tonumber(top-1))
535 call_arith(L, top, TM_SUB);
536 else
537 nvalue(top-2) -= nvalue(top-1);
538 top--;
539 break;
541 case OP_MULT: {
542 if (tonumber(top-2) || tonumber(top-1))
543 call_arith(L, top, TM_MUL);
544 else
545 nvalue(top-2) *= nvalue(top-1);
546 top--;
547 break;
549 case OP_DIV: {
550 if (tonumber(top-2) || tonumber(top-1))
551 call_arith(L, top, TM_DIV);
552 else
553 nvalue(top-2) /= nvalue(top-1);
554 top--;
555 break;
557 case OP_POW: {
558 if (!call_binTM(L, top, TM_POW))
559 lua_error(L, "undefined operation");
560 top--;
561 break;
563 case OP_CONCAT: {
564 int n = GETARG_U(i);
565 luaV_strconc(L, n, top);
566 top -= n-1;
567 L->top = top;
568 luaC_checkGC(L);
569 break;
571 case OP_MINUS: {
572 if (tonumber(top-1)) {
573 ttype(top) = LUA_TNIL;
574 call_arith(L, top+1, TM_UNM);
576 else
577 nvalue(top-1) = -nvalue(top-1);
578 break;
580 case OP_NOT: {
581 ttype(top-1) =
582 (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL;
583 nvalue(top-1) = 1;
584 break;
586 case OP_JMPNE: {
587 top -= 2;
588 if (!luaO_equalObj(top, top+1)) dojump(pc, i);
589 break;
591 case OP_JMPEQ: {
592 top -= 2;
593 if (luaO_equalObj(top, top+1)) dojump(pc, i);
594 break;
596 case OP_JMPLT: {
597 top -= 2;
598 if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
599 break;
601 case OP_JMPLE: { /* a <= b === !(b<a) */
602 top -= 2;
603 if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
604 break;
606 case OP_JMPGT: { /* a > b === (b<a) */
607 top -= 2;
608 if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
609 break;
611 case OP_JMPGE: { /* a >= b === !(a<b) */
612 top -= 2;
613 if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
614 break;
616 case OP_JMPT: {
617 if (ttype(--top) != LUA_TNIL) dojump(pc, i);
618 break;
620 case OP_JMPF: {
621 if (ttype(--top) == LUA_TNIL) dojump(pc, i);
622 break;
624 case OP_JMPONT: {
625 if (ttype(top-1) == LUA_TNIL) top--;
626 else dojump(pc, i);
627 break;
629 case OP_JMPONF: {
630 if (ttype(top-1) != LUA_TNIL) top--;
631 else dojump(pc, i);
632 break;
634 case OP_JMP: {
635 dojump(pc, i);
636 break;
638 case OP_PUSHNILJMP: {
639 ttype(top++) = LUA_TNIL;
640 pc++;
641 break;
643 case OP_FORPREP: {
644 if (tonumber(top-1))
645 lua_error(L, "`for' step must be a number");
646 if (tonumber(top-2))
647 lua_error(L, "`for' limit must be a number");
648 if (tonumber(top-3))
649 lua_error(L, "`for' initial value must be a number");
650 if (nvalue(top-1) > 0 ?
651 nvalue(top-3) > nvalue(top-2) :
652 nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
653 top -= 3; /* remove control variables */
654 dojump(pc, i); /* jump to loop end */
656 break;
658 case OP_FORLOOP: {
659 LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
660 LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
661 if (ttype(top-3) != LUA_TNUMBER)
662 lua_error(L, "`for' index must be a number");
663 nvalue(top-3) += nvalue(top-1); /* increment index */
664 if (nvalue(top-1) > 0 ?
665 nvalue(top-3) > nvalue(top-2) :
666 nvalue(top-3) < nvalue(top-2))
667 top -= 3; /* end loop: remove control variables */
668 else
669 dojump(pc, i); /* repeat loop */
670 break;
672 case OP_LFORPREP: {
673 Node *node;
674 if (ttype(top-1) != LUA_TTABLE)
675 lua_error(L, "`for' table must be a table");
676 node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
677 if (node == NULL) { /* `empty' loop? */
678 top--; /* remove table */
679 dojump(pc, i); /* jump to loop end */
681 else {
682 top += 2; /* index,value */
683 *(top-2) = *key(node);
684 *(top-1) = *val(node);
686 break;
688 case OP_LFORLOOP: {
689 Node *node;
690 LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
691 node = luaH_next(L, hvalue(top-3), top-2);
692 if (node == NULL) /* end loop? */
693 top -= 3; /* remove table, key, and value */
694 else {
695 *(top-2) = *key(node);
696 *(top-1) = *val(node);
697 dojump(pc, i); /* repeat loop */
699 break;
701 case OP_CLOSURE: {
702 L->top = top;
703 luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
704 top = L->top;
705 luaC_checkGC(L);
706 break;