Commit 44b63a61 authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by Kevin Modzelewski

Change from throwing a Box* to an ExcInfo triple

ExcInfo is a triple of exc_type, exc_value, exc_traceback -
analogous to Python's sys.exc_info().  Previously, we were just
throwing exc_value.

I still don't understand all the rules for when type(exc_value)
is not necessarily exc_type.  But this also makes it easier to
pass exc_traceback around, and should make it possible to make
our handling more consistent.

This commit just changes the runtime; the generated code currently
still expects a Box* to be thrown and will crash.
parent 05e14eb3
...@@ -39,8 +39,8 @@ extern "C" PyObject* _PyObject_Str(PyObject* v) noexcept { ...@@ -39,8 +39,8 @@ extern "C" PyObject* _PyObject_Str(PyObject* v) noexcept {
try { try {
return str(v); return str(v);
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -79,8 +79,8 @@ extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) noexc ...@@ -79,8 +79,8 @@ extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) noexc
try { try {
return getattr(o, attr); return getattr(o, attr);
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return NULL; return NULL;
} }
} }
......
...@@ -484,8 +484,8 @@ static PyObject* call_maybe(PyObject* o, const char* name, PyObject** nameobj, c ...@@ -484,8 +484,8 @@ static PyObject* call_maybe(PyObject* o, const char* name, PyObject** nameobj, c
PyObject* slot_tp_repr(PyObject* self) noexcept { PyObject* slot_tp_repr(PyObject* self) noexcept {
try { try {
return repr(self); return repr(self);
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -493,8 +493,8 @@ PyObject* slot_tp_repr(PyObject* self) noexcept { ...@@ -493,8 +493,8 @@ PyObject* slot_tp_repr(PyObject* self) noexcept {
PyObject* slot_tp_str(PyObject* self) noexcept { PyObject* slot_tp_str(PyObject* self) noexcept {
try { try {
return str(self); return str(self);
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -542,8 +542,8 @@ PyObject* slot_tp_call(PyObject* self, PyObject* args, PyObject* kwds) noexcept ...@@ -542,8 +542,8 @@ PyObject* slot_tp_call(PyObject* self, PyObject* args, PyObject* kwds) noexcept
// TODO: runtime ICs? // TODO: runtime ICs?
return runtimeCall(self, ArgPassSpec(0, 0, true, true), args, kwds, NULL, NULL, NULL); return runtimeCall(self, ArgPassSpec(0, 0, true, true), args, kwds, NULL, NULL, NULL);
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -631,8 +631,8 @@ static PyObject* slot_tp_new(PyTypeObject* self, PyObject* args, PyObject* kwds) ...@@ -631,8 +631,8 @@ static PyObject* slot_tp_new(PyTypeObject* self, PyObject* args, PyObject* kwds)
new_attr = processDescriptor(new_attr, None, self); new_attr = processDescriptor(new_attr, None, self);
return runtimeCall(new_attr, ArgPassSpec(1, 0, true, true), self, args, kwds, NULL, NULL); return runtimeCall(new_attr, ArgPassSpec(1, 0, true, true), self, args, kwds, NULL, NULL);
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -660,8 +660,8 @@ static int slot_tp_init(PyObject* self, PyObject* args, PyObject* kwds) noexcept ...@@ -660,8 +660,8 @@ static int slot_tp_init(PyObject* self, PyObject* args, PyObject* kwds) noexcept
PyObject* slot_sq_item(PyObject* self, Py_ssize_t i) noexcept { PyObject* slot_sq_item(PyObject* self, Py_ssize_t i) noexcept {
try { try {
return getitem(self, boxInt(i)); return getitem(self, boxInt(i));
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -1781,7 +1781,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept { ...@@ -1781,7 +1781,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
try { try {
add_operators(cls); add_operators(cls);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
......
...@@ -123,7 +123,7 @@ private: ...@@ -123,7 +123,7 @@ private:
SymMap sym_table; SymMap sym_table;
CFGBlock* next_block, *current_block; CFGBlock* next_block, *current_block;
AST_stmt* current_inst; AST_stmt* current_inst;
Box* last_exception; ExcInfo last_exception;
BoxedClosure* passed_closure, *created_closure; BoxedClosure* passed_closure, *created_closure;
BoxedGenerator* generator; BoxedGenerator* generator;
unsigned edgecount; unsigned edgecount;
...@@ -224,7 +224,7 @@ void gatherInterpreterRoots(GCVisitor* visitor) { ...@@ -224,7 +224,7 @@ void gatherInterpreterRoots(GCVisitor* visitor) {
ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function) ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function)
: compiled_func(compiled_function), source_info(compiled_function->clfunc->source), scope_info(0), next_block(0), : compiled_func(compiled_function), source_info(compiled_function->clfunc->source), scope_info(0), next_block(0),
current_block(0), current_inst(0), last_exception(0), passed_closure(0), created_closure(0), generator(0), current_block(0), current_inst(0), last_exception(NULL, NULL, NULL), passed_closure(0), created_closure(0), generator(0),
edgecount(0) { edgecount(0) {
CLFunction* f = compiled_function->clfunc; CLFunction* f = compiled_function->clfunc;
...@@ -506,9 +506,9 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) { ...@@ -506,9 +506,9 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
try { try {
v = visit_stmt(node->stmt); v = visit_stmt(node->stmt);
next_block = node->normal_dest; next_block = node->normal_dest;
} catch (Box* b) { } catch (ExcInfo e) {
next_block = node->exc_dest; next_block = node->exc_dest;
last_exception = b; last_exception = e;
} }
return v; return v;
...@@ -561,8 +561,10 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -561,8 +561,10 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
} else if (node->opcode == AST_LangPrimitive::NONE) { } else if (node->opcode == AST_LangPrimitive::NONE) {
v = None; v = None;
} else if (node->opcode == AST_LangPrimitive::LANDINGPAD) { } else if (node->opcode == AST_LangPrimitive::LANDINGPAD) {
v = last_exception; abort();
last_exception = nullptr; // Have to figure out how to represent landingpads
//v = last_exception;
//last_exception = nullptr;
} else if (node->opcode == AST_LangPrimitive::ISINSTANCE) { } else if (node->opcode == AST_LangPrimitive::ISINSTANCE) {
assert(node->args.size() == 3); assert(node->args.size() == 3);
Value obj = visit_expr(node->args[0]); Value obj = visit_expr(node->args[0]);
......
...@@ -469,6 +469,14 @@ public: ...@@ -469,6 +469,14 @@ public:
LineInfo(int line, int column, const std::string& file, const std::string& func) LineInfo(int line, int column, const std::string& file, const std::string& func)
: line(line), column(column), file(file), func(func) {} : line(line), column(column), file(file), func(func) {}
}; };
struct ExcInfo {
Box* type, *value, *traceback;
ExcInfo(Box* type, Box* value, Box* traceback) : type(type), value(value), traceback(traceback) {}
bool matches(BoxedClass* cls) const;
};
} }
#endif #endif
...@@ -42,6 +42,7 @@ public: ...@@ -42,6 +42,7 @@ public:
void operator=(Box* b) { value = b; } void operator=(Box* b) { value = b; }
operator Box*() { return value; } operator Box*() { return value; }
Box* operator->() { return value; }
}; };
void runCollection(); void runCollection();
......
...@@ -150,12 +150,12 @@ int main(int argc, char** argv) { ...@@ -150,12 +150,12 @@ int main(int argc, char** argv) {
try { try {
main_module = createAndRunModule("__main__", fn); main_module = createAndRunModule("__main__", fn);
} catch (Box* b) { } catch (ExcInfo e) {
if (isInstance(b, SystemExit)) { if (e.matches(SystemExit)) {
printf("Warning: ignoring SystemExit code\n"); printf("Warning: ignoring SystemExit code\n");
return 1; return 1;
} else { } else {
std::string msg = formatException(b); std::string msg = formatException(e.value);
printLastTraceback(); printLastTraceback();
fprintf(stderr, "%s\n", msg.c_str()); fprintf(stderr, "%s\n", msg.c_str());
return 1; return 1;
...@@ -222,12 +222,12 @@ int main(int argc, char** argv) { ...@@ -222,12 +222,12 @@ int main(int argc, char** argv) {
try { try {
compileAndRunModule(m, main_module); compileAndRunModule(m, main_module);
} catch (Box* b) { } catch (ExcInfo e) {
if (isInstance(b, SystemExit)) { if (e.matches(SystemExit)) {
printf("Warning: ignoring SystemExit code\n"); printf("Warning: ignoring SystemExit code\n");
return 1; return 1;
} else { } else {
std::string msg = formatException(b); std::string msg = formatException(e.value);
printLastTraceback(); printLastTraceback();
fprintf(stderr, "%s\n", msg.c_str()); fprintf(stderr, "%s\n", msg.c_str());
} }
......
...@@ -446,8 +446,8 @@ Box* hasattr(Box* obj, Box* _str) { ...@@ -446,8 +446,8 @@ Box* hasattr(Box* obj, Box* _str) {
Box* attr; Box* attr;
try { try {
attr = getattrInternal(obj, str->s, NULL); attr = getattrInternal(obj, str->s, NULL);
} catch (Box* e) { } catch (ExcInfo e) {
if (isSubclass(e->cls, Exception)) if (e.matches(Exception))
return False; return False;
throw; throw;
} }
...@@ -623,7 +623,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d ...@@ -623,7 +623,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
// TODO Not sure if this should be called here // TODO Not sure if this should be called here
fixup_slot_dispatchers(cls); fixup_slot_dispatchers(cls);
return cls; return cls;
} catch (Box* e) { } catch (ExcInfo e) {
abort(); abort();
} }
} }
......
...@@ -82,7 +82,7 @@ extern "C" int PySys_SetObject(const char* name, PyObject* v) noexcept { ...@@ -82,7 +82,7 @@ extern "C" int PySys_SetObject(const char* name, PyObject* v) noexcept {
sys_module->delattr(name, NULL); sys_module->delattr(name, NULL);
} else } else
sys_module->setattr(name, v, NULL); sys_module->setattr(name, v, NULL);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
return 0; return 0;
......
...@@ -31,8 +31,8 @@ static void* thread_start(Box* target, Box* varargs, Box* kwargs) { ...@@ -31,8 +31,8 @@ static void* thread_start(Box* target, Box* varargs, Box* kwargs) {
try { try {
runtimeCall(target, ArgPassSpec(0, 0, true, kwargs != NULL), varargs, kwargs, NULL, NULL, NULL); runtimeCall(target, ArgPassSpec(0, 0, true, kwargs != NULL), varargs, kwargs, NULL, NULL, NULL);
} catch (Box* b) { } catch (ExcInfo e) {
std::string msg = formatException(b); std::string msg = formatException(e.value);
printLastTraceback(); printLastTraceback();
fprintf(stderr, "%s\n", msg.c_str()); fprintf(stderr, "%s\n", msg.c_str());
} }
......
...@@ -158,7 +158,7 @@ extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept ...@@ -158,7 +158,7 @@ extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept
try { try {
Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL); Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
return r; return r;
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -174,8 +174,8 @@ extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* f ...@@ -174,8 +174,8 @@ extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* f
extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept { extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept {
try { try {
return len(o)->n; return len(o)->n;
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return -1; return -1;
} }
} }
...@@ -183,8 +183,8 @@ extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept { ...@@ -183,8 +183,8 @@ extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept {
extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept { extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept {
try { try {
return getiter(o); return getiter(o);
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -192,8 +192,8 @@ extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept { ...@@ -192,8 +192,8 @@ extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept {
extern "C" PyObject* PyObject_Repr(PyObject* obj) noexcept { extern "C" PyObject* PyObject_Repr(PyObject* obj) noexcept {
try { try {
return repr(obj); return repr(obj);
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -352,7 +352,7 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) noexcept ...@@ -352,7 +352,7 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) noexcept
try { try {
return getattr(o, static_cast<BoxedString*>(attr_name)->s.c_str()); return getattr(o, static_cast<BoxedString*>(attr_name)->s.c_str());
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -364,8 +364,8 @@ extern "C" PyObject* PyObject_GenericGetAttr(PyObject* o, PyObject* name) noexce ...@@ -364,8 +364,8 @@ extern "C" PyObject* PyObject_GenericGetAttr(PyObject* o, PyObject* name) noexce
extern "C" PyObject* PyObject_GetItem(PyObject* o, PyObject* key) noexcept { extern "C" PyObject* PyObject_GetItem(PyObject* o, PyObject* key) noexcept {
try { try {
return getitem(o, key); return getitem(o, key);
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -389,7 +389,7 @@ int _Py_SwappedOp[] = { Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE }; ...@@ -389,7 +389,7 @@ int _Py_SwappedOp[] = { Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE };
extern "C" long PyObject_Hash(PyObject* o) noexcept { extern "C" long PyObject_Hash(PyObject* o) noexcept {
try { try {
return hash(o)->n; return hash(o)->n;
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -419,7 +419,7 @@ extern "C" long _Py_HashPointer(void* p) noexcept { ...@@ -419,7 +419,7 @@ extern "C" long _Py_HashPointer(void* p) noexcept {
extern "C" int PyObject_IsTrue(PyObject* o) noexcept { extern "C" int PyObject_IsTrue(PyObject* o) noexcept {
try { try {
return nonzero(o); return nonzero(o);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -459,7 +459,7 @@ extern "C" PyObject* PyObject_Call(PyObject* callable_object, PyObject* args, Py ...@@ -459,7 +459,7 @@ extern "C" PyObject* PyObject_Call(PyObject* callable_object, PyObject* args, Py
return runtimeCall(callable_object, ArgPassSpec(0, 0, true, true), args, kw, NULL, NULL, NULL); return runtimeCall(callable_object, ArgPassSpec(0, 0, true, true), args, kw, NULL, NULL, NULL);
else else
return runtimeCall(callable_object, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL); return runtimeCall(callable_object, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -496,7 +496,7 @@ extern "C" PyObject* PySequence_GetItem(PyObject* o, Py_ssize_t i) noexcept { ...@@ -496,7 +496,7 @@ extern "C" PyObject* PySequence_GetItem(PyObject* o, Py_ssize_t i) noexcept {
try { try {
// Not sure if this is really the same: // Not sure if this is really the same:
return getitem(o, boxInt(i)); return getitem(o, boxInt(i));
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -505,7 +505,7 @@ extern "C" PyObject* PySequence_GetSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t ...@@ -505,7 +505,7 @@ extern "C" PyObject* PySequence_GetSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t
try { try {
// Not sure if this is really the same: // Not sure if this is really the same:
return getitem(o, new BoxedSlice(boxInt(i1), boxInt(i2), None)); return getitem(o, new BoxedSlice(boxInt(i1), boxInt(i2), None));
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -551,8 +551,8 @@ extern "C" PyObject* PyIter_Next(PyObject* iter) noexcept { ...@@ -551,8 +551,8 @@ extern "C" PyObject* PyIter_Next(PyObject* iter) noexcept {
try { try {
return callattr(iter, &next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), return callattr(iter, &next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -672,6 +672,12 @@ finally: ...@@ -672,6 +672,12 @@ finally:
--tstate->recursion_depth; --tstate->recursion_depth;
} }
void setCAPIException(const ExcInfo& e) {
cur_thread_state.curexc_type = e.type;
cur_thread_state.curexc_value = e.value;
cur_thread_state.curexc_traceback = e.traceback;
}
void checkAndThrowCAPIException() { void checkAndThrowCAPIException() {
Box* _type = cur_thread_state.curexc_type; Box* _type = cur_thread_state.curexc_type;
if (!_type) if (!_type)
...@@ -859,7 +865,7 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept { ...@@ -859,7 +865,7 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
try { try {
return import(-1, None, &static_cast<BoxedString*>(module_name)->s); return import(-1, None, &static_cast<BoxedString*>(module_name)->s);
} catch (Box* e) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -895,7 +901,7 @@ extern "C" int PyNumber_Check(PyObject* obj) noexcept { ...@@ -895,7 +901,7 @@ extern "C" int PyNumber_Check(PyObject* obj) noexcept {
extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) noexcept { extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) noexcept {
try { try {
return binop(lhs, rhs, AST_TYPE::Add); return binop(lhs, rhs, AST_TYPE::Add);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -903,7 +909,7 @@ extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) noexcept { ...@@ -903,7 +909,7 @@ extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) noexcept {
extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) noexcept { extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) noexcept {
try { try {
return binop(lhs, rhs, AST_TYPE::Sub); return binop(lhs, rhs, AST_TYPE::Sub);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -911,7 +917,7 @@ extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) noexcept { ...@@ -911,7 +917,7 @@ extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) noexcept {
extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) noexcept { extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) noexcept {
try { try {
return binop(lhs, rhs, AST_TYPE::Mult); return binop(lhs, rhs, AST_TYPE::Mult);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -919,7 +925,7 @@ extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) noexcept { ...@@ -919,7 +925,7 @@ extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) noexcept {
extern "C" PyObject* PyNumber_Divide(PyObject* lhs, PyObject* rhs) noexcept { extern "C" PyObject* PyNumber_Divide(PyObject* lhs, PyObject* rhs) noexcept {
try { try {
return binop(lhs, rhs, AST_TYPE::Div); return binop(lhs, rhs, AST_TYPE::Div);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -935,7 +941,7 @@ extern "C" PyObject* PyNumber_TrueDivide(PyObject*, PyObject*) noexcept { ...@@ -935,7 +941,7 @@ extern "C" PyObject* PyNumber_TrueDivide(PyObject*, PyObject*) noexcept {
extern "C" PyObject* PyNumber_Remainder(PyObject* lhs, PyObject* rhs) noexcept { extern "C" PyObject* PyNumber_Remainder(PyObject* lhs, PyObject* rhs) noexcept {
try { try {
return binop(lhs, rhs, AST_TYPE::Mod); return binop(lhs, rhs, AST_TYPE::Mod);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -959,7 +965,7 @@ extern "C" PyObject* PyNumber_Positive(PyObject* o) noexcept { ...@@ -959,7 +965,7 @@ extern "C" PyObject* PyNumber_Positive(PyObject* o) noexcept {
extern "C" PyObject* PyNumber_Absolute(PyObject* o) noexcept { extern "C" PyObject* PyNumber_Absolute(PyObject* o) noexcept {
try { try {
return abs_(o); return abs_(o);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -975,7 +981,7 @@ extern "C" PyObject* PyNumber_Lshift(PyObject*, PyObject*) noexcept { ...@@ -975,7 +981,7 @@ extern "C" PyObject* PyNumber_Lshift(PyObject*, PyObject*) noexcept {
extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) noexcept { extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) noexcept {
try { try {
return binop(lhs, rhs, AST_TYPE::RShift); return binop(lhs, rhs, AST_TYPE::RShift);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
...@@ -983,7 +989,7 @@ extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) noexcept { ...@@ -983,7 +989,7 @@ extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) noexcept {
extern "C" PyObject* PyNumber_And(PyObject* lhs, PyObject* rhs) noexcept { extern "C" PyObject* PyNumber_And(PyObject* lhs, PyObject* rhs) noexcept {
try { try {
return binop(lhs, rhs, AST_TYPE::BitAnd); return binop(lhs, rhs, AST_TYPE::BitAnd);
} catch (Box* b) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
} }
......
...@@ -23,6 +23,8 @@ class BoxedModule; ...@@ -23,6 +23,8 @@ class BoxedModule;
BoxedModule* importTestExtension(const std::string&); BoxedModule* importTestExtension(const std::string&);
void checkAndThrowCAPIException(); void checkAndThrowCAPIException();
struct ExcInfo;
void setCAPIException(const ExcInfo& e);
} }
#endif #endif
...@@ -224,17 +224,17 @@ Box* instanceNonzero(Box* _inst) { ...@@ -224,17 +224,17 @@ Box* instanceNonzero(Box* _inst) {
Box* nonzero_func = NULL; Box* nonzero_func = NULL;
try { try {
nonzero_func = _instanceGetattribute(inst, boxStrConstant("__nonzero__"), false); nonzero_func = _instanceGetattribute(inst, boxStrConstant("__nonzero__"), false);
} catch (Box* b) { } catch (ExcInfo e) {
if (!isInstance(b, AttributeError)) if (!e.matches(AttributeError))
throw; throw e;
} }
if (nonzero_func == NULL) { if (nonzero_func == NULL) {
try { try {
nonzero_func = _instanceGetattribute(inst, boxStrConstant("__len__"), false); nonzero_func = _instanceGetattribute(inst, boxStrConstant("__len__"), false);
} catch (Box* b) { } catch (ExcInfo e) {
if (!isInstance(b, AttributeError)) if (!e.matches(AttributeError))
throw; throw e;
} }
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "runtime/dict.h" #include "runtime/dict.h"
#include "capi/types.h"
#include "core/common.h" #include "core/common.h"
#include "core/stats.h" #include "core/stats.h"
#include "core/types.h" #include "core/types.h"
...@@ -136,8 +137,8 @@ extern "C" PyObject* PyDict_Copy(PyObject* o) noexcept { ...@@ -136,8 +137,8 @@ extern "C" PyObject* PyDict_Copy(PyObject* o) noexcept {
RELEASE_ASSERT(PyDict_Check(o), ""); RELEASE_ASSERT(PyDict_Check(o), "");
try { try {
return dictCopy(static_cast<BoxedDict*>(o)); return dictCopy(static_cast<BoxedDict*>(o));
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -179,7 +180,7 @@ extern "C" int PyDict_SetItem(PyObject* mp, PyObject* _key, PyObject* _item) noe ...@@ -179,7 +180,7 @@ extern "C" int PyDict_SetItem(PyObject* mp, PyObject* _key, PyObject* _item) noe
try { try {
// TODO should demote GIL? // TODO should demote GIL?
setitem(b, key, item); setitem(b, key, item);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
return 0; return 0;
...@@ -189,7 +190,7 @@ extern "C" int PyDict_SetItemString(PyObject* mp, const char* key, PyObject* ite ...@@ -189,7 +190,7 @@ extern "C" int PyDict_SetItemString(PyObject* mp, const char* key, PyObject* ite
Box* key_s; Box* key_s;
try { try {
key_s = boxStrConstant(key); key_s = boxStrConstant(key);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
...@@ -200,8 +201,8 @@ extern "C" PyObject* PyDict_GetItem(PyObject* dict, PyObject* key) noexcept { ...@@ -200,8 +201,8 @@ extern "C" PyObject* PyDict_GetItem(PyObject* dict, PyObject* key) noexcept {
ASSERT(dict->cls == dict_cls || dict->cls == attrwrapper_cls, "%s", getTypeName(dict)->c_str()); ASSERT(dict->cls == dict_cls || dict->cls == attrwrapper_cls, "%s", getTypeName(dict)->c_str());
try { try {
return getitem(dict, key); return getitem(dict, key);
} catch (Box* b) { } catch (ExcInfo e) {
if (isSubclass(b->cls, KeyError)) if (e.matches(KeyError))
return NULL; return NULL;
abort(); abort();
} }
...@@ -215,7 +216,7 @@ extern "C" PyObject* PyDict_GetItemString(PyObject* dict, const char* key) noexc ...@@ -215,7 +216,7 @@ extern "C" PyObject* PyDict_GetItemString(PyObject* dict, const char* key) noexc
Box* key_s; Box* key_s;
try { try {
key_s = boxStrConstant(key); key_s = boxStrConstant(key);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
return PyDict_GetItem(dict, key_s); return PyDict_GetItem(dict, key_s);
...@@ -404,8 +405,8 @@ extern "C" int PyDict_Merge(PyObject* a, PyObject* b, int override_) noexcept { ...@@ -404,8 +405,8 @@ extern "C" int PyDict_Merge(PyObject* a, PyObject* b, int override_) noexcept {
try { try {
dictMerge(static_cast<BoxedDict*>(a), b); dictMerge(static_cast<BoxedDict*>(a), b);
return 0; return 0;
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return -1; return -1;
} }
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include "capi/types.h"
#include "core/common.h" #include "core/common.h"
#include "core/stats.h" #include "core/stats.h"
#include "core/types.h" #include "core/types.h"
...@@ -205,8 +206,8 @@ extern "C" int PyFile_WriteObject(PyObject* v, PyObject* f, int flags) noexcept ...@@ -205,8 +206,8 @@ extern "C" int PyFile_WriteObject(PyObject* v, PyObject* f, int flags) noexcept
Box* r = fileWrite(static_cast<BoxedFile*>(f), v); Box* r = fileWrite(static_cast<BoxedFile*>(f), v);
assert(r == None); assert(r == None);
return 0; return 0;
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return -1; return -1;
} }
} }
...@@ -271,7 +272,7 @@ extern "C" int PyObject_AsFileDescriptor(PyObject* o) noexcept { ...@@ -271,7 +272,7 @@ extern "C" int PyObject_AsFileDescriptor(PyObject* o) noexcept {
extern "C" int PyFile_SoftSpace(PyObject* f, int newflag) noexcept { extern "C" int PyFile_SoftSpace(PyObject* f, int newflag) noexcept {
try { try {
return softspace(f, newflag); return softspace(f, newflag);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
} }
......
...@@ -53,7 +53,7 @@ static void generatorEntry(BoxedGenerator* g) { ...@@ -53,7 +53,7 @@ static void generatorEntry(BoxedGenerator* g) {
Box** args = g->args ? &g->args->elts[0] : nullptr; Box** args = g->args ? &g->args->elts[0] : nullptr;
callCLFunc(func->f, nullptr, func->f->numReceivedArgs(), func->closure, g, g->arg1, g->arg2, g->arg3, args); callCLFunc(func->f, nullptr, func->f->numReceivedArgs(), func->closure, g, g->arg1, g->arg2, g->arg3, args);
} catch (Box* e) { } catch (ExcInfo e) {
// unhandled exception: propagate the exception to the caller // unhandled exception: propagate the exception to the caller
g->exception = e; g->exception = e;
} }
...@@ -85,8 +85,8 @@ Box* generatorSend(Box* s, Box* v) { ...@@ -85,8 +85,8 @@ Box* generatorSend(Box* s, Box* v) {
self->running = false; self->running = false;
// propagate exception to the caller // propagate exception to the caller
if (self->exception) if (self->exception.type)
raiseExc(self->exception); raiseRaw(self->exception);
// throw StopIteration if the generator exited // throw StopIteration if the generator exited
if (self->entryExited) if (self->entryExited)
...@@ -99,7 +99,8 @@ Box* generatorThrow(Box* s, BoxedClass* e) { ...@@ -99,7 +99,8 @@ Box* generatorThrow(Box* s, BoxedClass* e) {
assert(s->cls == generator_cls); assert(s->cls == generator_cls);
assert(isSubclass(e, Exception)); assert(isSubclass(e, Exception));
BoxedGenerator* self = static_cast<BoxedGenerator*>(s); BoxedGenerator* self = static_cast<BoxedGenerator*>(s);
self->exception = exceptionNew1(e); Box* ex = exceptionNew1(e);
self->exception = ExcInfo(ex->cls, ex, NULL);
return generatorSend(self, None); return generatorSend(self, None);
} }
...@@ -128,10 +129,10 @@ extern "C" Box* yield(BoxedGenerator* obj, Box* value) { ...@@ -128,10 +129,10 @@ extern "C" Box* yield(BoxedGenerator* obj, Box* value) {
threading::pushGenerator(obj, obj->stack_begin, (void*)obj->returnContext.uc_mcontext.gregs[REG_RSP]); threading::pushGenerator(obj, obj->stack_begin, (void*)obj->returnContext.uc_mcontext.gregs[REG_RSP]);
// if the generator receives a exception from the caller we have to throw it // if the generator receives a exception from the caller we have to throw it
if (self->exception) { if (self->exception.type) {
Box* exception = self->exception; ExcInfo e = self->exception;
self->exception = nullptr; self->exception = ExcInfo(NULL, NULL, NULL);
raiseExc(exception); raiseRaw(e);
} }
return self->returnValue; return self->returnValue;
} }
...@@ -146,7 +147,7 @@ extern "C" BoxedGenerator* createGenerator(BoxedFunction* function, Box* arg1, B ...@@ -146,7 +147,7 @@ extern "C" BoxedGenerator* createGenerator(BoxedFunction* function, Box* arg1, B
extern "C" BoxedGenerator::BoxedGenerator(BoxedFunction* function, Box* arg1, Box* arg2, Box* arg3, Box** args) extern "C" BoxedGenerator::BoxedGenerator(BoxedFunction* function, Box* arg1, Box* arg2, Box* arg3, Box** args)
: function(function), arg1(arg1), arg2(arg2), arg3(arg3), args(nullptr), entryExited(false), running(false), : function(function), arg1(arg1), arg2(arg2), arg3(arg3), args(nullptr), entryExited(false), running(false),
returnValue(nullptr), exception(nullptr) { returnValue(nullptr), exception(nullptr, nullptr, nullptr) {
giveAttr("__name__", boxString(function->f->source->getName())); giveAttr("__name__", boxString(function->f->source->getName()));
...@@ -214,8 +215,12 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) { ...@@ -214,8 +215,12 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
reinterpret_cast<void* const*>(&g->args->elts[num_args - 3])); reinterpret_cast<void* const*>(&g->args->elts[num_args - 3]));
if (g->returnValue) if (g->returnValue)
v->visit(g->returnValue); v->visit(g->returnValue);
if (g->exception) if (g->exception.type)
v->visit(g->exception); v->visit(g->exception.type);
if (g->exception.value)
v->visit(g->exception.value);
if (g->exception.traceback)
v->visit(g->exception.traceback);
if (g->running) { if (g->running) {
v->visitPotentialRange((void**)&g->returnContext, v->visitPotentialRange((void**)&g->returnContext,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <cmath> #include <cmath>
#include <sstream> #include <sstream>
#include "capi/types.h"
#include "core/common.h" #include "core/common.h"
#include "core/options.h" #include "core/options.h"
#include "core/stats.h" #include "core/stats.h"
...@@ -39,7 +40,7 @@ Box* seqiterHasnext(Box* s) { ...@@ -39,7 +40,7 @@ Box* seqiterHasnext(Box* s) {
Box* next; Box* next;
try { try {
next = getitem(self->b, boxInt(self->idx)); next = getitem(self->b, boxInt(self->idx));
} catch (Box* b) { } catch (ExcInfo e) {
return False; return False;
} }
self->idx++; self->idx++;
...@@ -75,12 +76,12 @@ Box* iterwrapperHasnext(Box* s) { ...@@ -75,12 +76,12 @@ Box* iterwrapperHasnext(Box* s) {
try { try {
next = callattr(self->iter, &next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), next = callattr(self->iter, &next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
} catch (Box* b) { } catch (ExcInfo e) {
if (isSubclass(b->cls, StopIteration)) { if (e.matches(StopIteration)) {
self->next = NULL; self->next = NULL;
return False; return False;
} }
throw; throw e;
} }
self->next = next; self->next = next;
return True; return True;
...@@ -99,8 +100,8 @@ Box* iterwrapperNext(Box* s) { ...@@ -99,8 +100,8 @@ Box* iterwrapperNext(Box* s) {
extern "C" PyObject* PySeqIter_New(PyObject* seq) noexcept { extern "C" PyObject* PySeqIter_New(PyObject* seq) noexcept {
try { try {
return new BoxedSeqIter(seq); return new BoxedSeqIter(seq);
} catch (Box* e) { } catch (ExcInfo e) {
PyErr_SetObject(e->cls, e); setCAPIException(e);
return NULL; return NULL;
} }
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include "capi/types.h"
#include "core/ast.h" #include "core/ast.h"
#include "core/common.h" #include "core/common.h"
#include "core/stats.h" #include "core/stats.h"
...@@ -32,7 +33,7 @@ namespace pyston { ...@@ -32,7 +33,7 @@ namespace pyston {
extern "C" int PyList_Append(PyObject* op, PyObject* newitem) noexcept { extern "C" int PyList_Append(PyObject* op, PyObject* newitem) noexcept {
try { try {
listAppend(op, newitem); listAppend(op, newitem);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
return 0; return 0;
...@@ -149,7 +150,7 @@ extern "C" PyObject* PyList_GetItem(PyObject* op, Py_ssize_t i) noexcept { ...@@ -149,7 +150,7 @@ extern "C" PyObject* PyList_GetItem(PyObject* op, Py_ssize_t i) noexcept {
RELEASE_ASSERT(i >= 0, ""); // unlike list.__getitem__, PyList_GetItem doesn't do index wrapping RELEASE_ASSERT(i >= 0, ""); // unlike list.__getitem__, PyList_GetItem doesn't do index wrapping
try { try {
return listGetitemUnboxed(static_cast<BoxedList*>(op), i); return listGetitemUnboxed(static_cast<BoxedList*>(op), i);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
} }
...@@ -539,7 +540,7 @@ extern "C" PyObject* PyList_New(Py_ssize_t size) noexcept { ...@@ -539,7 +540,7 @@ extern "C" PyObject* PyList_New(Py_ssize_t size) noexcept {
RELEASE_ASSERT(size == 0, ""); RELEASE_ASSERT(size == 0, "");
try { try {
return new BoxedList(); return new BoxedList();
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
} }
...@@ -622,8 +623,8 @@ extern "C" PyObject* _PyList_Extend(PyListObject* self, PyObject* b) noexcept { ...@@ -622,8 +623,8 @@ extern "C" PyObject* _PyList_Extend(PyListObject* self, PyObject* b) noexcept {
try { try {
return listIAdd(l, b); return listIAdd(l, b);
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return NULL; return NULL;
} }
} }
...@@ -643,8 +644,8 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P ...@@ -643,8 +644,8 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
else else
listDelitemSlice(l, new BoxedSlice(boxInt(ilow), boxInt(ihigh), None)); listDelitemSlice(l, new BoxedSlice(boxInt(ilow), boxInt(ihigh), None));
return 0; return 0;
} catch (Box* b) { } catch (ExcInfo e) {
PyErr_SetObject(b->cls, b); setCAPIException(e);
return -1; return -1;
} }
} }
......
...@@ -94,7 +94,7 @@ extern "C" unsigned long PyLong_AsUnsignedLong(PyObject* vv) noexcept { ...@@ -94,7 +94,7 @@ extern "C" unsigned long PyLong_AsUnsignedLong(PyObject* vv) noexcept {
try { try {
return asUnsignedLong(l); return asUnsignedLong(l);
} catch (Box* e) { } catch (ExcInfo e) {
abort(); abort();
} }
} }
......
...@@ -1748,7 +1748,7 @@ extern "C" BoxedString* reprOrNull(Box* obj) { ...@@ -1748,7 +1748,7 @@ extern "C" BoxedString* reprOrNull(Box* obj) {
Box* r = repr(obj); Box* r = repr(obj);
assert(r->cls == str_cls); // this should be checked by repr() assert(r->cls == str_cls); // this should be checked by repr()
return static_cast<BoxedString*>(r); return static_cast<BoxedString*>(r);
} catch (Box* b) { } catch (ExcInfo e) {
return nullptr; return nullptr;
} }
} }
...@@ -1757,7 +1757,7 @@ extern "C" BoxedString* strOrNull(Box* obj) { ...@@ -1757,7 +1757,7 @@ extern "C" BoxedString* strOrNull(Box* obj) {
try { try {
BoxedString* r = str(obj); BoxedString* r = str(obj);
return static_cast<BoxedString*>(r); return static_cast<BoxedString*>(r);
} catch (Box* b) { } catch (ExcInfo e) {
return nullptr; return nullptr;
} }
} }
...@@ -3879,10 +3879,10 @@ extern "C" Box* importStar(Box* _from_module, BoxedModule* to_module) { ...@@ -3879,10 +3879,10 @@ extern "C" Box* importStar(Box* _from_module, BoxedModule* to_module) {
Box* attr_name; Box* attr_name;
try { try {
attr_name = runtimeCallInternal2(all_getitem, NULL, ArgPassSpec(2), all, boxInt(idx)); attr_name = runtimeCallInternal2(all_getitem, NULL, ArgPassSpec(2), all, boxInt(idx));
} catch (Box* b) { } catch (ExcInfo e) {
if (b->cls == IndexError) if (e.matches(IndexError))
break; break;
throw; throw e;
} }
idx++; idx++;
......
...@@ -34,6 +34,7 @@ class BoxedGenerator; ...@@ -34,6 +34,7 @@ class BoxedGenerator;
extern "C" void raise0() __attribute__((__noreturn__)); extern "C" void raise0() __attribute__((__noreturn__));
extern "C" void raise3(Box*, Box*, Box*) __attribute__((__noreturn__)); extern "C" void raise3(Box*, Box*, Box*) __attribute__((__noreturn__));
void raiseExc(Box* exc_obj) __attribute__((__noreturn__)); void raiseExc(Box* exc_obj) __attribute__((__noreturn__));
void raiseRaw(const ExcInfo& e) __attribute__((__noreturn__));
// helper function for raising from the runtime: // helper function for raising from the runtime:
void raiseExcHelper(BoxedClass*, const char* fmt, ...) __attribute__((__noreturn__)); void raiseExcHelper(BoxedClass*, const char* fmt, ...) __attribute__((__noreturn__));
...@@ -138,5 +139,7 @@ static const char* objectNewParameterTypeErrorMsg() { ...@@ -138,5 +139,7 @@ static const char* objectNewParameterTypeErrorMsg() {
return "object.__new__() takes no parameters"; return "object.__new__() takes no parameters";
} }
} }
bool exceptionMatches(const ExcInfo& e, BoxedClass* cls);
} }
#endif #endif
...@@ -98,10 +98,10 @@ void unwindExc(Box* exc_obj) { ...@@ -98,10 +98,10 @@ void unwindExc(Box* exc_obj) {
static gc::GCRootHandle last_exc; static gc::GCRootHandle last_exc;
static std::vector<const LineInfo*> last_tb; static std::vector<const LineInfo*> last_tb;
void raiseRaw(Box* exc_obj) __attribute__((__noreturn__)); void raiseRaw(const ExcInfo& e) __attribute__((__noreturn__));
void raiseRaw(Box* exc_obj) { void raiseRaw(const ExcInfo& e) {
// Using libgcc: // Using libgcc:
throw exc_obj; throw e;
// Using libunwind // Using libunwind
// unwindExc(exc_obj); // unwindExc(exc_obj);
...@@ -112,7 +112,7 @@ void raiseExc(Box* exc_obj) { ...@@ -112,7 +112,7 @@ void raiseExc(Box* exc_obj) {
last_tb = std::move(entries); last_tb = std::move(entries);
last_exc = exc_obj; last_exc = exc_obj;
raiseRaw(exc_obj); raiseRaw(ExcInfo(exc_obj->cls, exc_obj, NULL));
} }
// Have a special helper function for syntax errors, since we want to include the location // Have a special helper function for syntax errors, since we want to include the location
...@@ -125,7 +125,7 @@ void raiseSyntaxError(const char* msg, int lineno, int col_offset, const std::st ...@@ -125,7 +125,7 @@ void raiseSyntaxError(const char* msg, int lineno, int col_offset, const std::st
// TODO: leaks this! // TODO: leaks this!
last_tb.push_back(new LineInfo(lineno, col_offset, file, func)); last_tb.push_back(new LineInfo(lineno, col_offset, file, func));
raiseRaw(last_exc); raiseRaw(ExcInfo(SyntaxError, last_exc, NULL));
} }
static void _printTraceback(const std::vector<const LineInfo*>& tb) { static void _printTraceback(const std::vector<const LineInfo*>& tb) {
...@@ -216,7 +216,12 @@ extern "C" void exit(int code) { ...@@ -216,7 +216,12 @@ extern "C" void exit(int code) {
} }
void raise0() { void raise0() {
raiseRaw(last_exc); raiseRaw(ExcInfo(last_exc->cls, last_exc, NULL));
}
bool ExcInfo::matches(BoxedClass* cls) const {
RELEASE_ASSERT(isSubclass(this->type->cls, type_cls), "throwing old-style objects not supported yet");
return isSubclass(static_cast<BoxedClass*>(this->type), cls);
} }
void raise3(Box* arg0, Box* arg1, Box* arg2) { void raise3(Box* arg0, Box* arg1, Box* arg2) {
......
...@@ -73,7 +73,7 @@ extern "C" PyObject* PyTuple_GetItem(PyObject* op, Py_ssize_t i) noexcept { ...@@ -73,7 +73,7 @@ extern "C" PyObject* PyTuple_GetItem(PyObject* op, Py_ssize_t i) noexcept {
RELEASE_ASSERT(i >= 0, ""); // unlike tuple.__getitem__, PyTuple_GetItem doesn't do index wrapping RELEASE_ASSERT(i >= 0, ""); // unlike tuple.__getitem__, PyTuple_GetItem doesn't do index wrapping
try { try {
return tupleGetitemUnboxed(static_cast<BoxedTuple*>(op), i); return tupleGetitemUnboxed(static_cast<BoxedTuple*>(op), i);
} catch (Box* b) { } catch (ExcInfo e) {
abort(); abort();
} }
} }
......
...@@ -240,12 +240,12 @@ BoxIterator& BoxIterator::operator++() { ...@@ -240,12 +240,12 @@ BoxIterator& BoxIterator::operator++() {
} else { } else {
try { try {
value = iter->nextIC(); value = iter->nextIC();
} catch (Box* e) { } catch (ExcInfo e) {
if ((e == StopIteration) || isSubclass(e->cls, StopIteration)) { if (e.matches(StopIteration)) {
iter = nullptr; iter = nullptr;
value = nullptr; value = nullptr;
} else } else
throw; throw e;
} }
} }
return *this; return *this;
...@@ -531,12 +531,12 @@ extern "C" Box* createUserClass(std::string* name, Box* _bases, Box* _attr_dict) ...@@ -531,12 +531,12 @@ extern "C" Box* createUserClass(std::string* name, Box* _bases, Box* _attr_dict)
Box* r = runtimeCall(metaclass, ArgPassSpec(3), boxStringPtr(name), _bases, _attr_dict, NULL, NULL); Box* r = runtimeCall(metaclass, ArgPassSpec(3), boxStringPtr(name), _bases, _attr_dict, NULL, NULL);
RELEASE_ASSERT(r, ""); RELEASE_ASSERT(r, "");
return r; return r;
} catch (Box* b) { } catch (ExcInfo e) {
// TODO [CAPI] bad error handling... // TODO [CAPI] bad error handling...
RELEASE_ASSERT(isSubclass(b->cls, BaseException), ""); RELEASE_ASSERT(e.matches(BaseException), "");
Box* msg = b->getattr("message"); Box* msg = e.value->getattr("message");
RELEASE_ASSERT(msg, ""); RELEASE_ASSERT(msg, "");
RELEASE_ASSERT(msg->cls == str_cls, ""); RELEASE_ASSERT(msg->cls == str_cls, "");
...@@ -545,7 +545,7 @@ extern "C" Box* createUserClass(std::string* name, Box* _bases, Box* _attr_dict) ...@@ -545,7 +545,7 @@ extern "C" Box* createUserClass(std::string* name, Box* _bases, Box* _attr_dict)
" %s", " %s",
PyString_AS_STRING(msg)); PyString_AS_STRING(msg));
PyErr_Restore(b->cls, newmsg, NULL); PyErr_Restore(e.type, newmsg, NULL);
checkAndThrowCAPIException(); checkAndThrowCAPIException();
// Should not reach here // Should not reach here
......
...@@ -557,7 +557,7 @@ public: ...@@ -557,7 +557,7 @@ public:
bool entryExited; bool entryExited;
bool running; bool running;
Box* returnValue; Box* returnValue;
Box* exception; ExcInfo exception;
ucontext_t context, returnContext; ucontext_t context, returnContext;
void* stack_begin; void* stack_begin;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment