Merge V8 5.2.361.47  DO NOT MERGE

https://chromium.googlesource.com/v8/v8/+/5.2.361.47

FPIIM-449

Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/runtime/runtime-generator.cc b/src/runtime/runtime-generator.cc
index 181b5f9..7ff7fc8 100644
--- a/src/runtime/runtime-generator.cc
+++ b/src/runtime/runtime-generator.cc
@@ -14,22 +14,27 @@
 
 RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
+  RUNTIME_ASSERT(function->shared()->is_resumable());
 
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  Handle<JSFunction> function(frame->function());
-  RUNTIME_ASSERT(function->shared()->is_generator());
+  Handle<FixedArray> operand_stack;
+  if (FLAG_ignition && FLAG_ignition_generators) {
+    int size = function->shared()->bytecode_array()->register_count();
+    operand_stack = isolate->factory()->NewFixedArray(size);
+  } else {
+    DCHECK(!function->shared()->HasBytecodeArray());
+    operand_stack = handle(isolate->heap()->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;
 }
 
@@ -41,7 +46,7 @@
 
   JavaScriptFrameIterator stack_iterator(isolate);
   JavaScriptFrame* frame = stack_iterator.frame();
-  RUNTIME_ASSERT(frame->function()->shared()->is_generator());
+  RUNTIME_ASSERT(frame->function()->shared()->is_resumable());
   DCHECK_EQ(frame->function(), generator_object->function());
   DCHECK(frame->function()->shared()->is_compiled());
   DCHECK(!frame->function()->IsOptimized());
@@ -73,62 +78,6 @@
 }
 
 
-// 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);
@@ -170,7 +119,26 @@
 }
 
 
-// Returns generator continuation as a PC offset, or the magic -1 or 0 values.
+// Returns resume mode of generator activation.
+RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  return Smi::FromInt(generator->resume_mode());
+}
+
+
+RUNTIME_FUNCTION(Runtime_GeneratorSetContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  generator->set_context(isolate->context());
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
@@ -180,6 +148,45 @@
 }
 
 
+RUNTIME_FUNCTION(Runtime_GeneratorSetContinuation) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+  CONVERT_SMI_ARG_CHECKED(continuation, 1);
+
+  generator->set_continuation(continuation);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GeneratorLoadRegister) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
+
+  DCHECK(FLAG_ignition && FLAG_ignition_generators);
+  DCHECK(generator->function()->shared()->HasBytecodeArray());
+
+  return generator->operand_stack()->get(index);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GeneratorStoreRegister) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+
+  DCHECK(FLAG_ignition && FLAG_ignition_generators);
+  DCHECK(generator->function()->shared()->HasBytecodeArray());
+
+  generator->operand_stack()->set(index, *value);
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
@@ -195,23 +202,5 @@
   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;
-}
-
 }  // namespace internal
 }  // namespace v8