Commit 2affae97 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Get rid of source->ast

parent bcd80646
...@@ -929,7 +929,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -929,7 +929,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
assert(node->args.size() == 1); assert(node->args.size() == 1);
assert(node->args[0]->type == AST_TYPE::Name); assert(node->args[0]->type == AST_TYPE::Name);
RELEASE_ASSERT(source_info->ast->type == AST_TYPE::Module || source_info->ast->type == AST_TYPE::Suite, RELEASE_ASSERT(source_info->ast_type == AST_TYPE::Module || source_info->ast_type == AST_TYPE::Suite,
"import * not supported in functions"); "import * not supported in functions");
Value module = visit_expr(node->args[0]); Value module = visit_expr(node->args[0]);
......
...@@ -59,9 +59,9 @@ void BoxedCode::addVersion(CompiledFunction* compiled) { ...@@ -59,9 +59,9 @@ void BoxedCode::addVersion(CompiledFunction* compiled) {
} }
SourceInfo::SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags future_flags, AST* ast) SourceInfo::SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags future_flags, AST* ast)
: parent_module(m), scoping(std::move(scoping)), ast(ast), cfg(NULL), future_flags(future_flags) { : parent_module(m), scoping(std::move(scoping)), cfg(NULL), future_flags(future_flags), ast_type(ast->type) {
switch (ast->type) { switch (ast_type) {
case AST_TYPE::ClassDef: case AST_TYPE::ClassDef:
case AST_TYPE::Module: case AST_TYPE::Module:
case AST_TYPE::Expression: case AST_TYPE::Expression:
...@@ -73,7 +73,7 @@ SourceInfo::SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags futur ...@@ -73,7 +73,7 @@ SourceInfo::SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags futur
is_generator = containsYield(ast); is_generator = containsYield(ast);
break; break;
default: default:
RELEASE_ASSERT(0, "Unknown type: %d", ast->type); RELEASE_ASSERT(0, "Unknown type: %d", ast_type);
break; break;
} }
} }
......
...@@ -551,8 +551,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -551,8 +551,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
if (block == cfg->getStartingBlock()) { if (block == cfg->getStartingBlock()) {
assert(entry_descriptor == NULL); assert(entry_descriptor == NULL);
if (ENABLE_REOPT && effort < EffortLevel::MAXIMAL && source->ast != NULL if (ENABLE_REOPT && effort < EffortLevel::MAXIMAL && source->ast_type != AST_TYPE::Module) {
&& source->ast->type != AST_TYPE::Module) {
llvm::BasicBlock* preentry_bb = llvm::BasicBlock::Create( llvm::BasicBlock* preentry_bb = llvm::BasicBlock::Create(
g.context, "pre_entry", irstate->getLLVMFunction(), llvm_entry_blocks[cfg->getStartingBlock()]); g.context, "pre_entry", irstate->getLLVMFunction(), llvm_entry_blocks[cfg->getStartingBlock()]);
llvm::BasicBlock* reopt_bb = llvm::BasicBlock::Create(g.context, "reopt", irstate->getLLVMFunction()); llvm::BasicBlock* reopt_bb = llvm::BasicBlock::Create(g.context, "reopt", irstate->getLLVMFunction());
...@@ -989,9 +988,7 @@ static void computeBlockSetClosure(BlockSet& blocks) { ...@@ -989,9 +988,7 @@ static void computeBlockSetClosure(BlockSet& blocks) {
} }
// returns a pointer to the function-info mdnode // returns a pointer to the function-info mdnode
static llvm::MDNode* setupDebugInfo(BoxedCode* code, llvm::Function* f, std::string origname) { static llvm::MDNode* setupDebugInfo(BoxedCode* code, llvm::Function* f, std::string origname) {
int lineno = 0; int lineno = code->firstlineno;
if (code->source->ast)
lineno = code->source->ast->lineno;
llvm::DIBuilder builder(*g.cur_module); llvm::DIBuilder builder(*g.cur_module);
......
...@@ -54,31 +54,6 @@ ...@@ -54,31 +54,6 @@
namespace pyston { namespace pyston {
llvm::ArrayRef<AST_stmt*> SourceInfo::getBody() const {
switch (ast->type) {
case AST_TYPE::ClassDef:
return ((AST_ClassDef*)ast)->body;
case AST_TYPE::Expression:
return ((AST_Expression*)ast)->body;
case AST_TYPE::FunctionDef:
return ((AST_FunctionDef*)ast)->body;
case AST_TYPE::Module:
return ((AST_Module*)ast)->body;
default:
RELEASE_ASSERT(0, "unknown %d", ast->type);
};
}
Box* SourceInfo::getDocString() {
auto body = getBody();
if (body.size() > 0 && body[0]->type == AST_TYPE::Expr
&& static_cast<AST_Expr*>(body[0])->value->type == AST_TYPE::Str) {
return boxString(static_cast<AST_Str*>(static_cast<AST_Expr*>(body[0])->value)->str_data);
}
return incref(Py_None);
}
LivenessAnalysis* SourceInfo::getLiveness() { LivenessAnalysis* SourceInfo::getLiveness() {
if (!liveness_info) if (!liveness_info)
liveness_info = computeLivenessInfo(cfg); liveness_info = computeLivenessInfo(cfg);
...@@ -258,11 +233,11 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) { ...@@ -258,11 +233,11 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
FutureFlags future_flags = getFutureFlags(m->body, fn); FutureFlags future_flags = getFutureFlags(m->body, fn);
computeAllCFGs(m, /* globals_from_module */ true, future_flags, autoDecref(boxString(fn)), bm); computeAllCFGs(m, /* globals_from_module */ true, future_flags, autoDecref(boxString(fn)), bm);
BoxedCode* code = codeForAST(m); BoxedCode* code = m->getCode();
assert(code); assert(code);
static BoxedString* doc_str = getStaticString("__doc__"); static BoxedString* doc_str = getStaticString("__doc__");
bm->setattr(doc_str, autoDecref(code->source->getDocString()), NULL); bm->setattr(doc_str, code->_doc, NULL);
static BoxedString* builtins_str = getStaticString("__builtins__"); static BoxedString* builtins_str = getStaticString("__builtins__");
if (!bm->hasattr(builtins_str)) if (!bm->hasattr(builtins_str))
...@@ -279,12 +254,11 @@ Box* evalOrExec(BoxedCode* code, Box* globals, Box* boxedLocals) { ...@@ -279,12 +254,11 @@ Box* evalOrExec(BoxedCode* code, Box* globals, Box* boxedLocals) {
assert(globals && (globals->cls == module_cls || globals->cls == dict_cls)); assert(globals && (globals->cls == module_cls || globals->cls == dict_cls));
Box* doc_string = code->source->getDocString(); // TODO: we're supposed to embed this directly into the bytecode
Box* doc_string = code->_doc;
if (doc_string != Py_None) { if (doc_string != Py_None) {
static BoxedString* doc_box = getStaticString("__doc__"); static BoxedString* doc_box = getStaticString("__doc__");
setGlobal(boxedLocals, doc_box, doc_string); setGlobal(boxedLocals, doc_box, incref(doc_string));
} else {
Py_DECREF(doc_string);
} }
return astInterpretFunctionEval(code, globals, boxedLocals); return astInterpretFunctionEval(code, globals, boxedLocals);
...@@ -306,7 +280,7 @@ static BoxedCode* compileForEvalOrExec(AST* source, llvm::ArrayRef<AST_stmt*> bo ...@@ -306,7 +280,7 @@ static BoxedCode* compileForEvalOrExec(AST* source, llvm::ArrayRef<AST_stmt*> bo
} }
computeAllCFGs(source, /* globals_from_module */ false, future_flags, fn, getCurrentModule()); computeAllCFGs(source, /* globals_from_module */ false, future_flags, fn, getCurrentModule());
return codeForAST(source); return source->getCode();
} }
static BoxedCode* compileExec(AST_Module* parsedModule, BoxedString* fn, PyCompilerFlags* flags) { static BoxedCode* compileExec(AST_Module* parsedModule, BoxedString* fn, PyCompilerFlags* flags) {
......
...@@ -988,7 +988,7 @@ private: ...@@ -988,7 +988,7 @@ private:
assert(node->args.size() == 1); assert(node->args.size() == 1);
assert(node->args[0]->type == AST_TYPE::Name); assert(node->args[0]->type == AST_TYPE::Name);
RELEASE_ASSERT(irstate->getSourceInfo()->ast->type == AST_TYPE::Module, RELEASE_ASSERT(irstate->getSourceInfo()->ast_type == AST_TYPE::Module,
"import * not supported in functions (yet)"); "import * not supported in functions (yet)");
CompilerVariable* module = evalExpr(node->args[0], unw_info); CompilerVariable* module = evalExpr(node->args[0], unw_info);
...@@ -1709,8 +1709,8 @@ private: ...@@ -1709,8 +1709,8 @@ private:
// I think it's better to just not generate bad speculations: // I think it's better to just not generate bad speculations:
if (rtn->canConvertTo(speculated_type)) { if (rtn->canConvertTo(speculated_type)) {
auto source = irstate->getSourceInfo(); auto source = irstate->getSourceInfo();
printf("On %s:%d, function %s:\n", irstate->getCode()->filename->c_str(), source->getBody()[0]->lineno, printf("On %s:%d, function %s:\n", irstate->getCode()->filename->c_str(),
irstate->getCode()->name->c_str()); irstate->getCode()->firstlineno, irstate->getCode()->name->c_str());
irstate->getSourceInfo()->cfg->print(); irstate->getSourceInfo()->cfg->print();
} }
RELEASE_ASSERT(!rtn->canConvertTo(speculated_type), "%s %s", rtn->getType()->debugName().c_str(), RELEASE_ASSERT(!rtn->canConvertTo(speculated_type), "%s %s", rtn->getType()->debugName().c_str(),
......
...@@ -2261,4 +2261,77 @@ void flatten(AST_expr* root, std::vector<AST*>& output, bool expand_scopes) { ...@@ -2261,4 +2261,77 @@ void flatten(AST_expr* root, std::vector<AST*>& output, bool expand_scopes) {
root->accept(&visitor); root->accept(&visitor);
} }
BoxedCode*& AST::getCode() {
switch (this->type) {
case AST_TYPE::Expression:
return ast_cast<AST_Expression>(this)->code;
case AST_TYPE::FunctionDef:
return ast_cast<AST_FunctionDef>(this)->code;
case AST_TYPE::ClassDef:
return ast_cast<AST_ClassDef>(this)->code;
case AST_TYPE::Module:
return ast_cast<AST_Module>(this)->code;
default:
break;
}
RELEASE_ASSERT(0, "%d", this->type);
}
InternedStringPool& AST::getStringpool() {
switch (this->type) {
case AST_TYPE::Expression:
return *ast_cast<AST_Expression>(this)->interned_strings;
case AST_TYPE::Module:
return *ast_cast<AST_Module>(this)->interned_strings;
default:
break;
}
RELEASE_ASSERT(0, "%d", this->type);
}
llvm::ArrayRef<AST_stmt*> AST::getBody() {
switch (this->type) {
case AST_TYPE::ClassDef:
return ((AST_ClassDef*)this)->body;
case AST_TYPE::Expression:
return ((AST_Expression*)this)->body;
case AST_TYPE::FunctionDef:
return ((AST_FunctionDef*)this)->body;
case AST_TYPE::Module:
return ((AST_Module*)this)->body;
default:
RELEASE_ASSERT(0, "unknown %d", this->type);
};
}
Box* AST::getDocString() {
auto body = this->getBody();
if (body.size() > 0 && body[0]->type == AST_TYPE::Expr
&& static_cast<AST_Expr*>(body[0])->value->type == AST_TYPE::Str) {
return boxString(static_cast<AST_Str*>(static_cast<AST_Expr*>(body[0])->value)->str_data);
}
return incref(Py_None);
}
BORROWED(BoxedString*) AST::getName() noexcept {
static BoxedString* lambda_name = getStaticString("<lambda>");
static BoxedString* module_name = getStaticString("<module>");
switch (this->type) {
case AST_TYPE::ClassDef:
return ast_cast<AST_ClassDef>(this)->name.getBox();
case AST_TYPE::FunctionDef:
if (ast_cast<AST_FunctionDef>(this)->name != InternedString())
return ast_cast<AST_FunctionDef>(this)->name.getBox();
return lambda_name;
case AST_TYPE::Module:
case AST_TYPE::Expression:
case AST_TYPE::Suite:
return module_name;
default:
RELEASE_ASSERT(0, "%d", this->type);
}
}
} }
...@@ -188,6 +188,14 @@ public: ...@@ -188,6 +188,14 @@ public:
#endif #endif
AST(AST_TYPE::AST_TYPE type, uint32_t lineno, uint32_t col_offset = 0) AST(AST_TYPE::AST_TYPE type, uint32_t lineno, uint32_t col_offset = 0)
: type(type), lineno(lineno), col_offset(col_offset) {} : type(type), lineno(lineno), col_offset(col_offset) {}
// These could be virtual methods, but since we already keep track of the type use a switch statement
// like everywhere else.
BoxedCode*& getCode();
InternedStringPool& getStringpool();
llvm::ArrayRef<AST_stmt*> getBody();
Box* getDocString();
BORROWED(BoxedString*) getName() noexcept;
}; };
class AST_expr : public AST { class AST_expr : public AST {
......
...@@ -251,7 +251,7 @@ public: ...@@ -251,7 +251,7 @@ public:
ModuleCFGProcessor(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn, BoxedModule* bm) ModuleCFGProcessor(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn, BoxedModule* bm)
: scoping(ast, globals_from_module), : scoping(ast, globals_from_module),
stringpool(stringpoolForAST(ast)), stringpool(ast->getStringpool()),
future_flags(future_flags), future_flags(future_flags),
fn(fn), fn(fn),
bm(bm) {} bm(bm) {}
...@@ -263,7 +263,7 @@ public: ...@@ -263,7 +263,7 @@ public:
void runRecursively(AST* ast, AST_arguments* args, AST* orig_node); void runRecursively(AST* ast, AST_arguments* args, AST* orig_node);
}; };
static CFG* computeCFG(BoxedString* fn, SourceInfo* source, const ParamNames& param_names, ScopeInfo* scoping, static CFG* computeCFG(AST* ast, BoxedString* fn, SourceInfo* source, const ParamNames& param_names, ScopeInfo* scoping,
ModuleCFGProcessor* cfgizer); ModuleCFGProcessor* cfgizer);
// A class that crawls the AST of a single function and computes the CFG // A class that crawls the AST of a single function and computes the CFG
...@@ -361,7 +361,7 @@ private: ...@@ -361,7 +361,7 @@ private:
unsigned int next_var_index = 0; unsigned int next_var_index = 0;
friend CFG* computeCFG(BoxedString* fn, SourceInfo* source, const ParamNames& param_names, ScopeInfo*, friend CFG* computeCFG(AST* ast, BoxedString* fn, SourceInfo* source, const ParamNames& param_names, ScopeInfo*,
ModuleCFGProcessor*); ModuleCFGProcessor*);
public: public:
...@@ -2961,32 +2961,32 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names) { ...@@ -2961,32 +2961,32 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names) {
} }
static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNames& param_names, ScopeInfo* scoping, static CFG* computeCFG(AST* ast, BoxedString* filename, SourceInfo* source, const ParamNames& param_names,
ModuleCFGProcessor* cfgizer) { ScopeInfo* scoping, ModuleCFGProcessor* cfgizer) {
STAT_TIMER(t0, "us_timer_computecfg", 0); STAT_TIMER(t0, "us_timer_computecfg", 0);
auto body = source->getBody(); auto body = ast->getBody();
CFG* rtn = new CFG(); CFG* rtn = new CFG();
auto&& stringpool = cfgizer->stringpool; auto&& stringpool = cfgizer->stringpool;
CFGVisitor visitor(filename, source, stringpool, scoping, source->ast->type, source->future_flags, rtn, cfgizer); CFGVisitor visitor(filename, source, stringpool, scoping, ast->type, source->future_flags, rtn, cfgizer);
bool skip_first = false; bool skip_first = false;
if (source->ast->type == AST_TYPE::ClassDef) { if (ast->type == AST_TYPE::ClassDef) {
// A classdef always starts with "__module__ = __name__" // A classdef always starts with "__module__ = __name__"
AST_Assign* module_assign = new AST_Assign(); AST_Assign* module_assign = new AST_Assign();
auto module_name_target = new AST_Name(stringpool.get("__module__"), AST_TYPE::Store, source->ast->lineno); auto module_name_target = new AST_Name(stringpool.get("__module__"), AST_TYPE::Store, ast->lineno);
fillScopingInfo(module_name_target, scoping); fillScopingInfo(module_name_target, scoping);
auto module_name_value = new AST_Name(stringpool.get("__name__"), AST_TYPE::Load, source->ast->lineno); auto module_name_value = new AST_Name(stringpool.get("__name__"), AST_TYPE::Load, ast->lineno);
fillScopingInfo(module_name_value, scoping); fillScopingInfo(module_name_value, scoping);
module_assign->targets.push_back(module_name_target); module_assign->targets.push_back(module_name_target);
module_assign->value = module_name_value; module_assign->value = module_name_value;
module_assign->lineno = source->ast->lineno; module_assign->lineno = ast->lineno;
visitor.push_back(module_assign); visitor.push_back(module_assign);
// If the first statement is just a single string, transform it to an assignment to __doc__ // If the first statement is just a single string, transform it to an assignment to __doc__
...@@ -2994,18 +2994,18 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam ...@@ -2994,18 +2994,18 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
AST_Expr* first_expr = ast_cast<AST_Expr>(body[0]); AST_Expr* first_expr = ast_cast<AST_Expr>(body[0]);
if (first_expr->value->type == AST_TYPE::Str) { if (first_expr->value->type == AST_TYPE::Str) {
AST_Assign* doc_assign = new AST_Assign(); AST_Assign* doc_assign = new AST_Assign();
auto doc_target_name = new AST_Name(stringpool.get("__doc__"), AST_TYPE::Store, source->ast->lineno); auto doc_target_name = new AST_Name(stringpool.get("__doc__"), AST_TYPE::Store, ast->lineno);
fillScopingInfo(doc_target_name, scoping); fillScopingInfo(doc_target_name, scoping);
doc_assign->targets.push_back(doc_target_name); doc_assign->targets.push_back(doc_target_name);
doc_assign->value = first_expr->value; doc_assign->value = first_expr->value;
doc_assign->lineno = source->ast->lineno; doc_assign->lineno = ast->lineno;
visitor.push_back(doc_assign); visitor.push_back(doc_assign);
skip_first = true; skip_first = true;
} }
} }
} }
if (source->ast->type == AST_TYPE::FunctionDef || source->ast->type == AST_TYPE::Lambda) { if (ast->type == AST_TYPE::FunctionDef || ast->type == AST_TYPE::Lambda) {
// Unpack tuple arguments // Unpack tuple arguments
// Tuple arguments get assigned names ".0", ".1" etc. So this // Tuple arguments get assigned names ".0", ".1" etc. So this
// def f(a, (b,c), (d,e)): // def f(a, (b,c), (d,e)):
...@@ -3014,10 +3014,10 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam ...@@ -3014,10 +3014,10 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
// (b, c) = .1 // (b, c) = .1
// (d, e) = .2 // (d, e) = .2
AST_arguments* args; AST_arguments* args;
if (source->ast->type == AST_TYPE::FunctionDef) { if (ast->type == AST_TYPE::FunctionDef) {
args = ast_cast<AST_FunctionDef>(source->ast)->args; args = ast_cast<AST_FunctionDef>(ast)->args;
} else { } else {
args = ast_cast<AST_Lambda>(source->ast)->args; args = ast_cast<AST_Lambda>(ast)->args;
} }
int counter = 0; int counter = 0;
for (AST_expr* arg_expr : args->args) { for (AST_expr* arg_expr : args->args) {
...@@ -3044,11 +3044,11 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam ...@@ -3044,11 +3044,11 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
// The functions we create for classdefs are supposed to return a dictionary of their locals. // The functions we create for classdefs are supposed to return a dictionary of their locals.
// This is the place that we add all of that: // This is the place that we add all of that:
if (source->ast->type == AST_TYPE::ClassDef) { if (ast->type == AST_TYPE::ClassDef) {
AST_LangPrimitive* locals = new AST_LangPrimitive(AST_LangPrimitive::LOCALS); AST_LangPrimitive* locals = new AST_LangPrimitive(AST_LangPrimitive::LOCALS);
AST_Return* rtn = new AST_Return(); AST_Return* rtn = new AST_Return();
rtn->lineno = getLastLineno(source->ast); rtn->lineno = getLastLineno(ast);
rtn->value = locals; rtn->value = locals;
visitor.push_back(rtn); visitor.push_back(rtn);
} else { } else {
...@@ -3056,7 +3056,7 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam ...@@ -3056,7 +3056,7 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
// we already have to support multiple return statements in a function, but this way we can avoid // we already have to support multiple return statements in a function, but this way we can avoid
// having to support not having a return statement: // having to support not having a return statement:
AST_Return* return_stmt = new AST_Return(); AST_Return* return_stmt = new AST_Return();
return_stmt->lineno = getLastLineno(source->ast); return_stmt->lineno = getLastLineno(ast);
return_stmt->col_offset = 0; return_stmt->col_offset = 0;
return_stmt->value = NULL; return_stmt->value = NULL;
visitor.push_back(return_stmt); visitor.push_back(return_stmt);
...@@ -3261,32 +3261,6 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam ...@@ -3261,32 +3261,6 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
return rtn; return rtn;
} }
BoxedCode*& codeForAST(AST* ast) {
switch (ast->type) {
case AST_TYPE::Expression:
return ast_cast<AST_Expression>(ast)->code;
case AST_TYPE::FunctionDef:
return ast_cast<AST_FunctionDef>(ast)->code;
case AST_TYPE::ClassDef:
return ast_cast<AST_ClassDef>(ast)->code;
case AST_TYPE::Module:
return ast_cast<AST_Module>(ast)->code;
default:
break;
}
RELEASE_ASSERT(0, "%d", ast->type);
}
InternedStringPool& stringpoolForAST(AST* ast) {
switch (ast->type) {
case AST_TYPE::Expression:
return *ast_cast<AST_Expression>(ast)->interned_strings;
case AST_TYPE::Module:
return *ast_cast<AST_Module>(ast)->interned_strings;
default:
break;
}
RELEASE_ASSERT(0, "%d", ast->type);
}
void ModuleCFGProcessor::runRecursively(AST* ast, AST_arguments* args, AST* orig_node) { void ModuleCFGProcessor::runRecursively(AST* ast, AST_arguments* args, AST* orig_node) {
ScopeInfo* scope_info = scoping.getScopeInfoForNode(orig_node); ScopeInfo* scope_info = scoping.getScopeInfoForNode(orig_node);
...@@ -3297,18 +3271,20 @@ void ModuleCFGProcessor::runRecursively(AST* ast, AST_arguments* args, AST* orig ...@@ -3297,18 +3271,20 @@ void ModuleCFGProcessor::runRecursively(AST* ast, AST_arguments* args, AST* orig
for (auto e : param_names.allArgsAsName()) for (auto e : param_names.allArgsAsName())
fillScopingInfo(e, scope_info); fillScopingInfo(e, scope_info);
si->cfg = computeCFG(fn, si.get(), param_names, scope_info, this); si->cfg = computeCFG(ast, fn, si.get(), param_names, scope_info, this);
BoxedCode* code; BoxedCode* code;
if (args) if (args)
code = new BoxedCode(args->args.size(), args->vararg, args->kwarg, std::move(si), std::move(param_names), fn); code = new BoxedCode(args->args.size(), args->vararg, args->kwarg, ast->lineno, std::move(si),
std::move(param_names), fn, ast->getName(), autoDecref(ast->getDocString()));
else else
code = new BoxedCode(0, false, false, std::move(si), std::move(param_names), fn); code = new BoxedCode(0, false, false, ast->lineno, std::move(si), std::move(param_names), fn, ast->getName(),
autoDecref(ast->getDocString()));
// XXX very bad! Should properly track this: // XXX very bad! Should properly track this:
constants.push_back(code); constants.push_back(code);
codeForAST(ast) = code; ast->getCode() = code;
} }
void computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn, BoxedModule* bm) { void computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn, BoxedModule* bm) {
......
...@@ -330,9 +330,6 @@ public: ...@@ -330,9 +330,6 @@ public:
iterator end() const { return iterator(*this, this->v.size()); } iterator end() const { return iterator(*this, this->v.size()); }
}; };
BoxedCode*& codeForAST(AST* ast);
InternedStringPool& stringpoolForAST(AST* ast);
void computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn, BoxedModule* bm); void computeAllCFGs(AST* ast, bool globals_from_module, FutureFlags future_flags, BoxedString* fn, BoxedModule* bm);
void printCFG(CFG* cfg); void printCFG(CFG* cfg);
} }
......
...@@ -491,16 +491,18 @@ private: ...@@ -491,16 +491,18 @@ private:
public: public:
BoxedModule* parent_module; BoxedModule* parent_module;
ScopingResults scoping; ScopingResults scoping;
AST* ast;
CFG* cfg; CFG* cfg;
FutureFlags future_flags; FutureFlags future_flags;
bool is_generator; bool is_generator;
LivenessAnalysis* getLiveness(); // This should really be an AST_TYPE::AST_TYPE, using that would require resolving a circular dependency
// between ast.h and core/types.h
int ast_type;
llvm::ArrayRef<AST_stmt*> getBody() const; LivenessAnalysis* getLiveness();
Box* getDocString(); // llvm::ArrayRef<AST_stmt*> getBody() const;
// Box* getDocString();
SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags future_flags, AST* ast); SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags future_flags, AST* ast);
~SourceInfo(); ~SourceInfo();
......
...@@ -58,17 +58,11 @@ Box* BoxedCode::co_filename(Box* b, void* arg) noexcept { ...@@ -58,17 +58,11 @@ Box* BoxedCode::co_filename(Box* b, void* arg) noexcept {
return incref(code->filename); return incref(code->filename);
} }
Box* BoxedCode::firstlineno(Box* b, void*) noexcept { Box* BoxedCode::co_firstlineno(Box* b, void*) noexcept {
RELEASE_ASSERT(b->cls == code_cls, ""); RELEASE_ASSERT(b->cls == code_cls, "");
BoxedCode* code = static_cast<BoxedCode*>(b); BoxedCode* code = static_cast<BoxedCode*>(b);
if (!code || !code->source) return boxInt(code->firstlineno);
return boxInt(code->_firstline);
if (code->source->ast->lineno == (uint32_t)-1)
return boxInt(-1);
return boxInt(code->source->ast->lineno);
} }
Box* BoxedCode::argcount(Box* b, void*) noexcept { Box* BoxedCode::argcount(Box* b, void*) noexcept {
...@@ -112,39 +106,21 @@ void BoxedCode::dealloc(Box* b) noexcept { ...@@ -112,39 +106,21 @@ void BoxedCode::dealloc(Box* b) noexcept {
Py_XDECREF(o->filename); Py_XDECREF(o->filename);
Py_XDECREF(o->name); Py_XDECREF(o->name);
Py_XDECREF(o->_doc);
o->source.~decltype(o->source)(); o->source.~decltype(o->source)();
o->cls->tp_free(o); o->cls->tp_free(o);
} }
BORROWED(BoxedString*) getASTName(AST* ast) noexcept { BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, int firstlineno,
assert(ast); std::unique_ptr<SourceInfo> source, ParamNames param_names, BoxedString* filename,
BoxedString* name, Box* doc)
static BoxedString* lambda_name = getStaticString("<lambda>");
static BoxedString* module_name = getStaticString("<module>");
switch (ast->type) {
case AST_TYPE::ClassDef:
return ast_cast<AST_ClassDef>(ast)->name.getBox();
case AST_TYPE::FunctionDef:
if (ast_cast<AST_FunctionDef>(ast)->name != InternedString())
return ast_cast<AST_FunctionDef>(ast)->name.getBox();
return lambda_name;
case AST_TYPE::Module:
case AST_TYPE::Expression:
case AST_TYPE::Suite:
return module_name;
default:
RELEASE_ASSERT(0, "%d", ast->type);
}
}
BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, std::unique_ptr<SourceInfo> source,
ParamNames param_names, BoxedString* filename)
: source(std::move(source)), : source(std::move(source)),
filename(incref(filename)), filename(incref(filename)),
name(incref(getASTName(this->source->ast))), name(incref(name)),
firstlineno(firstlineno),
_doc(incref(doc)),
param_names(std::move(param_names)), param_names(std::move(param_names)),
takes_varargs(takes_varargs), takes_varargs(takes_varargs),
takes_kwargs(takes_kwargs), takes_kwargs(takes_kwargs),
...@@ -153,12 +129,14 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, std::u ...@@ -153,12 +129,14 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, std::u
internal_callable(NULL, NULL) { internal_callable(NULL, NULL) {
} }
BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names, BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names)
BoxedString* filename)
: source(nullptr), : source(nullptr),
// This should probably be just an "incref"? // TODO what to do with these?
filename(xincref(filename)), filename(nullptr),
name(boxString("???")), name(nullptr),
firstlineno(-1),
_doc(nullptr),
param_names(param_names), param_names(param_names),
takes_varargs(takes_varargs), takes_varargs(takes_varargs),
takes_kwargs(takes_kwargs), takes_kwargs(takes_kwargs),
...@@ -171,7 +149,9 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const ...@@ -171,7 +149,9 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const
BoxedCode::BoxedCode(BoxedString* filename, BoxedString* name, int firstline) BoxedCode::BoxedCode(BoxedString* filename, BoxedString* name, int firstline)
: filename(filename), : filename(filename),
name(name), name(name),
_firstline(firstline), firstlineno(firstline),
_doc(nullptr),
param_names(ParamNames::empty()), param_names(ParamNames::empty()),
takes_varargs(false), takes_varargs(false),
takes_kwargs(false), takes_kwargs(false),
...@@ -273,7 +253,7 @@ void setupCode() { ...@@ -273,7 +253,7 @@ void setupCode() {
code_cls->giveAttrDescriptor("co_name", BoxedCode::co_name, NULL); code_cls->giveAttrDescriptor("co_name", BoxedCode::co_name, NULL);
code_cls->giveAttrDescriptor("co_filename", BoxedCode::co_filename, NULL); code_cls->giveAttrDescriptor("co_filename", BoxedCode::co_filename, NULL);
code_cls->giveAttrDescriptor("co_firstlineno", BoxedCode::firstlineno, NULL); code_cls->giveAttrDescriptor("co_firstlineno", BoxedCode::co_firstlineno, NULL);
code_cls->giveAttrDescriptor("co_argcount", BoxedCode::argcount, NULL); code_cls->giveAttrDescriptor("co_argcount", BoxedCode::argcount, NULL);
code_cls->giveAttrDescriptor("co_varnames", BoxedCode::varnames, NULL); code_cls->giveAttrDescriptor("co_varnames", BoxedCode::varnames, NULL);
code_cls->giveAttrDescriptor("co_flags", BoxedCode::flags, NULL); code_cls->giveAttrDescriptor("co_flags", BoxedCode::flags, NULL);
......
...@@ -364,7 +364,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(BoxedCode* code, llvm::ArrayRef< ...@@ -364,7 +364,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(BoxedCode* code, llvm::ArrayRef<
} }
// It's ok for modname to be NULL // It's ok for modname to be NULL
this->doc = code->source->getDocString(); this->doc = xincref(code->_doc);
} else { } else {
this->modname = PyString_InternFromString("__builtin__"); this->modname = PyString_InternFromString("__builtin__");
this->doc = incref(Py_None); this->doc = incref(Py_None);
...@@ -379,7 +379,7 @@ BoxedFunction::BoxedFunction(BoxedCode* code, llvm::ArrayRef<Box*> defaults, Box ...@@ -379,7 +379,7 @@ BoxedFunction::BoxedFunction(BoxedCode* code, llvm::ArrayRef<Box*> defaults, Box
: BoxedFunctionBase(code, defaults, closure, globals, can_change_defaults) { : BoxedFunctionBase(code, defaults, closure, globals, can_change_defaults) {
assert(!this->name); assert(!this->name);
this->name = incref(code->name); this->name = xincref(code->name);
} }
BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(BoxedCode* code, const char* name, const char* doc) BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(BoxedCode* code, const char* name, const char* doc)
......
...@@ -1080,7 +1080,9 @@ public: ...@@ -1080,7 +1080,9 @@ public:
BoxedString* filename = nullptr; BoxedString* filename = nullptr;
BoxedString* name = nullptr; BoxedString* name = nullptr;
int _firstline; int firstlineno;
// In CPython, this is just stored as consts[0]
Box* _doc = nullptr;
const ParamNames param_names; const ParamNames param_names;
const bool takes_varargs, takes_kwargs; const bool takes_varargs, takes_kwargs;
...@@ -1109,10 +1111,9 @@ public: ...@@ -1109,10 +1111,9 @@ public:
Box**, const std::vector<BoxedString*>*> InternalCallable; Box**, const std::vector<BoxedString*>*> InternalCallable;
InternalCallable internal_callable; InternalCallable internal_callable;
BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, std::unique_ptr<SourceInfo> source, BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, int firstlineno, std::unique_ptr<SourceInfo> source,
ParamNames param_names, BoxedString* filename); ParamNames param_names, BoxedString* filename, BoxedString* name, Box* doc);
BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names = ParamNames::empty(), BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names = ParamNames::empty());
BoxedString* filename = nullptr);
~BoxedCode(); ~BoxedCode();
// The dummy constructor for PyCode_New: // The dummy constructor for PyCode_New:
...@@ -1166,7 +1167,7 @@ public: ...@@ -1166,7 +1167,7 @@ public:
// static BORROWED(Box*) filename(Box* b, void*) noexcept; // static BORROWED(Box*) filename(Box* b, void*) noexcept;
static Box* co_name(Box* b, void*) noexcept; static Box* co_name(Box* b, void*) noexcept;
static Box* co_filename(Box* b, void*) noexcept; static Box* co_filename(Box* b, void*) noexcept;
static Box* firstlineno(Box* b, void*) noexcept; static Box* co_firstlineno(Box* b, void*) noexcept;
static Box* argcount(Box* b, void*) noexcept; static Box* argcount(Box* b, void*) noexcept;
static Box* varnames(Box* b, void*) noexcept; static Box* varnames(Box* b, void*) noexcept;
static Box* flags(Box* b, void*) noexcept; static Box* flags(Box* b, void*) noexcept;
......
...@@ -251,7 +251,7 @@ extern "C" void dumpEx(void* p, int levels) { ...@@ -251,7 +251,7 @@ extern "C" void dumpEx(void* p, int levels) {
BoxedCode* code = f->code; BoxedCode* code = f->code;
if (code->source) { if (code->source) {
printf("User-defined function '%s'\n", code->name->c_str()); printf("User-defined function '%s'\n", code->name->c_str());
printf("Defined at %s:%d\n", code->filename->c_str(), code->source->ast->lineno); printf("Defined at %s:%d\n", code->filename->c_str(), code->firstlineno);
if (code->source->cfg && levels > 0) { if (code->source->cfg && levels > 0) {
code->source->cfg->print(); code->source->cfg->print();
......
...@@ -55,3 +55,8 @@ class C4(object): ...@@ -55,3 +55,8 @@ class C4(object):
("a") ("a")
assert C3.__doc__ is None assert C3.__doc__ is None
""" """
exec """
"hello world"
print __doc__
"""
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