diff options
-rw-r--r-- | lcode.c | 10 | ||||
-rw-r--r-- | ldebug.c | 47 | ||||
-rw-r--r-- | lopcodes.c | 85 | ||||
-rw-r--r-- | lopcodes.h | 30 | ||||
-rw-r--r-- | lvm.c | 14 |
5 files changed, 100 insertions, 86 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.116 2003/02/27 12:33:07 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 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 | */ |
@@ -88,7 +88,7 @@ static int luaK_getjump (FuncState *fs, int pc) { | |||
88 | 88 | ||
89 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { | 89 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { |
90 | Instruction *pi = &fs->f->code[pc]; | 90 | Instruction *pi = &fs->f->code[pc]; |
91 | if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT)) | 91 | if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) |
92 | return pi-1; | 92 | return pi-1; |
93 | else | 93 | else |
94 | return pi; | 94 | return pi; |
@@ -462,8 +462,7 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | |||
462 | 462 | ||
463 | static void invertjump (FuncState *fs, expdesc *e) { | 463 | static void invertjump (FuncState *fs, expdesc *e) { |
464 | Instruction *pc = getjumpcontrol(fs, e->info); | 464 | Instruction *pc = getjumpcontrol(fs, e->info); |
465 | lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) && | 465 | lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TEST); |
466 | GET_OPCODE(*pc) != OP_TEST); | ||
467 | SETARG_A(*pc, !(GETARG_A(*pc))); | 466 | SETARG_A(*pc, !(GETARG_A(*pc))); |
468 | } | 467 | } |
469 | 468 | ||
@@ -703,12 +702,15 @@ int luaK_code (FuncState *fs, Instruction i, int line) { | |||
703 | 702 | ||
704 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { | 703 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { |
705 | lua_assert(getOpMode(o) == iABC); | 704 | lua_assert(getOpMode(o) == iABC); |
705 | lua_assert(getBMode(o) != OpArgN || b == 0); | ||
706 | lua_assert(getCMode(o) != OpArgN || c == 0); | ||
706 | return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); | 707 | return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); |
707 | } | 708 | } |
708 | 709 | ||
709 | 710 | ||
710 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | 711 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { |
711 | lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); | 712 | lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); |
713 | lua_assert(getCMode(o) == OpArgN); | ||
712 | return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); | 714 | return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); |
713 | } | 715 | } |
714 | 716 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.151 2003/04/28 13:31:06 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.152 2003/05/13 20:15:59 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -296,8 +296,16 @@ static int checkopenop (const Proto *pt, int pc) { | |||
296 | } | 296 | } |
297 | 297 | ||
298 | 298 | ||
299 | static int checkRK (const Proto *pt, int r) { | 299 | static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { |
300 | return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek)); | 300 | switch (mode) { |
301 | case OpArgN: check(r == 0); break; | ||
302 | case OpArgU: break; | ||
303 | case OpArgR: checkreg(pt, r); break; | ||
304 | case OpArgK: | ||
305 | check(r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek)); | ||
306 | break; | ||
307 | } | ||
308 | return 1; | ||
301 | } | 309 | } |
302 | 310 | ||
303 | 311 | ||
@@ -317,29 +325,28 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
317 | case iABC: { | 325 | case iABC: { |
318 | b = GETARG_B(i); | 326 | b = GETARG_B(i); |
319 | c = GETARG_C(i); | 327 | c = GETARG_C(i); |
320 | if (testOpMode(op, OpModeBreg)) { | 328 | check(checkArgMode(pt, b, getBMode(op))); |
321 | checkreg(pt, b); | 329 | check(checkArgMode(pt, c, getCMode(op))); |
322 | } | ||
323 | else if (testOpMode(op, OpModeBrk)) | ||
324 | check(checkRK(pt, b)); | ||
325 | if (testOpMode(op, OpModeCrk)) | ||
326 | check(checkRK(pt, c)); | ||
327 | break; | 330 | break; |
328 | } | 331 | } |
329 | case iABx: { | 332 | case iABx: { |
330 | b = GETARG_Bx(i); | 333 | b = GETARG_Bx(i); |
331 | if (testOpMode(op, OpModeK)) check(b < pt->sizek); | 334 | if (getBMode(op) == OpArgK) check(b < pt->sizek); |
332 | break; | 335 | break; |
333 | } | 336 | } |
334 | case iAsBx: { | 337 | case iAsBx: { |
335 | b = GETARG_sBx(i); | 338 | b = GETARG_sBx(i); |
339 | if (getBMode(op) == OpArgR) { | ||
340 | int dest = pc+1+b; | ||
341 | check(0 <= dest && dest < pt->sizecode); | ||
342 | } | ||
336 | break; | 343 | break; |
337 | } | 344 | } |
338 | } | 345 | } |
339 | if (testOpMode(op, OpModesetA)) { | 346 | if (testAMode(op)) { |
340 | if (a == reg) last = pc; /* change register `a' */ | 347 | if (a == reg) last = pc; /* change register `a' */ |
341 | } | 348 | } |
342 | if (testOpMode(op, OpModeT)) { | 349 | if (testTMode(op)) { |
343 | check(pc+2 < pt->sizecode); /* check skip */ | 350 | check(pc+2 < pt->sizecode); /* check skip */ |
344 | check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); | 351 | check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); |
345 | } | 352 | } |
@@ -369,21 +376,21 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
369 | break; | 376 | break; |
370 | } | 377 | } |
371 | case OP_CONCAT: { | 378 | case OP_CONCAT: { |
372 | /* `c' is a register, and at least two operands */ | 379 | check(b < c); /* at least two operands */ |
373 | check(c < MAXSTACK && b < c); | ||
374 | break; | 380 | break; |
375 | } | 381 | } |
376 | case OP_TFORLOOP: | 382 | case OP_TFORLOOP: { |
377 | checkreg(pt, a+5); | 383 | checkreg(pt, a+5); /* space for control variables */ |
378 | if (reg >= a) last = pc; /* affect all registers above base */ | 384 | if (reg >= a) last = pc; /* affect all registers above base */ |
379 | /* go through */ | 385 | break; |
386 | } | ||
387 | case OP_TFORPREP: | ||
380 | case OP_FORLOOP: | 388 | case OP_FORLOOP: |
381 | case OP_FORPREP: | 389 | case OP_FORPREP: |
382 | checkreg(pt, a+2); | 390 | checkreg(pt, a+3); |
383 | /* go through */ | 391 | /* go through */ |
384 | case OP_JMP: { | 392 | case OP_JMP: { |
385 | int dest = pc+1+b; | 393 | int dest = pc+1+b; |
386 | check(0 <= dest && dest < pt->sizecode); | ||
387 | /* not full check and jump is forward and do not skip `lastpc'? */ | 394 | /* not full check and jump is forward and do not skip `lastpc'? */ |
388 | if (reg != NO_REG && pc < dest && dest <= lastpc) | 395 | if (reg != NO_REG && pc < dest && dest <= lastpc) |
389 | pc += b; /* do the jump */ | 396 | pc += b; /* do the jump */ |
@@ -1,7 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.22 2002/12/04 17:38:31 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.23 2003/05/13 20:15:59 roberto Exp roberto $ |
3 | ** extracted automatically from lopcodes.h by mkprint.lua | ||
4 | ** DO NOT EDIT | ||
5 | ** See Copyright Notice in lua.h | 3 | ** See Copyright Notice in lua.h |
6 | */ | 4 | */ |
7 | 5 | ||
@@ -14,6 +12,8 @@ | |||
14 | #include "lopcodes.h" | 12 | #include "lopcodes.h" |
15 | 13 | ||
16 | 14 | ||
15 | /* ORDER OP */ | ||
16 | |||
17 | #ifdef LUA_OPNAMES | 17 | #ifdef LUA_OPNAMES |
18 | 18 | ||
19 | const char *const luaP_opnames[] = { | 19 | const char *const luaP_opnames[] = { |
@@ -57,48 +57,45 @@ const char *const luaP_opnames[] = { | |||
57 | 57 | ||
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | #define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \ | 60 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) |
61 | ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \ | ||
62 | ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m)) | ||
63 | |||
64 | 61 | ||
65 | const lu_byte luaP_opmodes[NUM_OPCODES] = { | 62 | const lu_byte luaP_opmodes[NUM_OPCODES] = { |
66 | /* T B Bk Ck sA K mode opcode */ | 63 | /* T A B C mode opcode */ |
67 | opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_MOVE */ | 64 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ |
68 | ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_LOADK */ | 65 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ |
69 | ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_LOADBOOL */ | 66 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ |
70 | ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_LOADNIL */ | 67 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ |
71 | ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_GETUPVAL */ | 68 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ |
72 | ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_GETGLOBAL */ | 69 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ |
73 | ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_GETTABLE */ | 70 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ |
74 | ,opmode(0, 0, 0, 0, 0, 1, iABx) /* OP_SETGLOBAL */ | 71 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ |
75 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ | 72 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ |
76 | ,opmode(0, 0, 1, 1, 0, 0, iABC) /* OP_SETTABLE */ | 73 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ |
77 | ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_NEWTABLE */ | 74 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ |
78 | ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_SELF */ | 75 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ |
79 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_ADD */ | 76 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ |
80 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_SUB */ | 77 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ |
81 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_MUL */ | 78 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ |
82 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_DIV */ | 79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ |
83 | ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_POW */ | 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ |
84 | ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_UNM */ | 81 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ |
85 | ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_NOT */ | 82 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ |
86 | ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_CONCAT */ | 83 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ |
87 | ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_JMP */ | 84 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ |
88 | ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_EQ */ | 85 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ |
89 | ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LT */ | 86 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ |
90 | ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LE */ | 87 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ |
91 | ,opmode(1, 1, 0, 0, 1, 0, iABC) /* OP_TEST */ | 88 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ |
92 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CALL */ | 89 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ |
93 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */ | 90 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ |
94 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */ | 91 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ |
95 | ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */ | 92 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ |
96 | ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORPREP */ | 93 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ |
97 | ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */ | 94 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ |
98 | ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */ | 95 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_TFORPREP */ |
99 | ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */ | 96 | ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLIST */ |
100 | ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLISTO */ | 97 | ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */ |
101 | ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ | 98 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ |
102 | ,opmode(0, 0, 0, 0, 1, 0, iABx) /* OP_CLOSURE */ | 99 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ |
103 | }; | 100 | }; |
104 | 101 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.102 2002/08/21 18:56:09 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.103 2003/05/13 20:15:59 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 | */ |
@@ -206,22 +206,28 @@ OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ | |||
206 | 206 | ||
207 | 207 | ||
208 | /* | 208 | /* |
209 | ** masks for instruction properties | 209 | ** masks for instruction properties. The format is: |
210 | ** bits 0-1: op mode | ||
211 | ** bits 2-3: C arg mode | ||
212 | ** bits 4-5: B arg mode | ||
213 | ** bit 6: instruction set register A | ||
214 | ** bit 7: operator is a test | ||
210 | */ | 215 | */ |
211 | enum OpModeMask { | ||
212 | OpModeBreg = 2, /* B is a register */ | ||
213 | OpModeBrk, /* B is a register/constant */ | ||
214 | OpModeCrk, /* C is a register/constant */ | ||
215 | OpModesetA, /* instruction set register A */ | ||
216 | OpModeK, /* Bx is a constant */ | ||
217 | OpModeT /* operator is a test */ | ||
218 | }; | ||
219 | 216 | ||
217 | enum OpArgMask { | ||
218 | OpArgN, /* argument is not used */ | ||
219 | OpArgU, /* argument is used */ | ||
220 | OpArgR, /* argument is a register or a jump offset */ | ||
221 | OpArgK /* argument is a constant or register/constant */ | ||
222 | }; | ||
220 | 223 | ||
221 | extern const lu_byte luaP_opmodes[NUM_OPCODES]; | 224 | extern const lu_byte luaP_opmodes[NUM_OPCODES]; |
222 | 225 | ||
223 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) | 226 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) |
224 | #define testOpMode(m, b) (luaP_opmodes[m] & (1 << (b))) | 227 | #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) |
228 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) | ||
229 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) | ||
230 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) | ||
225 | 231 | ||
226 | 232 | ||
227 | #ifdef LUA_OPNAMES | 233 | #ifdef LUA_OPNAMES |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.285 2003/05/05 18:39:57 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.286 2003/05/13 20:15:59 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -361,11 +361,13 @@ static void Arith (lua_State *L, StkId ra, | |||
361 | #define RA(i) (base+GETARG_A(i)) | 361 | #define RA(i) (base+GETARG_A(i)) |
362 | /* to be used after possible stack reallocation */ | 362 | /* to be used after possible stack reallocation */ |
363 | #define XRA(i) (L->base+GETARG_A(i)) | 363 | #define XRA(i) (L->base+GETARG_A(i)) |
364 | #define RB(i) (base+GETARG_B(i)) | 364 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) |
365 | #define RKB(i) ((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK) | 365 | #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) |
366 | #define RC(i) (base+GETARG_C(i)) | 366 | #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ |
367 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK) | 367 | (GETARG_B(i) < MAXSTACK) ? base+GETARG_B(i) : k+GETARG_B(i)-MAXSTACK) |
368 | #define KBx(i) (k+GETARG_Bx(i)) | 368 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ |
369 | (GETARG_C(i) < MAXSTACK) ? base+GETARG_C(i) : k+GETARG_C(i)-MAXSTACK) | ||
370 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) | ||
369 | 371 | ||
370 | 372 | ||
371 | #define dojump(pc, i) ((pc) += (i)) | 373 | #define dojump(pc, i) ((pc) += (i)) |