diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-03 15:53:17 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-03 15:53:17 -0300 |
| commit | d1ea38580ae35a3a34e7122c41682af7f9901030 (patch) | |
| tree | ce7fa1568be9eb757805966b77ea1eac2bc604f6 | |
| parent | 3c9d999424520c809e05bee11d81788b488434f6 (diff) | |
| download | lua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.gz lua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.bz2 lua-d1ea38580ae35a3a34e7122c41682af7f9901030.zip | |
change of code generation design (independent functions for each opcode)
Diffstat (limited to '')
| -rw-r--r-- | lcode.c | 223 | ||||
| -rw-r--r-- | lcode.h | 25 | ||||
| -rw-r--r-- | lopcodes.h | 7 | ||||
| -rw-r--r-- | lparser.c | 85 | ||||
| -rw-r--r-- | lparser.h | 28 |
5 files changed, 180 insertions, 188 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.3 2000/03/03 14:58:26 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -20,12 +20,10 @@ void luaK_error (LexState *ls, const char *msg) { | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | static Instruction *last_i (FuncState *fs) { | 23 | static Instruction *last_i (LexState *ls, expdesc *v) { |
| 24 | static Instruction dummy = SET_OPCODE(0, ENDCODE); | 24 | FuncState *fs = ls->fs; |
| 25 | if (fs->last_pc < 0) | 25 | int last_pc = (v->info != NOJUMPS) ? v->info : fs->pc-1; |
| 26 | return &dummy; | 26 | return &fs->f->code[last_pc]; |
| 27 | else | ||
| 28 | return &fs->f->code[fs->last_pc]; | ||
| 29 | } | 27 | } |
| 30 | 28 | ||
| 31 | 29 | ||
| @@ -37,58 +35,64 @@ int luaK_primitivecode (LexState *ls, Instruction i) { | |||
| 37 | } | 35 | } |
| 38 | 36 | ||
| 39 | 37 | ||
| 38 | static void luaK_minus (LexState *ls, expdesc *v) { | ||
| 39 | Instruction *last = last_i(ls, v); | ||
| 40 | switch(GET_OPCODE(*last)) { | ||
| 41 | case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); return; | ||
| 42 | case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); return; | ||
| 43 | case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); return; | ||
| 44 | default: luaK_primitivecode(ls, CREATE_0(MINUSOP)); | ||
| 45 | } | ||
| 46 | } | ||
| 40 | 47 | ||
| 41 | int luaK_code (LexState *ls, Instruction i) { | ||
| 42 | FuncState *fs = ls->fs; | ||
| 43 | Instruction *last = last_i(fs); | ||
| 44 | switch (GET_OPCODE(i)) { | ||
| 45 | |||
| 46 | case MINUSOP: | ||
| 47 | switch(GET_OPCODE(*last)) { | ||
| 48 | case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); break; | ||
| 49 | case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); break; | ||
| 50 | case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); break; | ||
| 51 | default: fs->last_pc = luaK_primitivecode(ls, i); | ||
| 52 | } | ||
| 53 | break; | ||
| 54 | 48 | ||
| 55 | case GETTABLE: | 49 | static void luaK_gettable (LexState *ls, expdesc *v) { |
| 56 | switch(GET_OPCODE(*last)) { | 50 | Instruction *last = last_i(ls, v); |
| 57 | case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break; | 51 | luaK_deltastack(ls, -1); |
| 58 | default: fs->last_pc = luaK_primitivecode(ls, i); | 52 | switch(GET_OPCODE(*last)) { |
| 59 | } | 53 | case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break; |
| 60 | break; | 54 | default: luaK_primitivecode(ls, CREATE_0(GETTABLE)); |
| 55 | } | ||
| 56 | } | ||
| 61 | 57 | ||
| 62 | case RETCODE: | ||
| 63 | switch(GET_OPCODE(*last)) { | ||
| 64 | case CALL: | ||
| 65 | *last = SET_OPCODE(*last, TAILCALL); | ||
| 66 | *last = SETARG_B(*last, GETARG_U(i)); | ||
| 67 | break; | ||
| 68 | default: fs->last_pc = luaK_primitivecode(ls, i); | ||
| 69 | } | ||
| 70 | break; | ||
| 71 | 58 | ||
| 72 | case ADDOP: | 59 | static void luaK_add (LexState *ls, expdesc *v) { |
| 73 | switch(GET_OPCODE(*last)) { | 60 | Instruction *last = last_i(ls, v); |
| 74 | case PUSHINT: *last = SET_OPCODE(*last, ADDI); break; | 61 | luaK_deltastack(ls, -1); |
| 75 | default: fs->last_pc = luaK_primitivecode(ls, i); | 62 | switch(GET_OPCODE(*last)) { |
| 76 | } | 63 | case PUSHINT: *last = SET_OPCODE(*last, ADDI); break; |
| 77 | break; | 64 | default: luaK_primitivecode(ls, CREATE_0(ADDOP)); |
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 78 | 68 | ||
| 79 | case SUBOP: | 69 | static void luaK_sub (LexState *ls, expdesc *v) { |
| 80 | switch(GET_OPCODE(*last)) { | 70 | Instruction *last = last_i(ls, v); |
| 81 | case PUSHINT: | 71 | luaK_deltastack(ls, -1); |
| 82 | *last = SET_OPCODE(*last, ADDI); | 72 | switch(GET_OPCODE(*last)) { |
| 83 | *last = SETARG_S(*last, -GETARG_S(*last)); | 73 | case PUSHINT: |
| 84 | break; | 74 | *last = SET_OPCODE(*last, ADDI); |
| 85 | default: fs->last_pc = luaK_primitivecode(ls, i); | 75 | *last = SETARG_S(*last, -GETARG_S(*last)); |
| 86 | } | ||
| 87 | break; | 76 | break; |
| 77 | default: luaK_primitivecode(ls, CREATE_0(SUBOP)); | ||
| 78 | } | ||
| 79 | } | ||
| 88 | 80 | ||
| 89 | default: fs->last_pc = luaK_primitivecode(ls, i); | 81 | |
| 82 | void luaK_retcode (LexState *ls, int nlocals, listdesc *e) { | ||
| 83 | if (e->n > 0 && luaK_iscall(ls, e->info)) { | ||
| 84 | Instruction *last = &ls->fs->f->code[ls->fs->pc-1]; | ||
| 85 | *last = SET_OPCODE(*last, TAILCALL); | ||
| 86 | *last = SETARG_B(*last, nlocals); | ||
| 90 | } | 87 | } |
| 91 | return fs->last_pc; | 88 | else |
| 89 | luaK_U(ls, RETCODE, nlocals, 0); | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 93 | int luaK_code (LexState *ls, Instruction i, int delta) { | ||
| 94 | luaK_deltastack(ls, delta); | ||
| 95 | return luaK_primitivecode(ls, i); | ||
| 92 | } | 96 | } |
| 93 | 97 | ||
| 94 | 98 | ||
| @@ -97,7 +101,6 @@ void luaK_fixjump (LexState *ls, int pc, int dest) { | |||
| 97 | Instruction *jmp = &fs->f->code[pc]; | 101 | Instruction *jmp = &fs->f->code[pc]; |
| 98 | /* jump is relative to position following jump instruction */ | 102 | /* jump is relative to position following jump instruction */ |
| 99 | *jmp = SETARG_S(*jmp, dest-(pc+1)); | 103 | *jmp = SETARG_S(*jmp, dest-(pc+1)); |
| 100 | fs->last_pc = pc; | ||
| 101 | } | 104 | } |
| 102 | 105 | ||
| 103 | 106 | ||
| @@ -112,38 +115,8 @@ void luaK_deltastack (LexState *ls, int delta) { | |||
| 112 | } | 115 | } |
| 113 | 116 | ||
| 114 | 117 | ||
| 115 | static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { | 118 | void luaK_kstr (LexState *ls, int c) { |
| 116 | luaK_deltastack(ls, delta); | 119 | luaK_U(ls, PUSHSTRING, c, 1); |
| 117 | return luaK_code(ls, SET_OPCODE(i, op)); | ||
| 118 | } | ||
| 119 | |||
| 120 | |||
| 121 | int luaK_0 (LexState *ls, OpCode op, int delta) { | ||
| 122 | return aux_code(ls, op, 0, delta); | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | int luaK_U (LexState *ls, OpCode op, int u, int delta) { | ||
| 127 | Instruction i = SETARG_U(0, u); | ||
| 128 | return aux_code(ls, op, i, delta); | ||
| 129 | } | ||
| 130 | |||
| 131 | |||
| 132 | int luaK_S (LexState *ls, OpCode op, int s, int delta) { | ||
| 133 | Instruction i = SETARG_S(0, s); | ||
| 134 | return aux_code(ls, op, i, delta); | ||
| 135 | } | ||
| 136 | |||
| 137 | |||
| 138 | int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta) { | ||
| 139 | Instruction i = SETARG_A(0, a); | ||
| 140 | i = SETARG_B(i, b); | ||
| 141 | return aux_code(ls, op, i, delta); | ||
| 142 | } | ||
| 143 | |||
| 144 | |||
| 145 | int luaK_kstr (LexState *ls, int c) { | ||
| 146 | return luaK_U(ls, PUSHSTRING, c, 1); | ||
| 147 | } | 120 | } |
| 148 | 121 | ||
| 149 | 122 | ||
| @@ -166,37 +139,40 @@ static int real_constant (LexState *ls, real r) { | |||
| 166 | } | 139 | } |
| 167 | 140 | ||
| 168 | 141 | ||
| 169 | int luaK_number (LexState *ls, real f) { | 142 | void luaK_number (LexState *ls, real f) { |
| 170 | if (f <= (real)MAXARG_S && (int)f == f) | 143 | if (f <= (real)MAXARG_S && (int)f == f) |
| 171 | return luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ | 144 | luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ |
| 172 | else | 145 | else |
| 173 | return luaK_U(ls, PUSHNUM, real_constant(ls, f), 1); | 146 | luaK_U(ls, PUSHNUM, real_constant(ls, f), 1); |
| 174 | } | 147 | } |
| 175 | 148 | ||
| 176 | 149 | ||
| 177 | int luaK_adjuststack (LexState *ls, int n) { | 150 | void luaK_adjuststack (LexState *ls, int n) { |
| 178 | if (n > 0) | 151 | if (n > 0) |
| 179 | return luaK_U(ls, POP, n, -n); | 152 | luaK_U(ls, POP, n, -n); |
| 180 | else if (n < 0) | 153 | else if (n < 0) |
| 181 | return luaK_U(ls, PUSHNIL, (-n)-1, -n); | 154 | luaK_U(ls, PUSHNIL, (-n)-1, -n); |
| 182 | else return 0; | ||
| 183 | } | 155 | } |
| 184 | 156 | ||
| 185 | 157 | ||
| 186 | int luaK_iscall (LexState *ls, int pc) { | 158 | int luaK_iscall (LexState *ls, int hasjumps) { |
| 187 | return (GET_OPCODE(ls->fs->f->code[pc]) == CALL); | 159 | if (hasjumps) return 0; /* a call cannot have internal jumps */ |
| 160 | else /* check whether last instruction is a function call */ | ||
| 161 | return (GET_OPCODE(ls->fs->f->code[ls->fs->pc-1]) == CALL); | ||
| 188 | } | 162 | } |
| 189 | 163 | ||
| 190 | 164 | ||
| 191 | void luaK_setcallreturns (LexState *ls, int pc, int nresults) { | 165 | void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults) { |
| 192 | if (luaK_iscall(ls, pc)) { /* expression is a function call? */ | 166 | if (!hasjumps) { /* if `hasjumps' cannot be a function call */ |
| 193 | Instruction *i = &ls->fs->f->code[pc]; | 167 | Instruction *i = &ls->fs->f->code[ls->fs->pc-1]; |
| 194 | int old_nresults = GETARG_B(*i); | 168 | if (GET_OPCODE(*i) == CALL) { /* expression is a function call? */ |
| 195 | if (old_nresults != MULT_RET) | 169 | int old_nresults = GETARG_B(*i); |
| 196 | luaK_deltastack(ls, -old_nresults); /* pop old nresults */ | 170 | if (old_nresults != MULT_RET) |
| 197 | *i = SETARG_B(*i, nresults); /* set nresults */ | 171 | luaK_deltastack(ls, -old_nresults); /* pop old nresults */ |
| 198 | if (nresults != MULT_RET) | 172 | *i = SETARG_B(*i, nresults); /* set nresults */ |
| 199 | luaK_deltastack(ls, nresults); /* push results */ | 173 | if (nresults != MULT_RET) |
| 174 | luaK_deltastack(ls, nresults); /* push results */ | ||
| 175 | } | ||
| 200 | } | 176 | } |
| 201 | } | 177 | } |
| 202 | 178 | ||
| @@ -209,20 +185,21 @@ static void assertglobal (LexState *ls, int index) { | |||
| 209 | void luaK_2stack (LexState *ls, expdesc *var) { | 185 | void luaK_2stack (LexState *ls, expdesc *var) { |
| 210 | switch (var->k) { | 186 | switch (var->k) { |
| 211 | case VLOCAL: | 187 | case VLOCAL: |
| 212 | var->info = luaK_U(ls, PUSHLOCAL, var->info, 1); | 188 | luaK_U(ls, PUSHLOCAL, var->info, 1); |
| 213 | break; | 189 | break; |
| 214 | case VGLOBAL: | 190 | case VGLOBAL: |
| 191 | luaK_U(ls, GETGLOBAL, var->info, 1); | ||
| 215 | assertglobal(ls, var->info); /* make sure that there is a global */ | 192 | assertglobal(ls, var->info); /* make sure that there is a global */ |
| 216 | var->info = luaK_U(ls, GETGLOBAL, var->info, 1); | ||
| 217 | break; | 193 | break; |
| 218 | case VINDEXED: | 194 | case VINDEXED: |
| 219 | var->info = luaK_0(ls, GETTABLE, -1); | 195 | luaK_gettable(ls, var); |
| 220 | break; | 196 | break; |
| 221 | case VEXP: | 197 | case VEXP: |
| 222 | luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */ | 198 | luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */ |
| 223 | break; | 199 | return; /* does not change var->info */ |
| 224 | } | 200 | } |
| 225 | var->k = VEXP; | 201 | var->k = VEXP; |
| 202 | var->info = NOJUMPS; | ||
| 226 | } | 203 | } |
| 227 | 204 | ||
| 228 | 205 | ||
| @@ -246,10 +223,9 @@ void luaK_storevar (LexState *ls, const expdesc *var) { | |||
| 246 | 223 | ||
| 247 | void luaK_prefix (LexState *ls, int op, expdesc *v) { | 224 | void luaK_prefix (LexState *ls, int op, expdesc *v) { |
| 248 | luaK_2stack(ls, v); | 225 | luaK_2stack(ls, v); |
| 249 | if (op == '-') | 226 | if (op == '-') luaK_minus(ls, v); |
| 250 | v->info = luaK_0(ls, MINUSOP, 0); | 227 | else luaK_0(ls, NOTOP, 0); |
| 251 | else | 228 | v->info = NOJUMPS; |
| 252 | v->info = luaK_0(ls, NOTOP, 0); | ||
| 253 | } | 229 | } |
| 254 | 230 | ||
| 255 | 231 | ||
| @@ -267,19 +243,20 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { | |||
| 267 | switch (op) { | 243 | switch (op) { |
| 268 | case AND: case OR: | 244 | case AND: case OR: |
| 269 | luaK_fixjump(ls, v1->info, ls->fs->pc); | 245 | luaK_fixjump(ls, v1->info, ls->fs->pc); |
| 270 | break; | 246 | return; /* keep v1->info != NOJUMPS */ |
| 271 | case '+': v1->info = luaK_0(ls, ADDOP, -1); break; | 247 | case '+': luaK_add(ls, v2); break; |
| 272 | case '-': v1->info = luaK_0(ls, SUBOP, -1); break; | 248 | case '-': luaK_sub(ls, v2); break; |
| 273 | case '*': v1->info = luaK_0(ls, MULTOP, -1); break; | 249 | case '*': luaK_0(ls, MULTOP, -1); break; |
| 274 | case '/': v1->info = luaK_0(ls, DIVOP, -1); break; | 250 | case '/': luaK_0(ls, DIVOP, -1); break; |
| 275 | case '^': v1->info = luaK_0(ls, POWOP, -1); break; | 251 | case '^': luaK_0(ls, POWOP, -1); break; |
| 276 | case CONC: v1->info = luaK_0(ls, CONCOP, -1); break; | 252 | case CONC: luaK_0(ls, CONCOP, -1); break; |
| 277 | case EQ: v1->info = luaK_0(ls, EQOP, -1); break; | 253 | case EQ: luaK_0(ls, EQOP, -1); break; |
| 278 | case NE: v1->info = luaK_0(ls, NEQOP, -1); break; | 254 | case NE: luaK_0(ls, NEQOP, -1); break; |
| 279 | case '>': v1->info = luaK_0(ls, GTOP, -1); break; | 255 | case '>': luaK_0(ls, GTOP, -1); break; |
| 280 | case '<': v1->info = luaK_0(ls, LTOP, -1); break; | 256 | case '<': luaK_0(ls, LTOP, -1); break; |
| 281 | case GE: v1->info = luaK_0(ls, GEOP, -1); break; | 257 | case GE: luaK_0(ls, GEOP, -1); break; |
| 282 | case LE: v1->info = luaK_0(ls, LEOP, -1); break; | 258 | case LE: luaK_0(ls, LEOP, -1); break; |
| 283 | } | 259 | } |
| 260 | v1->info = NOJUMPS; | ||
| 284 | } | 261 | } |
| 285 | 262 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.h,v 1.1 2000/02/22 13:31:19 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -13,20 +13,23 @@ | |||
| 13 | #include "lparser.h" | 13 | #include "lparser.h" |
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | #define luaK_0(ls,o,d) luaK_code(ls, CREATE_0(o), d) | ||
| 17 | #define luaK_U(ls,o,u,d) luaK_code(ls, CREATE_U(o,u), d) | ||
| 18 | #define luaK_S(ls,o,s,d) luaK_code(ls, CREATE_S(o,s), d) | ||
| 19 | #define luaK_AB(ls,o,a,b,d) luaK_code(ls, CREATE_AB(o,a,b), d) | ||
| 20 | |||
| 21 | |||
| 16 | void luaK_error (LexState *ls, const char *msg); | 22 | void luaK_error (LexState *ls, const char *msg); |
| 17 | int luaK_primitivecode (LexState *ls, Instruction i); | 23 | int luaK_primitivecode (LexState *ls, Instruction i); |
| 18 | int luaK_code (LexState *ls, Instruction i); | 24 | int luaK_code (LexState *ls, Instruction i, int delta); |
| 25 | void luaK_retcode (LexState *ls, int nlocals, listdesc *e); | ||
| 19 | void luaK_fixjump (LexState *ls, int pc, int dest); | 26 | void luaK_fixjump (LexState *ls, int pc, int dest); |
| 20 | void luaK_deltastack (LexState *ls, int delta); | 27 | void luaK_deltastack (LexState *ls, int delta); |
| 21 | int luaK_0 (LexState *ls, OpCode op, int delta); | 28 | void luaK_kstr (LexState *ls, int c); |
| 22 | int luaK_U (LexState *ls, OpCode op, int u, int delta); | 29 | void luaK_number (LexState *ls, real f); |
| 23 | int luaK_S (LexState *ls, OpCode op, int s, int delta); | 30 | void luaK_adjuststack (LexState *ls, int n); |
| 24 | int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta); | 31 | int luaK_iscall (LexState *ls, int hasjumps); |
| 25 | int luaK_kstr (LexState *ls, int c); | 32 | void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults); |
| 26 | int luaK_number (LexState *ls, real f); | ||
| 27 | int luaK_adjuststack (LexState *ls, int n); | ||
| 28 | int luaK_iscall (LexState *ls, int pc); | ||
| 29 | void luaK_setcallreturns (LexState *ls, int pc, int nresults); | ||
| 30 | void luaK_2stack (LexState *ls, expdesc *var); | 33 | void luaK_2stack (LexState *ls, expdesc *var); |
| 31 | void luaK_storevar (LexState *ls, const expdesc *var); | 34 | void luaK_storevar (LexState *ls, const expdesc *var); |
| 32 | void luaK_prefix (LexState *ls, int op, expdesc *v); | 35 | void luaK_prefix (LexState *ls, int op, expdesc *v); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.42 2000/03/02 12:32:53 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.43 2000/03/03 14:58:26 roberto Exp roberto $ |
| 3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -47,6 +47,11 @@ | |||
| 47 | #define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16)) | 47 | #define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16)) |
| 48 | #define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8)) | 48 | #define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8)) |
| 49 | 49 | ||
| 50 | #define CREATE_0(o) ((Instruction)(o)) | ||
| 51 | #define CREATE_U(o,u) ((Instruction)(o) | (Instruction)(u)<<8) | ||
| 52 | #define CREATE_S(o,s) ((Instruction)(o) | ((Instruction)(s)+EXCESS_S)<<8) | ||
| 53 | #define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<16) \ | ||
| 54 | | ((Instruction)(b)<<8)) | ||
| 50 | 55 | ||
| 51 | 56 | ||
| 52 | /* | 57 | /* |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.61 2000/03/03 12:33:59 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.62 2000/03/03 14:58:26 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,15 +23,13 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | ** Expression List descriptor: | 26 | ** check whether arbitrary limits fit in respective opcode types |
| 27 | ** tells number of expressions in the list, | ||
| 28 | ** and, if last expression is open (a function call), | ||
| 29 | ** where is the call pc index. | ||
| 30 | */ | 27 | */ |
| 31 | typedef struct listdesc { | 28 | #if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \ |
| 32 | int n; | 29 | MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B |
| 33 | int pc; /* 0 if last expression is closed */ | 30 | #error invalid limits |
| 34 | } listdesc; | 31 | #endif |
| 32 | |||
| 35 | 33 | ||
| 36 | 34 | ||
| 37 | /* | 35 | /* |
| @@ -51,11 +49,11 @@ typedef struct constdesc { | |||
| 51 | /* | 49 | /* |
| 52 | ** prototypes for recursive non-terminal functions | 50 | ** prototypes for recursive non-terminal functions |
| 53 | */ | 51 | */ |
| 54 | static int body (LexState *ls, int needself, int line); | 52 | static void body (LexState *ls, int needself, int line); |
| 55 | static void chunk (LexState *ls); | 53 | static void chunk (LexState *ls); |
| 56 | static int constructor (LexState *ls); | 54 | static void constructor (LexState *ls); |
| 57 | static void expr (LexState *ls, expdesc *v); | 55 | static void expr (LexState *ls, expdesc *v); |
| 58 | static void exp1 (LexState *ls); | 56 | static int exp1 (LexState *ls); |
| 59 | 57 | ||
| 60 | 58 | ||
| 61 | static void next (LexState *ls) { | 59 | static void next (LexState *ls) { |
| @@ -145,8 +143,8 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) { | |||
| 145 | } | 143 | } |
| 146 | 144 | ||
| 147 | 145 | ||
| 148 | static int code_string (LexState *ls, TaggedString *s) { | 146 | static void code_string (LexState *ls, TaggedString *s) { |
| 149 | return luaK_kstr(ls, string_constant(ls, ls->fs, s)); | 147 | luaK_kstr(ls, string_constant(ls, ls->fs, s)); |
| 150 | } | 148 | } |
| 151 | 149 | ||
| 152 | 150 | ||
| @@ -249,18 +247,18 @@ static int indexupvalue (LexState *ls, TaggedString *n) { | |||
| 249 | } | 247 | } |
| 250 | 248 | ||
| 251 | 249 | ||
| 252 | static int pushupvalue (LexState *ls, TaggedString *n) { | 250 | static void pushupvalue (LexState *ls, TaggedString *n) { |
| 253 | if (ls->fs->prev == NULL) | 251 | if (ls->fs->prev == NULL) |
| 254 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | 252 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); |
| 255 | if (aux_localname(ls->fs, n) >= 0) | 253 | if (aux_localname(ls->fs, n) >= 0) |
| 256 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | 254 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); |
| 257 | return luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); | 255 | luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); |
| 258 | } | 256 | } |
| 259 | 257 | ||
| 260 | 258 | ||
| 261 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | 259 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { |
| 262 | int diff = d->n - nvars; | 260 | int diff = d->n - nvars; |
| 263 | if (d->n == 0 || !luaK_iscall(ls, d->pc)) { /* list is empty or closed */ | 261 | if (d->n == 0 || !luaK_iscall(ls, d->info)) { /* list is empty or closed */ |
| 264 | /* push or pop eventual difference between list lengths */ | 262 | /* push or pop eventual difference between list lengths */ |
| 265 | luaK_adjuststack(ls, diff); | 263 | luaK_adjuststack(ls, diff); |
| 266 | } | 264 | } |
| @@ -268,10 +266,10 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | |||
| 268 | diff--; /* do not count function call itself */ | 266 | diff--; /* do not count function call itself */ |
| 269 | if (diff <= 0) { /* more variables than values? */ | 267 | if (diff <= 0) { /* more variables than values? */ |
| 270 | /* function call must provide extra values */ | 268 | /* function call must provide extra values */ |
| 271 | luaK_setcallreturns(ls, d->pc, -diff); | 269 | luaK_setcallreturns(ls, d->info, -diff); |
| 272 | } | 270 | } |
| 273 | else { /* more values than variables */ | 271 | else { /* more values than variables */ |
| 274 | luaK_setcallreturns(ls, d->pc, 0); /* call should provide no value */ | 272 | luaK_setcallreturns(ls, d->info, 0); /* call should provide no value */ |
| 275 | luaK_adjuststack(ls, diff); /* pop eventual extra values */ | 273 | luaK_adjuststack(ls, diff); /* pop eventual extra values */ |
| 276 | } | 274 | } |
| 277 | } | 275 | } |
| @@ -308,7 +306,7 @@ static int getvarname (LexState *ls, expdesc *var) { | |||
| 308 | } | 306 | } |
| 309 | 307 | ||
| 310 | 308 | ||
| 311 | static int func_onstack (LexState *ls, FuncState *func) { | 309 | static void func_onstack (LexState *ls, FuncState *func) { |
| 312 | TProtoFunc *f = ls->fs->f; | 310 | TProtoFunc *f = ls->fs->f; |
| 313 | int i; | 311 | int i; |
| 314 | for (i=0; i<func->nupvalues; i++) | 312 | for (i=0; i<func->nupvalues; i++) |
| @@ -317,7 +315,7 @@ static int func_onstack (LexState *ls, FuncState *func) { | |||
| 317 | constantEM, MAXARG_A); | 315 | constantEM, MAXARG_A); |
| 318 | f->kproto[f->nkproto++] = func->f; | 316 | f->kproto[f->nkproto++] = func->f; |
| 319 | luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */ | 317 | luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */ |
| 320 | return luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); | 318 | luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); |
| 321 | } | 319 | } |
| 322 | 320 | ||
| 323 | 321 | ||
| @@ -333,7 +331,6 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |||
| 333 | fs->f = f; | 331 | fs->f = f; |
| 334 | f->source = source; | 332 | f->source = source; |
| 335 | fs->pc = 0; | 333 | fs->pc = 0; |
| 336 | fs->last_pc = -1; /* invalid index to signal no last instruction */ | ||
| 337 | f->code = NULL; | 334 | f->code = NULL; |
| 338 | f->maxstacksize = 0; | 335 | f->maxstacksize = 0; |
| 339 | f->numparams = 0; /* default for main chunk */ | 336 | f->numparams = 0; /* default for main chunk */ |
| @@ -395,7 +392,7 @@ static void explist1 (LexState *ls, listdesc *d) { | |||
| 395 | } | 392 | } |
| 396 | luaK_2stack(ls, &v); | 393 | luaK_2stack(ls, &v); |
| 397 | luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ | 394 | luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ |
| 398 | d->pc = v.info; | 395 | d->info = v.info; |
| 399 | } | 396 | } |
| 400 | 397 | ||
| 401 | 398 | ||
| @@ -412,7 +409,7 @@ static void explist (LexState *ls, listdesc *d) { | |||
| 412 | } | 409 | } |
| 413 | 410 | ||
| 414 | 411 | ||
| 415 | static int funcparams (LexState *ls, int slf) { | 412 | static void funcparams (LexState *ls, int slf) { |
| 416 | FuncState *fs = ls->fs; | 413 | FuncState *fs = ls->fs; |
| 417 | int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ | 414 | int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ |
| 418 | switch (ls->token) { | 415 | switch (ls->token) { |
| @@ -443,7 +440,7 @@ static int funcparams (LexState *ls, int slf) { | |||
| 443 | break; | 440 | break; |
| 444 | } | 441 | } |
| 445 | fs->stacksize = slevel; /* call will remove func and params */ | 442 | fs->stacksize = slevel; /* call will remove func and params */ |
| 446 | return luaK_AB(ls, CALL, slevel, 0, 0); | 443 | luaK_AB(ls, CALL, slevel, 0, 0); |
| 447 | } | 444 | } |
| 448 | 445 | ||
| 449 | 446 | ||
| @@ -455,14 +452,15 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
| 455 | luaK_2stack(ls, v); /* `v' must be on stack */ | 452 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 456 | luaK_kstr(ls, checkname(ls)); | 453 | luaK_kstr(ls, checkname(ls)); |
| 457 | v->k = VINDEXED; | 454 | v->k = VINDEXED; |
| 455 | v->info = NOJUMPS; | ||
| 458 | break; | 456 | break; |
| 459 | 457 | ||
| 460 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ | 458 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ |
| 461 | next(ls); | 459 | next(ls); |
| 462 | luaK_2stack(ls, v); /* `v' must be on stack */ | 460 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 463 | exp1(ls); | ||
| 464 | check(ls, ']'); | ||
| 465 | v->k = VINDEXED; | 461 | v->k = VINDEXED; |
| 462 | v->info = exp1(ls); | ||
| 463 | check(ls, ']'); | ||
| 466 | break; | 464 | break; |
| 467 | 465 | ||
| 468 | case ':': { /* var_or_func_tail -> ':' NAME funcparams */ | 466 | case ':': { /* var_or_func_tail -> ':' NAME funcparams */ |
| @@ -471,15 +469,17 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
| 471 | name = checkname(ls); | 469 | name = checkname(ls); |
| 472 | luaK_2stack(ls, v); /* `v' must be on stack */ | 470 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 473 | luaK_U(ls, PUSHSELF, name, 1); | 471 | luaK_U(ls, PUSHSELF, name, 1); |
| 472 | funcparams(ls, 1); | ||
| 474 | v->k = VEXP; | 473 | v->k = VEXP; |
| 475 | v->info = funcparams(ls, 1); | 474 | v->info = NOJUMPS; |
| 476 | break; | 475 | break; |
| 477 | } | 476 | } |
| 478 | 477 | ||
| 479 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ | 478 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ |
| 480 | luaK_2stack(ls, v); /* `v' must be on stack */ | 479 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 480 | funcparams(ls, 0); | ||
| 481 | v->k = VEXP; | 481 | v->k = VEXP; |
| 482 | v->info = funcparams(ls, 0); | 482 | v->info = NOJUMPS; |
| 483 | break; | 483 | break; |
| 484 | 484 | ||
| 485 | default: return; /* should be follow... */ | 485 | default: return; /* should be follow... */ |
| @@ -491,8 +491,9 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
| 491 | static void var_or_func (LexState *ls, expdesc *v) { | 491 | static void var_or_func (LexState *ls, expdesc *v) { |
| 492 | /* var_or_func -> ['%'] NAME var_or_func_tail */ | 492 | /* var_or_func -> ['%'] NAME var_or_func_tail */ |
| 493 | if (optional(ls, '%')) { /* upvalue? */ | 493 | if (optional(ls, '%')) { /* upvalue? */ |
| 494 | pushupvalue(ls, str_checkname(ls)); | ||
| 494 | v->k = VEXP; | 495 | v->k = VEXP; |
| 495 | v->info = pushupvalue(ls, str_checkname(ls)); | 496 | v->info = NOJUMPS; |
| 496 | } | 497 | } |
| 497 | else /* variable name */ | 498 | else /* variable name */ |
| 498 | singlevar(ls, str_checkname(ls), v, 0); | 499 | singlevar(ls, str_checkname(ls), v, 0); |
| @@ -614,7 +615,7 @@ static void constructor_part (LexState *ls, constdesc *cd) { | |||
| 614 | } | 615 | } |
| 615 | 616 | ||
| 616 | 617 | ||
| 617 | static int constructor (LexState *ls) { | 618 | static void constructor (LexState *ls) { |
| 618 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ | 619 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ |
| 619 | int line = ls->linenumber; | 620 | int line = ls->linenumber; |
| 620 | int pc = luaK_U(ls, CREATETABLE, 0, 1); | 621 | int pc = luaK_U(ls, CREATETABLE, 0, 1); |
| @@ -634,7 +635,6 @@ static int constructor (LexState *ls) { | |||
| 634 | check_match(ls, '}', '{', line); | 635 | check_match(ls, '}', '{', line); |
| 635 | /* set initial table size */ | 636 | /* set initial table size */ |
| 636 | ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); | 637 | ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); |
| 637 | return pc; | ||
| 638 | } | 638 | } |
| 639 | 639 | ||
| 640 | /* }====================================================================== */ | 640 | /* }====================================================================== */ |
| @@ -655,28 +655,27 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
| 655 | case NUMBER: { /* simpleexp -> NUMBER */ | 655 | case NUMBER: { /* simpleexp -> NUMBER */ |
| 656 | real r = ls->seminfo.r; | 656 | real r = ls->seminfo.r; |
| 657 | next(ls); | 657 | next(ls); |
| 658 | v->info = luaK_number(ls, r); | 658 | luaK_number(ls, r); |
| 659 | break; | 659 | break; |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | case STRING: /* simpleexp -> STRING */ | 662 | case STRING: /* simpleexp -> STRING */ |
| 663 | /* must use `seminfo' before `next' */ | 663 | code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */ |
| 664 | v->info = code_string(ls, ls->seminfo.ts); | ||
| 665 | next(ls); | 664 | next(ls); |
| 666 | break; | 665 | break; |
| 667 | 666 | ||
| 668 | case NIL: /* simpleexp -> NIL */ | 667 | case NIL: /* simpleexp -> NIL */ |
| 669 | v->info = luaK_adjuststack(ls, -1); | 668 | luaK_adjuststack(ls, -1); |
| 670 | next(ls); | 669 | next(ls); |
| 671 | break; | 670 | break; |
| 672 | 671 | ||
| 673 | case '{': /* simpleexp -> constructor */ | 672 | case '{': /* simpleexp -> constructor */ |
| 674 | v->info = constructor(ls); | 673 | constructor(ls); |
| 675 | break; | 674 | break; |
| 676 | 675 | ||
| 677 | case FUNCTION: /* simpleexp -> FUNCTION body */ | 676 | case FUNCTION: /* simpleexp -> FUNCTION body */ |
| 678 | next(ls); | 677 | next(ls); |
| 679 | v->info = body(ls, 0, ls->linenumber); | 678 | body(ls, 0, ls->linenumber); |
| 680 | break; | 679 | break; |
| 681 | 680 | ||
| 682 | case '(': /* simpleexp -> '(' expr ')' */ | 681 | case '(': /* simpleexp -> '(' expr ')' */ |
| @@ -694,13 +693,15 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
| 694 | return; | 693 | return; |
| 695 | } | 694 | } |
| 696 | v->k = VEXP; | 695 | v->k = VEXP; |
| 696 | v->info = NOJUMPS; | ||
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | 699 | ||
| 700 | static void exp1 (LexState *ls) { | 700 | static int exp1 (LexState *ls) { |
| 701 | expdesc v; | 701 | expdesc v; |
| 702 | expr(ls, &v); | 702 | expr(ls, &v); |
| 703 | luaK_2stack(ls, &v); | 703 | luaK_2stack(ls, &v); |
| 704 | return v.info; | ||
| 704 | } | 705 | } |
| 705 | 706 | ||
| 706 | 707 | ||
| @@ -1052,7 +1053,7 @@ static void parlist (LexState *ls) { | |||
| 1052 | } | 1053 | } |
| 1053 | 1054 | ||
| 1054 | 1055 | ||
| 1055 | static int body (LexState *ls, int needself, int line) { | 1056 | static void body (LexState *ls, int needself, int line) { |
| 1056 | /* body -> '(' parlist ')' chunk END */ | 1057 | /* body -> '(' parlist ')' chunk END */ |
| 1057 | FuncState new_fs; | 1058 | FuncState new_fs; |
| 1058 | init_state(ls, &new_fs, ls->fs->f->source); | 1059 | init_state(ls, &new_fs, ls->fs->f->source); |
| @@ -1065,7 +1066,7 @@ static int body (LexState *ls, int needself, int line) { | |||
| 1065 | chunk(ls); | 1066 | chunk(ls); |
| 1066 | check_match(ls, END, FUNCTION, line); | 1067 | check_match(ls, END, FUNCTION, line); |
| 1067 | close_func(ls); | 1068 | close_func(ls); |
| 1068 | return func_onstack(ls, &new_fs); | 1069 | func_onstack(ls, &new_fs); |
| 1069 | } | 1070 | } |
| 1070 | 1071 | ||
| 1071 | 1072 | ||
| @@ -1076,7 +1077,7 @@ static void ret (LexState *ls) { | |||
| 1076 | check_debugline(ls); | 1077 | check_debugline(ls); |
| 1077 | next(ls); | 1078 | next(ls); |
| 1078 | explist(ls, &e); | 1079 | explist(ls, &e); |
| 1079 | luaK_U(ls, RETCODE, ls->fs->nlocalvar, 0); | 1080 | luaK_retcode(ls, ls->fs->nlocalvar, &e); |
| 1080 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | 1081 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ |
| 1081 | optional(ls, ';'); | 1082 | optional(ls, ';'); |
| 1082 | } | 1083 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.7 2000/03/03 12:33:59 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.8 2000/03/03 14:58:26 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -8,7 +8,6 @@ | |||
| 8 | #define lparser_h | 8 | #define lparser_h |
| 9 | 9 | ||
| 10 | #include "lobject.h" | 10 | #include "lobject.h" |
| 11 | #include "lopcodes.h" | ||
| 12 | #include "lzio.h" | 11 | #include "lzio.h" |
| 13 | 12 | ||
| 14 | 13 | ||
| @@ -42,21 +41,18 @@ | |||
| 42 | #endif | 41 | #endif |
| 43 | 42 | ||
| 44 | 43 | ||
| 45 | #if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \ | ||
| 46 | MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B | ||
| 47 | #error invalid limits | ||
| 48 | #endif | ||
| 49 | |||
| 50 | |||
| 51 | 44 | ||
| 52 | /* | 45 | /* |
| 53 | ** Expression descriptor | 46 | ** Expression descriptor |
| 54 | */ | 47 | */ |
| 48 | |||
| 49 | #define NOJUMPS 0 | ||
| 50 | |||
| 55 | typedef enum { | 51 | typedef enum { |
| 56 | VGLOBAL, /* info is constant index of global name */ | 52 | VGLOBAL, /* info is constant index of global name */ |
| 57 | VLOCAL, /* info is stack index */ | 53 | VLOCAL, /* info is stack index */ |
| 58 | VINDEXED, /* no info (table and index are on the stack) */ | 54 | VINDEXED, /* info is info of the index expression */ |
| 59 | VEXP /* info is pc index of exp main operator */ | 55 | VEXP /* info is NOJUMPS if exp has no internal jumps */ |
| 60 | } expkind; | 56 | } expkind; |
| 61 | 57 | ||
| 62 | typedef struct expdesc { | 58 | typedef struct expdesc { |
| @@ -65,12 +61,22 @@ typedef struct expdesc { | |||
| 65 | } expdesc; | 61 | } expdesc; |
| 66 | 62 | ||
| 67 | 63 | ||
| 64 | /* | ||
| 65 | ** Expression List descriptor: | ||
| 66 | ** tells number of expressions in the list, | ||
| 67 | ** and gives the `info' of last expression. | ||
| 68 | */ | ||
| 69 | typedef struct listdesc { | ||
| 70 | int n; | ||
| 71 | int info; /* 0 if last expression has no internal jumps */ | ||
| 72 | } listdesc; | ||
| 73 | |||
| 74 | |||
| 68 | /* state needed to generate code for a given function */ | 75 | /* state needed to generate code for a given function */ |
| 69 | typedef struct FuncState { | 76 | typedef struct FuncState { |
| 70 | TProtoFunc *f; /* current function header */ | 77 | TProtoFunc *f; /* current function header */ |
| 71 | struct FuncState *prev; /* enclosing function */ | 78 | struct FuncState *prev; /* enclosing function */ |
| 72 | int pc; /* next position to code */ | 79 | int pc; /* next position to code */ |
| 73 | int last_pc; /* last instruction coded (for optimizations) */ | ||
| 74 | int stacksize; /* number of values on activation register */ | 80 | int stacksize; /* number of values on activation register */ |
| 75 | int nlocalvar; /* number of active local variables */ | 81 | int nlocalvar; /* number of active local variables */ |
| 76 | int nupvalues; /* number of upvalues */ | 82 | int nupvalues; /* number of upvalues */ |
