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 {
DS_DEFINE_RWLOCK(codegen_rwlock);
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) {
SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, AST* ast, const std::vector<AST_stmt*>& 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) {
case AST_TYPE::ClassDef:
case AST_TYPE::Lambda:
......
......@@ -918,7 +918,7 @@ static llvm::MDNode* setupDebugInfo(SourceInfo* source, llvm::Function* f, std::
llvm::DIBuilder builder(*g.cur_module);
std::string fn = source->parent_module->fn;
const std::string& fn = source->fn;
std::string dir = "";
std::string producer = "pyston; git rev " STRINGIFY(GITREV);
......
......@@ -198,7 +198,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
llvm::raw_string_ostream ss(s);
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++) {
if (i > 0)
ss << ", ";
......@@ -208,7 +208,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
ss << ") -> ";
ss << spec->rtn_type->debugName();
} 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;
}
ss << " at effort level " << (int)effort;
......@@ -259,7 +259,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
static StatCounter us_compiling("us_compiling");
us_compiling.log(us);
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");
......@@ -309,11 +309,13 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
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);
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);
CLFunction* cl_f = new CLFunction(0, 0, false, false, std::move(si));
......@@ -351,20 +353,21 @@ Box* evalOrExec(CLFunction* cl, Box* globals, Box* 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());
Timer _t("for evalOrExec()");
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));
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 should have a cleaner interface that can parse the Expression directly
// TODO this memory leaks
......@@ -373,7 +376,7 @@ CLFunction* compileExec(llvm::StringRef source) {
AST_Suite* parsedSuite = new AST_Suite(std::move(parsedModule->interned_strings));
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) {
......@@ -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 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), "");
llvm::StringRef source_str = static_cast<BoxedString*>(source)->s;
CLFunction* cl;
if (type_str == "exec") {
cl = compileExec(source_str);
cl = compileExec(source_str, filename_str);
} else if (type_str == "eval") {
fatalOrError(NotImplemented, "unimplemented");
throwCAPIException();
......@@ -472,7 +472,7 @@ Box* eval(Box* boxedCode) {
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);
}
......@@ -530,7 +530,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
CLFunction* cl;
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) {
cl = clfunctionFromCode(boxedCode);
} else {
......
......@@ -2591,7 +2591,7 @@ CLFunction* wrapFunction(AST* node, AST_arguments* args, const std::vector<AST_s
CLFunction*& cl = made[node];
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)
cl = new CLFunction(args->args.size(), args->defaults.size(), args->vararg.str().size(),
args->kwarg.str().size(), std::move(si));
......
......@@ -499,16 +499,7 @@ static const LineInfo* lineInfoForFrame(PythonFrameIteratorImpl& frame_it) {
auto source = cf->clfunc->source.get();
// Hack: the "filename" for eval and exec statements is "<string>", not the filename
// 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());
return new LineInfo(current_stmt->lineno, current_stmt->col_offset, source->fn, source->getName());
}
static StatCounter us_gettraceback("us_gettraceback");
......
......@@ -246,6 +246,7 @@ public:
LivenessAnalysis* liveness;
std::unordered_map<const OSREntryDescriptor*, PhiAnalysis*> phis;
bool is_generator;
std::string fn; // equivalent of code.co_filename
InternedStringPool& getInternedStrings();
......@@ -260,7 +261,7 @@ public:
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;
......
......@@ -283,7 +283,7 @@ static int main(int argc, char** argv) {
if (!main_module) {
main_module = createModule("__main__", "<stdin>");
} else {
main_module->fn = "<stdin>";
// main_module->fn = "<stdin>";
}
for (;;) {
......
......@@ -1273,8 +1273,31 @@ extern "C" void PyEval_InitThreads(void) noexcept {
}
extern "C" char* PyModule_GetName(PyObject* m) noexcept {
assert(m->cls == module_cls);
return &static_cast<BoxedModule*>(m)->fn[0];
PyObject* d;
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) {
......@@ -1315,7 +1338,6 @@ BoxedModule* importCExtension(const std::string& full_name, const std::string& l
BoxedModule* m = static_cast<BoxedModule*>(_m);
m->setattr("__file__", boxString(path), NULL);
m->fn = path;
return m;
}
......
......@@ -48,7 +48,7 @@ public:
static Box* filename(Box* b, void*) {
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*) {
......
......@@ -381,7 +381,8 @@ static void functionDtor(Box* b) {
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("__file__", boxString(fn));
this->giveAttr("__doc__", doc ? boxStrConstant(doc) : None);
......@@ -1094,10 +1095,13 @@ Box* moduleRepr(BoxedModule* m) {
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)>";
} else {
os << "from '" << m->fn << "'>";
os << "from '" << filename << "'>";
}
return boxString(os.str());
}
......
......@@ -633,8 +633,6 @@ class BoxedModule : public Box {
public:
HCAttrs attrs;
// for traceback purposes; not the same as __file__. This corresponds to co_filename
std::string fn;
FutureFlags future_flags;
BoxedModule(const std::string& name, const std::string& fn, const char* doc = NULL);
......
......@@ -5,4 +5,4 @@ print 1 / 2
exec "print 1 / 2"
exec compile("print 1 / 2", "<string>", "exec")
# 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