deterministic, then the generated bytecode is not deterministic.
*/
sorted_keys = PyDict_Keys(src);
- if (sorted_keys == NULL)
+ if (sorted_keys == NULL) {
+ Py_DECREF(dest);
return NULL;
+ }
if (PyList_Sort(sorted_keys) != 0) {
Py_DECREF(sorted_keys);
+ Py_DECREF(dest);
return NULL;
}
num_keys = PyList_GET_SIZE(sorted_keys);
for (key_i = 0; key_i < num_keys; key_i++) {
- /* XXX this should probably be a macro in symtable.h */
- long vi;
k = PyList_GET_ITEM(sorted_keys, key_i);
v = PyDict_GetItemWithError(src, k);
- assert(v && PyLong_Check(v));
- vi = PyLong_AS_LONG(v);
+ if (!v) {
+ if (!PyErr_Occurred()) {
+ PyErr_SetObject(PyExc_KeyError, k);
+ }
+ Py_DECREF(sorted_keys);
+ Py_DECREF(dest);
+ return NULL;
+ }
+ long vi = PyLong_AsLong(v);
+ if (vi == -1 && PyErr_Occurred()) {
+ Py_DECREF(sorted_keys);
+ Py_DECREF(dest);
+ return NULL;
+ }
+ /* XXX this should probably be a macro in symtable.h */
scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
if (scope == scope_type || vi & flag) {
scope = _PyST_GetScope(parent->u_ste, mangled);
Py_DECREF(mangled);
+ RETURN_IF_ERROR(scope);
assert(scope != GLOBAL_IMPLICIT);
if (scope == GLOBAL_EXPLICIT)
force_global = 1;
if (v == NULL) {
return ERROR;
}
- return PyLong_AS_LONG(v);
+ return PyLong_AsLong(v);
}
static int
else {
arg = dict_lookup_arg(c->u->u_metadata.u_freevars, name);
}
- if (arg == -1) {
+ if (arg == -1 && !PyErr_Occurred()) {
PyObject *freevars = _PyCode_GetFreevars(co);
if (freevars == NULL) {
PyErr_Clear();
case GLOBAL_EXPLICIT:
optype = OP_GLOBAL;
break;
+ case -1:
+ goto error;
default:
/* scope can be 0 */
break;
}
long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
+ RETURN_IF_ERROR(flags);
return flags & DEF_IMPORT;
}
PyObject *super_name = e->v.Call.func->v.Name.id;
// detect statically-visible shadowing of 'super' name
int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
+ RETURN_IF_ERROR(scope);
if (scope != GLOBAL_IMPLICIT) {
return 0;
}
scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
+ RETURN_IF_ERROR(scope);
if (scope != 0) {
return 0;
}
}
/* Check that the base object is not something that is imported */
- if (is_import_originated(c, meth->v.Attribute.value)) {
+ int ret = is_import_originated(c, meth->v.Attribute.value);
+ RETURN_IF_ERROR(ret);
+ if (ret) {
return 0;
}
/* Alright, we can optimize the code. */
location loc = LOC(meth);
- if (can_optimize_super_call(c, meth)) {
+ ret = can_optimize_super_call(c, meth);
+ RETURN_IF_ERROR(ret);
+ if (ret) {
RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value));
int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ?
LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD;
PyObject *k, *v;
Py_ssize_t pos = 0;
while (PyDict_Next(entry->ste_symbols, &pos, &k, &v)) {
- assert(PyLong_Check(v));
- long symbol = PyLong_AS_LONG(v);
+ long symbol = PyLong_AsLong(v);
+ if (symbol == -1 && PyErr_Occurred()) {
+ return ERROR;
+ }
long scope = (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
PyObject *outv = PyDict_GetItemWithError(SYMTABLE_ENTRY(c)->ste_symbols, k);
if (outv == NULL) {
}
outv = _PyLong_GetZero();
}
- assert(PyLong_CheckExact(outv));
- long outsc = (PyLong_AS_LONG(outv) >> SCOPE_OFFSET) & SCOPE_MASK;
+ long outsymbol = PyLong_AsLong(outv);
+ if (outsymbol == -1 && PyErr_Occurred()) {
+ return ERROR;
+ }
+ long outsc = (outsymbol >> SCOPE_OFFSET) & SCOPE_MASK;
// If a name has different scope inside than outside the comprehension,
// we need to temporarily handle it with the right scope while
// compiling the comprehension. If it's free in the comprehension
return compiler_formatted_value(c, e);
/* The following exprs can be assignment targets. */
case Attribute_kind:
- if (e->v.Attribute.ctx == Load && can_optimize_super_call(c, e)) {
- RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
- int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
- LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
- ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
- loc = update_start_location_to_match_attr(c, loc, e);
- ADDOP(c, loc, NOP);
- return SUCCESS;
+ if (e->v.Attribute.ctx == Load) {
+ int ret = can_optimize_super_call(c, e);
+ RETURN_IF_ERROR(ret);
+ if (ret) {
+ RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
+ int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
+ LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
+ ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
+ loc = update_start_location_to_match_attr(c, loc, e);
+ ADDOP(c, loc, NOP);
+ return SUCCESS;
+ }
}
RETURN_IF_ERROR(compiler_maybe_add_static_attribute_to_class(c, e));
VISIT(c, expr, e->v.Attribute.value);
if (consts == NULL)
return NULL;
while (PyDict_Next(dict, &pos, &k, &v)) {
- i = PyLong_AS_LONG(v);
+ assert(PyLong_CheckExact(v));
+ i = PyLong_AsLong(v);
/* The keys of the dictionary can be tuples wrapping a constant.
* (see dict_add_o and _PyCode_ConstantKey). In that case
* the object we want is always second. */
long
_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name)
{
- PyObject *v = PyDict_GetItemWithError(ste->ste_symbols, name);
- if (!v)
+ PyObject *v;
+ if (PyDict_GetItemRef(ste->ste_symbols, name, &v) < 0) {
+ return -1;
+ }
+ if (!v) {
return 0;
- assert(PyLong_Check(v));
- return PyLong_AS_LONG(v);
+ }
+ long symbol = PyLong_AsLong(v);
+ Py_DECREF(v);
+ if (symbol < 0) {
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_SystemError, "invalid symbol");
+ }
+ return -1;
+ }
+ return symbol;
}
int
_PyST_GetScope(PySTEntryObject *ste, PyObject *name)
{
long symbol = _PyST_GetSymbol(ste, name);
+ if (symbol < 0) {
+ return -1;
+ }
return (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
}
// global statement), we want to also treat it as a global in this scope.
if (class_entry != NULL) {
long class_flags = _PyST_GetSymbol(class_entry, name);
+ if (class_flags < 0) {
+ return 0;
+ }
if (class_flags & DEF_GLOBAL) {
SET_SCOPE(scopes, name, GLOBAL_EXPLICIT);
return 1;
}
- else if (class_flags & DEF_BOUND && !(class_flags & DEF_NONLOCAL)) {
+ else if ((class_flags & DEF_BOUND) && !(class_flags & DEF_NONLOCAL)) {
SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
return 1;
}
PySTEntryObject *child_ste = (PySTEntryObject *)PyList_GET_ITEM(
entry->ste_children, i);
long scope = _PyST_GetScope(child_ste, key);
+ if (scope < 0) {
+ return -1;
+ }
if (scope == FREE) {
return 1;
}
while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) {
// skip comprehension parameter
- long comp_flags = PyLong_AS_LONG(v);
+ long comp_flags = PyLong_AsLong(v);
+ if (comp_flags == -1 && PyErr_Occurred()) {
+ return 0;
+ }
if (comp_flags & DEF_PARAM) {
assert(_PyUnicode_EqualToASCIIString(k, ".0"));
continue;
SET_SCOPE(scopes, k, scope);
}
else {
- if (PyLong_AsLong(existing) & DEF_BOUND) {
+ long flags = PyLong_AsLong(existing);
+ if (flags == -1 && PyErr_Occurred()) {
+ return 0;
+ }
+ if ((flags & DEF_BOUND) && ste->ste_type != ClassBlock) {
// free vars in comprehension that are locals in outer scope can
// now simply be locals, unless they are free in comp children,
// or if the outer scope is a class block
- if (!is_free_in_any_child(comp, k) && ste->ste_type != ClassBlock) {
+ int ok = is_free_in_any_child(comp, k);
+ if (ok < 0) {
+ return 0;
+ }
+ if (!ok) {
if (PySet_Discard(comp_free, k) < 0) {
return 0;
}
if (!v_cell)
return 0;
while (PyDict_Next(scopes, &pos, &name, &v)) {
- long scope;
- assert(PyLong_Check(v));
- scope = PyLong_AS_LONG(v);
+ long scope = PyLong_AsLong(v);
+ if (scope == -1 && PyErr_Occurred()) {
+ goto error;
+ }
if (scope != LOCAL)
continue;
int contains = PySet_Contains(free, name);
/* Update scope information for all symbols in this scope */
while (PyDict_Next(symbols, &pos, &name, &v)) {
- long scope, flags;
- assert(PyLong_Check(v));
- flags = PyLong_AS_LONG(v);
+ long flags = PyLong_AsLong(v);
+ if (flags == -1 && PyErr_Occurred()) {
+ return 0;
+ }
int contains = PySet_Contains(inlined_cells, name);
if (contains < 0) {
return 0;
if (contains) {
flags |= DEF_COMP_CELL;
}
- v_scope = PyDict_GetItemWithError(scopes, name);
- assert(v_scope && PyLong_Check(v_scope));
- scope = PyLong_AS_LONG(v_scope);
+ if (PyDict_GetItemRef(scopes, name, &v_scope) < 0) {
+ return 0;
+ }
+ if (!v_scope) {
+ PyErr_SetObject(PyExc_KeyError, name);
+ return 0;
+ }
+ long scope = PyLong_AsLong(v_scope);
+ Py_DECREF(v_scope);
+ if (scope == -1 && PyErr_Occurred()) {
+ return 0;
+ }
flags |= (scope << SCOPE_OFFSET);
v_new = PyLong_FromLong(flags);
if (!v_new)
or global in the class scope.
*/
if (classflag) {
- long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS;
+ long flags = PyLong_AsLong(v);
+ if (flags == -1 && PyErr_Occurred()) {
+ goto error;
+ }
+ flags |= DEF_FREE_CLASS;
v_new = PyLong_FromLong(flags);
if (!v_new) {
goto error;
}
while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
- long flags = PyLong_AS_LONG(v);
+ long flags = PyLong_AsLong(v);
+ if (flags == -1 && PyErr_Occurred()) {
+ goto error;
+ }
if (!analyze_name(ste, scopes, name, flags,
bound, local, free, global, type_params, class_entry))
goto error;
{
PyObject *mangled = _Py_MaybeMangle(st->st_private, ste, name);
if (!mangled)
- return 0;
+ return -1;
long ret = _PyST_GetSymbol(ste, mangled);
Py_DECREF(mangled);
+ if (ret < 0) {
+ return -1;
+ }
return ret;
}
return 0;
dict = ste->ste_symbols;
if ((o = PyDict_GetItemWithError(dict, mangled))) {
- val = PyLong_AS_LONG(o);
+ val = PyLong_AsLong(o);
+ if (val == -1 && PyErr_Occurred()) {
+ goto error;
+ }
if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
/* Is it better to use 'mangled' or 'name' here? */
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name);
if (flag & DEF_PARAM) {
if (PyList_Append(ste->ste_varnames, mangled) < 0)
goto error;
- } else if (flag & DEF_GLOBAL) {
+ } else if (flag & DEF_GLOBAL) {
/* XXX need to update DEF_GLOBAL for other flags too;
perhaps only DEF_FREE_GLOBAL */
- val = flag;
+ val = 0;
if ((o = PyDict_GetItemWithError(st->st_global, mangled))) {
- val |= PyLong_AS_LONG(o);
+ val = PyLong_AsLong(o);
+ if (val == -1 && PyErr_Occurred()) {
+ goto error;
+ }
}
else if (PyErr_Occurred()) {
goto error;
}
+ val |= flag;
o = PyLong_FromLong(val);
if (o == NULL)
goto error;
*/
if (ste->ste_comprehension) {
long target_in_scope = symtable_lookup_entry(st, ste, target_name);
+ if (target_in_scope < 0) {
+ return 0;
+ }
if ((target_in_scope & DEF_COMP_ITER) &&
(target_in_scope & DEF_LOCAL)) {
PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name);
/* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */
if (ste->ste_type == FunctionBlock) {
long target_in_scope = symtable_lookup_entry(st, ste, target_name);
+ if (target_in_scope < 0) {
+ return 0;
+ }
if (target_in_scope & DEF_GLOBAL) {
if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e)))
return 0;
{
Py_ssize_t i;
- if (!args)
- return -1;
-
for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
if (!symtable_add_def(st, arg->arg, DEF_PARAM, LOCATION(arg)))
{
Py_ssize_t i;
- if (!args)
- return -1;
-
for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
if (arg->annotation) {