summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime/runtime-generator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime/runtime-generator.cc')
-rw-r--r--deps/v8/src/runtime/runtime-generator.cc146
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