2 ** $Id: lvm.c,v 1.146a 2000/10/26 12:47:05 roberto Exp $
4 ** See Copyright Notice in lua.h
29 #define strcoll(a,b) strcmp(a,b)
35 ** Extra stack size to run a function:
36 ** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
42 int luaV_tonumber (TObject
*obj
) {
43 if (ttype(obj
) != LUA_TSTRING
)
46 if (!luaO_str2d(svalue(obj
), &nvalue(obj
)))
48 ttype(obj
) = LUA_TNUMBER
;
54 int luaV_tostring (lua_State
*L
, TObject
*obj
) { /* LUA_NUMBER */
55 if (ttype(obj
) != LUA_TNUMBER
)
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
;
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;
72 if (pc
== 0) { /* may be first time? */
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
) {
82 luaD_lineHook(L
, base
-1, newline
, linehook
);
88 static Closure
*luaV_closure (lua_State
*L
, int nelems
) {
89 Closure
*c
= luaF_newclosure(L
, nelems
);
92 c
->upvalue
[nelems
] = *(L
->top
+nelems
);
94 ttype(L
->top
) = LUA_TFUNCTION
;
100 void luaV_Cclosure (lua_State
*L
, lua_CFunction c
, int nelems
) {
101 Closure
*cl
= luaV_closure(L
, nelems
);
107 void luaV_Lclosure (lua_State
*L
, Proto
*l
, int nelems
) {
108 Closure
*cl
= luaV_closure(L
, nelems
);
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
) {
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
;
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
) {
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
);
163 luaD_checkstack(L
, 3);
164 *(L
->top
+2) = *(L
->top
-1);
167 clvalue(L
->top
-1) = tm
;
168 ttype(L
->top
-1) = LUA_TFUNCTION
;
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
;
191 luaD_call(L
, L
->top
- 3, 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);
207 ttype(&key
) = LUA_TSTRING
;
209 *luaH_set(L
, L
->gt
, &key
) = *(L
->top
- 1);
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
;
218 clvalue(L
->top
-1) = tm
;
219 ttype(L
->top
-1) = LUA_TFUNCTION
;
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
);
231 tm
= luaT_gettmbyObj(L
, top
-1, event
); /* try second operand */
233 tm
= luaT_gettm(L
, 0, event
); /* try a `global' method */
235 return 0; /* error */
238 lua_pushstring(L
, luaT_eventname
[event
]);
239 luaD_callTM(L
, tm
, 3, 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
;
253 const char *r
= rs
->str
;
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') */
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);
278 luaD_checkstack(L
, 2);
281 if (!call_binTM(L
, top
, TM_LT
))
282 luaG_ordererror(L
, top
-2);
284 return (ttype(L
->top
) != LUA_TNIL
);
289 void luaV_strconc (lua_State
*L
, int total
, StkId top
) {
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
;
302 while (n
< total
&& !tostring(L
, top
-n
-1)) { /* collect total length */
303 tl
+= tsvalue(top
-n
-1)->len
;
306 if (tl
> MAX_SIZET
) lua_error(L
, "string size overflow");
307 buffer
= luaO_openspace(L
, tl
);
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
);
314 tsvalue(top
-n
) = luaS_newlstr(L
, buffer
, tl
);
316 total
-= n
-1; /* got `n' strings to create 1 new */
318 } while (total
> 1); /* repeat until only 1 result left */
322 static void luaV_pack (lua_State
*L
, StkId firstelem
) {
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
;
336 static void adjust_varargs (lua_State
*L
, StkId base
, int nfixargs
) {
337 int nvararg
= (L
->top
-base
) - nfixargs
;
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
);
362 luaD_adjusttop(L
, base
, tf
->numparams
);
364 /* main loop of interpreter */
366 const Instruction i
= *pc
++;
368 traceexec(L
, base
, top
, linehook
);
369 switch (GET_OPCODE(i
)) {
376 return base
+GETARG_U(i
);
379 int nres
= GETARG_B(i
);
380 if (nres
== MULT_RET
) nres
= LUA_MULTRET
;
382 luaD_call(L
, base
+GETARG_A(i
), nres
);
388 luaD_call(L
, base
+GETARG_A(i
), LUA_MULTRET
);
389 return base
+GETARG_B(i
);
393 LUA_ASSERT(n
>0, "invalid argument");
395 ttype(top
++) = LUA_TNIL
;
404 ttype(top
) = LUA_TNUMBER
;
405 nvalue(top
) = (Number
)GETARG_S(i
);
409 case OP_PUSHSTRING
: {
410 ttype(top
) = LUA_TSTRING
;
411 tsvalue(top
) = kstr
[GETARG_U(i
)];
416 ttype(top
) = LUA_TNUMBER
;
417 nvalue(top
) = tf
->knum
[GETARG_U(i
)];
421 case OP_PUSHNEGNUM
: {
422 ttype(top
) = LUA_TNUMBER
;
423 nvalue(top
) = -tf
->knum
[GETARG_U(i
)];
427 case OP_PUSHUPVALUE
: {
428 *top
++ = cl
->upvalue
[GETARG_U(i
)];
432 *top
++ = *(base
+GETARG_U(i
));
437 *top
= *luaV_getglobal(L
, kstr
[GETARG_U(i
)]);
444 *(top
-1) = *luaV_gettable(L
, top
-1);
448 ttype(top
) = LUA_TSTRING
;
449 tsvalue(top
) = kstr
[GETARG_U(i
)];
451 *(top
-1) = *luaV_gettable(L
, top
-1);
454 case OP_GETINDEXED
: {
455 *top
= *(base
+GETARG_U(i
));
457 *(top
-1) = *luaV_gettable(L
, top
-1);
463 ttype(top
) = LUA_TSTRING
;
464 tsvalue(top
++) = kstr
[GETARG_U(i
)];
466 *(top
-2) = *luaV_gettable(L
, top
-2);
470 case OP_CREATETABLE
: {
473 hvalue(top
) = luaH_new(L
, GETARG_U(i
));
474 ttype(top
) = LUA_TTABLE
;
479 *(base
+GETARG_U(i
)) = *(--top
);
484 luaV_setglobal(L
, kstr
[GETARG_U(i
)]);
489 StkId t
= top
-GETARG_A(i
);
491 luaV_settable(L
, t
, t
+1);
492 top
-= GETARG_B(i
); /* pop values */
496 int aux
= GETARG_A(i
) * LFIELDS_PER_FLUSH
;
498 Hash
*arr
= hvalue(top
-n
-1);
499 L
->top
= top
-n
; /* final value of `top' (in case of errors) */
501 *luaH_setint(L
, arr
, n
+aux
) = *(--top
);
506 StkId finaltop
= top
-2*n
;
507 Hash
*arr
= hvalue(finaltop
-1);
508 L
->top
= finaltop
; /* final value of `top' (in case of errors) */
511 *luaH_set(L
, arr
, top
) = *(top
+1);
516 if (tonumber(top
-2) || tonumber(top
-1))
517 call_arith(L
, top
, TM_ADD
);
519 nvalue(top
-2) += nvalue(top
-1);
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
);
530 nvalue(top
-1) += (Number
)GETARG_S(i
);
534 if (tonumber(top
-2) || tonumber(top
-1))
535 call_arith(L
, top
, TM_SUB
);
537 nvalue(top
-2) -= nvalue(top
-1);
542 if (tonumber(top
-2) || tonumber(top
-1))
543 call_arith(L
, top
, TM_MUL
);
545 nvalue(top
-2) *= nvalue(top
-1);
550 if (tonumber(top
-2) || tonumber(top
-1))
551 call_arith(L
, top
, TM_DIV
);
553 nvalue(top
-2) /= nvalue(top
-1);
558 if (!call_binTM(L
, top
, TM_POW
))
559 lua_error(L
, "undefined operation");
565 luaV_strconc(L
, n
, top
);
572 if (tonumber(top
-1)) {
573 ttype(top
) = LUA_TNIL
;
574 call_arith(L
, top
+1, TM_UNM
);
577 nvalue(top
-1) = -nvalue(top
-1);
582 (ttype(top
-1) == LUA_TNIL
) ? LUA_TNUMBER
: LUA_TNIL
;
588 if (!luaO_equalObj(top
, top
+1)) dojump(pc
, i
);
593 if (luaO_equalObj(top
, top
+1)) dojump(pc
, i
);
598 if (luaV_lessthan(L
, top
, top
+1, top
+2)) dojump(pc
, i
);
601 case OP_JMPLE
: { /* a <= b === !(b<a) */
603 if (!luaV_lessthan(L
, top
+1, top
, top
+2)) dojump(pc
, i
);
606 case OP_JMPGT
: { /* a > b === (b<a) */
608 if (luaV_lessthan(L
, top
+1, top
, top
+2)) dojump(pc
, i
);
611 case OP_JMPGE
: { /* a >= b === !(a<b) */
613 if (!luaV_lessthan(L
, top
, top
+1, top
+2)) dojump(pc
, i
);
617 if (ttype(--top
) != LUA_TNIL
) dojump(pc
, i
);
621 if (ttype(--top
) == LUA_TNIL
) dojump(pc
, i
);
625 if (ttype(top
-1) == LUA_TNIL
) top
--;
630 if (ttype(top
-1) != LUA_TNIL
) top
--;
638 case OP_PUSHNILJMP
: {
639 ttype(top
++) = LUA_TNIL
;
645 lua_error(L
, "`for' step must be a number");
647 lua_error(L
, "`for' limit must be a number");
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 */
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 */
669 dojump(pc
, i
); /* repeat loop */
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 */
682 top
+= 2; /* index,value */
683 *(top
-2) = *key(node
);
684 *(top
-1) = *val(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 */
695 *(top
-2) = *key(node
);
696 *(top
-1) = *val(node
);
697 dojump(pc
, i
); /* repeat loop */
703 luaV_Lclosure(L
, tf
->kproto
[GETARG_A(i
)], GETARG_B(i
));