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

Unified Diff: src/runtime.cc

Issue 13704010: Generator objects can suspend (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Use sentinel values for continuations 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
« no previous file with comments | « src/runtime.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 843b8d701cbcb3cf2b09d3eedf80bc2cb65c1852..87cdaa95802ed755b88e887f2b631af9dfcbf393 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2295,6 +2295,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
NoHandleAllocation ha(isolate);
ASSERT(args.length() == 0);
+
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
JSFunction* function = JSFunction::cast(frame->function());
@@ -2309,7 +2310,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
if (!maybe_generator->To(&generator)) return maybe_generator;
}
generator->set_function(function);
- generator->set_context(isolate->heap()->undefined_value());
+ generator->set_context(Context::cast(frame->context()));
generator->set_continuation(0);
generator->set_operand_stack(isolate->heap()->empty_fixed_array());
@@ -2317,6 +2318,61 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
+
+ JavaScriptFrameIterator stack_iterator(isolate);
+ JavaScriptFrame *frame = stack_iterator.frame();
+ Handle<JSFunction> function(JSFunction::cast(frame->function()));
+ RUNTIME_ASSERT(function->shared()->is_generator());
+
+ intptr_t offset = frame->pc() - function->code()->instruction_start();
+ ASSERT(*function == generator_object->function());
+ ASSERT(offset > 0 && Smi::IsValid(offset));
+ generator_object->set_continuation(offset);
+
+ // Generator functions force context allocation for locals, so Local0 points
+ // to the bottom of the operand stack. Assume the stack grows down.
+ //
+ // TODO(wingo): Move these magical calculations to frames.h when the
+ // generators implementation has stabilized.
+ intptr_t stack_size_in_bytes =
+ (frame->fp() + JavaScriptFrameConstants::kLocal0Offset) -
+ (frame->sp() - kPointerSize);
+ ASSERT(IsAddressAligned(frame->fp(), kPointerSize));
+ ASSERT(IsAligned(stack_size_in_bytes, kPointerSize));
+ ASSERT(stack_size_in_bytes >= 0);
+ ASSERT(Smi::IsValid(stack_size_in_bytes));
+ unsigned stack_size = stack_size_in_bytes >> kPointerSizeLog2;
+
+ // We expect there to be at least two values on the stack: the return value of
+ // the yield expression, and the argument to this runtime call. Neither of
+ // those should be saved.
+ ASSERT(stack_size >= 2);
+ stack_size -= 2;
+
+ if (stack_size == 0) {
+ ASSERT_EQ(generator_object->operand_stack(),
+ isolate->heap()->empty_fixed_array());
+ // If there are no operands on the stack, there shouldn't be a handler
+ // active either. Also, the active context will be the same as the function
+ // itself, so there is no need to save the context.
+ ASSERT_EQ(frame->context(), generator_object->context());
+ ASSERT(!frame->HasHandler());
+ } else {
+ generator_object->set_context(Context::cast(frame->context()));
+ // TODO(wingo): Save the operand stack and/or the stack handlers.
+ UNIMPLEMENTED();
+ }
+
+ // The return value is the hole for a suspend return, and anything else for a
+ // resume return.
+ return isolate->heap()->the_hole_value();
+}
+
+
MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
Object* char_code) {
uint32_t code;
« no previous file with comments | « src/runtime.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698