Commit 7efd8225 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Exceptions part #2: AST and CFG support

parent a4b0c853
......@@ -283,7 +283,7 @@ $(UNITTEST_DIR)/$1: $(GTEST_DIR)/src/gtest-all.o $(NON_ENTRY_OBJS) $(BUILD_SYSTE
$(ECHO) Linking $$@
$(VERB) $(CXX) $(NON_ENTRY_OBJS) $(GTEST_DIR)/src/gtest-all.o $(GTEST_DIR)/src/gtest_main.o $(UNITTEST_DIR)/$1.o $(LDFLAGS) -o $$@
dbg_$1_unittests: $(UNITTEST_DIR)/$1
zsh -c 'ulimit -v $(MAX_MEM_KB); ulimit -d $(MAX_MEM_KB); time gdb $(GDB_CMDS) --args ./$(UNITTEST_DIR)/$1 --gtest_break_on_failure $(ARGS)'
zsh -c 'ulimit -v $(MAX_MEM_KB); ulimit -d $(MAX_MEM_KB); time $(GDB) $(GDB_CMDS) --args ./$(UNITTEST_DIR)/$1 --gtest_break_on_failure $(ARGS)'
run_$1_unittests: $(UNITTEST_DIR)/$1
zsh -c 'ulimit -v $(MAX_MEM_KB); ulimit -d $(MAX_MEM_KB); time ./$(UNITTEST_DIR)/$1 $(ARGS)'
run_unittests:: run_$1_unittests
......
......@@ -177,9 +177,11 @@ public:
virtual bool visit_branch(AST_Branch* node) { return true; }
virtual bool visit_expr(AST_Expr* node) { return true; }
virtual bool visit_global(AST_Global* node) { return true; }
virtual bool visit_invoke(AST_Invoke* node) { return false; }
virtual bool visit_jump(AST_Jump* node) { return true; }
virtual bool visit_pass(AST_Pass* node) { return true; }
virtual bool visit_print(AST_Print* node) { return true; }
virtual bool visit_raise(AST_Raise* node) { return true; }
virtual bool visit_return(AST_Return* node) { return true; }
virtual bool visit_classdef(AST_ClassDef* node) {
......
......@@ -145,6 +145,7 @@ public:
}
virtual bool visit_arguments(AST_arguments* node) { return false; }
virtual bool visit_assert(AST_Assert* node) { return false; }
virtual bool visit_assign(AST_Assign* node) { return false; }
virtual bool visit_augassign(AST_AugAssign* node) { return false; }
virtual bool visit_attribute(AST_Attribute* node) { return false; }
......@@ -157,6 +158,7 @@ public:
// virtual bool visit_classdef(AST_ClassDef *node) { return false; }
virtual bool visit_continue(AST_Continue* node) { return false; }
virtual bool visit_dict(AST_Dict* node) { return false; }
virtual bool visit_excepthandler(AST_ExceptHandler* node) { return false; }
virtual bool visit_expr(AST_Expr* node) { return false; }
virtual bool visit_for(AST_For* node) { return false; }
// virtual bool visit_functiondef(AST_FunctionDef *node) { return false; }
......@@ -172,11 +174,14 @@ public:
virtual bool visit_num(AST_Num* node) { return false; }
virtual bool visit_pass(AST_Pass* node) { return false; }
virtual bool visit_print(AST_Print* node) { return false; }
virtual bool visit_raise(AST_Raise* node) { return false; }
virtual bool visit_repr(AST_Repr* node) { return false; }
virtual bool visit_return(AST_Return* node) { return false; }
virtual bool visit_slice(AST_Slice* node) { return false; }
virtual bool visit_str(AST_Str* node) { return false; }
virtual bool visit_subscript(AST_Subscript* node) { return false; }
virtual bool visit_tryexcept(AST_TryExcept* node) { return false; }
virtual bool visit_tryfinally(AST_TryFinally* node) { return false; }
virtual bool visit_tuple(AST_Tuple* node) { return false; }
virtual bool visit_unaryop(AST_UnaryOp* node) { return false; }
virtual bool visit_while(AST_While* node) { return false; }
......
......@@ -329,6 +329,17 @@ private:
virtual void* visit_index(AST_Index* node) { return getType(node->value); }
virtual void* visit_langprimitive(AST_LangPrimitive* node) {
switch (node->opcode) {
case AST_LangPrimitive::ISINSTANCE:
return BOOL;
case AST_LangPrimitive::LANDINGPAD:
return UNKNOWN;
default:
RELEASE_ASSERT(0, "%d", node->opcode);
}
}
virtual void* visit_list(AST_List* node) {
// Get all the sub-types, even though they're not necessary to
// determine the expression type, so that things like speculations
......@@ -459,6 +470,8 @@ private:
visit_alias(alias);
}
virtual void visit_invoke(AST_Invoke* node) { node->stmt->accept_stmt(this); }
virtual void visit_jump(AST_Jump* node) {}
virtual void visit_pass(AST_Pass* node) {}
......@@ -473,6 +486,17 @@ private:
}
}
virtual void visit_raise(AST_Raise* node) {
if (EXPAND_UNNEEDED) {
if (node->arg0)
getType(node->arg0);
if (node->arg1)
getType(node->arg1);
if (node->arg2)
getType(node->arg2);
}
}
virtual void visit_return(AST_Return* node) {
if (EXPAND_UNNEEDED) {
if (node->value != NULL)
......
......@@ -144,6 +144,7 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage& Obj) {
code = I->getName(name);
assert(!code);
uint64_t address, size;
const char* type = "unknown";
bool b;
code = I->isText(b);
......@@ -162,7 +163,11 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage& Obj) {
assert(!code);
if (b)
type = "rodata";
printf("Section: %s %s\n", name.data(), type);
code = I->getAddress(address);
assert(!code);
code = I->getSize(size);
assert(!code);
printf("Section: %s %s (%lx %lx)\n", name.data(), type, address, size);
#if LLVMREV < 200442
I = I.increment(code);
......
......@@ -104,9 +104,9 @@ private:
continue;
}
if (CallInst* si = dyn_cast<CallInst>(user)) {
if (llvm::isa<CallInst>(user) || llvm::isa<InvokeInst>(user)) {
if (VERBOSITY() >= 2)
errs() << "Not dead; used here: " << *si << '\n';
errs() << "Not dead; used here: " << *user << '\n';
return true;
}
......
......@@ -132,10 +132,10 @@ bool EscapeAnalysis::runOnFunction(Function& F) {
continue;
}
if (CallInst* si = dyn_cast<CallInst>(user)) {
if (llvm::isa<CallInst>(user) || llvm::isa<InvokeInst>(user)) {
if (VERBOSITY() >= 2)
errs() << "Escapes here: " << *si << '\n';
chain->escape_points.insert(si);
errs() << "Escapes here: " << *user << '\n';
chain->escape_points.insert(dyn_cast<Instruction>(user));
continue;
}
......
......@@ -790,12 +790,24 @@ AST* readASTMisc(BufferedReader* reader) {
}
}
static std::string getParserCommandLine(const char* fn) {
llvm::SmallString<128> parse_ast_fn;
// TODO supposed to pass argv0, main_addr to this function:
parse_ast_fn = llvm::sys::fs::getMainExecutable(NULL, NULL);
assert(parse_ast_fn.size() && "could not find the path to the pyston src dir");
while (llvm::sys::path::filename(parse_ast_fn) != "pyston") {
llvm::sys::path::remove_filename(parse_ast_fn);
}
llvm::sys::path::append(parse_ast_fn, "src/codegen/parse_ast.py");
return std::string("python -S ") + parse_ast_fn.str().str() + " " + fn;
}
AST_Module* parse(const char* fn) {
Timer _t("parsing");
std::string cmdline = "python codegen/parse_ast.py ";
cmdline += fn;
FILE* fp = popen(cmdline.c_str(), "r");
FILE* fp = popen(getParserCommandLine(fn).c_str(), "r");
BufferedReader* reader = new BufferedReader(fp);
AST* rtn = readASTMisc(reader);
......@@ -820,15 +832,7 @@ AST_Module* parse(const char* fn) {
#define LENGTH_SUFFIX_LENGTH 4
static void _reparse(const char* fn, const std::string& cache_fn) {
llvm::SmallString<128> parse_ast_fn;
// TODO supposed to pass argv0, main_addr to this function:
parse_ast_fn = llvm::sys::fs::getMainExecutable(NULL, NULL);
assert(parse_ast_fn.size() && "could not find the path to the pyston src dir");
llvm::sys::path::remove_filename(parse_ast_fn);
llvm::sys::path::append(parse_ast_fn, "codegen/parse_ast.py");
std::string cmdline = std::string("python -S ") + parse_ast_fn.str().str() + " " + fn;
FILE* parser = popen(cmdline.c_str(), "r");
FILE* parser = popen(getParserCommandLine(fn).c_str(), "r");
FILE* cache_fp = fopen(cache_fn.c_str(), "w");
assert(cache_fp);
......
......@@ -513,6 +513,18 @@ void* AST_Index::accept_expr(ExprVisitor* v) {
return v->visit_index(this);
}
void AST_Invoke::accept(ASTVisitor* v) {
bool skip = v->visit_invoke(this);
if (skip)
return;
this->stmt->accept(v);
}
void AST_Invoke::accept_stmt(StmtVisitor* v) {
return v->visit_invoke(this);
}
void AST_keyword::accept(ASTVisitor* v) {
bool skip = v->visit_keyword(this);
if (skip)
......@@ -521,6 +533,18 @@ void AST_keyword::accept(ASTVisitor* v) {
value->accept(v);
}
void AST_LangPrimitive::accept(ASTVisitor* v) {
bool skip = v->visit_langprimitive(this);
if (skip)
return;
visitVector(args, v);
}
void* AST_LangPrimitive::accept_expr(ExprVisitor* v) {
return v->visit_langprimitive(this);
}
void AST_List::accept(ASTVisitor* v) {
bool skip = v->visit_list(this);
if (skip)
......@@ -1175,6 +1199,38 @@ bool PrintVisitor::visit_index(AST_Index* node) {
return false;
}
bool PrintVisitor::visit_invoke(AST_Invoke* node) {
// printf("invoke: ");
// node->value->accept(this);
// printf("; on success goto %d; on error goto %d", node->normal_dest->idx, node->exc_dest->idx);
printf("invoke %d %d: ", node->normal_dest->idx, node->exc_dest->idx);
node->stmt->accept(this);
return true;
}
bool PrintVisitor::visit_langprimitive(AST_LangPrimitive* node) {
printf(":");
switch (node->opcode) {
case AST_LangPrimitive::ISINSTANCE:
printf("isinstance");
break;
case AST_LangPrimitive::LANDINGPAD:
printf("landingpad");
break;
default:
RELEASE_ASSERT(0, "%d", node->opcode);
}
printf("(");
for (int i = 0, n = node->args.size(); i < n; ++i) {
if (i > 0)
printf(", ");
node->args[i]->accept(this);
}
printf(")");
return true;
}
bool PrintVisitor::visit_list(AST_List* node) {
printf("[");
for (int i = 0, n = node->elts.size(); i < n; ++i) {
......@@ -1548,6 +1604,10 @@ public:
output->push_back(node);
return false;
}
virtual bool visit_excepthandler(AST_ExceptHandler* node) {
output->push_back(node);
return false;
}
virtual bool visit_expr(AST_Expr* node) {
output->push_back(node);
return false;
......@@ -1588,6 +1648,10 @@ public:
output->push_back(node);
return false;
}
virtual bool visit_langprimitive(AST_LangPrimitive* node) {
output->push_back(node);
return false;
}
virtual bool visit_list(AST_List* node) {
output->push_back(node);
return false;
......@@ -1616,6 +1680,10 @@ public:
output->push_back(node);
return false;
}
virtual bool visit_raise(AST_Raise* node) {
output->push_back(node);
return false;
}
virtual bool visit_repr(AST_Repr* node) {
output->push_back(node);
return false;
......@@ -1636,6 +1704,14 @@ public:
output->push_back(node);
return false;
}
virtual bool visit_tryexcept(AST_TryExcept* node) {
output->push_back(node);
return false;
}
virtual bool visit_tryfinally(AST_TryFinally* node) {
output->push_back(node);
return false;
}
virtual bool visit_tuple(AST_Tuple* node) {
output->push_back(node);
return false;
......
......@@ -120,6 +120,8 @@ enum AST_TYPE {
Jump = 201,
ClsAttribute = 202,
AugBinOp = 203,
Invoke = 204,
LangPrimitive = 205,
};
};
......@@ -620,7 +622,7 @@ public:
virtual void accept(ASTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
AST_Raise() : AST_stmt(AST_TYPE::Raise) {}
AST_Raise() : AST_stmt(AST_TYPE::Raise), arg0(NULL), arg1(NULL), arg2(NULL) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Raise;
};
......@@ -795,6 +797,41 @@ public:
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::ClsAttribute;
};
class AST_Invoke : public AST_stmt {
public:
AST_stmt* stmt;
CFGBlock* normal_dest, *exc_dest;
virtual void accept(ASTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
AST_Invoke(AST_stmt* stmt) : AST_stmt(AST_TYPE::Invoke), stmt(stmt) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Invoke;
};
// "LangPrimitive" represents operations that "primitive" to the language,
// but aren't directly *exactly* representable as normal Python.
// ClsAttribute would fall into this category, as would isinstance (which
// is not the same as the "isinstance" name since that could get redefined).
class AST_LangPrimitive : public AST_expr {
public:
enum Opcodes {
ISINSTANCE,
LANDINGPAD,
} opcode;
std::vector<AST_expr*> args;
virtual void accept(ASTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
AST_LangPrimitive(Opcodes opcode) : AST_expr(AST_TYPE::LangPrimitive), opcode(opcode) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::LangPrimitive;
};
template <typename T> T* ast_cast(AST* node) {
assert(node->type == T::TYPE);
return static_cast<T*>(node);
......@@ -834,7 +871,9 @@ public:
virtual bool visit_import(AST_Import* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_importfrom(AST_ImportFrom* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_index(AST_Index* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_invoke(AST_Invoke* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_keyword(AST_keyword* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_langprimitive(AST_LangPrimitive* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_list(AST_List* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_listcomp(AST_ListComp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_module(AST_Module* node) { RELEASE_ASSERT(0, ""); }
......@@ -891,7 +930,9 @@ public:
virtual bool visit_import(AST_Import* node) { return false; }
virtual bool visit_importfrom(AST_ImportFrom* node) { return false; }
virtual bool visit_index(AST_Index* node) { return false; }
virtual bool visit_invoke(AST_Invoke* node) { return false; }
virtual bool visit_keyword(AST_keyword* node) { return false; }
virtual bool visit_langprimitive(AST_LangPrimitive* node) { return false; }
virtual bool visit_list(AST_List* node) { return false; }
virtual bool visit_listcomp(AST_ListComp* node) { return false; }
virtual bool visit_module(AST_Module* node) { return false; }
......@@ -931,6 +972,7 @@ public:
virtual void* visit_dict(AST_Dict* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_ifexp(AST_IfExp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_index(AST_Index* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_langprimitive(AST_LangPrimitive* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_list(AST_List* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_listcomp(AST_ListComp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_name(AST_Name* node) { RELEASE_ASSERT(0, ""); }
......@@ -961,6 +1003,7 @@ public:
virtual void visit_if(AST_If* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_import(AST_Import* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_importfrom(AST_ImportFrom* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_invoke(AST_Invoke* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_pass(AST_Pass* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_print(AST_Print* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_raise(AST_Raise* node) { RELEASE_ASSERT(0, ""); }
......@@ -1011,7 +1054,9 @@ public:
virtual bool visit_import(AST_Import* node);
virtual bool visit_importfrom(AST_ImportFrom* node);
virtual bool visit_index(AST_Index* node);
virtual bool visit_invoke(AST_Invoke* node);
virtual bool visit_keyword(AST_keyword* node);
virtual bool visit_langprimitive(AST_LangPrimitive* node);
virtual bool visit_list(AST_List* node);
virtual bool visit_listcomp(AST_ListComp* node);
virtual bool visit_module(AST_Module* node);
......@@ -1050,6 +1095,8 @@ template <class T, class R> void findNodes(const R& roots, std::vector<T*>& outp
output.push_back(reinterpret_cast<T*>(n));
}
}
std::string getOpSymbol(int op_type);
};
#endif
This diff is collapsed.
......@@ -228,7 +228,6 @@ extern "C" Box* callCompiledFunc(CompiledFunction* cf, int64_t nargs, Box* arg1,
std::string getOpName(int op_type);
std::string getReverseOpName(int op_type);
std::string getInplaceOpName(int op_type);
std::string getOpSymbol(int op_type);
std::string getInplaceOpSymbol(int op_type);
typedef bool i1;
......
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