MIPS: Generator objects can suspend
Port r14353 (f4bb81d1) Original commit message: * src/ast.h: * src/parser.cc: Differentiate between the different kinds of yields, in anticipation of boxing return values. Parse `return' into `yield' in a generator. * src/runtime.h: * src/runtime.cc (Runtime_SuspendJSGeneratorObject): New horrible runtime function: saves continuation, context, and operands into the generator object. * src/arm/full-codegen-arm.cc (VisitYield): * src/ia32/full-codegen-ia32.cc (VisitYield): * src/x64/full-codegen-x64.cc (VisitYield): Arrange to call SuspendJSGeneratorObject. If the call returns the hole, we suspend. Otherwise we resume. BUG=v8:2355 TEST=These codepaths are tested when the generator is first invoked, and so are covered by mjsunit/harmony/generators-objects.js. Review URL: https://codereview.chromium.org/14091006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14363 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3575f97036
commit
f51b76425a
@ -1926,6 +1926,60 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
Comment cmnt(masm_, "[ Yield");
|
||||
// Evaluate yielded value first; the initial iterator definition depends on
|
||||
// this. It stays on the stack while we update the iterator.
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
switch (expr->yield_kind()) {
|
||||
case Yield::INITIAL:
|
||||
case Yield::SUSPEND: {
|
||||
VisitForStackValue(expr->generator_object());
|
||||
__ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
|
||||
__ lw(context_register(),
|
||||
MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
|
||||
Label resume;
|
||||
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
|
||||
__ Branch(&resume, ne, result_register(), Operand(at));
|
||||
__ pop(result_register());
|
||||
if (expr->yield_kind() == Yield::SUSPEND) {
|
||||
// TODO(wingo): Box into { value: VALUE, done: false }.
|
||||
}
|
||||
EmitReturnSequence();
|
||||
|
||||
__ bind(&resume);
|
||||
context()->Plug(result_register());
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::FINAL: {
|
||||
VisitForAccumulatorValue(expr->generator_object());
|
||||
__ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
|
||||
__ sw(a1, FieldMemOperand(result_register(),
|
||||
JSGeneratorObject::kContinuationOffset));
|
||||
__ pop(result_register());
|
||||
// TODO(wingo): Box into { value: VALUE, done: true }.
|
||||
|
||||
// Exit all nested statements.
|
||||
NestedStatement* current = nesting_stack_;
|
||||
int stack_depth = 0;
|
||||
int context_length = 0;
|
||||
while (current != NULL) {
|
||||
current = current->Exit(&stack_depth, &context_length);
|
||||
}
|
||||
__ Drop(stack_depth);
|
||||
EmitReturnSequence();
|
||||
break;
|
||||
}
|
||||
|
||||
case Yield::DELEGATING:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
SetSourcePosition(prop->position());
|
||||
Literal* key = prop->key()->AsLiteral();
|
||||
|
Loading…
Reference in New Issue
Block a user