Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(635)

Unified Diff: src/runtime.cc

Issue 14066016: Generators can resume (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: ia32 fixups Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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()) {

Powered by Google App Engine
This is Rietveld 408576698