Commit be3e46f6 authored by Marius Wachtler's avatar Marius Wachtler

Clear the exc_info when resuming a generator

parent d55d8e07
......@@ -372,6 +372,7 @@ private:
return UNKNOWN;
case AST_LangPrimitive::NONE:
case AST_LangPrimitive::SET_EXC_INFO:
case AST_LangPrimitive::UNCACHE_EXC_INFO:
return NONE;
case AST_LangPrimitive::NONZERO:
return BOOL;
......
......@@ -562,6 +562,10 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
getFrameInfo()->exc = ExcInfo(type.o, value.o, traceback.o);
v = None;
} else if (node->opcode == AST_LangPrimitive::UNCACHE_EXC_INFO) {
assert(node->args.empty());
getFrameInfo()->exc = ExcInfo(NULL, NULL, NULL);
v = None;
} else
RELEASE_ASSERT(0, "not implemented");
return v;
......
......@@ -638,6 +638,22 @@ private:
return getNone();
}
case AST_LangPrimitive::UNCACHE_EXC_INFO: {
assert(node->args.empty());
auto* builder = emitter.getBuilder();
llvm::Value* frame_info = irstate->getFrameInfoVar();
llvm::Value* exc_info = builder->CreateConstInBoundsGEP2_32(frame_info, 0, 0);
assert(exc_info->getType() == g.llvm_excinfo_type->getPointerTo());
llvm::Constant* v = embedConstantPtr(0, g.llvm_value_type_ptr);
builder->CreateStore(v, builder->CreateConstInBoundsGEP2_32(exc_info, 0, 0));
builder->CreateStore(v, builder->CreateConstInBoundsGEP2_32(exc_info, 0, 1));
builder->CreateStore(v, builder->CreateConstInBoundsGEP2_32(exc_info, 0, 2));
return getNone();
}
default:
RELEASE_ASSERT(0, "%d", node->opcode);
}
......
......@@ -1454,6 +1454,9 @@ bool PrintVisitor::visit_langprimitive(AST_LangPrimitive* node) {
case AST_LangPrimitive::SET_EXC_INFO:
printf("SET_EXC_INFO");
break;
case AST_LangPrimitive::UNCACHE_EXC_INFO:
printf("UNCACHE_EXC_INFO");
break;
default:
RELEASE_ASSERT(0, "%d", node->opcode);
}
......
......@@ -997,6 +997,7 @@ public:
NONE,
NONZERO,
SET_EXC_INFO,
UNCACHE_EXC_INFO,
} opcode;
std::vector<AST_expr*> args;
......
......@@ -1006,7 +1006,13 @@ private:
rtn->lineno = node->lineno;
rtn->col_offset = node->col_offset;
rtn->value = remapExpr(node->value);
return rtn;
InternedString node_name(nodeName(rtn));
pushAssign(node_name, rtn);
push_back(makeExpr(new AST_LangPrimitive(AST_LangPrimitive::UNCACHE_EXC_INFO)));
return makeName(node_name, AST_TYPE::Load, node->lineno);
}
AST_expr* remapExpr(AST_expr* node, bool wrap_with_assign = true) {
......
# expected: fail
# - wip
# Generators participate in the notional Python stack just like normal function calls do,
# even if we implement them using separate C stacks.
#
......@@ -8,6 +5,7 @@
# get inherited when we go into a generator
# exc_info gets passed into generators (at both begin and send()) and cleared like normal on the way out:
import sys
def f12():
print
print "f12"
......@@ -25,6 +23,7 @@ def f12():
print "after KeyError:", sys.exc_info()[0]
yield 2
print list(g())
try:
raise AttributeError()
except:
......@@ -32,6 +31,7 @@ def f12():
i = g()
i.next()
print list(g())
try:
1/0
except:
......
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