| Index: src/full-codegen/arm64/full-codegen-arm64.cc
|
| diff --git a/src/full-codegen/arm64/full-codegen-arm64.cc b/src/full-codegen/arm64/full-codegen-arm64.cc
|
| index eb044dbfd9dd0a650fa31dc1fba10a8933a6dab8..fbd653e9eccb575d1a2c2241cabd923323f65dbe 100644
|
| --- a/src/full-codegen/arm64/full-codegen-arm64.cc
|
| +++ b/src/full-codegen/arm64/full-codegen-arm64.cc
|
| @@ -3744,7 +3744,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
| // and suchlike. The implementation changes a little by bleeding_edge so I
|
| // don't want to spend too much time on it now.
|
|
|
| - Label suspend, continuation, post_runtime, resume;
|
| + Label suspend, continuation, post_runtime, resume, exception;
|
|
|
| __ B(&suspend);
|
| // TODO(jbramley): This label is bound here because the following code
|
| @@ -3756,12 +3756,18 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
| // respective resume operation).
|
| __ RecordGeneratorContinuation();
|
| __ Pop(x1);
|
| - __ Cmp(x1, Smi::FromInt(JSGeneratorObject::RETURN));
|
| - __ B(ne, &resume);
|
| + STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
| + STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
| + __ Cmp(x1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
|
| + __ B(lt, &resume);
|
| __ Push(result_register());
|
| + __ B(gt, &exception);
|
| EmitCreateIteratorResult(true);
|
| EmitUnwindAndReturn();
|
|
|
| + __ Bind(&exception);
|
| + __ CallRuntime(Runtime::kThrow);
|
| +
|
| __ Bind(&suspend);
|
| OperandStackDepthIncrement(1); // Not popped on this path.
|
| VisitForAccumulatorValue(expr->generator_object());
|
| @@ -3786,110 +3792,6 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
| context()->Plug(result_register());
|
| }
|
|
|
| -
|
| -void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
|
| - Expression *value,
|
| - JSGeneratorObject::ResumeMode resume_mode) {
|
| - ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume");
|
| - Register generator_object = x1;
|
| - Register the_hole = x2;
|
| - Register operand_stack_size = w3;
|
| - Register function = x4;
|
| -
|
| - // The value stays in x0, and is ultimately read by the resumed generator, as
|
| - // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
|
| - // is read to throw the value when the resumed generator is already closed. x1
|
| - // will hold the generator object until the activation has been resumed.
|
| - VisitForStackValue(generator);
|
| - VisitForAccumulatorValue(value);
|
| - PopOperand(generator_object);
|
| -
|
| - // Store input value into generator object.
|
| - __ Str(result_register(),
|
| - FieldMemOperand(x1, JSGeneratorObject::kInputOffset));
|
| - __ Mov(x2, result_register());
|
| - __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x2, x3,
|
| - kLRHasBeenSaved, kDontSaveFPRegs);
|
| -
|
| - // Load suspended function and context.
|
| - __ Ldr(cp, FieldMemOperand(generator_object,
|
| - JSGeneratorObject::kContextOffset));
|
| - __ Ldr(function, FieldMemOperand(generator_object,
|
| - JSGeneratorObject::kFunctionOffset));
|
| -
|
| - // Load receiver and store as the first argument.
|
| - __ Ldr(x10, FieldMemOperand(generator_object,
|
| - JSGeneratorObject::kReceiverOffset));
|
| - __ Push(x10);
|
| -
|
| - // Push holes for arguments to generator function. Since the parser forced
|
| - // context allocation for any variables in generators, the actual argument
|
| - // values have already been copied into the context and these dummy values
|
| - // will never be used.
|
| - __ Ldr(x10, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
|
| -
|
| - // The number of arguments is stored as an int32_t, and -1 is a marker
|
| - // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign
|
| - // extension to correctly handle it. However, in this case, we operate on
|
| - // 32-bit W registers, so extension isn't required.
|
| - __ Ldr(w10, FieldMemOperand(x10,
|
| - SharedFunctionInfo::kFormalParameterCountOffset));
|
| - __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
|
| - __ PushMultipleTimes(the_hole, w10);
|
| -
|
| - // Enter a new JavaScript frame, and initialize its slots as they were when
|
| - // the generator was suspended.
|
| - Label resume_frame, done;
|
| - __ Bl(&resume_frame);
|
| - __ B(&done);
|
| -
|
| - __ Bind(&resume_frame);
|
| - __ Push(lr, // Return address.
|
| - fp, // Caller's frame pointer.
|
| - cp, // Callee's context.
|
| - function); // Callee's JS Function.
|
| - __ Add(fp, __ StackPointer(), kPointerSize * 2);
|
| -
|
| - // Load and untag the operand stack size.
|
| - __ Ldr(x10, FieldMemOperand(generator_object,
|
| - JSGeneratorObject::kOperandStackOffset));
|
| - __ Ldr(operand_stack_size,
|
| - UntagSmiFieldMemOperand(x10, FixedArray::kLengthOffset));
|
| -
|
| - // If we are sending a value and there is no operand stack, we can jump back
|
| - // in directly.
|
| - if (resume_mode == JSGeneratorObject::NEXT) {
|
| - Label slow_resume;
|
| - __ Cbnz(operand_stack_size, &slow_resume);
|
| - __ Ldr(x10, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
|
| - __ Ldrsw(x11,
|
| - UntagSmiFieldMemOperand(generator_object,
|
| - JSGeneratorObject::kContinuationOffset));
|
| - __ Add(x10, x10, x11);
|
| - __ Mov(x12, Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
|
| - __ Str(x12, FieldMemOperand(generator_object,
|
| - JSGeneratorObject::kContinuationOffset));
|
| - __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
|
| - __ Br(x10);
|
| -
|
| - __ Bind(&slow_resume);
|
| - }
|
| -
|
| - // Otherwise, we push holes for the operand stack and call the runtime to fix
|
| - // up the stack and the handlers.
|
| - __ PushMultipleTimes(the_hole, operand_stack_size);
|
| -
|
| - __ Mov(x10, Smi::FromInt(resume_mode));
|
| - __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
|
| - __ Push(generator_object, result_register(), x10);
|
| - __ CallRuntime(Runtime::kResumeJSGeneratorObject);
|
| - // Not reached: the runtime call returns elsewhere.
|
| - __ Unreachable();
|
| -
|
| - __ Bind(&done);
|
| - context()->Plug(result_register());
|
| -}
|
| -
|
| void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
|
| OperandStackDepthIncrement(2);
|
| __ Push(reg1, reg2);
|
|
|