diff options
Diffstat (limited to 'deps/v8/src/runtime/runtime-generator.cc')
-rw-r--r-- | deps/v8/src/runtime/runtime-generator.cc | 146 |
1 files changed, 37 insertions, 109 deletions
diff --git a/deps/v8/src/runtime/runtime-generator.cc b/deps/v8/src/runtime/runtime-generator.cc index 181b5f9540..dcc48c5c9e 100644 --- a/deps/v8/src/runtime/runtime-generator.cc +++ b/deps/v8/src/runtime/runtime-generator.cc @@ -5,6 +5,7 @@ #include "src/runtime/runtime-utils.h" #include "src/arguments.h" +#include "src/debug/debug.h" #include "src/factory.h" #include "src/frames-inl.h" #include "src/objects-inl.h" @@ -14,26 +15,33 @@ namespace internal { RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) { HandleScope scope(isolate); - DCHECK(args.length() == 0); - - JavaScriptFrameIterator it(isolate); - JavaScriptFrame* frame = it.frame(); - Handle<JSFunction> function(frame->function()); - RUNTIME_ASSERT(function->shared()->is_generator()); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); + CHECK(function->shared()->is_resumable()); + + Handle<FixedArray> operand_stack; + if (function->shared()->HasBytecodeArray()) { + // New-style generators. + DCHECK(!function->shared()->HasBaselineCode()); + int size = function->shared()->bytecode_array()->register_count(); + operand_stack = isolate->factory()->NewFixedArray(size); + } else { + // Old-style generators. + DCHECK(function->shared()->HasBaselineCode()); + operand_stack = isolate->factory()->empty_fixed_array(); + } - Handle<JSGeneratorObject> generator; - DCHECK(!frame->IsConstructor()); - generator = isolate->factory()->NewJSGeneratorObject(function); + Handle<JSGeneratorObject> generator = + isolate->factory()->NewJSGeneratorObject(function); generator->set_function(*function); - generator->set_context(Context::cast(frame->context())); - generator->set_receiver(frame->receiver()); - generator->set_continuation(0); - generator->set_operand_stack(isolate->heap()->empty_fixed_array()); - + generator->set_context(isolate->context()); + generator->set_receiver(*receiver); + generator->set_operand_stack(*operand_stack); + generator->set_continuation(JSGeneratorObject::kGeneratorExecuting); return *generator; } - RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) { HandleScope handle_scope(isolate); DCHECK(args.length() == 1); @@ -41,11 +49,13 @@ RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) { JavaScriptFrameIterator stack_iterator(isolate); JavaScriptFrame* frame = stack_iterator.frame(); - RUNTIME_ASSERT(frame->function()->shared()->is_generator()); + CHECK(frame->function()->shared()->is_resumable()); DCHECK_EQ(frame->function(), generator_object->function()); DCHECK(frame->function()->shared()->is_compiled()); DCHECK(!frame->function()->IsOptimized()); + isolate->debug()->RecordAsyncFunction(generator_object); + // The caller should have saved the context and continuation already. DCHECK_EQ(generator_object->context(), Context::cast(frame->context())); DCHECK_LT(0, generator_object->continuation()); @@ -72,63 +82,6 @@ RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) { return isolate->heap()->undefined_value(); } - -// 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::EmitGeneratorResume(), which is -// inlined into GeneratorNext, GeneratorReturn, and GeneratorThrow. -// EmitGeneratorResume is called in any case, as it needs to reconstruct the -// stack frame and make space for arguments and operands. -RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 3); - CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); - CONVERT_ARG_CHECKED(Object, value, 1); - CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2); - JavaScriptFrameIterator stack_iterator(isolate); - JavaScriptFrame* frame = stack_iterator.frame(); - - DCHECK_EQ(frame->function(), generator_object->function()); - DCHECK(frame->function()->shared()->is_compiled()); - DCHECK(!frame->function()->IsOptimized()); - - STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); - STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); - - Code* code = generator_object->function()->shared()->code(); - int offset = generator_object->continuation(); - DCHECK_GT(offset, 0); - frame->set_pc(code->instruction_start() + offset); - if (FLAG_enable_embedded_constant_pool) { - frame->set_constant_pool(code->constant_pool()); - } - generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting); - - FixedArray* operand_stack = generator_object->operand_stack(); - int operands_count = operand_stack->length(); - if (operands_count != 0) { - frame->RestoreOperandStack(operand_stack); - generator_object->set_operand_stack(isolate->heap()->empty_fixed_array()); - } - - JSGeneratorObject::ResumeMode resume_mode = - static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int); - switch (resume_mode) { - // Note: this looks like NEXT and RETURN are the same but RETURN receives - // special treatment in the generator code (to which we return here). - case JSGeneratorObject::NEXT: - case JSGeneratorObject::RETURN: - return value; - case JSGeneratorObject::THROW: - return isolate->Throw(value); - } - - UNREACHABLE(); - return isolate->ThrowIllegalOperation(); -} - - RUNTIME_FUNCTION(Runtime_GeneratorClose) { HandleScope scope(isolate); DCHECK(args.length() == 1); @@ -139,8 +92,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorClose) { return isolate->heap()->undefined_value(); } - -// Returns function of generator activation. RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) { HandleScope scope(isolate); DCHECK(args.length() == 1); @@ -149,8 +100,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) { return generator->function(); } - -// Returns receiver of generator activation. RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) { HandleScope scope(isolate); DCHECK(args.length() == 1); @@ -159,18 +108,22 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) { return generator->receiver(); } - -// Returns input of generator activation. -RUNTIME_FUNCTION(Runtime_GeneratorGetInput) { +RUNTIME_FUNCTION(Runtime_GeneratorGetInputOrDebugPos) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); - return generator->input(); + return generator->input_or_debug_pos(); } +RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); + + return Smi::FromInt(generator->resume_mode()); +} -// Returns generator continuation as a PC offset, or the magic -1 or 0 values. RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) { HandleScope scope(isolate); DCHECK(args.length() == 1); @@ -179,38 +132,13 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) { return Smi::FromInt(generator->continuation()); } - RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); - if (generator->is_suspended()) { - Handle<Code> code(generator->function()->code(), isolate); - int offset = generator->continuation(); - RUNTIME_ASSERT(0 <= offset && offset < code->instruction_size()); - return Smi::FromInt(code->SourcePosition(offset)); - } - - return isolate->heap()->undefined_value(); -} - -// Optimization for builtins calling any of the following three functions is -// disabled in js/generator.js and compiler.cc, hence they are unreachable. - -RUNTIME_FUNCTION(Runtime_GeneratorNext) { - UNREACHABLE(); - return nullptr; -} - -RUNTIME_FUNCTION(Runtime_GeneratorReturn) { - UNREACHABLE(); - return nullptr; -} - -RUNTIME_FUNCTION(Runtime_GeneratorThrow) { - UNREACHABLE(); - return nullptr; + if (!generator->is_suspended()) return isolate->heap()->undefined_value(); + return Smi::FromInt(generator->source_position()); } } // namespace internal |