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.
This commit is contained in:
Victor Stinner 2013-11-19 22:23:20 +01:00
parent 1540b16ff4
commit ad9a066050
1 changed files with 68 additions and 48 deletions

View File

@ -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;
@ -2542,7 +2552,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
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,7 +2988,7 @@ 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 */
Py_ssize_t n, /* Args already pushed */
asdl_seq *args,
asdl_seq *keywords,
expr_ty starargs,
@ -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)
@ -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);
}