Commit b495325d authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix import handling wrt exceptions

Also fix a bug where we were rewriting all member descriptors
as OBJECT types (ie just load the offset), which is what was making
hashlib crash (the first thing that uses non-OBJECT member types).
parent 042eb9a9
......@@ -360,11 +360,11 @@ private:
switch (node->opcode) {
case AST_LangPrimitive::ISINSTANCE:
return BOOL;
case AST_LangPrimitive::LANDINGPAD:
return UNKNOWN;
case AST_LangPrimitive::LOCALS:
return DICT;
case AST_LangPrimitive::LANDINGPAD:
case AST_LangPrimitive::GET_ITER:
case AST_LangPrimitive::IMPORT_FROM:
return UNKNOWN;
default:
RELEASE_ASSERT(0, "%d", node->opcode);
......
......@@ -411,6 +411,26 @@ private:
return new ConcreteCompilerVariable(UNKNOWN, v, true);
}
case AST_LangPrimitive::IMPORT_FROM: {
assert(node->args.size() == 2);
assert(node->args[0]->type == AST_TYPE::Name);
assert(node->args[1]->type == AST_TYPE::Name);
CompilerVariable* module = evalExpr(node->args[0], exc_info);
ConcreteCompilerVariable* converted_module = module->makeConverted(emitter, module->getBoxType());
module->decvref(emitter);
const std::string& name = ast_cast<AST_Name>(node->args[1])->id;
assert(name.size());
llvm::Value* r = emitter.createCall2(exc_info, g.funcs.importFrom, converted_module->getValue(),
embedConstantPtr(&name, g.llvm_str_type_ptr)).getInstruction();
CompilerVariable* v = new ConcreteCompilerVariable(UNKNOWN, r, true);
module->decvref(emitter);
return v;
}
default:
RELEASE_ASSERT(0, "%d", node->opcode);
}
......@@ -1621,13 +1641,14 @@ private:
.getInstruction();
ConcreteCompilerVariable* module = new ConcreteCompilerVariable(typeFromClass(module_cls), imported_v, true);
// ImportFrom statements should only get generated for "import *"; all other import from's
// should get translated to IMPORT_FROM bytecodes.
for (int i = 0; i < node->names.size(); i++) {
AST_alias* alias = node->names[i];
const std::string& name = alias->name;
const std::string& asname = alias->asname.size() ? alias->asname : alias->name;
assert(alias->name == "*");
assert(alias->asname == "");
if (name == "*") {
RELEASE_ASSERT(irstate->getSourceInfo()->ast->type == AST_TYPE::Module,
"import * not supported in functions");
emitter.createCall2(exc_info, g.funcs.importStar, imported_v,
......@@ -1635,15 +1656,6 @@ private:
continue;
}
// TODO add patchpoints to this?
llvm::Value* r = emitter.createCall2(exc_info, g.funcs.importFrom, module->getValue(),
embedConstantPtr(&name, g.llvm_str_type_ptr)).getInstruction();
CompilerVariable* v = new ConcreteCompilerVariable(UNKNOWN, r, true);
_doSet(asname, v, exc_info);
v->decvref(emitter);
}
module->decvref(emitter);
}
......
......@@ -1368,6 +1368,9 @@ bool PrintVisitor::visit_langprimitive(AST_LangPrimitive* node) {
case AST_LangPrimitive::GET_ITER:
printf("GET_ITER");
break;
case AST_LangPrimitive::IMPORT_FROM:
printf("IMPORT_FROM");
break;
default:
RELEASE_ASSERT(0, "%d", node->opcode);
}
......
......@@ -922,6 +922,7 @@ public:
LANDINGPAD,
LOCALS,
GET_ITER,
IMPORT_FROM,
} opcode;
std::vector<AST_expr*> args;
......
......@@ -1071,12 +1071,59 @@ public:
}
virtual bool visit_import(AST_Import* node) {
push_back(node);
for (AST_alias* a : node->names) {
AST_Import* remapped = new AST_Import();
remapped->lineno = node->lineno;
remapped->col_offset = node->col_offset;
std::string tmpname = nodeName(a);
AST_alias* remapped_alias = new AST_alias(a->name, tmpname);
remapped->names.push_back(remapped_alias);
push_back(remapped);
pushAssign(a->asname.size() ? a->asname : a->name, makeName(tmpname, AST_TYPE::Load));
}
return true;
}
virtual bool visit_importfrom(AST_ImportFrom* node) {
push_back(node);
RELEASE_ASSERT(node->level == 0, "");
AST_Import* import = new AST_Import();
import->lineno = node->lineno;
import->col_offset = node->col_offset;
std::string tmp_module_name = nodeName(node);
AST_alias* tmp_alias = new AST_alias(node->module, tmp_module_name);
import->names.push_back(tmp_alias);
push_back(import);
for (AST_alias* a : node->names) {
if (a->name == "*") {
assert(a->asname.size() == 0);
AST_ImportFrom* remapped = new AST_ImportFrom();
remapped->lineno = node->lineno;
remapped->col_offset = node->col_offset;
remapped->module = node->module;
remapped->level = node->level;
remapped->names.push_back(a);
push_back(remapped);
} else {
AST_LangPrimitive* import_from = new AST_LangPrimitive(AST_LangPrimitive::IMPORT_FROM);
import_from->lineno = node->lineno;
import_from->col_offset = node->col_offset;
import_from->args.push_back(makeName(tmp_module_name, AST_TYPE::Load));
import_from->args.push_back(makeName(a->name, AST_TYPE::Load));
std::string tmp_import_name = nodeName(a);
pushAssign(tmp_import_name, import_from);
pushAssign(a->asname.size() ? a->asname : a->name, makeName(tmp_import_name, AST_TYPE::Load));
}
}
return true;
}
......
......@@ -47,10 +47,6 @@
#define NOINLINE
#endif
namespace pyston {
void _printStacktrace();
}
// From http://stackoverflow.com/questions/3767869/adding-message-to-assert, modified to use fprintf and give a Python
// stacktrace
#define RELEASE_ASSERT(condition, fmt, ...) \
......@@ -58,7 +54,6 @@ void _printStacktrace();
if (!(condition)) { \
::fprintf(stderr, __FILE__ ":" STRINGIFY(__LINE__) ": %s: Assertion `" #condition "' failed: " fmt "\n", \
__PRETTY_FUNCTION__, ##__VA_ARGS__); \
::pyston::_printStacktrace(); \
::abort(); \
} \
} while (false)
......
......@@ -837,13 +837,6 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box* o
if (!rewrite_args->more_guards_after)
rewrite_args->rewriter->setDoneGuarding();
r_descr.setDoneUsing();
// TODO figure out guards
// do i need to have the rewriter write code to lookup the
// offset or do the guards protect that?
rewrite_args->out_rtn = rewrite_args->obj.getAttr(member_desc->offset, RewriterVarUsage::KillFlag::Kill,
rewrite_args->destination);
rewrite_args->out_success = true;
}
switch (member_desc->type) {
......@@ -851,6 +844,13 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box* o
assert(member_desc->offset % sizeof(Box*) == 0);
Box* rtn = reinterpret_cast<Box**>(obj)[member_desc->offset / sizeof(Box*)];
RELEASE_ASSERT(rtn, "");
if (rewrite_args) {
rewrite_args->out_rtn = rewrite_args->obj.getAttr(
member_desc->offset, RewriterVarUsage::KillFlag::Kill, rewrite_args->destination);
rewrite_args->out_success = true;
}
return rtn;
}
case BoxedMemberDescriptor::BYTE: {
......
# skip-if: True
# - WIP, crashing somewhere
import hashlib
#for m in [hashlib.md5(), hashlib.sha1(), hashlib.sha256(), hashlib.sha512()]:
......
# expected: fail
# - wip
# allow-warning: converting unicode literal to str
try:
import non_existent_module
......@@ -59,7 +58,7 @@ def f2():
except ImportError, e:
print e
print path
print type(path)
try:
print doesnt_exist
except NameError, e:
......
......@@ -121,6 +121,10 @@ def run_test(fn, check_stats, run_memcheck):
jit_args += l
elif l.startswith("# expected:"):
expected = l[len("# expected:"):].strip()
elif l.startswith("# fail-if:"):
condition = l.split(':', 1)[1].strip()
if eval(condition):
expected = "fail"
elif l.startswith("# skip-if:"):
skip_if = l[len("# skip-if:"):].strip()
skip = eval(skip_if)
......
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