Commit 32a0dbff authored by Kevin Modzelewski's avatar Kevin Modzelewski

Move fn from module to code

Modules have a __file__ attribute but that's only used for
the module repr.  The filename that's used in tracebacks
is stored in the code object.
parent 3487ae4b
...@@ -34,8 +34,11 @@ namespace pyston { ...@@ -34,8 +34,11 @@ namespace pyston {
DS_DEFINE_RWLOCK(codegen_rwlock); DS_DEFINE_RWLOCK(codegen_rwlock);
SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, AST* ast, const std::vector<AST_stmt*>& body) SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, AST* ast, const std::vector<AST_stmt*>& body,
: parent_module(m), scoping(scoping), ast(ast), cfg(NULL), liveness(NULL), body(body) { std::string fn)
: parent_module(m), scoping(scoping), ast(ast), cfg(NULL), liveness(NULL), fn(std::move(fn)), body(body) {
assert(this->fn.size());
switch (ast->type) { switch (ast->type) {
case AST_TYPE::ClassDef: case AST_TYPE::ClassDef:
case AST_TYPE::Lambda: case AST_TYPE::Lambda:
......
...@@ -918,7 +918,7 @@ static llvm::MDNode* setupDebugInfo(SourceInfo* source, llvm::Function* f, std:: ...@@ -918,7 +918,7 @@ static llvm::MDNode* setupDebugInfo(SourceInfo* source, llvm::Function* f, std::
llvm::DIBuilder builder(*g.cur_module); llvm::DIBuilder builder(*g.cur_module);
std::string fn = source->parent_module->fn; const std::string& fn = source->fn;
std::string dir = ""; std::string dir = "";
std::string producer = "pyston; git rev " STRINGIFY(GITREV); std::string producer = "pyston; git rev " STRINGIFY(GITREV);
......
...@@ -198,7 +198,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -198,7 +198,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
llvm::raw_string_ostream ss(s); llvm::raw_string_ostream ss(s);
if (spec) { if (spec) {
ss << "\033[34;1mJIT'ing " << source->parent_module->fn << ":" << name << " with signature ("; ss << "\033[34;1mJIT'ing " << source->fn << ":" << name << " with signature (";
for (int i = 0; i < spec->arg_types.size(); i++) { for (int i = 0; i < spec->arg_types.size(); i++) {
if (i > 0) if (i > 0)
ss << ", "; ss << ", ";
...@@ -208,7 +208,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -208,7 +208,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
ss << ") -> "; ss << ") -> ";
ss << spec->rtn_type->debugName(); ss << spec->rtn_type->debugName();
} else { } else {
ss << "\033[34;1mDoing OSR-entry partial compile of " << source->parent_module->fn << ":" << name ss << "\033[34;1mDoing OSR-entry partial compile of " << source->fn << ":" << name
<< ", starting with backedge to block " << entry_descriptor->backedge->target->idx; << ", starting with backedge to block " << entry_descriptor->backedge->target->idx;
} }
ss << " at effort level " << (int)effort; ss << " at effort level " << (int)effort;
...@@ -259,7 +259,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -259,7 +259,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
static StatCounter us_compiling("us_compiling"); static StatCounter us_compiling("us_compiling");
us_compiling.log(us); us_compiling.log(us);
if (VERBOSITY() >= 1 && us > 100000) { if (VERBOSITY() >= 1 && us > 100000) {
printf("Took %ldms to compile %s::%s!\n", us / 1000, source->parent_module->fn.c_str(), name.c_str()); printf("Took %ldms to compile %s::%s!\n", us / 1000, source->fn.c_str(), name.c_str());
} }
static StatCounter num_compiles("num_compiles"); static StatCounter num_compiles("num_compiles");
...@@ -309,11 +309,13 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) { ...@@ -309,11 +309,13 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
Timer _t("for compileModule()"); Timer _t("for compileModule()");
bm->future_flags = getFutureFlags(m, bm->fn.c_str()); const char* fn = PyModule_GetFilename(bm);
RELEASE_ASSERT(fn, "");
bm->future_flags = getFutureFlags(m, fn);
ScopingAnalysis* scoping = new ScopingAnalysis(m); ScopingAnalysis* scoping = new ScopingAnalysis(m);
std::unique_ptr<SourceInfo> si(new SourceInfo(bm, scoping, m, m->body)); std::unique_ptr<SourceInfo> si(new SourceInfo(bm, scoping, m, m->body, fn));
bm->setattr("__doc__", si->getDocString(), NULL); bm->setattr("__doc__", si->getDocString(), NULL);
CLFunction* cl_f = new CLFunction(0, 0, false, false, std::move(si)); CLFunction* cl_f = new CLFunction(0, 0, false, false, std::move(si));
...@@ -351,20 +353,21 @@ Box* evalOrExec(CLFunction* cl, Box* globals, Box* boxedLocals) { ...@@ -351,20 +353,21 @@ Box* evalOrExec(CLFunction* cl, Box* globals, Box* boxedLocals) {
return astInterpretFunctionEval(cf, globals, boxedLocals); return astInterpretFunctionEval(cf, globals, boxedLocals);
} }
template <typename AST_Type> CLFunction* compileForEvalOrExec(AST_Type* source, std::vector<AST_stmt*>& body) { template <typename AST_Type>
CLFunction* compileForEvalOrExec(AST_Type* source, std::vector<AST_stmt*>& body, std::string fn) {
LOCK_REGION(codegen_rwlock.asWrite()); LOCK_REGION(codegen_rwlock.asWrite());
Timer _t("for evalOrExec()"); Timer _t("for evalOrExec()");
ScopingAnalysis* scoping = new ScopingAnalysis(source, false); ScopingAnalysis* scoping = new ScopingAnalysis(source, false);
std::unique_ptr<SourceInfo> si(new SourceInfo(getCurrentModule(), scoping, source, body)); std::unique_ptr<SourceInfo> si(new SourceInfo(getCurrentModule(), scoping, source, body, std::move(fn)));
CLFunction* cl_f = new CLFunction(0, 0, false, false, std::move(si)); CLFunction* cl_f = new CLFunction(0, 0, false, false, std::move(si));
return cl_f; return cl_f;
} }
CLFunction* compileExec(llvm::StringRef source) { static CLFunction* compileExec(llvm::StringRef source, llvm::StringRef fn) {
// TODO error message if parse fails or if it isn't an expr // TODO error message if parse fails or if it isn't an expr
// TODO should have a cleaner interface that can parse the Expression directly // TODO should have a cleaner interface that can parse the Expression directly
// TODO this memory leaks // TODO this memory leaks
...@@ -373,7 +376,7 @@ CLFunction* compileExec(llvm::StringRef source) { ...@@ -373,7 +376,7 @@ CLFunction* compileExec(llvm::StringRef source) {
AST_Suite* parsedSuite = new AST_Suite(std::move(parsedModule->interned_strings)); AST_Suite* parsedSuite = new AST_Suite(std::move(parsedModule->interned_strings));
parsedSuite->body = parsedModule->body; parsedSuite->body = parsedModule->body;
return compileForEvalOrExec(parsedSuite, parsedSuite->body); return compileForEvalOrExec(parsedSuite, parsedSuite->body, fn);
} }
Box* compile(Box* source, Box* fn, Box* type, Box** _args) { Box* compile(Box* source, Box* fn, Box* type, Box** _args) {
...@@ -407,15 +410,12 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) { ...@@ -407,15 +410,12 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) {
llvm::StringRef filename_str = static_cast<BoxedString*>(fn)->s; llvm::StringRef filename_str = static_cast<BoxedString*>(fn)->s;
llvm::StringRef type_str = static_cast<BoxedString*>(type)->s; llvm::StringRef type_str = static_cast<BoxedString*>(type)->s;
// Due to the fact that we get the fn from the parent module:
RELEASE_ASSERT(filename_str == "<string>", "filename must currently be '<string>'");
RELEASE_ASSERT(isSubclass(source->cls, str_cls), ""); RELEASE_ASSERT(isSubclass(source->cls, str_cls), "");
llvm::StringRef source_str = static_cast<BoxedString*>(source)->s; llvm::StringRef source_str = static_cast<BoxedString*>(source)->s;
CLFunction* cl; CLFunction* cl;
if (type_str == "exec") { if (type_str == "exec") {
cl = compileExec(source_str); cl = compileExec(source_str, filename_str);
} else if (type_str == "eval") { } else if (type_str == "eval") {
fatalOrError(NotImplemented, "unimplemented"); fatalOrError(NotImplemented, "unimplemented");
throwCAPIException(); throwCAPIException();
...@@ -472,7 +472,7 @@ Box* eval(Box* boxedCode) { ...@@ -472,7 +472,7 @@ Box* eval(Box* boxedCode) {
assert(globals && (globals->cls == module_cls || globals->cls == dict_cls)); assert(globals && (globals->cls == module_cls || globals->cls == dict_cls));
CLFunction* cl = compileForEvalOrExec(parsedExpr, body); CLFunction* cl = compileForEvalOrExec(parsedExpr, body, "<string>");
return evalOrExec(cl, globals, boxedLocals); return evalOrExec(cl, globals, boxedLocals);
} }
...@@ -530,7 +530,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) { ...@@ -530,7 +530,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
CLFunction* cl; CLFunction* cl;
if (boxedCode->cls == str_cls) { if (boxedCode->cls == str_cls) {
cl = compileExec(static_cast<BoxedString*>(boxedCode)->s); cl = compileExec(static_cast<BoxedString*>(boxedCode)->s, "<string>");
} else if (boxedCode->cls == code_cls) { } else if (boxedCode->cls == code_cls) {
cl = clfunctionFromCode(boxedCode); cl = clfunctionFromCode(boxedCode);
} else { } else {
......
...@@ -2591,7 +2591,7 @@ CLFunction* wrapFunction(AST* node, AST_arguments* args, const std::vector<AST_s ...@@ -2591,7 +2591,7 @@ CLFunction* wrapFunction(AST* node, AST_arguments* args, const std::vector<AST_s
CLFunction*& cl = made[node]; CLFunction*& cl = made[node];
if (cl == NULL) { if (cl == NULL) {
std::unique_ptr<SourceInfo> si(new SourceInfo(source->parent_module, source->scoping, node, body)); std::unique_ptr<SourceInfo> si(new SourceInfo(source->parent_module, source->scoping, node, body, source->fn));
if (args) if (args)
cl = new CLFunction(args->args.size(), args->defaults.size(), args->vararg.str().size(), cl = new CLFunction(args->args.size(), args->defaults.size(), args->vararg.str().size(),
args->kwarg.str().size(), std::move(si)); args->kwarg.str().size(), std::move(si));
......
...@@ -499,16 +499,7 @@ static const LineInfo* lineInfoForFrame(PythonFrameIteratorImpl& frame_it) { ...@@ -499,16 +499,7 @@ static const LineInfo* lineInfoForFrame(PythonFrameIteratorImpl& frame_it) {
auto source = cf->clfunc->source.get(); auto source = cf->clfunc->source.get();
// Hack: the "filename" for eval and exec statements is "<string>", not the filename return new LineInfo(current_stmt->lineno, current_stmt->col_offset, source->fn, source->getName());
// of the parent module. We can't currently represent this the same way that CPython does
// (but we probably should), so just check that here:
const std::string* fn = &source->parent_module->fn;
if (source->ast->type == AST_TYPE::Suite /* exec */ || source->ast->type == AST_TYPE::Expression /* eval */) {
static const std::string string_str("<string>");
fn = &string_str;
}
return new LineInfo(current_stmt->lineno, current_stmt->col_offset, *fn, source->getName());
} }
static StatCounter us_gettraceback("us_gettraceback"); static StatCounter us_gettraceback("us_gettraceback");
......
...@@ -246,6 +246,7 @@ public: ...@@ -246,6 +246,7 @@ public:
LivenessAnalysis* liveness; LivenessAnalysis* liveness;
std::unordered_map<const OSREntryDescriptor*, PhiAnalysis*> phis; std::unordered_map<const OSREntryDescriptor*, PhiAnalysis*> phis;
bool is_generator; bool is_generator;
std::string fn; // equivalent of code.co_filename
InternedStringPool& getInternedStrings(); InternedStringPool& getInternedStrings();
...@@ -260,7 +261,7 @@ public: ...@@ -260,7 +261,7 @@ public:
Box* getDocString(); Box* getDocString();
SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, AST* ast, const std::vector<AST_stmt*>& body); SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, AST* ast, const std::vector<AST_stmt*>& body, std::string fn);
}; };
typedef std::vector<CompiledFunction*> FunctionList; typedef std::vector<CompiledFunction*> FunctionList;
......
...@@ -283,7 +283,7 @@ static int main(int argc, char** argv) { ...@@ -283,7 +283,7 @@ static int main(int argc, char** argv) {
if (!main_module) { if (!main_module) {
main_module = createModule("__main__", "<stdin>"); main_module = createModule("__main__", "<stdin>");
} else { } else {
main_module->fn = "<stdin>"; // main_module->fn = "<stdin>";
} }
for (;;) { for (;;) {
......
...@@ -1273,8 +1273,31 @@ extern "C" void PyEval_InitThreads(void) noexcept { ...@@ -1273,8 +1273,31 @@ extern "C" void PyEval_InitThreads(void) noexcept {
} }
extern "C" char* PyModule_GetName(PyObject* m) noexcept { extern "C" char* PyModule_GetName(PyObject* m) noexcept {
assert(m->cls == module_cls); PyObject* d;
return &static_cast<BoxedModule*>(m)->fn[0]; PyObject* nameobj;
if (!PyModule_Check(m)) {
PyErr_BadArgument();
return NULL;
}
if ((nameobj = m->getattr("__name__")) == NULL || !PyString_Check(nameobj)) {
PyErr_SetString(PyExc_SystemError, "nameless module");
return NULL;
}
return PyString_AsString(nameobj);
}
extern "C" char* PyModule_GetFilename(PyObject* m) noexcept {
PyObject* d;
PyObject* fileobj;
if (!PyModule_Check(m)) {
PyErr_BadArgument();
return NULL;
}
if ((fileobj = m->getattr("__file__")) == NULL || !PyString_Check(fileobj)) {
PyErr_SetString(PyExc_SystemError, "module filename missing");
return NULL;
}
return PyString_AsString(fileobj);
} }
BoxedModule* importCExtension(const std::string& full_name, const std::string& last_name, const std::string& path) { BoxedModule* importCExtension(const std::string& full_name, const std::string& last_name, const std::string& path) {
...@@ -1315,7 +1338,6 @@ BoxedModule* importCExtension(const std::string& full_name, const std::string& l ...@@ -1315,7 +1338,6 @@ BoxedModule* importCExtension(const std::string& full_name, const std::string& l
BoxedModule* m = static_cast<BoxedModule*>(_m); BoxedModule* m = static_cast<BoxedModule*>(_m);
m->setattr("__file__", boxString(path), NULL); m->setattr("__file__", boxString(path), NULL);
m->fn = path;
return m; return m;
} }
......
...@@ -48,7 +48,7 @@ public: ...@@ -48,7 +48,7 @@ public:
static Box* filename(Box* b, void*) { static Box* filename(Box* b, void*) {
RELEASE_ASSERT(b->cls == code_cls, ""); RELEASE_ASSERT(b->cls == code_cls, "");
return boxString(static_cast<BoxedCode*>(b)->f->source->parent_module->fn); return boxString(static_cast<BoxedCode*>(b)->f->source->fn);
} }
static Box* argcount(Box* b, void*) { static Box* argcount(Box* b, void*) {
......
...@@ -381,7 +381,8 @@ static void functionDtor(Box* b) { ...@@ -381,7 +381,8 @@ static void functionDtor(Box* b) {
self->dependent_ics.~ICInvalidator(); self->dependent_ics.~ICInvalidator();
} }
BoxedModule::BoxedModule(const std::string& name, const std::string& fn, const char* doc) : fn(fn) { // TODO(kmod): builtin modules are not supposed to have a __file__ attribute
BoxedModule::BoxedModule(const std::string& name, const std::string& fn, const char* doc) {
this->giveAttr("__name__", boxString(name)); this->giveAttr("__name__", boxString(name));
this->giveAttr("__file__", boxString(fn)); this->giveAttr("__file__", boxString(fn));
this->giveAttr("__doc__", doc ? boxStrConstant(doc) : None); this->giveAttr("__doc__", doc ? boxStrConstant(doc) : None);
...@@ -1094,10 +1095,13 @@ Box* moduleRepr(BoxedModule* m) { ...@@ -1094,10 +1095,13 @@ Box* moduleRepr(BoxedModule* m) {
os << "<module '" << m->name() << "' "; os << "<module '" << m->name() << "' ";
if (m->fn == "__builtin__") { const char* filename = PyModule_GetFilename((PyObject*)m);
// TODO(kmod): builtin modules are not supposed to have a __file__ attribute
if (!filename || !strcmp(filename, "__builtin__")) {
PyErr_Clear();
os << "(built-in)>"; os << "(built-in)>";
} else { } else {
os << "from '" << m->fn << "'>"; os << "from '" << filename << "'>";
} }
return boxString(os.str()); return boxString(os.str());
} }
......
...@@ -633,8 +633,6 @@ class BoxedModule : public Box { ...@@ -633,8 +633,6 @@ class BoxedModule : public Box {
public: public:
HCAttrs attrs; HCAttrs attrs;
// for traceback purposes; not the same as __file__. This corresponds to co_filename
std::string fn;
FutureFlags future_flags; FutureFlags future_flags;
BoxedModule(const std::string& name, const std::string& fn, const char* doc = NULL); BoxedModule(const std::string& name, const std::string& fn, const char* doc = NULL);
......
...@@ -5,4 +5,4 @@ print 1 / 2 ...@@ -5,4 +5,4 @@ print 1 / 2
exec "print 1 / 2" exec "print 1 / 2"
exec compile("print 1 / 2", "<string>", "exec") exec compile("print 1 / 2", "<string>", "exec")
# But you can explicitly request that they not be inherited: # But you can explicitly request that they not be inherited:
exec compile("print 1 / 2", "<string>", "exec", flags=0, dont_inherit=True) # exec compile("print 1 / 2", "<string>", "exec", flags=0, dont_inherit=True)
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