diff options
author | Fred Drake <fdrake@acm.org> | 2000-08-24 00:32:09 (GMT) |
---|---|---|
committer | Fred Drake <fdrake@acm.org> | 2000-08-24 00:32:09 (GMT) |
commit | ef8ace3a6f6cf8396fa92ae62352e8a29ddfca1d (patch) | |
tree | 799778ef59de6c384636792eb8f1e2ddc1e918a8 /Python/compile.c | |
parent | e266e42c9c1d20b24d18def1c4398e75fe1620f0 (diff) | |
download | cpython-ef8ace3a6f6cf8396fa92ae62352e8a29ddfca1d.zip cpython-ef8ace3a6f6cf8396fa92ae62352e8a29ddfca1d.tar.gz cpython-ef8ace3a6f6cf8396fa92ae62352e8a29ddfca1d.tar.bz2 |
Charles G. Waldman <cgw@fnal.gov>:
Add the EXTENDED_ARG opcode to the virtual machine, allowing 32-bit
arguments to opcodes instead of being forced to stick to the 16-bit
limit. This is especially useful for machine-generated code, which
can be too long for the SET_LINENO parameter to fit into 16 bits.
This closes the implementation portion of SourceForge patch #100893.
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/Python/compile.c b/Python/compile.c index f239bb6..3b7c87a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -36,6 +36,9 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. #ifdef HAVE_LIMITS_H #include <limits.h> #endif +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif /* Three symbols from graminit.h are also defined in Python.h, with Py_ prefixes to their names. Python.h can't include graminit.h @@ -572,11 +575,17 @@ com_set_lineno(struct compiling *c, int lineno) static void com_addoparg(struct compiling *c, int op, int arg) { + int extended_arg = arg >> 16; if (op == SET_LINENO) { com_set_lineno(c, arg); if (Py_OptimizeFlag) return; } + if (extended_arg){ + com_addbyte(c, EXTENDED_ARG); + com_addint(c, extended_arg); + arg &= 0xffff; + } com_addbyte(c, op); com_addint(c, arg); } @@ -606,7 +615,14 @@ com_backpatch(struct compiling *c, int anchor) prev = code[anchor] + (code[anchor+1] << 8); dist = target - (anchor+2); code[anchor] = dist & 0xff; - code[anchor+1] = dist >> 8; + dist >>= 8; + code[anchor+1] = dist; + dist >>= 8; + if (dist) { + com_error(c, PyExc_SystemError, + "com_backpatch: offset too large"); + break; + } if (!prev) break; anchor -= prev; @@ -3364,6 +3380,7 @@ optimize(struct compiling *c) break; if (HAS_ARG(opcode)) oparg = NEXTARG(); + dispatch_opcode1: switch (opcode) { case STORE_NAME: case DELETE_NAME: @@ -3374,6 +3391,11 @@ optimize(struct compiling *c) case EXEC_STMT: c->c_flags &= ~CO_OPTIMIZED; break; + case EXTENDED_ARG: + opcode = NEXTOP(); + oparg = oparg<<16 | NEXTARG(); + goto dispatch_opcode1; + break; } } @@ -3389,6 +3411,7 @@ optimize(struct compiling *c) break; if (HAS_ARG(opcode)) oparg = NEXTARG(); + dispatch_opcode2: if (opcode == LOAD_NAME || opcode == STORE_NAME || opcode == DELETE_NAME) { @@ -3403,13 +3426,20 @@ optimize(struct compiling *c) continue; } i = PyInt_AsLong(v); + if (i >> 16) /* too big for 2 bytes */ + continue; switch (opcode) { case LOAD_NAME: cur_instr[0] = LOAD_FAST; break; case STORE_NAME: cur_instr[0] = STORE_FAST; break; case DELETE_NAME: cur_instr[0] = DELETE_FAST; break; } cur_instr[1] = i & 0xff; - cur_instr[2] = (i>>8) & 0xff; + cur_instr[2] = i >> 8; + } + if (opcode == EXTENDED_ARG) { + opcode = NEXTOP(); + oparg = oparg<<16 | NEXTARG(); + goto dispatch_opcode2; } } |