diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2013-11-19 21:23:20 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2013-11-19 21:23:20 (GMT) |
commit | ad9a066050ff4cf7863b9ed4dc24e284a077c1de (patch) | |
tree | ce5d159a887b84c8e00f2dad88a0f1aeeef75c62 /Python/compile.c | |
parent | 1540b16ff424fe1d6ec0a94ef83a76b3df31d0eb (diff) | |
download | cpython-ad9a066050ff4cf7863b9ed4dc24e284a077c1de.zip cpython-ad9a066050ff4cf7863b9ed4dc24e284a077c1de.tar.gz cpython-ad9a066050ff4cf7863b9ed4dc24e284a077c1de.tar.bz2 |
Issue #9566: compile.c uses Py_ssize_t instead of int to store sizes to fix
compiler warnings on Windows 64-bit. Use Py_SAFE_DOWNCAST() where the final
downcast is needed.
The bytecode doesn't support integer parameters larger than 32-bit yet.
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 116 |
1 files changed, 68 insertions, 48 deletions
diff --git a/Python/compile.c b/Python/compile.c index 8b00211..dde6dcf 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -170,7 +170,7 @@ static basicblock *compiler_new_block(struct compiler *); static int compiler_next_instr(struct compiler *, basicblock *); static int compiler_addop(struct compiler *, int); static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *); -static int compiler_addop_i(struct compiler *, int, int); +static int compiler_addop_i(struct compiler *, Py_ssize_t, Py_ssize_t); static int compiler_addop_j(struct compiler *, int, basicblock *, int); static basicblock *compiler_use_new_block(struct compiler *); static int compiler_error(struct compiler *, const char *); @@ -195,7 +195,7 @@ static int inplace_binop(struct compiler *, operator_ty); static int expr_constant(struct compiler *, expr_ty); static int compiler_with(struct compiler *, stmt_ty, int); -static int compiler_call_helper(struct compiler *c, int n, +static int compiler_call_helper(struct compiler *c, Py_ssize_t n, asdl_seq *args, asdl_seq *keywords, expr_ty starargs, @@ -388,7 +388,7 @@ list2dict(PyObject *list) n = PyList_Size(list); for (i = 0; i < n; i++) { - v = PyLong_FromLong(i); + v = PyLong_FromSsize_t(i); if (!v) { Py_DECREF(dict); return NULL; @@ -416,7 +416,7 @@ each key. */ static PyObject * -dictbytype(PyObject *src, int scope_type, int flag, int offset) +dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) { Py_ssize_t i = offset, scope, num_keys, key_i; PyObject *k, *v, *dest = PyDict_New(); @@ -450,7 +450,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset) scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK; if (scope == scope_type || vi & flag) { - PyObject *tuple, *item = PyLong_FromLong(i); + PyObject *tuple, *item = PyLong_FromSsize_t(i); if (item == NULL) { Py_DECREF(sorted_keys); Py_DECREF(dest); @@ -635,7 +635,7 @@ compiler_enter_scope(struct compiler *c, identifier name, static void compiler_exit_scope(struct compiler *c) { - int n; + Py_ssize_t n; PyObject *capsule; c->c_nestlevel--; @@ -1128,7 +1128,7 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) if (PyErr_Occurred()) return -1; arg = PyDict_Size(dict); - v = PyLong_FromLong(arg); + v = PyLong_FromSsize_t(arg); if (!v) { Py_DECREF(t); return -1; @@ -1150,7 +1150,7 @@ static int compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { - int arg = compiler_add_o(c, dict, o); + Py_ssize_t arg = compiler_add_o(c, dict, o); if (arg < 0) return 0; return compiler_addop_i(c, opcode, arg); @@ -1160,7 +1160,7 @@ static int compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { - int arg; + Py_ssize_t arg; PyObject *mangled = _Py_Mangle(c->u->u_private, o); if (!mangled) return 0; @@ -1176,15 +1176,21 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, */ static int -compiler_addop_i(struct compiler *c, int opcode, int oparg) +compiler_addop_i(struct compiler *c, Py_ssize_t opcode, Py_ssize_t oparg) { struct instr *i; int off; + + /* Integer arguments are limit to 16-bit. There is an extension for 32-bit + integer arguments. */ + assert(INT32_MIN <= opcode); + assert(opcode <= INT32_MAX); + off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; i = &c->u->u_curblock->b_instr[off]; - i->i_opcode = opcode; + i->i_opcode = Py_SAFE_DOWNCAST(opcode, Py_ssize_t, int); i->i_oparg = oparg; i->i_hasarg = 1; compiler_set_lineno(c, off); @@ -1436,9 +1442,9 @@ compiler_lookup_arg(PyObject *dict, PyObject *name) } static int -compiler_make_closure(struct compiler *c, PyCodeObject *co, int args, PyObject *qualname) +compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t args, PyObject *qualname) { - int i, free = PyCode_GetNumFree(co); + Py_ssize_t i, free = PyCode_GetNumFree(co); if (qualname == NULL) qualname = co->co_name; @@ -1565,7 +1571,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, */ static identifier return_str; PyObject *names; - int len; + Py_ssize_t len; names = PyList_New(0); if (!names) return -1; @@ -1602,7 +1608,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (len) { /* convert names to a tuple and place on stack */ PyObject *elt; - int i; + Py_ssize_t i; PyObject *s = PyTuple_New(len); if (!s) goto error; @@ -1616,7 +1622,9 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, len++; /* include the just-pushed tuple */ } Py_DECREF(names); - return len; + + /* We just checked that len <= 65535, see above */ + return Py_SAFE_DOWNCAST(len, Py_ssize_t, int); error: Py_DECREF(names); @@ -1632,7 +1640,8 @@ compiler_function(struct compiler *c, stmt_ty s) expr_ty returns = s->v.FunctionDef.returns; asdl_seq* decos = s->v.FunctionDef.decorator_list; stmt_ty st; - int i, n, docstring, kw_default_count = 0, arglength; + Py_ssize_t i, n, arglength; + int docstring, kw_default_count = 0; int num_annotations; assert(s->kind == FunctionDef_kind); @@ -1851,7 +1860,8 @@ compiler_lambda(struct compiler *c, expr_ty e) PyCodeObject *co; PyObject *qualname; static identifier name; - int kw_default_count = 0, arglength; + int kw_default_count = 0; + Py_ssize_t arglength; arguments_ty args = e->v.Lambda.args; assert(e->kind == Lambda_kind); @@ -2162,7 +2172,7 @@ static int compiler_try_except(struct compiler *c, stmt_ty s) { basicblock *body, *orelse, *except, *end; - int i, n; + Py_ssize_t i, n; body = compiler_new_block(c); except = compiler_new_block(c); @@ -2328,7 +2338,7 @@ compiler_import(struct compiler *c, stmt_ty s) module names. XXX Perhaps change the representation to make this case simpler? */ - int i, n = asdl_seq_LEN(s->v.Import.names); + Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names); for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); @@ -2372,7 +2382,7 @@ compiler_import(struct compiler *c, stmt_ty s) static int compiler_from_import(struct compiler *c, stmt_ty s) { - int i, n = asdl_seq_LEN(s->v.ImportFrom.names); + Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names); PyObject *names = PyTuple_New(n); PyObject *level; @@ -2489,7 +2499,7 @@ compiler_assert(struct compiler *c, stmt_ty s) static int compiler_visit_stmt(struct compiler *c, stmt_ty s) { - int i, n; + Py_ssize_t i, n; /* Always assign a lineno to the next instruction for a stmt. */ c->u->u_lineno = s->lineno; @@ -2537,12 +2547,12 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) if (s->v.Raise.exc) { VISIT(c, expr, s->v.Raise.exc); n++; - if (s->v.Raise.cause) { - VISIT(c, expr, s->v.Raise.cause); - n++; - } + if (s->v.Raise.cause) { + VISIT(c, expr, s->v.Raise.cause); + n++; + } } - ADDOP_I(c, RAISE_VARARGS, n); + ADDOP_I(c, RAISE_VARARGS, (int)n); break; case Try_kind: return compiler_try(c, s); @@ -2702,7 +2712,8 @@ inplace_binop(struct compiler *c, operator_ty op) static int compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) { - int op, scope, arg; + int op, scope; + Py_ssize_t arg; enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; PyObject *dict = c->u->u_names; @@ -2828,7 +2839,8 @@ static int compiler_boolop(struct compiler *c, expr_ty e) { basicblock *end; - int jumpi, i, n; + int jumpi; + Py_ssize_t i, n; asdl_seq *s; assert(e->kind == BoolOp_kind); @@ -2854,7 +2866,7 @@ compiler_boolop(struct compiler *c, expr_ty e) static int compiler_list(struct compiler *c, expr_ty e) { - int n = asdl_seq_LEN(e->v.List.elts); + Py_ssize_t n = asdl_seq_LEN(e->v.List.elts); if (e->v.List.ctx == Store) { int i, seen_star = 0; for (i = 0; i < n; i++) { @@ -2887,7 +2899,7 @@ compiler_list(struct compiler *c, expr_ty e) static int compiler_tuple(struct compiler *c, expr_ty e) { - int n = asdl_seq_LEN(e->v.Tuple.elts); + Py_ssize_t n = asdl_seq_LEN(e->v.Tuple.elts); if (e->v.Tuple.ctx == Store) { int i, seen_star = 0; for (i = 0; i < n; i++) { @@ -2920,7 +2932,7 @@ compiler_tuple(struct compiler *c, expr_ty e) static int compiler_compare(struct compiler *c, expr_ty e) { - int i, n; + Py_ssize_t i, n; basicblock *cleanup = NULL; /* XXX the logic can be cleaned up for 1 or multiple comparisons */ @@ -2976,11 +2988,11 @@ compiler_call(struct compiler *c, expr_ty e) /* shared code between compiler_call and compiler_class */ static int compiler_call_helper(struct compiler *c, - int n, /* Args already pushed */ - asdl_seq *args, - asdl_seq *keywords, - expr_ty starargs, - expr_ty kwargs) + Py_ssize_t n, /* Args already pushed */ + asdl_seq *args, + asdl_seq *keywords, + expr_ty starargs, + expr_ty kwargs) { int code = 0; @@ -3041,7 +3053,7 @@ compiler_comprehension_generator(struct compiler *c, comprehension_ty gen; basicblock *start, *anchor, *skip, *if_cleanup; - int i, n; + Py_ssize_t i, n; start = compiler_new_block(c); skip = compiler_new_block(c); @@ -3380,7 +3392,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) static int compiler_visit_expr(struct compiler *c, expr_ty e) { - int i, n; + Py_ssize_t i, n; /* If expr e has a different line number than the last expr/stmt, set a new line number for the next instruction. @@ -3409,6 +3421,8 @@ compiler_visit_expr(struct compiler *c, expr_ty e) return compiler_ifexp(c, e); case Dict_kind: n = asdl_seq_LEN(e->v.Dict.values); + /* BUILD_MAP parameter is only used to preallocate the dictionary, + it doesn't need to be exact */ ADDOP_I(c, BUILD_MAP, (n>0xFFFF ? 0xFFFF : n)); for (i = 0; i < n; i++) { VISIT(c, expr, @@ -3756,7 +3770,7 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) case ExtSlice_kind: kindname = "extended slice"; if (ctx != AugStore) { - int i, n = asdl_seq_LEN(s->v.ExtSlice.dims); + Py_ssize_t i, n = asdl_seq_LEN(s->v.ExtSlice.dims); for (i = 0; i < n; i++) { slice_ty sub = (slice_ty)asdl_seq_GET( s->v.ExtSlice.dims, i); @@ -3934,7 +3948,7 @@ static int assemble_lnotab(struct assembler *a, struct instr *i) { int d_bytecode, d_lineno; - int len; + Py_ssize_t len; unsigned char *lnotab; d_bytecode = a->a_offset - a->a_lineno_off; @@ -4125,7 +4139,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) } static PyObject * -dict_keys_inorder(PyObject *dict, int offset) +dict_keys_inorder(PyObject *dict, Py_ssize_t offset) { PyObject *tuple, *k, *v; Py_ssize_t i, pos = 0, size = PyDict_Size(dict); @@ -4150,7 +4164,8 @@ static int compute_code_flags(struct compiler *c) { PySTEntryObject *ste = c->u->u_ste; - int flags = 0, n; + int flags = 0; + Py_ssize_t n; if (ste->ste_type == FunctionBlock) { flags |= CO_NEWLOCALS; if (!ste->ste_unoptimized) @@ -4174,9 +4189,9 @@ compute_code_flags(struct compiler *c) if (n == 0) { n = PyDict_Size(c->u->u_cellvars); if (n < 0) - return -1; + return -1; if (n == 0) { - flags |= CO_NOFREE; + flags |= CO_NOFREE; } } @@ -4195,7 +4210,9 @@ makecode(struct compiler *c, struct assembler *a) PyObject *freevars = NULL; PyObject *cellvars = NULL; PyObject *bytecode = NULL; - int nlocals, flags; + Py_ssize_t nlocals; + int nlocals_int; + int flags; tmp = dict_keys_inorder(c->u->u_consts, 0); if (!tmp) @@ -4214,7 +4231,11 @@ makecode(struct compiler *c, struct assembler *a) freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); if (!freevars) goto error; + nlocals = PyDict_Size(c->u->u_varnames); + assert(nlocals < INT_MAX); + nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int); + flags = compute_code_flags(c); if (flags < 0) goto error; @@ -4230,7 +4251,7 @@ makecode(struct compiler *c, struct assembler *a) consts = tmp; co = PyCode_New(c->u->u_argcount, c->u->u_kwonlyargcount, - nlocals, stackdepth(c), flags, + nlocals_int, stackdepth(c), flags, bytecode, consts, names, varnames, freevars, cellvars, c->c_filename, c->u->u_name, @@ -4349,4 +4370,3 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, return PyAST_CompileEx(mod, filename, flags, -1, arena); } - |