6 char *rcs_opcode
="$Id: opcode.c,v 3.34 1995/02/06 19:35:09 roberto Exp $";
22 #define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0))
23 #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0))
26 #define STACK_BUFFER (STACKGAP+128)
28 typedef int StkId
; /* index to stack elements */
30 static Long maxstack
= 0L;
31 static Object
*stack
= NULL
;
32 static Object
*top
= NULL
;
35 /* macros to convert from lua_Object to (Object *) and back */
37 #define Address(lo) ((lo)+stack-1)
38 #define Ref(st) ((st)-stack+1)
41 static StkId CBase
= 0; /* when Lua calls C or C calls Lua, points to */
42 /* the first slot after the last parameter. */
43 static int CnResults
= 0; /* when Lua calls C, has the number of parameters; */
44 /* when C calls Lua, has the number of results. */
46 static jmp_buf *errorJmp
= NULL
; /* current error recover point */
49 static StkId
lua_execute (Byte
*pc
, StkId base
);
50 static void do_call (Object
*func
, StkId base
, int nResults
, StkId whereRes
);
54 Object
*luaI_Address (lua_Object o
)
64 static void lua_message (char *s
)
67 do_call(&luaI_fallBacks
[FB_ERROR
].function
, (top
-stack
)-1, 0, (top
-stack
)-1);
71 ** Reports an error, and jumps up to the available recover label
73 void lua_error (char *s
)
75 if (s
) lua_message(s
);
77 longjmp(*errorJmp
, 1);
80 fprintf (stderr
, "lua: exit(1). Unable to recover\n");
89 static void lua_initstack (void)
91 maxstack
= STACK_BUFFER
;
92 stack
= newvector(maxstack
, Object
);
98 ** Check stack overflow and, if necessary, realloc vector
100 #define lua_checkstack(n) if ((Long)(n) > maxstack) checkstack(n)
102 static void checkstack (StkId n
)
107 if (maxstack
>= MAX_INT
)
108 lua_error("stack size overflow");
111 if (maxstack
>= MAX_INT
)
113 stack
= growvector(stack
, maxstack
, Object
);
119 ** Concatenate two given strings. Return the new string pointer.
121 static char *lua_strconc (char *l
, char *r
)
123 static char *buffer
= NULL
;
124 static int buffer_size
= 0;
126 int n
= nl
+strlen(r
)+1;
132 buffer
= newvector(buffer_size
, char);
135 strcpy(buffer
+nl
, r
);
141 ** Convert, if possible, to a number object.
142 ** Return 0 if success, not 0 if error.
144 static int lua_tonumber (Object
*obj
)
148 if (tag(obj
) != LUA_T_STRING
)
150 else if (sscanf(svalue(obj
), "%f %c",&t
, &c
) == 1)
153 tag(obj
) = LUA_T_NUMBER
;
162 ** Convert, if possible, to a string tag
163 ** Return 0 in success or not 0 on error.
165 static int lua_tostring (Object
*obj
)
168 if (tag(obj
) != LUA_T_NUMBER
)
170 if ((int) nvalue(obj
) == nvalue(obj
))
171 sprintf (s
, "%d", (int) nvalue(obj
));
173 sprintf (s
, "%g", nvalue(obj
));
174 tsvalue(obj
) = lua_createstring(s
);
175 if (tsvalue(obj
) == NULL
)
177 tag(obj
) = LUA_T_STRING
;
183 ** Adjust stack. Set top to the given value, pushing NILs if needed.
185 static void adjust_top (StkId newtop
)
187 Object
*nt
= stack
+newtop
;
188 while (top
< nt
) tag(top
++) = LUA_T_NIL
;
189 top
= nt
; /* top could be bigger than newtop */
193 static void adjustC (int nParams
)
195 adjust_top(CBase
+nParams
);
200 ** Call a C function. CBase will point to the top of the stack,
201 ** and CnResults is the number of parameters. Returns an index
202 ** to the first result from C.
204 static StkId
callC (lua_CFunction func
, StkId base
)
206 StkId oldBase
= CBase
;
207 int oldCnResults
= CnResults
;
209 CnResults
= (top
-stack
) - base
;
210 /* incorporate parameters on the stack */
211 CBase
= base
+CnResults
;
215 CnResults
= oldCnResults
;
220 ** Call the fallback for invalid functions (see do_call)
222 static void call_funcFB (Object
*func
, StkId base
, int nResults
, StkId whereRes
)
225 /* open space for first parameter (func) */
226 for (i
=top
-stack
; i
>base
; i
--)
227 stack
[i
] = stack
[i
-1];
230 do_call(&luaI_fallBacks
[FB_FUNCTION
].function
, base
, nResults
, whereRes
);
235 ** Call a function (C or Lua). The parameters must be on the stack,
236 ** between [stack+base,top). When returns, the results are on the stack,
237 ** between [stack+whereRes,top). The number of results is nResults, unless
238 ** nResults=MULT_RET.
240 static void do_call (Object
*func
, StkId base
, int nResults
, StkId whereRes
)
243 if (tag(func
) == LUA_T_CFUNCTION
)
244 firstResult
= callC(fvalue(func
), base
);
245 else if (tag(func
) == LUA_T_FUNCTION
)
246 firstResult
= lua_execute(bvalue(func
), base
);
248 { /* func is not a function */
249 call_funcFB(func
, base
, nResults
, whereRes
);
252 /* adjust the number of results */
253 if (nResults
!= MULT_RET
&& top
- (stack
+firstResult
) != nResults
)
254 adjust_top(firstResult
+nResults
);
255 /* move results to the given position */
256 if (firstResult
!= whereRes
)
259 nResults
= top
- (stack
+firstResult
); /* actual number of results */
260 for (i
=0; i
<nResults
; i
++)
261 *(stack
+whereRes
+i
) = *(stack
+firstResult
+i
);
262 top
-= firstResult
-whereRes
;
268 ** Function to index a table. Receives the table at top-2 and the index
271 static void pushsubscript (void)
273 if (tag(top
-2) != LUA_T_ARRAY
)
274 do_call(&luaI_fallBacks
[FB_GETTABLE
].function
, (top
-stack
)-2, 1, (top
-stack
)-2);
277 Object
*h
= lua_hashget(avalue(top
-2), top
-1);
278 if (h
== NULL
|| tag(h
) == LUA_T_NIL
)
279 do_call(&luaI_fallBacks
[FB_INDEX
].function
, (top
-stack
)-2, 1, (top
-stack
)-2);
290 ** Function to store indexed based on values at the top
292 static void storesubscript (void)
294 if (tag(top
-3) != LUA_T_ARRAY
)
295 do_call(&luaI_fallBacks
[FB_SETTABLE
].function
, (top
-stack
)-3, 0, (top
-stack
)-3);
298 Object
*h
= lua_hashdefine (avalue(top
-3), top
-2);
306 ** Traverse all objects on stack
308 void lua_travstack (void (*fn
)(Object
*))
311 for (o
= top
-1; o
>= stack
; o
--)
317 ** Execute a protected call. If function is null compiles the pre-set input.
318 ** Leave nResults on the stack.
320 static int do_protectedrun (Object
*function
, int nResults
)
324 StkId oldCBase
= CBase
;
325 jmp_buf *oldErr
= errorJmp
;
326 errorJmp
= &myErrorJmp
;
327 if (setjmp(myErrorJmp
) == 0)
329 do_call(function
, CBase
, nResults
, CBase
);
330 CnResults
= (top
-stack
) - CBase
; /* number of results */
331 CBase
+= CnResults
; /* incorporate results on the stack */
345 static int do_protectedmain (void)
349 StkId oldCBase
= CBase
;
351 jmp_buf *oldErr
= errorJmp
;
352 errorJmp
= &myErrorJmp
;
353 if (setjmp(myErrorJmp
) == 0)
357 tag(&f
) = LUA_T_FUNCTION
; bvalue(&f
) = code
;
358 do_call(&f
, CBase
, 0, CBase
);
373 ** Execute the given lua function. Return 0 on success or 1 on error.
375 int lua_callfunction (lua_Object function
)
377 if (function
== LUA_NOOBJECT
)
380 return do_protectedrun (Address(function
), MULT_RET
);
384 int lua_call (char *funcname
)
386 Word n
= luaI_findsymbolbyname(funcname
);
387 return do_protectedrun(&s_object(n
), MULT_RET
);
392 ** Open file, generate opcode and execute global statement. Return 0 on
393 ** success or 1 on error.
395 int lua_dofile (char *filename
)
398 char *message
= lua_openfile (filename
);
401 lua_message(message
);
404 status
= do_protectedmain();
410 ** Generate opcode stored on string and execute global statement. Return 0 on
411 ** success or 1 on error.
413 int lua_dostring (char *string
)
416 char *message
= lua_openstring(string
);
419 lua_message(message
);
422 status
= do_protectedmain();
429 ** API: set a function as a fallback
431 lua_Object
lua_setfallback (char *name
, lua_CFunction fallback
)
433 static Object func
= {LUA_T_CFUNCTION
, luaI_setfallback
};
435 lua_pushstring(name
);
436 lua_pushcfunction(fallback
);
437 do_protectedrun(&func
, 1);
443 ** API: receives on the stack the table and the index.
444 ** returns the value.
446 lua_Object
lua_getsubscript (void)
450 CBase
++; /* incorporate object in the stack */
455 #define MAX_C_BLOCKS 10
457 static int numCblocks
= 0;
458 static StkId Cblocks
[MAX_C_BLOCKS
];
461 ** API: starts a new block
463 void lua_beginblock (void)
465 if (numCblocks
< MAX_C_BLOCKS
)
466 Cblocks
[numCblocks
] = CBase
;
473 void lua_endblock (void)
476 if (numCblocks
< MAX_C_BLOCKS
)
478 CBase
= Cblocks
[numCblocks
];
484 ** API: receives on the stack the table, the index, and the new value.
486 void lua_storesubscript (void)
493 ** API: creates a new table
495 lua_Object
lua_createtable (void)
498 avalue(top
) = lua_createarray(0);
499 tag(top
) = LUA_T_ARRAY
;
501 CBase
++; /* incorporate object in the stack */
506 ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
507 ** 'number' must be 1 to get the first parameter.
509 lua_Object
lua_getparam (int number
)
511 if (number
<= 0 || number
> CnResults
) return LUA_NOOBJECT
;
512 /* Ref(stack+(CBase-CnResults+number-1)) ==
513 stack+(CBase-CnResults+number-1)-stack+1 == */
514 return CBase
-CnResults
+number
;
518 ** Given an object handle, return its number value. On error, return 0.0.
520 real
lua_getnumber (lua_Object object
)
522 if (object
== LUA_NOOBJECT
|| tag(Address(object
)) == LUA_T_NIL
) return 0.0;
523 if (tonumber (Address(object
))) return 0.0;
524 else return (nvalue(Address(object
)));
528 ** Given an object handle, return its string pointer. On error, return NULL.
530 char *lua_getstring (lua_Object object
)
532 if (object
== LUA_NOOBJECT
|| tag(Address(object
)) == LUA_T_NIL
) return NULL
;
533 if (tostring (Address(object
))) return NULL
;
534 else return (svalue(Address(object
)));
538 ** Given an object handle, return its cfuntion pointer. On error, return NULL.
540 lua_CFunction
lua_getcfunction (lua_Object object
)
542 if (object
== LUA_NOOBJECT
|| tag(Address(object
)) != LUA_T_CFUNCTION
)
544 else return (fvalue(Address(object
)));
548 ** Given an object handle, return its user data. On error, return NULL.
550 void *lua_getuserdata (lua_Object object
)
552 if (object
== LUA_NOOBJECT
|| tag(Address(object
)) < LUA_T_USERDATA
)
554 else return (uvalue(Address(object
)));
558 lua_Object
lua_getlocked (int ref
)
561 *top
= *luaI_getlocked(ref
);
563 CBase
++; /* incorporate object in the stack */
568 void lua_pushlocked (int ref
)
570 lua_checkstack(top
-stack
+1);
571 *top
= *luaI_getlocked(ref
);
579 return luaI_lock(--top
);
584 ** Get a global object. Return the object handle or NULL on error.
586 lua_Object
lua_getglobal (char *name
)
588 Word n
= luaI_findsymbolbyname(name
);
592 CBase
++; /* incorporate object in the stack */
597 ** Store top of the stack at a global variable array field.
599 void lua_storeglobal (char *name
)
601 Word n
= luaI_findsymbolbyname(name
);
603 s_object(n
) = *(--top
);
609 void lua_pushnil (void)
611 lua_checkstack(top
-stack
+1);
612 tag(top
++) = LUA_T_NIL
;
616 ** Push an object (tag=number) to stack.
618 void lua_pushnumber (real n
)
620 lua_checkstack(top
-stack
+1);
621 tag(top
) = LUA_T_NUMBER
; nvalue(top
++) = n
;
625 ** Push an object (tag=string) to stack.
627 void lua_pushstring (char *s
)
629 lua_checkstack(top
-stack
+1);
630 tsvalue(top
) = lua_createstring(s
);
631 tag(top
) = LUA_T_STRING
;
636 ** Push an object (tag=string) on stack and register it on the constant table.
638 void lua_pushliteral (char *s
)
640 lua_checkstack(top
-stack
+1);
641 tsvalue(top
) = lua_constant
[luaI_findconstant(lua_constcreate(s
))];
642 tag(top
) = LUA_T_STRING
;
647 ** Push an object (tag=cfunction) to stack.
649 void lua_pushcfunction (lua_CFunction fn
)
651 lua_checkstack(top
-stack
+1);
652 tag(top
) = LUA_T_CFUNCTION
; fvalue(top
++) = fn
;
656 ** Push an object (tag=userdata) to stack.
658 void lua_pushusertag (void *u
, int tag
)
660 if (tag
< LUA_T_USERDATA
) return;
661 lua_checkstack(top
-stack
+1);
662 tag(top
) = tag
; uvalue(top
++) = u
;
666 ** Push a lua_Object to stack.
668 void lua_pushobject (lua_Object o
)
670 lua_checkstack(top
-stack
+1);
671 *top
++ = *Address(o
);
675 ** Push an object on the stack.
677 void luaI_pushobject (Object
*o
)
679 lua_checkstack(top
-stack
+1);
683 int lua_type (lua_Object o
)
685 if (o
== LUA_NOOBJECT
)
688 return tag(Address(o
));
692 void luaI_gcFB (Object
*o
)
695 do_call(&luaI_fallBacks
[FB_GC
].function
, (top
-stack
)-1, 0, (top
-stack
)-1);
699 static void call_arith (char *op
)
702 do_call(&luaI_fallBacks
[FB_ARITH
].function
, (top
-stack
)-3, 1, (top
-stack
)-3);
705 static void comparison (lua_Type tag_less
, lua_Type tag_equal
,
706 lua_Type tag_great
, char *op
)
711 if (tag(l
) == LUA_T_NUMBER
&& tag(r
) == LUA_T_NUMBER
)
712 result
= (nvalue(l
) < nvalue(r
)) ? -1 : (nvalue(l
) == nvalue(r
)) ? 0 : 1;
713 else if (tostring(l
) || tostring(r
))
716 do_call(&luaI_fallBacks
[FB_ORDER
].function
, (top
-stack
)-3, 1, (top
-stack
)-3);
720 result
= strcmp(svalue(l
), svalue(r
));
723 tag(top
-1) = (result
< 0) ? tag_less
: (result
== 0) ? tag_equal
: tag_great
;
729 ** Execute the given opcode, until a RET. Parameters are between
730 ** [stack+base,top). Returns n such that the the results are between
733 static StkId
lua_execute (Byte
*pc
, StkId base
)
735 lua_checkstack(STACKGAP
+MAX_TEMPS
+base
);
739 switch (opcode
= (OpCode
)*pc
++)
741 case PUSHNIL
: tag(top
++) = LUA_T_NIL
; break;
743 case PUSH0
: case PUSH1
: case PUSH2
:
744 tag(top
) = LUA_T_NUMBER
;
745 nvalue(top
++) = opcode
-PUSH0
;
748 case PUSHBYTE
: tag(top
) = LUA_T_NUMBER
; nvalue(top
++) = *pc
++; break;
754 tag(top
) = LUA_T_NUMBER
; nvalue(top
++) = code
.w
;
762 tag(top
) = LUA_T_NUMBER
; nvalue(top
++) = code
.f
;
770 tag(top
) = LUA_T_STRING
; tsvalue(top
++) = lua_constant
[code
.w
];
778 tag(top
) = LUA_T_FUNCTION
; bvalue(top
++) = code
.b
;
782 case PUSHLOCAL0
: case PUSHLOCAL1
: case PUSHLOCAL2
:
783 case PUSHLOCAL3
: case PUSHLOCAL4
: case PUSHLOCAL5
:
784 case PUSHLOCAL6
: case PUSHLOCAL7
: case PUSHLOCAL8
:
785 case PUSHLOCAL9
: *top
++ = *((stack
+base
) + (int)(opcode
-PUSHLOCAL0
)); break;
787 case PUSHLOCAL
: *top
++ = *((stack
+base
) + (*pc
++)); break;
793 *top
++ = s_object(code
.w
);
803 Object receiver
= *(top
-1);
806 tag(top
) = LUA_T_STRING
; tsvalue(top
++) = lua_constant
[code
.w
];
812 case STORELOCAL0
: case STORELOCAL1
: case STORELOCAL2
:
813 case STORELOCAL3
: case STORELOCAL4
: case STORELOCAL5
:
814 case STORELOCAL6
: case STORELOCAL7
: case STORELOCAL8
:
816 *((stack
+base
) + (int)(opcode
-STORELOCAL0
)) = *(--top
);
819 case STORELOCAL
: *((stack
+base
) + (*pc
++)) = *(--top
); break;
825 s_object(code
.w
) = *(--top
);
836 if (tag(top
-3-n
) != LUA_T_ARRAY
)
840 *(top
-1) = *(top
-3-n
);
842 do_call(&luaI_fallBacks
[FB_SETTABLE
].function
, (top
-stack
)-3, 0, (top
-stack
)-3);
846 Object
*h
= lua_hashdefine (avalue(top
-3-n
), top
-2-n
);
858 if (opcode
== STORELIST0
) m
= 0;
859 else m
= *(pc
++) * FIELDS_PER_FLUSH
;
864 tag(top
) = LUA_T_NUMBER
; nvalue(top
) = n
+m
;
865 *(lua_hashdefine (avalue(arr
), top
)) = *(top
-1);
875 Object
*arr
= top
-n
-1;
880 tag(top
) = LUA_T_STRING
; tsvalue(top
) = lua_constant
[code
.w
];
881 *(lua_hashdefine (avalue(arr
), top
)) = *(top
-1);
893 adjust_top(base
+ *(pc
++));
900 avalue(top
) = lua_createarray(size
.w
);
901 tag(top
) = LUA_T_ARRAY
;
908 int res
= lua_equalObj(top
-2, top
-1);
910 tag(top
-1) = res
? LUA_T_NUMBER
: LUA_T_NIL
;
916 comparison(LUA_T_NUMBER
, LUA_T_NIL
, LUA_T_NIL
, "lt");
920 comparison(LUA_T_NUMBER
, LUA_T_NUMBER
, LUA_T_NIL
, "le");
924 comparison(LUA_T_NIL
, LUA_T_NIL
, LUA_T_NUMBER
, "gt");
928 comparison(LUA_T_NIL
, LUA_T_NUMBER
, LUA_T_NUMBER
, "ge");
935 if (tonumber(r
) || tonumber(l
))
939 nvalue(l
) += nvalue(r
);
949 if (tonumber(r
) || tonumber(l
))
953 nvalue(l
) -= nvalue(r
);
963 if (tonumber(r
) || tonumber(l
))
967 nvalue(l
) *= nvalue(r
);
977 if (tonumber(r
) || tonumber(l
))
981 nvalue(l
) /= nvalue(r
);
995 if (tostring(r
) || tostring(l
))
996 do_call(&luaI_fallBacks
[FB_CONCAT
].function
, (top
-stack
)-2, 1, (top
-stack
)-2);
999 tsvalue(l
) = lua_createstring (lua_strconc(svalue(l
),svalue(r
)));
1006 if (tonumber(top
-1))
1008 tag(top
++) = LUA_T_NIL
;
1012 nvalue(top
-1) = - nvalue(top
-1);
1016 tag(top
-1) = (tag(top
-1) == LUA_T_NIL
) ? LUA_T_NUMBER
: LUA_T_NIL
;
1024 if (tag(top
-1) != LUA_T_NIL
) pc
+= code
.w
;
1032 if (tag(top
-1) == LUA_T_NIL
) pc
+= code
.w
;
1057 if (tag(top
) == LUA_T_NIL
) pc
+= code
.w
;
1066 if (tag(top
) == LUA_T_NIL
) pc
-= code
.w
;
1070 case POP
: --top
; break;
1074 int nParams
= *(pc
++);
1075 int nResults
= *(pc
++);
1076 Object
*func
= top
-1-nParams
; /* function is below parameters */
1077 StkId newBase
= (top
-stack
)-nParams
;
1078 do_call(func
, newBase
, nResults
, newBase
-1);
1094 lua_pushfunction ((char *)file
.b
, func
.w
);
1102 lua_debugline
= code
.w
;
1111 lua_error ("internal error - opcode doesn't match");