*/
#include "Python.h"
+#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_long.h" // _PyLong_GetZero()
#include "Python-ast.h"
{
basicblock *block;
for (block = u->u_blocks; block != NULL; block = block->b_list) {
- assert((uintptr_t)block != 0xcbcbcbcbU);
- assert((uintptr_t)block != 0xfbfbfbfbU);
- assert((uintptr_t)block != 0xdbdbdbdbU);
+ assert(!_PyMem_IsPtrFreed(block));
if (block->b_instr != NULL) {
assert(block->b_ialloc > 0);
assert(block->b_iused >= 0);
assert(c->u);
/* we are deleting from a list so this really shouldn't fail */
if (PySequence_DelItem(c->c_stack, n) < 0) {
- Py_FatalError("PySequence_DelItem failed");
+ _PyErr_WriteUnraisableMsg("on removing the last compiler "
+ "stack item", NULL);
}
compiler_unit_check(c->u);
}
return CELL;
scope = PyST_GetScope(c->u->u_ste, name);
if (scope == 0) {
- _Py_FatalErrorFormat(__func__,
- "unknown scope for %.100s in %.100s(%s)\n"
- "symbols: %s\nlocals: %s\nglobals: %s",
- PyUnicode_AsUTF8(name),
- PyUnicode_AsUTF8(c->u->u_name),
- PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)),
- PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)),
- PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)),
- PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names)));
+ PyErr_Format(PyExc_SystemError,
+ "PyST_GetScope(name=%R) failed: "
+ "unknown scope in unit %S (%R); "
+ "symbols: %R; locals: %R; globals: %R",
+ name,
+ c->u->u_name, c->u->u_ste->ste_id,
+ c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names);
+ return -1;
}
-
return scope;
}
}
static int
-compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, PyObject *qualname)
+compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags,
+ PyObject *qualname)
{
Py_ssize_t i, free = PyCode_GetNumFree(co);
if (qualname == NULL)
LOAD_DEREF but LOAD_CLOSURE is needed.
*/
PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i);
- int arg, reftype;
/* Special case: If a class contains a method with a
free variable that has the same name as a method,
class. It should be handled by the closure, as
well as by the normal name lookup logic.
*/
- reftype = get_ref_type(c, name);
- if (reftype == CELL)
+ int reftype = get_ref_type(c, name);
+ if (reftype == -1) {
+ return 0;
+ }
+ int arg;
+ if (reftype == CELL) {
arg = compiler_lookup_arg(c->u->u_cellvars, name);
- else /* (reftype == FREE) */
+ }
+ else {
arg = compiler_lookup_arg(c->u->u_freevars, name);
+ }
if (arg == -1) {
- _Py_FatalErrorFormat(__func__,
- "lookup %s in %s %d %d\n"
- "freevars of %s: %s\n",
- PyUnicode_AsUTF8(PyObject_Repr(name)),
- PyUnicode_AsUTF8(c->u->u_name),
- reftype, arg,
- PyUnicode_AsUTF8(co->co_name),
- PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars)));
+ PyErr_Format(PyExc_SystemError,
+ "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
+ "freevars of code %S: %R",
+ name,
+ reftype,
+ c->u->u_name,
+ co->co_name,
+ co->co_freevars);
+ return 0;
}
ADDOP_I(c, LOAD_CLOSURE, arg);
}
return 0;
}
- compiler_make_closure(c, co, funcflags, qualname);
+ if (!compiler_make_closure(c, co, funcflags, qualname)) {
+ Py_DECREF(qualname);
+ Py_DECREF(co);
+ return 0;
+ }
Py_DECREF(qualname);
Py_DECREF(co);
ADDOP(c, LOAD_BUILD_CLASS);
/* 3. load a function (or closure) made from the code object */
- compiler_make_closure(c, co, 0, NULL);
+ if (!compiler_make_closure(c, co, 0, NULL)) {
+ Py_DECREF(co);
+ return 0;
+ }
Py_DECREF(co);
/* 4. load class name */
return 0;
}
- compiler_make_closure(c, co, funcflags, qualname);
+ if (!compiler_make_closure(c, co, funcflags, qualname)) {
+ Py_DECREF(qualname);
+ Py_DECREF(co);
+ return 0;
+ }
Py_DECREF(qualname);
Py_DECREF(co);
if (co == NULL)
goto error;
- if (!compiler_make_closure(c, co, 0, qualname))
+ if (!compiler_make_closure(c, co, 0, qualname)) {
goto error;
+ }
Py_DECREF(qualname);
Py_DECREF(co);
struct instr *instr = &b->b_instr[i];
int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
if (effect == PY_INVALID_STACK_EFFECT) {
- _Py_FatalErrorFormat(__func__,
- "opcode = %d", instr->i_opcode);
+ PyErr_Format(PyExc_SystemError,
+ "compiler stack_effect(opcode=%d, arg=%i) failed",
+ instr->i_opcode, instr->i_oparg);
+ return -1;
}
int new_depth = depth + effect;
if (new_depth > maxdepth) {
Py_INCREF(code);
return code;
}
-