diff options
Diffstat (limited to 'opcode.c')
-rw-r--r-- | opcode.c | 131 |
1 files changed, 73 insertions, 58 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 1.4 1994/04/13 21:37:20 celes Exp celes $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 2.1 1994/04/20 22:07:57 celes Exp celes $"; |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
@@ -23,43 +23,71 @@ char *rcs_opcode="$Id: opcode.c,v 1.4 1994/04/13 21:37:20 celes Exp celes $"; | |||
23 | #define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0)) | 23 | #define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0)) |
24 | #define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0)) | 24 | #define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0)) |
25 | 25 | ||
26 | #ifndef MAXSTACK | 26 | |
27 | #define MAXSTACK 256 | 27 | #define STACK_BUFFER (STACKGAP+128) |
28 | #endif | 28 | |
29 | static Object stack[MAXSTACK] = {{T_MARK, {NULL}}}; | 29 | static Word maxstack; |
30 | static Object *top=stack+1, *base=stack+1; | 30 | static Object *stack=NULL; |
31 | static Object *top, *base; | ||
31 | 32 | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | ** Concatenate two given string, creating a mark space at the beginning. | 35 | ** Init stack |
35 | ** Return the new string pointer. | ||
36 | */ | 36 | */ |
37 | static char *lua_strconc (char *l, char *r) | 37 | static int lua_initstack (void) |
38 | { | 38 | { |
39 | char *s = calloc (strlen(l)+strlen(r)+2, sizeof(char)); | 39 | maxstack = STACK_BUFFER; |
40 | if (s == NULL) | 40 | stack = (Object *)calloc(maxstack, sizeof(Object)); |
41 | if (stack == NULL) | ||
41 | { | 42 | { |
42 | lua_error ("not enough memory"); | 43 | lua_error("stack - not enough memory"); |
43 | return NULL; | 44 | return 1; |
44 | } | 45 | } |
45 | *s++ = 0; /* create mark space */ | 46 | tag(stack) = T_MARK; |
46 | return strcat(strcpy(s,l),r); | 47 | top = base = stack+1; |
48 | return 0; | ||
47 | } | 49 | } |
48 | 50 | ||
51 | |||
49 | /* | 52 | /* |
50 | ** Duplicate a string, creating a mark space at the beginning. | 53 | ** Check stack overflow and, if necessary, realloc vector |
54 | */ | ||
55 | static int lua_checkstack (Word n) | ||
56 | { | ||
57 | if (stack == NULL) | ||
58 | return lua_initstack(); | ||
59 | if (n > maxstack) | ||
60 | { | ||
61 | Word t = top-stack; | ||
62 | Word b = base-stack; | ||
63 | maxstack *= 2; | ||
64 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); | ||
65 | if (stack == NULL) | ||
66 | { | ||
67 | lua_error("stack - not enough memory"); | ||
68 | return 1; | ||
69 | } | ||
70 | top = stack + t; | ||
71 | base = stack + b; | ||
72 | } | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | |||
77 | /* | ||
78 | ** Concatenate two given string, creating a mark space at the beginning. | ||
51 | ** Return the new string pointer. | 79 | ** Return the new string pointer. |
52 | */ | 80 | */ |
53 | char *lua_strdup (char *l) | 81 | static char *lua_strconc (char *l, char *r) |
54 | { | 82 | { |
55 | char *s = calloc (strlen(l)+2, sizeof(char)); | 83 | static char buffer[1024]; |
56 | if (s == NULL) | 84 | int n = strlen(l)+strlen(r)+1; |
85 | if (n > 1024) | ||
57 | { | 86 | { |
58 | lua_error ("not enough memory"); | 87 | lua_error ("string too large"); |
59 | return NULL; | 88 | return NULL; |
60 | } | 89 | } |
61 | *s++ = 0; /* create mark space */ | 90 | return strcat(strcpy(buffer,l),r); |
62 | return strcpy(s,l); | ||
63 | } | 91 | } |
64 | 92 | ||
65 | /* | 93 | /* |
@@ -127,7 +155,7 @@ static int lua_tostring (Object *obj) | |||
127 | sprintf (s, "%d", (int) nvalue(obj)); | 155 | sprintf (s, "%d", (int) nvalue(obj)); |
128 | else | 156 | else |
129 | sprintf (s, "%g", nvalue(obj)); | 157 | sprintf (s, "%g", nvalue(obj)); |
130 | svalue(obj) = lua_createstring(lua_strdup(s)); | 158 | svalue(obj) = lua_createstring(s); |
131 | if (svalue(obj) == NULL) | 159 | if (svalue(obj) == NULL) |
132 | return 1; | 160 | return 1; |
133 | tag(obj) = T_STRING; | 161 | tag(obj) = T_STRING; |
@@ -140,7 +168,12 @@ static int lua_tostring (Object *obj) | |||
140 | */ | 168 | */ |
141 | int lua_execute (Byte *pc) | 169 | int lua_execute (Byte *pc) |
142 | { | 170 | { |
143 | Object *oldbase = base; | 171 | Word oldbase; |
172 | |||
173 | if (stack == NULL) | ||
174 | lua_initstack(); | ||
175 | |||
176 | oldbase = base-stack; | ||
144 | base = top; | 177 | base = top; |
145 | while (1) | 178 | while (1) |
146 | { | 179 | { |
@@ -516,11 +549,8 @@ int lua_execute (Byte *pc) | |||
516 | nvalue(b) = (base-stack); /* store base value */ | 549 | nvalue(b) = (base-stack); /* store base value */ |
517 | base = b+1; | 550 | base = b+1; |
518 | pc = newpc; | 551 | pc = newpc; |
519 | if (MAXSTACK-(base-stack) < STACKGAP) | 552 | if (lua_checkstack(STACKGAP+(base-stack))) |
520 | { | ||
521 | lua_error ("stack overflow"); | ||
522 | return 1; | 553 | return 1; |
523 | } | ||
524 | } | 554 | } |
525 | else if (tag(b-1) == T_CFUNCTION) | 555 | else if (tag(b-1) == T_CFUNCTION) |
526 | { | 556 | { |
@@ -569,7 +599,7 @@ int lua_execute (Byte *pc) | |||
569 | break; | 599 | break; |
570 | 600 | ||
571 | case HALT: | 601 | case HALT: |
572 | base = oldbase; | 602 | base = stack+oldbase; |
573 | return 0; /* success */ | 603 | return 0; /* success */ |
574 | 604 | ||
575 | case SETFUNCTION: | 605 | case SETFUNCTION: |
@@ -726,7 +756,7 @@ Object *lua_getfield (Object *object, char *field) | |||
726 | { | 756 | { |
727 | Object ref; | 757 | Object ref; |
728 | tag(&ref) = T_STRING; | 758 | tag(&ref) = T_STRING; |
729 | svalue(&ref) = lua_createstring(lua_strdup(field)); | 759 | svalue(&ref) = lua_createstring(field); |
730 | return (lua_hashdefine(avalue(object), &ref)); | 760 | return (lua_hashdefine(avalue(object), &ref)); |
731 | } | 761 | } |
732 | } | 762 | } |
@@ -774,12 +804,9 @@ Object *lua_pop (void) | |||
774 | */ | 804 | */ |
775 | int lua_pushnil (void) | 805 | int lua_pushnil (void) |
776 | { | 806 | { |
777 | if ((top-stack) >= MAXSTACK-1) | 807 | if (lua_checkstack(top-stack+1) == 1) |
778 | { | ||
779 | lua_error ("stack overflow"); | ||
780 | return 1; | 808 | return 1; |
781 | } | 809 | tag(top++) = T_NIL; |
782 | tag(top) = T_NIL; | ||
783 | return 0; | 810 | return 0; |
784 | } | 811 | } |
785 | 812 | ||
@@ -788,11 +815,8 @@ int lua_pushnil (void) | |||
788 | */ | 815 | */ |
789 | int lua_pushnumber (real n) | 816 | int lua_pushnumber (real n) |
790 | { | 817 | { |
791 | if ((top-stack) >= MAXSTACK-1) | 818 | if (lua_checkstack(top-stack+1) == 1) |
792 | { | ||
793 | lua_error ("stack overflow"); | ||
794 | return 1; | 819 | return 1; |
795 | } | ||
796 | tag(top) = T_NUMBER; nvalue(top++) = n; | 820 | tag(top) = T_NUMBER; nvalue(top++) = n; |
797 | return 0; | 821 | return 0; |
798 | } | 822 | } |
@@ -802,13 +826,10 @@ int lua_pushnumber (real n) | |||
802 | */ | 826 | */ |
803 | int lua_pushstring (char *s) | 827 | int lua_pushstring (char *s) |
804 | { | 828 | { |
805 | if ((top-stack) >= MAXSTACK-1) | 829 | if (lua_checkstack(top-stack+1) == 1) |
806 | { | ||
807 | lua_error ("stack overflow"); | ||
808 | return 1; | 830 | return 1; |
809 | } | ||
810 | tag(top) = T_STRING; | 831 | tag(top) = T_STRING; |
811 | svalue(top++) = lua_createstring(lua_strdup(s)); | 832 | svalue(top++) = lua_createstring(s); |
812 | return 0; | 833 | return 0; |
813 | } | 834 | } |
814 | 835 | ||
@@ -817,11 +838,8 @@ int lua_pushstring (char *s) | |||
817 | */ | 838 | */ |
818 | int lua_pushcfunction (lua_CFunction fn) | 839 | int lua_pushcfunction (lua_CFunction fn) |
819 | { | 840 | { |
820 | if ((top-stack) >= MAXSTACK-1) | 841 | if (lua_checkstack(top-stack+1) == 1) |
821 | { | ||
822 | lua_error ("stack overflow"); | ||
823 | return 1; | 842 | return 1; |
824 | } | ||
825 | tag(top) = T_CFUNCTION; fvalue(top++) = fn; | 843 | tag(top) = T_CFUNCTION; fvalue(top++) = fn; |
826 | return 0; | 844 | return 0; |
827 | } | 845 | } |
@@ -831,11 +849,8 @@ int lua_pushcfunction (lua_CFunction fn) | |||
831 | */ | 849 | */ |
832 | int lua_pushuserdata (void *u) | 850 | int lua_pushuserdata (void *u) |
833 | { | 851 | { |
834 | if ((top-stack) >= MAXSTACK-1) | 852 | if (lua_checkstack(top-stack+1) == 1) |
835 | { | ||
836 | lua_error ("stack overflow"); | ||
837 | return 1; | 853 | return 1; |
838 | } | ||
839 | tag(top) = T_USERDATA; uvalue(top++) = u; | 854 | tag(top) = T_USERDATA; uvalue(top++) = u; |
840 | return 0; | 855 | return 0; |
841 | } | 856 | } |
@@ -845,11 +860,8 @@ int lua_pushuserdata (void *u) | |||
845 | */ | 860 | */ |
846 | int lua_pushobject (Object *o) | 861 | int lua_pushobject (Object *o) |
847 | { | 862 | { |
848 | if ((top-stack) >= MAXSTACK-1) | 863 | if (lua_checkstack(top-stack+1) == 1) |
849 | { | ||
850 | lua_error ("stack overflow"); | ||
851 | return 1; | 864 | return 1; |
852 | } | ||
853 | *top++ = *o; | 865 | *top++ = *o; |
854 | return 0; | 866 | return 0; |
855 | } | 867 | } |
@@ -878,7 +890,7 @@ int lua_storefield (lua_Object object, char *field) | |||
878 | { | 890 | { |
879 | Object ref, *h; | 891 | Object ref, *h; |
880 | tag(&ref) = T_STRING; | 892 | tag(&ref) = T_STRING; |
881 | svalue(&ref) = lua_createstring(lua_strdup(field)); | 893 | svalue(&ref) = lua_createstring(field); |
882 | h = lua_hashdefine(avalue(object), &ref); | 894 | h = lua_hashdefine(avalue(object), &ref); |
883 | if (h == NULL) return 1; | 895 | if (h == NULL) return 1; |
884 | if (tag(top-1) == T_MARK) return 1; | 896 | if (tag(top-1) == T_MARK) return 1; |
@@ -963,6 +975,9 @@ int lua_isuserdata (Object *object) | |||
963 | void lua_type (void) | 975 | void lua_type (void) |
964 | { | 976 | { |
965 | Object *o = lua_getparam(1); | 977 | Object *o = lua_getparam(1); |
978 | |||
979 | if (lua_constant == NULL) | ||
980 | lua_initconstant(); | ||
966 | lua_pushstring (lua_constant[tag(o)]); | 981 | lua_pushstring (lua_constant[tag(o)]); |
967 | } | 982 | } |
968 | 983 | ||
@@ -981,7 +996,7 @@ void lua_obj2number (void) | |||
981 | void lua_print (void) | 996 | void lua_print (void) |
982 | { | 997 | { |
983 | int i=1; | 998 | int i=1; |
984 | void *obj; | 999 | Object *obj; |
985 | while ((obj=lua_getparam (i++)) != NULL) | 1000 | while ((obj=lua_getparam (i++)) != NULL) |
986 | { | 1001 | { |
987 | if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj)); | 1002 | if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj)); |