Commit 14b247f7 authored by Kevin Modzelewski's avatar Kevin Modzelewski

'raise Exception' behaves the same as 'raise Exception()'

The python stdlib apparently uses a bunch of old-style ways
of doing things.

Instead of doing the throwing directly in the generated IR, call
a runtime function raise1 which will take care of the semantics
of checking the type of the raised object, etc.
parent 212383bf
......@@ -31,13 +31,6 @@
#include "runtime/objmodel.h"
#include "runtime/types.h"
extern "C" {
// Hack: we only need RTTI for a single type (Box*), which we know will get emmitted,
// so just use the mangled name directly instead of using typeid() since that requires
// turning on RTTI for *everything* (including llvm)
extern void* _ZTIPN6pyston3BoxE;
}
namespace pyston {
llvm::Value* IRGenState::getScratchSpace(int min_bytes) {
......@@ -1745,15 +1738,7 @@ private:
ConcreteCompilerVariable* converted_arg0 = arg0->makeConverted(emitter, arg0->getBoxType());
arg0->decvref(emitter);
llvm::Value* exc_mem
= emitter.getBuilder()->CreateCall(g.funcs.__cxa_allocate_exception, getConstantInt(sizeof(void*), g.i64));
llvm::Value* bitcasted = emitter.getBuilder()->CreateBitCast(exc_mem, g.llvm_value_type_ptr->getPointerTo());
emitter.getBuilder()->CreateStore(converted_arg0->getValue(), bitcasted);
converted_arg0->decvref(emitter);
void* type_id = &_ZTIPN6pyston3BoxE /* &typeid(Box*) */;
emitter.createCall(exc_info, g.funcs.__cxa_throw,
{ exc_mem, embedConstantPtr(type_id, g.i8_ptr), embedConstantPtr(nullptr, g.i8_ptr) });
emitter.createCall(exc_info, g.funcs.raise1, { converted_arg0->getValue() });
emitter.getBuilder()->CreateUnreachable();
endBlock(DEAD);
......
......@@ -41,8 +41,6 @@
extern "C" void* __cxa_begin_catch(void*);
extern "C" void __cxa_end_catch();
extern "C" void* __cxa_allocate_exception(size_t);
extern "C" void __cxa_throw(void*, void*, void (*)(void*));
namespace pyston {
......@@ -221,8 +219,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(__cxa_begin_catch);
g.funcs.__cxa_end_catch = addFunc((void*)__cxa_end_catch, g.void_);
g.funcs.__cxa_allocate_exception = addFunc((void*)__cxa_allocate_exception, g.i8_ptr, g.i64);
g.funcs.__cxa_throw = addFunc((void*)__cxa_throw, g.void_, g.i8_ptr, g.i8_ptr, g.i8_ptr);
GET(raise1);
g.funcs.div_i64_i64 = getFunc((void*)div_i64_i64, "div_i64_i64");
g.funcs.mod_i64_i64 = getFunc((void*)mod_i64_i64, "mod_i64_i64");
......
......@@ -43,7 +43,8 @@ struct GlobalFuncs {
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr;
llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* __cxa_begin_catch, *__cxa_end_catch, *__cxa_allocate_exception, *__cxa_throw;
llvm::Value* __cxa_begin_catch, *__cxa_end_catch;
llvm::Value* raise1;
llvm::Value* div_i64_i64, *mod_i64_i64, *pow_i64_i64;
llvm::Value* div_float_float, *mod_float_float, *pow_float_float;
......
......@@ -1413,6 +1413,9 @@ public:
remapped->arg2 = remapExpr(node->arg2);
push_back(remapped);
if (!curblock)
return true;
curblock->push_back(new AST_Unreachable());
curblock = NULL;
......
......@@ -90,6 +90,8 @@ void force() {
FORCE(runtimeCall);
FORCE(callattr);
FORCE(raise1);
FORCE(div_i64_i64);
FORCE(mod_i64_i64);
FORCE(pow_i64_i64);
......
......@@ -28,7 +28,13 @@ class BoxedInt;
class BoxedList;
class BoxedString;
void raiseExc(Box*) __attribute__((__noreturn__));
// "raw" raising function that will engage the unwinding machinery
void raiseRaw(Box*) __attribute__((__noreturn__));
// user-level raise function that implements some python-level semantics
extern "C" void raise1(Box*) __attribute__((__noreturn__));
extern "C" void raise2(Box*, Box*) __attribute__((__noreturn__));
extern "C" void raise3(Box*, Box*, Box*) __attribute__((__noreturn__));
// helper function for raising from the runtime:
void raiseExcHelper(BoxedClass*, const char* fmt, ...) __attribute__((__noreturn__));
extern "C" const std::string* getTypeName(Box* o);
......
......@@ -99,7 +99,7 @@ void unwindExc(Box* exc_obj) {
abort();
}
void raiseExc(Box* exc_obj) {
void raiseRaw(Box* exc_obj) {
// Using libgcc:
throw exc_obj;
......@@ -183,6 +183,23 @@ static std::vector<const LineInfo*> getTracebackEntries() {
return entries;
}
void raise1(Box* b) {
if (b->cls == type_cls) {
BoxedClass* c = static_cast<BoxedClass*>(b);
if (isSubclass(c, Exception)) {
auto exc_obj = exceptionNew1(c);
raiseRaw(exc_obj);
} else {
raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s",
getTypeName(b)->c_str());
}
}
// TODO: should only allow throwing of old-style classes or things derived
// from BaseException:
raiseRaw(b);
}
void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
auto entries = getTracebackEntries();
last_tb = std::move(entries);
......@@ -203,10 +220,10 @@ void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
BoxedString* message = boxStrConstant(buf);
Box* exc_obj = exceptionNew2(cls, message);
raiseExc(exc_obj);
raiseRaw(exc_obj);
} else {
Box* exc_obj = exceptionNew1(cls);
raiseExc(exc_obj);
raiseRaw(exc_obj);
}
}
......@@ -223,6 +240,8 @@ std::string formatException(Box* b) {
assert(r->cls == str_cls);
const std::string* msg = &r->s;
return *name + ": " + *msg;
if (msg->size())
return *name + ": " + *msg;
return *name;
}
}
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