aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opcode.c317
1 files changed, 202 insertions, 115 deletions
diff --git a/opcode.c b/opcode.c
index 298b172f..1c79e535 100644
--- a/opcode.c
+++ b/opcode.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $"; 6char *rcs_opcode="$Id: opcode.c,v 3.2 1994/11/04 10:47:49 roberto Exp roberto $";
7 7
8#include <stdio.h> 8#include <stdio.h>
9#include <stdlib.h> 9#include <stdlib.h>
@@ -19,6 +19,7 @@ char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $"
19#include "inout.h" 19#include "inout.h"
20#include "table.h" 20#include "table.h"
21#include "lua.h" 21#include "lua.h"
22#include "fallback.h"
22 23
23#define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) 24#define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0))
24#define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) 25#define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0))
@@ -26,9 +27,9 @@ char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $"
26 27
27#define STACK_BUFFER (STACKGAP+128) 28#define STACK_BUFFER (STACKGAP+128)
28 29
29static Long maxstack; 30static Long maxstack = 0L;
30static Object *stack=NULL; 31static Object *stack = NULL;
31static Object *top; 32static Object *top = NULL;
32 33
33 34
34static int CBase = 0; /* when Lua calls C or C calls Lua, points to the */ 35static int CBase = 0; /* when Lua calls C or C calls Lua, points to the */
@@ -40,11 +41,69 @@ static jmp_buf *errorJmp = NULL; /* current error recover point */
40 41
41 42
42static int lua_execute (Byte *pc, int base); 43static int lua_execute (Byte *pc, int base);
44static void do_call (Object *func, int base, int nResults, int whereRes);
43 45
44 46
47/*
48** Fallbacks
49*/
50
51static struct FB {
52 char *kind;
53 Object function;
54} fallBacks[] = {
55#define FB_ERROR 0
56{"error", {LUA_T_CFUNCTION, luaI_errorFB}},
57#define FB_INDEX 1
58{"index", {LUA_T_CFUNCTION, luaI_indexFB}},
59#define FB_GETTABLE 2
60{"gettable", {LUA_T_CFUNCTION, luaI_gettableFB}},
61#define FB_ARITH 3
62{"arith", {LUA_T_CFUNCTION, luaI_arithFB}},
63#define FB_ORDER 4
64{"order", {LUA_T_CFUNCTION, luaI_orderFB}},
65#define FB_CONCAT 5
66{"concat", {LUA_T_CFUNCTION, luaI_concatFB}},
67#define FB_UNMINUS 6
68{"unminus", {LUA_T_CFUNCTION, luaI_arithFB}},
69#define FB_SETTABLE 7
70{"settable", {LUA_T_CFUNCTION, luaI_gettableFB}}
71};
72
73#define N_FB (sizeof(fallBacks)/sizeof(struct FB))
74
75
76void luaI_setfallback (void)
77{
78 int i;
79 char *name = lua_getstring(lua_getparam(1));
80 lua_Object func = lua_getparam(2);
81 if (name == NULL || !(lua_isfunction(func) || lua_iscfunction(func)))
82 {
83 lua_pushnil();
84 return;
85 }
86 for (i=0; i<N_FB; i++)
87 {
88 if (strcmp(fallBacks[i].kind, name) == 0)
89 {
90 lua_pushobject(&fallBacks[i].function);
91 fallBacks[i].function = *func;
92 return;
93 }
94 }
95 /* name not found */
96 lua_pushnil();
97}
98
99/*
100** Error messages
101*/
102
45static void lua_message (char *s) 103static void lua_message (char *s)
46{ 104{
47 fprintf (stderr, "lua: %s\n", s); 105 lua_pushstring(s);
106 do_call(&fallBacks[FB_ERROR].function, (top-stack)-1, 0, (top-stack)-1);
48} 107}
49 108
50/* 109/*
@@ -81,11 +140,12 @@ static void lua_initstack (void)
81*/ 140*/
82static void lua_checkstack (Word n) 141static void lua_checkstack (Word n)
83{ 142{
84 if (stack == NULL)
85 lua_initstack();
86 if (n > maxstack) 143 if (n > maxstack)
87 { 144 {
88 int t = top-stack; 145 int t;
146 if (stack == NULL)
147 lua_initstack();
148 t = top-stack;
89 maxstack *= 2; 149 maxstack *= 2;
90 stack = (Object *)realloc(stack, maxstack*sizeof(Object)); 150 stack = (Object *)realloc(stack, maxstack*sizeof(Object));
91 if (stack == NULL) 151 if (stack == NULL)
@@ -101,11 +161,22 @@ static void lua_checkstack (Word n)
101*/ 161*/
102static char *lua_strconc (char *l, char *r) 162static char *lua_strconc (char *l, char *r)
103{ 163{
104 static char buffer[1024]; 164 static char *buffer = NULL;
165 static int buffer_size = 0;
105 int n = strlen(l)+strlen(r)+1; 166 int n = strlen(l)+strlen(r)+1;
106 if (n > 1024) 167 if (n > buffer_size)
107 lua_error ("string too large"); 168 {
108 return strcat(strcpy(buffer,l),r); 169 buffer_size = n;
170 if (buffer != NULL)
171 free(buffer);
172 buffer = (char *)malloc(buffer_size);
173 if (buffer == NULL)
174 {
175 buffer_size = 0;
176 lua_error("concat - not enough memory");
177 }
178 }
179 return strcat(strcpy(buffer,l),r);
109} 180}
110 181
111 182
@@ -138,11 +209,11 @@ static int lua_tostring (Object *obj)
138{ 209{
139 static char s[256]; 210 static char s[256];
140 if (tag(obj) != LUA_T_NUMBER) 211 if (tag(obj) != LUA_T_NUMBER)
141 lua_reportbug ("unexpected type at conversion to string"); 212 return 1;
142 if ((int) nvalue(obj) == nvalue(obj)) 213 if ((int) nvalue(obj) == nvalue(obj))
143 sprintf (s, "%d", (int) nvalue(obj)); 214 sprintf (s, "%d", (int) nvalue(obj));
144 else 215 else
145 sprintf (s, "%g", nvalue(obj)); 216 sprintf (s, "%g", nvalue(obj));
146 svalue(obj) = lua_createstring(s); 217 svalue(obj) = lua_createstring(s);
147 if (svalue(obj) == NULL) 218 if (svalue(obj) == NULL)
148 return 1; 219 return 1;
@@ -217,32 +288,35 @@ static void do_call (Object *func, int base, int nResults, int whereRes)
217*/ 288*/
218static void pushsubscript (void) 289static void pushsubscript (void)
219{ 290{
220 Object *h;
221 if (tag(top-2) != LUA_T_ARRAY) 291 if (tag(top-2) != LUA_T_ARRAY)
222 lua_reportbug ("indexed expression not a table"); 292 do_call(&fallBacks[FB_GETTABLE].function, (top-stack)-2, 1, (top-stack)-2);
223 h = lua_hashget (avalue(top-2), top-1); 293 else
224 --top; 294 {
225 *(top-1) = *h; 295 Object *h = lua_hashget(avalue(top-2), top-1);
296 if (h == NULL)
297 do_call(&fallBacks[FB_INDEX].function, (top-stack)-2, 1, (top-stack)-2);
298 else
299 {
300 --top;
301 *(top-1) = *h;
302 }
303 }
226} 304}
227 305
228 306
229/* 307/*
230** Function to store indexed based on values at the top 308** Function to store indexed based on values at the top
231*/ 309*/
232int lua_storesubscript (void) 310static void storesubscript (void)
233{ 311{
234 if (tag(top-3) != LUA_T_ARRAY) 312 if (tag(top-3) != LUA_T_ARRAY)
235 { 313 do_call(&fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3);
236 lua_reportbug ("indexed expression not a table"); 314 else
237 return 1;
238 }
239 { 315 {
240 Object *h = lua_hashdefine (avalue(top-3), top-2); 316 Object *h = lua_hashdefine (avalue(top-3), top-2);
241 if (h == NULL) return 1;
242 *h = *(top-1); 317 *h = *(top-1);
318 top -= 3;
243 } 319 }
244 top -= 3;
245 return 0;
246} 320}
247 321
248 322
@@ -273,10 +347,12 @@ static int do_protectedrun (Object *function, int nResults)
273 { 347 {
274 if (function == NULL) 348 if (function == NULL)
275 { 349 {
350 tag(&f) = LUA_T_FUNCTION;
351 bvalue(&f) = lua_parse();
276 function = &f; 352 function = &f;
277 tag(function) = LUA_T_FUNCTION;
278 bvalue(function) = lua_parse();
279 } 353 }
354 else
355 tag(&f) = LUA_T_NIL;
280 do_call(function, CBase, nResults, CBase); 356 do_call(function, CBase, nResults, CBase);
281 CnResults = (top-stack) - CBase; /* number of results */ 357 CnResults = (top-stack) - CBase; /* number of results */
282 CBase += CnResults; /* incorporate results on the stack */ 358 CBase += CnResults; /* incorporate results on the stack */
@@ -288,6 +364,8 @@ static int do_protectedrun (Object *function, int nResults)
288 top = stack+CBase; 364 top = stack+CBase;
289 status = 1; 365 status = 1;
290 } 366 }
367 if (tag(&f) == LUA_T_FUNCTION)
368 free(bvalue(&f));
291 errorJmp = oldErr; 369 errorJmp = oldErr;
292 return status; 370 return status;
293} 371}
@@ -402,16 +480,6 @@ void *lua_getuserdata (Object *object)
402} 480}
403 481
404/* 482/*
405** Given an object handle, return its table. On error, return NULL.
406*/
407void *lua_gettable (Object *object)
408{
409 if (object == NULL) return NULL;
410 if (tag(object) != LUA_T_ARRAY) return NULL;
411 else return (avalue(object));
412}
413
414/*
415** Get a global object. Return the object handle or NULL on error. 483** Get a global object. Return the object handle or NULL on error.
416*/ 484*/
417Object *lua_getglobal (char *name) 485Object *lua_getglobal (char *name)
@@ -473,16 +541,6 @@ int lua_pushuserdata (void *u)
473} 541}
474 542
475/* 543/*
476** Push an object (tag=userdata) to stack. Return 0 on success or 1 on error.
477*/
478int lua_pushtable (void *t)
479{
480 lua_checkstack(top-stack+1);
481 tag(top) = LUA_T_ARRAY; avalue(top++) = t;
482 return 0;
483}
484
485/*
486** Push an object to stack. 544** Push an object to stack.
487*/ 545*/
488int lua_pushobject (Object *o) 546int lua_pushobject (Object *o)
@@ -557,6 +615,35 @@ int lua_type (lua_Object o)
557} 615}
558 616
559 617
618static void call_arith (char *op)
619{
620 lua_pushstring(op);
621 do_call(&fallBacks[FB_ARITH].function, (top-stack)-3, 1, (top-stack)-3);
622}
623
624static void comparison (lua_Type tag_less, lua_Type tag_equal,
625 lua_Type tag_great, char *op)
626{
627 Object *l = top-2;
628 Object *r = top-1;
629 int result;
630 if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER)
631 result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
632 else if (tostring(l) || tostring(r))
633 {
634 lua_pushstring(op);
635 do_call(&fallBacks[FB_ORDER].function, (top-stack)-3, 1, (top-stack)-3);
636 return;
637 }
638 else
639 result = strcmp(svalue(l), svalue(r));
640 top--;
641 nvalue(top-1) = 1;
642 tag(top-1) = (result < 0) ? tag_less : (result == 0) ? tag_equal : tag_great;
643}
644
645
646
560/* 647/*
561** Execute the given opcode, until a RET. Parameters are between 648** Execute the given opcode, until a RET. Parameters are between
562** [stack+base,top). Returns n such that the the results are between 649** [stack+base,top). Returns n such that the the results are between
@@ -656,23 +743,26 @@ static int lua_execute (Byte *pc, int base)
656 break; 743 break;
657 744
658 case STOREINDEXED0: 745 case STOREINDEXED0:
659 { 746 storesubscript();
660 int s = lua_storesubscript(); 747 break;
661 if (s == 1) return 1;
662 }
663 break;
664 748
665 case STOREINDEXED: 749 case STOREINDEXED:
666 { 750 {
667 int n = *pc++; 751 int n = *pc++;
668 if (tag(top-3-n) != LUA_T_ARRAY) 752 if (tag(top-3-n) != LUA_T_ARRAY)
669 lua_reportbug ("indexed expression not a table"); 753 {
754 *(top+1) = *(top-1);
755 *(top) = *(top-2-n);
756 *(top-1) = *(top-3-n);
757 top += 2;
758 do_call(&fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3);
759 }
760 else
670 { 761 {
671 Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); 762 Object *h = lua_hashdefine (avalue(top-3-n), top-2-n);
672 if (h == NULL) return 1;
673 *h = *(top-1); 763 *h = *(top-1);
764 top--;
674 } 765 }
675 top--;
676 } 766 }
677 break; 767 break;
678 768
@@ -766,48 +856,33 @@ static int lua_execute (Byte *pc, int base)
766 } 856 }
767 break; 857 break;
768 858
769 case LTOP: 859 case LTOP:
770 { 860 comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, "<");
771 Object *l = top-2; 861 break;
772 Object *r = top-1;
773 --top;
774 if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER)
775 tag(top-1) = (nvalue(l) < nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL;
776 else
777 {
778 if (tostring(l) || tostring(r))
779 return 1;
780 tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? LUA_T_NUMBER : LUA_T_NIL;
781 }
782 nvalue(top-1) = 1;
783 }
784 break;
785 862
786 case LEOP: 863 case LEOP:
787 { 864 comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, "<=");
788 Object *l = top-2; 865 break;
789 Object *r = top-1; 866
790 --top; 867 case GTOP:
791 if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) 868 comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, ">");
792 tag(top-1) = (nvalue(l) <= nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; 869 break;
793 else 870
794 { 871 case GEOP:
795 if (tostring(l) || tostring(r)) 872 comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, ">=");
796 return 1; 873 break;
797 tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? LUA_T_NUMBER : LUA_T_NIL;
798 }
799 nvalue(top-1) = 1;
800 }
801 break;
802 874
803 case ADDOP: 875 case ADDOP:
804 { 876 {
805 Object *l = top-2; 877 Object *l = top-2;
806 Object *r = top-1; 878 Object *r = top-1;
807 if (tonumber(r) || tonumber(l)) 879 if (tonumber(r) || tonumber(l))
808 return 1; 880 call_arith("+");
809 nvalue(l) += nvalue(r); 881 else
810 --top; 882 {
883 nvalue(l) += nvalue(r);
884 --top;
885 }
811 } 886 }
812 break; 887 break;
813 888
@@ -816,9 +891,12 @@ static int lua_execute (Byte *pc, int base)
816 Object *l = top-2; 891 Object *l = top-2;
817 Object *r = top-1; 892 Object *r = top-1;
818 if (tonumber(r) || tonumber(l)) 893 if (tonumber(r) || tonumber(l))
819 return 1; 894 call_arith("-");
820 nvalue(l) -= nvalue(r); 895 else
821 --top; 896 {
897 nvalue(l) -= nvalue(r);
898 --top;
899 }
822 } 900 }
823 break; 901 break;
824 902
@@ -827,9 +905,12 @@ static int lua_execute (Byte *pc, int base)
827 Object *l = top-2; 905 Object *l = top-2;
828 Object *r = top-1; 906 Object *r = top-1;
829 if (tonumber(r) || tonumber(l)) 907 if (tonumber(r) || tonumber(l))
830 return 1; 908 call_arith("*");
831 nvalue(l) *= nvalue(r); 909 else
832 --top; 910 {
911 nvalue(l) *= nvalue(r);
912 --top;
913 }
833 } 914 }
834 break; 915 break;
835 916
@@ -838,9 +919,12 @@ static int lua_execute (Byte *pc, int base)
838 Object *l = top-2; 919 Object *l = top-2;
839 Object *r = top-1; 920 Object *r = top-1;
840 if (tonumber(r) || tonumber(l)) 921 if (tonumber(r) || tonumber(l))
841 return 1; 922 call_arith("/");
842 nvalue(l) /= nvalue(r); 923 else
843 --top; 924 {
925 nvalue(l) /= nvalue(r);
926 --top;
927 }
844 } 928 }
845 break; 929 break;
846 930
@@ -849,9 +933,12 @@ static int lua_execute (Byte *pc, int base)
849 Object *l = top-2; 933 Object *l = top-2;
850 Object *r = top-1; 934 Object *r = top-1;
851 if (tonumber(r) || tonumber(l)) 935 if (tonumber(r) || tonumber(l))
852 return 1; 936 call_arith("^");
853 nvalue(l) = pow(nvalue(l), nvalue(r)); 937 else
854 --top; 938 {
939 nvalue(l) = pow(nvalue(l), nvalue(r));
940 --top;
941 }
855 } 942 }
856 break; 943 break;
857 944
@@ -860,22 +947,24 @@ static int lua_execute (Byte *pc, int base)
860 Object *l = top-2; 947 Object *l = top-2;
861 Object *r = top-1; 948 Object *r = top-1;
862 if (tostring(r) || tostring(l)) 949 if (tostring(r) || tostring(l))
863 return 1; 950 do_call(&fallBacks[FB_CONCAT].function, (top-stack)-2, 1, (top-stack)-2);
864 svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); 951 else
865 if (svalue(l) == NULL) 952 {
866 return 1; 953 svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r)));
867 --top; 954 --top;
955 }
868 } 956 }
869 break; 957 break;
870 958
871 case MINUSOP: 959 case MINUSOP:
872 if (tonumber(top-1)) 960 if (tonumber(top-1))
873 return 1; 961 do_call(&fallBacks[FB_UNMINUS].function, (top-stack)-1, 1, (top-stack)-1);
874 nvalue(top-1) = - nvalue(top-1); 962 else
963 nvalue(top-1) = - nvalue(top-1);
875 break; 964 break;
876 965
877 case NOTOP: 966 case NOTOP:
878 tag(top-1) = tag(top-1) == LUA_T_NIL ? LUA_T_NUMBER : LUA_T_NIL; 967 tag(top-1) = (tag(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
879 break; 968 break;
880 969
881 case ONTJMP: 970 case ONTJMP:
@@ -952,8 +1041,7 @@ static int lua_execute (Byte *pc, int base)
952 CodeWord func; 1041 CodeWord func;
953 get_code(file,pc); 1042 get_code(file,pc);
954 get_word(func,pc); 1043 get_word(func,pc);
955 if (lua_pushfunction ((char *)file.b, func.w)) 1044 lua_pushfunction ((char *)file.b, func.w);
956 return 1;
957 } 1045 }
958 break; 1046 break;
959 1047
@@ -971,7 +1059,6 @@ static int lua_execute (Byte *pc, int base)
971 1059
972 default: 1060 default:
973 lua_error ("internal error - opcode doesn't match"); 1061 lua_error ("internal error - opcode doesn't match");
974 return 1;
975 } 1062 }
976 } 1063 }
977} 1064}