Commit 702a57c7 authored by Marius Wachtler's avatar Marius Wachtler

yield: make it steal the passed argument

the idea is that stealing the value allows us to immediately free the variable in more case when it's unused
otherwise we would always have to continue the generator in order to decrease the refcount
parent 716ae2d6
......@@ -993,7 +993,6 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
Value ASTInterpreter::visit_yield(AST_Yield* node) {
Value value = node->value ? visit_expr(node->value) : getNone();
AUTO_DECREF(value.o);
assert(generator && generator->cls == generator_cls);
return Value(yield(generator, value.o), jit ? jit->emitYield(value) : NULL);
......
......@@ -537,7 +537,9 @@ std::vector<RewriterVar*> JitFragmentWriter::emitUnpackIntoArray(RewriterVar* v,
RewriterVar* JitFragmentWriter::emitYield(RewriterVar* v) {
RewriterVar* generator = getInterp()->getAttr(ASTInterpreterJitInterface::getGeneratorOffset());
return call(false, (void*)yield, generator, v)->setType(RefType::OWNED);
auto rtn = call(false, (void*)yield, generator, v)->setType(RefType::OWNED);
v->refConsumed();
return rtn;
}
void JitFragmentWriter::emitDelAttr(RewriterVar* target, BoxedString* attr) {
......
......@@ -1544,8 +1544,9 @@ private:
CompilerVariable* value = node->value ? evalExpr(node->value, unw_info) : emitter.getNone();
ConcreteCompilerVariable* convertedValue = value->makeConverted(emitter, value->getBoxType());
llvm::Value* rtn
llvm::Instruction* rtn
= emitter.createCall2(unw_info, g.funcs.yield, convertedGenerator->getValue(), convertedValue->getValue());
emitter.refConsumed(convertedValue->getValue(), rtn);
emitter.setType(rtn, RefType::OWNED);
return new ConcreteCompilerVariable(UNKNOWN, rtn);
......
......@@ -332,13 +332,13 @@ Box* generatorHasnext(Box* s) {
}
extern "C" Box* yield(BoxedGenerator* obj, Box* value) {
extern "C" Box* yield(BoxedGenerator* obj, STOLEN(Box*) value) {
STAT_TIMER(t0, "us_timer_generator_switching", 0);
assert(obj->cls == generator_cls);
BoxedGenerator* self = static_cast<BoxedGenerator*>(obj);
assert(!self->returnValue);
self->returnValue = incref(value);
self->returnValue = value;
threading::popGenerator();
......@@ -371,6 +371,7 @@ extern "C" Box* yield(BoxedGenerator* obj, Box* value) {
if (self->exception.type) {
ExcInfo e = self->exception;
self->exception = ExcInfo(NULL, NULL, NULL);
Py_CLEAR(self->returnValue);
throw e;
}
......
......@@ -29,7 +29,7 @@ void setupGenerator();
void generatorEntry(BoxedGenerator* g);
Context* getReturnContextForGeneratorFrame(void* frame_addr);
extern "C" Box* yield(BoxedGenerator* obj, Box* value);
extern "C" Box* yield(BoxedGenerator* obj, STOLEN(Box*) value);
extern "C" BoxedGenerator* createGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args);
}
......
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