Commit d2cbb9aa authored by Kevin Modzelewski's avatar Kevin Modzelewski

Handle bare 'raise' statements

Previously, a non-satisfied except filter would cause the traceback
to be lost, since we were using the one-argument 'raise exc' form.
parent 11dc4906
......@@ -1730,15 +1730,21 @@ private:
}
void doRaise(AST_Raise* node, ExcInfo exc_info) {
RELEASE_ASSERT(node->arg0 != NULL, "");
std::vector<llvm::Value*> args;
llvm::Value* raise_func = g.funcs.raise0;
if (node->arg0) {
raise_func = g.funcs.raise1;
CompilerVariable* arg0 = evalExpr(node->arg0, exc_info);
ConcreteCompilerVariable* converted_arg0 = arg0->makeConverted(emitter, arg0->getBoxType());
arg0->decvref(emitter);
args.push_back(converted_arg0->getValue());
}
RELEASE_ASSERT(node->arg1 == NULL, "");
RELEASE_ASSERT(node->arg2 == NULL, "");
CompilerVariable* arg0 = evalExpr(node->arg0, exc_info);
ConcreteCompilerVariable* converted_arg0 = arg0->makeConverted(emitter, arg0->getBoxType());
arg0->decvref(emitter);
emitter.createCall(exc_info, g.funcs.raise1, { converted_arg0->getValue() });
emitter.createCall(exc_info, raise_func, args);
emitter.getBuilder()->CreateUnreachable();
endBlock(DEAD);
......
......@@ -219,6 +219,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(__cxa_begin_catch);
g.funcs.__cxa_end_catch = addFunc((void*)__cxa_end_catch, g.void_);
GET(raise0);
GET(raise1);
g.funcs.div_i64_i64 = getFunc((void*)div_i64_i64, "div_i64_i64");
......
......@@ -44,7 +44,7 @@ struct GlobalFuncs {
llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* __cxa_begin_catch, *__cxa_end_catch;
llvm::Value* raise1;
llvm::Value* raise0, *raise1;
llvm::Value* div_i64_i64, *mod_i64_i64, *pow_i64_i64;
llvm::Value* div_float_float, *mod_float_float, *pow_float_float;
......
......@@ -1530,7 +1530,6 @@ public:
if (!caught_all) {
AST_Raise* raise = new AST_Raise();
raise->arg0 = exc_obj;
push_back(raise);
curblock->push_back(new AST_Unreachable());
curblock = NULL;
......
......@@ -42,6 +42,18 @@ void registerStaticRootObj(void* obj) {
roots.push(obj);
}
static std::unordered_set<StaticRootHandle*>* getRootHandles() {
static std::unordered_set<StaticRootHandle*> root_handles;
return &root_handles;
}
StaticRootHandle::StaticRootHandle() {
getRootHandles()->insert(this);
}
StaticRootHandle::~StaticRootHandle() {
getRootHandles()->erase(this);
}
bool TraceStackGCVisitor::isValid(void* p) {
return global_heap.getAllocationFromInteriorPointer(p);
}
......@@ -105,6 +117,10 @@ static void markPhase() {
TraceStackGCVisitor visitor(&stack);
for (auto h : *getRootHandles()) {
visitor.visitPotential(h->value);
}
// if (VERBOSITY()) printf("Found %d roots\n", stack.size());
while (void* p = stack.pop()) {
assert(((intptr_t)p) % 8 == 0);
......
......@@ -83,6 +83,19 @@ public:
// (that should be registerStaticRootPtr)
void registerStaticRootObj(void* root_obj);
void runCollection();
// If you want to have a static root "location" where multiple values could be stored, use this:
class StaticRootHandle {
public:
Box* value;
StaticRootHandle();
~StaticRootHandle();
void operator=(Box* b) { value = b; }
operator Box*() { return value; }
};
}
}
......
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cmath>
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/gc_runtime.h"
#include "runtime/inline/boxing.h"
#include "runtime/types.h"
#include "runtime/util.h"
namespace pyston {
BoxedModule* posix_module;
void setupPosix() {
posix_module = createModule("posix", "__builtin__");
}
}
......@@ -90,6 +90,7 @@ void force() {
FORCE(runtimeCall);
FORCE(callattr);
FORCE(raise0);
FORCE(raise1);
FORCE(div_i64_i64);
......
......@@ -28,7 +28,8 @@ class BoxedInt;
class BoxedList;
class BoxedString;
// user-level raise function that implements some python-level semantics
// user-level raise functions that implement python-level semantics
extern "C" void raise0() __attribute__((__noreturn__));
extern "C" void raise1(Box*) __attribute__((__noreturn__));
extern "C" void raise2(Box*, Box*) __attribute__((__noreturn__));
extern "C" void raise3(Box*, Box*, Box*) __attribute__((__noreturn__));
......
......@@ -20,6 +20,7 @@
#include "codegen/codegen.h"
#include "codegen/llvm_interpreter.h"
#include "core/options.h"
#include "gc/collector.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"
......@@ -100,21 +101,25 @@ void unwindExc(Box* exc_obj) {
}
static std::vector<const LineInfo*> getTracebackEntries();
static gc::StaticRootHandle last_exc;
static std::vector<const LineInfo*> last_tb;
void raiseExc(Box* exc_obj) __attribute__((__noreturn__));
void raiseExc(Box* exc_obj) {
auto entries = getTracebackEntries();
last_tb = std::move(entries);
void raiseRaw(Box* exc_obj) __attribute__((__noreturn__));
void raiseRaw(Box* exc_obj) {
// Using libgcc:
throw exc_obj;
// Using libunwind
// unwindExc(exc_obj);
}
abort();
void raiseExc(Box* exc_obj) __attribute__((__noreturn__));
void raiseExc(Box* exc_obj) {
auto entries = getTracebackEntries();
last_tb = std::move(entries);
last_exc = exc_obj;
raiseRaw(exc_obj);
}
void printLastTraceback() {
......@@ -190,6 +195,10 @@ static std::vector<const LineInfo*> getTracebackEntries() {
return entries;
}
void raise0() {
raiseRaw(last_exc);
}
void raise1(Box* b) {
if (b->cls == type_cls) {
BoxedClass* c = static_cast<BoxedClass*>(b);
......
......@@ -599,9 +599,10 @@ void setupRuntime() {
setupBuiltins();
setupMath();
setupErrno();
setupTime();
setupThread();
setupErrno();
setupPosix();
setupCAPI();
......
......@@ -58,6 +58,7 @@ void setupMath();
void setupTime();
void setupThread();
void setupErrno();
void setupPosix();
void setupSysEnd();
BoxedDict* getSysModulesDict();
......
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