Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 843b8d701cbcb3cf2b09d3eedf80bc2cb65c1852..cb84f5bfed4f18541babda11898edba8c0fb026b 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -2309,7 +2309,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 +2317,57 @@ 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())); |
|
Michael Starzinger
2013/04/17 13:43:48
Let's play it safe for now and add the following h
|
| + |
| + 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. |
| + intptr_t stack_size_in_bytes = |
| + (frame->fp() + JavaScriptFrameConstants::kLocal0Offset) - |
| + (frame->sp() - kPointerSize); |
|
Michael Starzinger
2013/04/17 13:43:48
Just for the record: This magic computation needs
|
| + 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; |
| + |
|
Michael Starzinger
2013/04/17 13:43:48
IIUC the current implementation relies and the con
Michael Starzinger
2013/04/17 13:49:02
That should have been "generator_object->context()
|
| + if (stack_size == 0) { |
| + ASSERT(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())); |
| + // Saving the operand stack or stack handlers is not currently implemented. |
|
Michael Starzinger
2013/04/17 13:43:48
Let's turn this comment into a TODO.
|
| + UNIMPLEMENTED(); |
| + } |
| + |
| + // The return value is the hole for a suspend return, and anything else for a |
| + // resume return. |
| + return *isolate->factory()->the_hole_value(); |
|
Michael Starzinger
2013/04/17 13:43:48
Use "isolate->heap()->the_hole_value()" here inste
|
| +} |
| + |
| + |
| MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, |
| Object* char_code) { |
| uint32_t code; |