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; |