Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 1df5653acfc5a772fc96ce4cde3bceac9ddaea12..ce56b6ccb221188a219fd3cc47188dea6711e00a 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -2475,6 +2475,61 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) { |
| } |
| +// Note that this function is the slow path for resuming generators. It is only |
| +// called if the suspended activation had operands on the stack, stack handlers |
| +// needing rewinding, or if the resume should throw an exception. The fast path |
| +// is handled directly in FullCodeGenerator::EmitResume(), which is inlined into |
| +// GeneratorNext, GeneratorSend, and GeneratorThrow. EmitResume is called in |
| +// any case, as it needs to reconstruct the stack frame and make space for |
| +// arguments and operands. |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_ResumeJSGeneratorObject) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 3); |
| + CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
| + CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2); |
| + JSGeneratorObject::ResumeMode resume_mode = |
|
Michael Starzinger
2013/04/21 22:45:21
Move the "resume_mode" local variable down to righ
wingo
2013/04/23 13:51:04
Done.
|
| + static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int); |
| + JavaScriptFrameIterator stack_iterator(isolate); |
| + JavaScriptFrame *frame = stack_iterator.frame(); |
| + |
| + ASSERT_EQ(frame->function(), generator_object->function()); |
| + |
| + byte* pc = generator_object->function()->code()->instruction_start(); |
|
Michael Starzinger
2013/04/21 22:45:21
Use "Address" instead of "byte*" here.
wingo
2013/04/23 13:51:04
Done.
|
| + int offset = generator_object->continuation(); |
| + ASSERT(offset > 0); |
| + frame->set_pc(pc + offset); |
| + generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting); |
| + |
| + if (generator_object->operand_stack()->length() != 0) { |
| + // TODO(wingo): Copy operand stack. Rewind handlers. |
| + UNIMPLEMENTED(); |
| + } |
| + |
| + switch (resume_mode) { |
| + default: |
|
Michael Starzinger
2013/04/21 22:45:21
Drop the default case for enums.
wingo
2013/04/23 13:51:04
Done, though I still had to have an UNREACHABLE at
|
| + UNREACHABLE(); |
| + case JSGeneratorObject::kSend: |
| + return *value; |
| + case JSGeneratorObject::kThrow: |
| + return isolate->Throw(*value); |
| + } |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowGeneratorStateError) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 1); |
| + CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); |
| + int continuation = generator->continuation(); |
| + const char *message = continuation == JSGeneratorObject::kGeneratorClosed ? |
| + "generator_finished" : "generator_running"; |
| + Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0); |
| + Handle<Object> error = isolate->factory()->NewError(message, argv); |
| + return isolate->Throw(*error); |
| +} |
| + |
| + |
| MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, |
| Object* char_code) { |
| if (char_code->IsNumber()) { |