[generators] Implement %GeneratorGetSourcePosition.
This runtime function now also works for Ignition generators. It returns the source position of the yield at which a suspended generator got suspended. This works by storing the current bytecode offset at suspension and using an existing mechanism to map it back to a source position. TBR=littledan@chromium.org BUG= Review-Url: https://codereview.chromium.org/2079613003 Cr-Commit-Position: refs/heads/master@{#37140}
This commit is contained in:
parent
1f12208101
commit
7c57ffc1df
@ -693,8 +693,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(r1);
|
__ AssertGeneratorObject(r1);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ str(r0, FieldMemOperand(r1, JSGeneratorObject::kInputOffset));
|
__ str(r0, FieldMemOperand(r1, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
__ RecordWriteField(r1, JSGeneratorObject::kInputOffset, r0, r3,
|
__ RecordWriteField(r1, JSGeneratorObject::kInputOrDebugPosOffset, r0, r3,
|
||||||
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -700,8 +700,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(x1);
|
__ AssertGeneratorObject(x1);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ Str(x0, FieldMemOperand(x1, JSGeneratorObject::kInputOffset));
|
__ Str(x0, FieldMemOperand(x1, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
__ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x0, x3,
|
__ RecordWriteField(x1, JSGeneratorObject::kInputOrDebugPosOffset, x0, x3,
|
||||||
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -152,10 +152,13 @@ FieldAccess AccessBuilder::ForJSGeneratorObjectContinuation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
FieldAccess AccessBuilder::ForJSGeneratorObjectInput() {
|
FieldAccess AccessBuilder::ForJSGeneratorObjectInputOrDebugPos() {
|
||||||
FieldAccess access = {
|
FieldAccess access = {kTaggedBase,
|
||||||
kTaggedBase, JSGeneratorObject::kInputOffset, Handle<Name>(),
|
JSGeneratorObject::kInputOrDebugPosOffset,
|
||||||
Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
|
Handle<Name>(),
|
||||||
|
Type::Any(),
|
||||||
|
MachineType::AnyTagged(),
|
||||||
|
kFullWriteBarrier};
|
||||||
return access;
|
return access;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ class AccessBuilder final : public AllStatic {
|
|||||||
// Provides access to JSGeneratorObject::continuation() field.
|
// Provides access to JSGeneratorObject::continuation() field.
|
||||||
static FieldAccess ForJSGeneratorObjectContinuation();
|
static FieldAccess ForJSGeneratorObjectContinuation();
|
||||||
|
|
||||||
// Provides access to JSGeneratorObject::input() field.
|
// Provides access to JSGeneratorObject::input_or_debug_pos() field.
|
||||||
static FieldAccess ForJSGeneratorObjectInput();
|
static FieldAccess ForJSGeneratorObjectInputOrDebugPos();
|
||||||
|
|
||||||
// Provides access to JSGeneratorObject::operand_stack() field.
|
// Provides access to JSGeneratorObject::operand_stack() field.
|
||||||
static FieldAccess ForJSGeneratorObjectOperandStack();
|
static FieldAccess ForJSGeneratorObjectOperandStack();
|
||||||
|
@ -1419,15 +1419,21 @@ void BytecodeGraphBuilder::VisitSuspendGenerator() {
|
|||||||
Node* state = environment()->LookupAccumulator();
|
Node* state = environment()->LookupAccumulator();
|
||||||
Node* generator = environment()->LookupRegister(
|
Node* generator = environment()->LookupRegister(
|
||||||
bytecode_iterator().GetRegisterOperand(0));
|
bytecode_iterator().GetRegisterOperand(0));
|
||||||
|
// The offsets used by the bytecode iterator are relative to a different base
|
||||||
|
// than what is used in the interpreter, hence the addition.
|
||||||
|
Node* offset =
|
||||||
|
jsgraph()->Constant(bytecode_iterator().current_offset() +
|
||||||
|
(BytecodeArray::kHeaderSize - kHeapObjectTag));
|
||||||
|
|
||||||
int register_count = environment()->register_count();
|
int register_count = environment()->register_count();
|
||||||
int value_input_count = 2 + register_count;
|
int value_input_count = 3 + register_count;
|
||||||
|
|
||||||
Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
|
Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
|
||||||
value_inputs[0] = generator;
|
value_inputs[0] = generator;
|
||||||
value_inputs[1] = state;
|
value_inputs[1] = state;
|
||||||
|
value_inputs[2] = offset;
|
||||||
for (int i = 0; i < register_count; ++i) {
|
for (int i = 0; i < register_count; ++i) {
|
||||||
value_inputs[2 + i] =
|
value_inputs[3 + i] =
|
||||||
environment()->LookupRegister(interpreter::Register(i));
|
environment()->LookupRegister(interpreter::Register(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
|||||||
return ReduceDoubleLo(node);
|
return ReduceDoubleLo(node);
|
||||||
case Runtime::kInlineGeneratorClose:
|
case Runtime::kInlineGeneratorClose:
|
||||||
return ReduceGeneratorClose(node);
|
return ReduceGeneratorClose(node);
|
||||||
case Runtime::kInlineGeneratorGetInput:
|
case Runtime::kInlineGeneratorGetInputOrDebugPos:
|
||||||
return ReduceGeneratorGetInput(node);
|
return ReduceGeneratorGetInputOrDebugPos(node);
|
||||||
case Runtime::kInlineGeneratorGetResumeMode:
|
case Runtime::kInlineGeneratorGetResumeMode:
|
||||||
return ReduceGeneratorGetResumeMode(node);
|
return ReduceGeneratorGetResumeMode(node);
|
||||||
case Runtime::kInlineIsArray:
|
case Runtime::kInlineIsArray:
|
||||||
@ -157,12 +157,12 @@ Reduction JSIntrinsicLowering::ReduceGeneratorClose(Node* node) {
|
|||||||
return Change(node, op, generator, closed, effect, control);
|
return Change(node, op, generator, closed, effect, control);
|
||||||
}
|
}
|
||||||
|
|
||||||
Reduction JSIntrinsicLowering::ReduceGeneratorGetInput(Node* node) {
|
Reduction JSIntrinsicLowering::ReduceGeneratorGetInputOrDebugPos(Node* node) {
|
||||||
Node* const generator = NodeProperties::GetValueInput(node, 0);
|
Node* const generator = NodeProperties::GetValueInput(node, 0);
|
||||||
Node* const effect = NodeProperties::GetEffectInput(node);
|
Node* const effect = NodeProperties::GetEffectInput(node);
|
||||||
Node* const control = NodeProperties::GetControlInput(node);
|
Node* const control = NodeProperties::GetControlInput(node);
|
||||||
Operator const* const op =
|
Operator const* const op = simplified()->LoadField(
|
||||||
simplified()->LoadField(AccessBuilder::ForJSGeneratorObjectInput());
|
AccessBuilder::ForJSGeneratorObjectInputOrDebugPos());
|
||||||
|
|
||||||
return Change(node, op, generator, effect, control);
|
return Change(node, op, generator, effect, control);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
|
|||||||
Reduction ReduceDoubleHi(Node* node);
|
Reduction ReduceDoubleHi(Node* node);
|
||||||
Reduction ReduceDoubleLo(Node* node);
|
Reduction ReduceDoubleLo(Node* node);
|
||||||
Reduction ReduceGeneratorClose(Node* node);
|
Reduction ReduceGeneratorClose(Node* node);
|
||||||
Reduction ReduceGeneratorGetInput(Node* node);
|
Reduction ReduceGeneratorGetInputOrDebugPos(Node* node);
|
||||||
Reduction ReduceGeneratorGetResumeMode(Node* node);
|
Reduction ReduceGeneratorGetResumeMode(Node* node);
|
||||||
Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
|
Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
|
||||||
Reduction ReduceIsJSReceiver(Node* node);
|
Reduction ReduceIsJSReceiver(Node* node);
|
||||||
|
@ -722,7 +722,7 @@ const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
|
|||||||
return new (zone()) Operator1<int>( // --
|
return new (zone()) Operator1<int>( // --
|
||||||
IrOpcode::kJSGeneratorStore, Operator::kNoThrow, // opcode
|
IrOpcode::kJSGeneratorStore, Operator::kNoThrow, // opcode
|
||||||
"JSGeneratorStore", // name
|
"JSGeneratorStore", // name
|
||||||
2 + register_count, 1, 1, 0, 1, 0, // counts
|
3 + register_count, 1, 1, 0, 1, 0, // counts
|
||||||
register_count); // parameter
|
register_count); // parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1743,6 +1743,7 @@ Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
|
|||||||
DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode());
|
DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode());
|
||||||
Node* generator = NodeProperties::GetValueInput(node, 0);
|
Node* generator = NodeProperties::GetValueInput(node, 0);
|
||||||
Node* continuation = NodeProperties::GetValueInput(node, 1);
|
Node* continuation = NodeProperties::GetValueInput(node, 1);
|
||||||
|
Node* offset = NodeProperties::GetValueInput(node, 2);
|
||||||
Node* context = NodeProperties::GetContextInput(node);
|
Node* context = NodeProperties::GetContextInput(node);
|
||||||
Node* effect = NodeProperties::GetEffectInput(node);
|
Node* effect = NodeProperties::GetEffectInput(node);
|
||||||
Node* control = NodeProperties::GetControlInput(node);
|
Node* control = NodeProperties::GetControlInput(node);
|
||||||
@ -1752,12 +1753,14 @@ Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
|
|||||||
FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext();
|
FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext();
|
||||||
FieldAccess continuation_field =
|
FieldAccess continuation_field =
|
||||||
AccessBuilder::ForJSGeneratorObjectContinuation();
|
AccessBuilder::ForJSGeneratorObjectContinuation();
|
||||||
|
FieldAccess input_or_debug_pos_field =
|
||||||
|
AccessBuilder::ForJSGeneratorObjectInputOrDebugPos();
|
||||||
|
|
||||||
Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
|
Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
|
||||||
generator, effect, control);
|
generator, effect, control);
|
||||||
|
|
||||||
for (int i = 0; i < register_count; ++i) {
|
for (int i = 0; i < register_count; ++i) {
|
||||||
Node* value = NodeProperties::GetValueInput(node, 2 + i);
|
Node* value = NodeProperties::GetValueInput(node, 3 + i);
|
||||||
effect = graph()->NewNode(
|
effect = graph()->NewNode(
|
||||||
simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array,
|
simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array,
|
||||||
value, effect, control);
|
value, effect, control);
|
||||||
@ -1767,6 +1770,8 @@ Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
|
|||||||
context, effect, control);
|
context, effect, control);
|
||||||
effect = graph()->NewNode(simplified()->StoreField(continuation_field),
|
effect = graph()->NewNode(simplified()->StoreField(continuation_field),
|
||||||
generator, continuation, effect, control);
|
generator, continuation, effect, control);
|
||||||
|
effect = graph()->NewNode(simplified()->StoreField(input_or_debug_pos_field),
|
||||||
|
generator, offset, effect, control);
|
||||||
|
|
||||||
ReplaceWithValue(node, effect, effect, control);
|
ReplaceWithValue(node, effect, effect, control);
|
||||||
return Changed(effect);
|
return Changed(effect);
|
||||||
|
@ -1828,7 +1828,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, r0 holds the generator object.
|
// When we arrive here, r0 holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ ldr(r1, FieldMemOperand(r0, JSGeneratorObject::kResumeModeOffset));
|
__ ldr(r1, FieldMemOperand(r0, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ ldr(r0, FieldMemOperand(r0, JSGeneratorObject::kInputOffset));
|
__ ldr(r0, FieldMemOperand(r0, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
||||||
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
||||||
__ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
|
__ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
|
||||||
|
@ -3567,7 +3567,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, x0 holds the generator object.
|
// When we arrive here, x0 holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ Ldr(x1, FieldMemOperand(x0, JSGeneratorObject::kResumeModeOffset));
|
__ Ldr(x1, FieldMemOperand(x0, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ Ldr(x0, FieldMemOperand(x0, JSGeneratorObject::kInputOffset));
|
__ Ldr(x0, FieldMemOperand(x0, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
||||||
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
||||||
__ Cmp(x1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
|
__ Cmp(x1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
|
||||||
|
@ -1744,7 +1744,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, eax holds the generator object.
|
// When we arrive here, eax holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ mov(ebx, FieldOperand(eax, JSGeneratorObject::kResumeModeOffset));
|
__ mov(ebx, FieldOperand(eax, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOffset));
|
__ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
||||||
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
||||||
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));
|
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));
|
||||||
|
@ -1823,7 +1823,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, v0 holds the generator object.
|
// When we arrive here, v0 holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ lw(a1, FieldMemOperand(v0, JSGeneratorObject::kResumeModeOffset));
|
__ lw(a1, FieldMemOperand(v0, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ lw(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOffset));
|
__ lw(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
__ Branch(&resume, eq, a1, Operand(Smi::FromInt(JSGeneratorObject::kNext)));
|
__ Branch(&resume, eq, a1, Operand(Smi::FromInt(JSGeneratorObject::kNext)));
|
||||||
__ Push(result_register());
|
__ Push(result_register());
|
||||||
__ Branch(&exception, eq, a1,
|
__ Branch(&exception, eq, a1,
|
||||||
|
@ -1824,7 +1824,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, v0 holds the generator object.
|
// When we arrive here, v0 holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ ld(a1, FieldMemOperand(v0, JSGeneratorObject::kResumeModeOffset));
|
__ ld(a1, FieldMemOperand(v0, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ ld(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOffset));
|
__ ld(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
__ Branch(&resume, eq, a1, Operand(Smi::FromInt(JSGeneratorObject::kNext)));
|
__ Branch(&resume, eq, a1, Operand(Smi::FromInt(JSGeneratorObject::kNext)));
|
||||||
__ Push(result_register());
|
__ Push(result_register());
|
||||||
__ Branch(&exception, eq, a1,
|
__ Branch(&exception, eq, a1,
|
||||||
|
@ -1786,7 +1786,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, r3 holds the generator object.
|
// When we arrive here, r3 holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ LoadP(r4, FieldMemOperand(r3, JSGeneratorObject::kResumeModeOffset));
|
__ LoadP(r4, FieldMemOperand(r3, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ LoadP(r3, FieldMemOperand(r3, JSGeneratorObject::kInputOffset));
|
__ LoadP(r3, FieldMemOperand(r3, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
||||||
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
||||||
__ CmpSmiLiteral(r4, Smi::FromInt(JSGeneratorObject::kReturn), r0);
|
__ CmpSmiLiteral(r4, Smi::FromInt(JSGeneratorObject::kReturn), r0);
|
||||||
|
@ -1744,7 +1744,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, r2 holds the generator object.
|
// When we arrive here, r2 holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ LoadP(r3, FieldMemOperand(r2, JSGeneratorObject::kResumeModeOffset));
|
__ LoadP(r3, FieldMemOperand(r2, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ LoadP(r2, FieldMemOperand(r2, JSGeneratorObject::kInputOffset));
|
__ LoadP(r2, FieldMemOperand(r2, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
||||||
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
||||||
__ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::kReturn), r0);
|
__ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::kReturn), r0);
|
||||||
|
@ -1768,7 +1768,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, rax holds the generator object.
|
// When we arrive here, rax holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ movp(rbx, FieldOperand(rax, JSGeneratorObject::kResumeModeOffset));
|
__ movp(rbx, FieldOperand(rax, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ movp(rax, FieldOperand(rax, JSGeneratorObject::kInputOffset));
|
__ movp(rax, FieldOperand(rax, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
||||||
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
||||||
__ SmiCompare(rbx, Smi::FromInt(JSGeneratorObject::kReturn));
|
__ SmiCompare(rbx, Smi::FromInt(JSGeneratorObject::kReturn));
|
||||||
|
@ -1741,7 +1741,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
|||||||
// When we arrive here, eax holds the generator object.
|
// When we arrive here, eax holds the generator object.
|
||||||
__ RecordGeneratorContinuation();
|
__ RecordGeneratorContinuation();
|
||||||
__ mov(ebx, FieldOperand(eax, JSGeneratorObject::kResumeModeOffset));
|
__ mov(ebx, FieldOperand(eax, JSGeneratorObject::kResumeModeOffset));
|
||||||
__ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOffset));
|
__ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
|
||||||
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
|
||||||
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));
|
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));
|
||||||
|
@ -384,8 +384,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(ebx);
|
__ AssertGeneratorObject(ebx);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), eax);
|
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
|
||||||
__ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, eax, ecx,
|
__ RecordWriteField(ebx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
|
||||||
kDontSaveFPRegs);
|
kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -2234,7 +2234,7 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
|
|||||||
|
|
||||||
Register input = register_allocator()->NewRegister();
|
Register input = register_allocator()->NewRegister();
|
||||||
builder()
|
builder()
|
||||||
->CallRuntime(Runtime::kInlineGeneratorGetInput, generator, 1)
|
->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, generator, 1)
|
||||||
.StoreAccumulatorInRegister(input);
|
.StoreAccumulatorInRegister(input);
|
||||||
|
|
||||||
Register resume_mode = register_allocator()->NewRegister();
|
Register resume_mode = register_allocator()->NewRegister();
|
||||||
|
@ -146,6 +146,9 @@ class InterpreterAssembler : public CodeStubAssembler {
|
|||||||
void AbortIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
|
void AbortIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
|
||||||
BailoutReason bailout_reason);
|
BailoutReason bailout_reason);
|
||||||
|
|
||||||
|
// Returns the offset from the BytecodeArrayPointer of the current bytecode.
|
||||||
|
compiler::Node* BytecodeOffset();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Bytecode bytecode() const { return bytecode_; }
|
Bytecode bytecode() const { return bytecode_; }
|
||||||
static bool TargetSupportsUnalignedAccess();
|
static bool TargetSupportsUnalignedAccess();
|
||||||
@ -153,8 +156,6 @@ class InterpreterAssembler : public CodeStubAssembler {
|
|||||||
private:
|
private:
|
||||||
// Returns a tagged pointer to the current function's BytecodeArray object.
|
// Returns a tagged pointer to the current function's BytecodeArray object.
|
||||||
compiler::Node* BytecodeArrayTaggedPointer();
|
compiler::Node* BytecodeArrayTaggedPointer();
|
||||||
// Returns the offset from the BytecodeArrayPointer of the current bytecode.
|
|
||||||
compiler::Node* BytecodeOffset();
|
|
||||||
// Returns a raw pointer to first entry in the interpreter dispatch table.
|
// Returns a raw pointer to first entry in the interpreter dispatch table.
|
||||||
compiler::Node* DispatchTableRawPointer();
|
compiler::Node* DispatchTableRawPointer();
|
||||||
|
|
||||||
|
@ -1791,7 +1791,8 @@ void Interpreter::DoNop(InterpreterAssembler* assembler) { __ Dispatch(); }
|
|||||||
// SuspendGenerator <generator>
|
// SuspendGenerator <generator>
|
||||||
//
|
//
|
||||||
// Exports the register file and stores it into the generator. Also stores the
|
// Exports the register file and stores it into the generator. Also stores the
|
||||||
// current context and the state given in the accumulator into the generator.
|
// current context, the state given in the accumulator, and the current bytecode
|
||||||
|
// offset (for debugging purposes) into the generator.
|
||||||
void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) {
|
void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) {
|
||||||
Node* generator_reg = __ BytecodeOperandReg(0);
|
Node* generator_reg = __ BytecodeOperandReg(0);
|
||||||
Node* generator = __ LoadRegister(generator_reg);
|
Node* generator = __ LoadRegister(generator_reg);
|
||||||
@ -1816,6 +1817,10 @@ void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) {
|
|||||||
__ StoreObjectField(generator, JSGeneratorObject::kContextOffset, context);
|
__ StoreObjectField(generator, JSGeneratorObject::kContextOffset, context);
|
||||||
__ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, state);
|
__ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, state);
|
||||||
|
|
||||||
|
Node* offset = __ SmiTag(__ BytecodeOffset());
|
||||||
|
__ StoreObjectField(generator, JSGeneratorObject::kInputOrDebugPosOffset,
|
||||||
|
offset);
|
||||||
|
|
||||||
__ Dispatch();
|
__ Dispatch();
|
||||||
|
|
||||||
__ Bind(&if_stepping);
|
__ Bind(&if_stepping);
|
||||||
|
@ -815,8 +815,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(a1);
|
__ AssertGeneratorObject(a1);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ sw(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
|
__ sw(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
__ RecordWriteField(a1, JSGeneratorObject::kInputOffset, v0, a3,
|
__ RecordWriteField(a1, JSGeneratorObject::kInputOrDebugPosOffset, v0, a3,
|
||||||
kRAHasNotBeenSaved, kDontSaveFPRegs);
|
kRAHasNotBeenSaved, kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -680,8 +680,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(a1);
|
__ AssertGeneratorObject(a1);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ sd(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
|
__ sd(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOrDebugPosOffset));
|
||||||
__ RecordWriteField(a1, JSGeneratorObject::kInputOffset, v0, a3,
|
__ RecordWriteField(a1, JSGeneratorObject::kInputOrDebugPosOffset, v0, a3,
|
||||||
kRAHasNotBeenSaved, kDontSaveFPRegs);
|
kRAHasNotBeenSaved, kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -6343,22 +6343,22 @@ void Foreign::set_foreign_address(Address value) {
|
|||||||
ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
|
ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
|
||||||
ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
|
ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
|
||||||
ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset)
|
ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset)
|
||||||
ACCESSORS(JSGeneratorObject, input, Object, kInputOffset)
|
ACCESSORS(JSGeneratorObject, input_or_debug_pos, Object, kInputOrDebugPosOffset)
|
||||||
SMI_ACCESSORS(JSGeneratorObject, resume_mode, kResumeModeOffset)
|
SMI_ACCESSORS(JSGeneratorObject, resume_mode, kResumeModeOffset)
|
||||||
SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
|
SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
|
||||||
ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
|
ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
|
||||||
|
|
||||||
bool JSGeneratorObject::is_suspended() {
|
bool JSGeneratorObject::is_suspended() const {
|
||||||
DCHECK_LT(kGeneratorExecuting, 0);
|
DCHECK_LT(kGeneratorExecuting, 0);
|
||||||
DCHECK_LT(kGeneratorClosed, 0);
|
DCHECK_LT(kGeneratorClosed, 0);
|
||||||
return continuation() >= 0;
|
return continuation() >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JSGeneratorObject::is_closed() {
|
bool JSGeneratorObject::is_closed() const {
|
||||||
return continuation() == kGeneratorClosed;
|
return continuation() == kGeneratorClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JSGeneratorObject::is_executing() {
|
bool JSGeneratorObject::is_executing() const {
|
||||||
return continuation() == kGeneratorExecuting;
|
return continuation() == kGeneratorExecuting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18863,5 +18863,22 @@ void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int JSGeneratorObject::source_position() const {
|
||||||
|
CHECK(is_suspended());
|
||||||
|
if (function()->shared()->HasBytecodeArray()) {
|
||||||
|
// New-style generators.
|
||||||
|
int offset = Smi::cast(input_or_debug_pos())->value();
|
||||||
|
// The stored bytecode offset is relative to a different base than what
|
||||||
|
// is used in the source position table, hence the subtraction.
|
||||||
|
offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
|
||||||
|
return function()->shared()->bytecode_array()->SourcePosition(offset);
|
||||||
|
} else {
|
||||||
|
// Old-style generators.
|
||||||
|
int offset = continuation();
|
||||||
|
CHECK(0 <= offset && offset < function()->code()->instruction_size());
|
||||||
|
return function()->code()->SourcePosition(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -7363,23 +7363,32 @@ class JSGeneratorObject: public JSObject {
|
|||||||
// [receiver]: The receiver of the suspended computation.
|
// [receiver]: The receiver of the suspended computation.
|
||||||
DECL_ACCESSORS(receiver, Object)
|
DECL_ACCESSORS(receiver, Object)
|
||||||
|
|
||||||
// [input]: The most recent input value.
|
// [input_or_debug_pos]
|
||||||
DECL_ACCESSORS(input, Object)
|
// For executing generators: the most recent input value.
|
||||||
|
// For suspended new-style generators: debug information (bytecode offset).
|
||||||
|
// For suspended old-style generators: unused.
|
||||||
|
// There is currently no need to remember the most recent input value for a
|
||||||
|
// suspended generator.
|
||||||
|
DECL_ACCESSORS(input_or_debug_pos, Object)
|
||||||
|
|
||||||
// [resume_mode]: The most recent resume mode.
|
// [resume_mode]: The most recent resume mode.
|
||||||
enum ResumeMode { kNext, kReturn, kThrow };
|
enum ResumeMode { kNext, kReturn, kThrow };
|
||||||
DECL_INT_ACCESSORS(resume_mode)
|
DECL_INT_ACCESSORS(resume_mode)
|
||||||
|
|
||||||
// [continuation]: Offset into code of continuation.
|
// [continuation]
|
||||||
//
|
//
|
||||||
// A positive offset indicates a suspended generator. The special
|
// A positive value indicates a suspended generator. The special
|
||||||
// kGeneratorExecuting and kGeneratorClosed values indicate that a generator
|
// kGeneratorExecuting and kGeneratorClosed values indicate that a generator
|
||||||
// cannot be resumed.
|
// cannot be resumed.
|
||||||
inline int continuation() const;
|
inline int continuation() const;
|
||||||
inline void set_continuation(int continuation);
|
inline void set_continuation(int continuation);
|
||||||
inline bool is_closed();
|
inline bool is_closed() const;
|
||||||
inline bool is_executing();
|
inline bool is_executing() const;
|
||||||
inline bool is_suspended();
|
inline bool is_suspended() const;
|
||||||
|
|
||||||
|
// For suspended generators: the source position at which the generator
|
||||||
|
// is suspended.
|
||||||
|
int source_position() const;
|
||||||
|
|
||||||
// [operand_stack]: Saved operand stack.
|
// [operand_stack]: Saved operand stack.
|
||||||
DECL_ACCESSORS(operand_stack, FixedArray)
|
DECL_ACCESSORS(operand_stack, FixedArray)
|
||||||
@ -7397,8 +7406,8 @@ class JSGeneratorObject: public JSObject {
|
|||||||
static const int kFunctionOffset = JSObject::kHeaderSize;
|
static const int kFunctionOffset = JSObject::kHeaderSize;
|
||||||
static const int kContextOffset = kFunctionOffset + kPointerSize;
|
static const int kContextOffset = kFunctionOffset + kPointerSize;
|
||||||
static const int kReceiverOffset = kContextOffset + kPointerSize;
|
static const int kReceiverOffset = kContextOffset + kPointerSize;
|
||||||
static const int kInputOffset = kReceiverOffset + kPointerSize;
|
static const int kInputOrDebugPosOffset = kReceiverOffset + kPointerSize;
|
||||||
static const int kResumeModeOffset = kInputOffset + kPointerSize;
|
static const int kResumeModeOffset = kInputOrDebugPosOffset + kPointerSize;
|
||||||
static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
|
static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
|
||||||
static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
|
static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
|
||||||
static const int kSize = kOperandStackOffset + kPointerSize;
|
static const int kSize = kOperandStackOffset + kPointerSize;
|
||||||
|
@ -680,13 +680,14 @@ Expression* ParserTraits::NewTargetExpression(Scope* scope,
|
|||||||
Expression* ParserTraits::FunctionSentExpression(Scope* scope,
|
Expression* ParserTraits::FunctionSentExpression(Scope* scope,
|
||||||
AstNodeFactory* factory,
|
AstNodeFactory* factory,
|
||||||
int pos) {
|
int pos) {
|
||||||
// We desugar function.sent into %_GeneratorGetInput(generator).
|
// We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
|
||||||
Zone* zone = parser_->zone();
|
Zone* zone = parser_->zone();
|
||||||
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
|
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
|
||||||
VariableProxy* generator = factory->NewVariableProxy(
|
VariableProxy* generator = factory->NewVariableProxy(
|
||||||
parser_->function_state_->generator_object_variable());
|
parser_->function_state_->generator_object_variable());
|
||||||
args->Add(generator, zone);
|
args->Add(generator, zone);
|
||||||
return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInput, args, pos);
|
return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
|
||||||
|
args, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -691,8 +691,9 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(r4);
|
__ AssertGeneratorObject(r4);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ StoreP(r3, FieldMemOperand(r4, JSGeneratorObject::kInputOffset), r0);
|
__ StoreP(r3, FieldMemOperand(r4, JSGeneratorObject::kInputOrDebugPosOffset),
|
||||||
__ RecordWriteField(r4, JSGeneratorObject::kInputOffset, r3, r6,
|
r0);
|
||||||
|
__ RecordWriteField(r4, JSGeneratorObject::kInputOrDebugPosOffset, r3, r6,
|
||||||
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -40,7 +40,6 @@ RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
|
|||||||
return *generator;
|
return *generator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
|
RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
|
||||||
HandleScope handle_scope(isolate);
|
HandleScope handle_scope(isolate);
|
||||||
DCHECK(args.length() == 1);
|
DCHECK(args.length() == 1);
|
||||||
@ -91,8 +90,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorClose) {
|
|||||||
return isolate->heap()->undefined_value();
|
return isolate->heap()->undefined_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns function of generator activation.
|
|
||||||
RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
|
RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
DCHECK(args.length() == 1);
|
DCHECK(args.length() == 1);
|
||||||
@ -101,8 +98,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
|
|||||||
return generator->function();
|
return generator->function();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns receiver of generator activation.
|
|
||||||
RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
|
RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
DCHECK(args.length() == 1);
|
DCHECK(args.length() == 1);
|
||||||
@ -111,17 +106,14 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
|
|||||||
return generator->receiver();
|
return generator->receiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RUNTIME_FUNCTION(Runtime_GeneratorGetInputOrDebugPos) {
|
||||||
// Returns input of generator activation.
|
|
||||||
RUNTIME_FUNCTION(Runtime_GeneratorGetInput) {
|
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
DCHECK(args.length() == 1);
|
DCHECK(args.length() == 1);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
|
||||||
|
|
||||||
return generator->input();
|
return generator->input_or_debug_pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns resume mode of generator activation.
|
|
||||||
RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) {
|
RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
DCHECK(args.length() == 1);
|
DCHECK(args.length() == 1);
|
||||||
@ -130,7 +122,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) {
|
|||||||
return Smi::FromInt(generator->resume_mode());
|
return Smi::FromInt(generator->resume_mode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
|
RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
DCHECK(args.length() == 1);
|
DCHECK(args.length() == 1);
|
||||||
@ -139,20 +130,13 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
|
|||||||
return Smi::FromInt(generator->continuation());
|
return Smi::FromInt(generator->continuation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
|
RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
DCHECK(args.length() == 1);
|
DCHECK(args.length() == 1);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
|
||||||
|
|
||||||
if (!generator->is_suspended()) return isolate->heap()->undefined_value();
|
if (!generator->is_suspended()) return isolate->heap()->undefined_value();
|
||||||
|
return Smi::FromInt(generator->source_position());
|
||||||
if (generator->function()->shared()->HasBytecodeArray()) UNIMPLEMENTED();
|
|
||||||
|
|
||||||
Handle<Code> code(generator->function()->code(), isolate);
|
|
||||||
int offset = generator->continuation();
|
|
||||||
CHECK(0 <= offset && offset < code->instruction_size());
|
|
||||||
return Smi::FromInt(code->SourcePosition(offset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -236,7 +236,7 @@ namespace internal {
|
|||||||
F(GeneratorClose, 1, 1) \
|
F(GeneratorClose, 1, 1) \
|
||||||
F(GeneratorGetFunction, 1, 1) \
|
F(GeneratorGetFunction, 1, 1) \
|
||||||
F(GeneratorGetReceiver, 1, 1) \
|
F(GeneratorGetReceiver, 1, 1) \
|
||||||
F(GeneratorGetInput, 1, 1) \
|
F(GeneratorGetInputOrDebugPos, 1, 1) \
|
||||||
F(GeneratorGetContinuation, 1, 1) \
|
F(GeneratorGetContinuation, 1, 1) \
|
||||||
F(GeneratorGetSourcePosition, 1, 1) \
|
F(GeneratorGetSourcePosition, 1, 1) \
|
||||||
F(GeneratorGetResumeMode, 1, 1)
|
F(GeneratorGetResumeMode, 1, 1)
|
||||||
|
@ -679,8 +679,9 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(r3);
|
__ AssertGeneratorObject(r3);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ StoreP(r2, FieldMemOperand(r3, JSGeneratorObject::kInputOffset), r0);
|
__ StoreP(r2, FieldMemOperand(r3, JSGeneratorObject::kInputOrDebugPosOffset),
|
||||||
__ RecordWriteField(r3, JSGeneratorObject::kInputOffset, r2, r5,
|
r0);
|
||||||
|
__ RecordWriteField(r3, JSGeneratorObject::kInputOrDebugPosOffset, r2, r5,
|
||||||
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
kLRHasNotBeenSaved, kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -458,8 +458,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(rbx);
|
__ AssertGeneratorObject(rbx);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ movp(FieldOperand(rbx, JSGeneratorObject::kInputOffset), rax);
|
__ movp(FieldOperand(rbx, JSGeneratorObject::kInputOrDebugPosOffset), rax);
|
||||||
__ RecordWriteField(rbx, JSGeneratorObject::kInputOffset, rax, rcx,
|
__ RecordWriteField(rbx, JSGeneratorObject::kInputOrDebugPosOffset, rax, rcx,
|
||||||
kDontSaveFPRegs);
|
kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -396,8 +396,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
|||||||
__ AssertGeneratorObject(ebx);
|
__ AssertGeneratorObject(ebx);
|
||||||
|
|
||||||
// Store input value into generator object.
|
// Store input value into generator object.
|
||||||
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), eax);
|
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
|
||||||
__ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, eax, ecx,
|
__ RecordWriteField(ebx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
|
||||||
kDontSaveFPRegs);
|
kDontSaveFPRegs);
|
||||||
|
|
||||||
// Store resume mode into generator object.
|
// Store resume mode into generator object.
|
||||||
|
@ -47,7 +47,7 @@ bytecodes: [
|
|||||||
/* 16 S> */ B(Return),
|
/* 16 S> */ B(Return),
|
||||||
B(LdaSmi), U8(-2),
|
B(LdaSmi), U8(-2),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetInput), R(6), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(6), U8(1),
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
@ -153,7 +153,7 @@ bytecodes: [
|
|||||||
/* 25 S> */ B(Return),
|
/* 25 S> */ B(Return),
|
||||||
B(LdaSmi), U8(-2),
|
B(LdaSmi), U8(-2),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetInput), R(6), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(6), U8(1),
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
@ -187,7 +187,7 @@ bytecodes: [
|
|||||||
/* 25 S> */ B(Return),
|
/* 25 S> */ B(Return),
|
||||||
B(LdaSmi), U8(-2),
|
B(LdaSmi), U8(-2),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetInput), R(5), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(5), U8(1),
|
||||||
B(Star), R(6),
|
B(Star), R(6),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(5), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(5), U8(1),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
@ -299,7 +299,7 @@ bytecodes: [
|
|||||||
/* 44 S> */ B(Return),
|
/* 44 S> */ B(Return),
|
||||||
B(LdaSmi), U8(-2),
|
B(LdaSmi), U8(-2),
|
||||||
B(Star), R(3),
|
B(Star), R(3),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetInput), R(8), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(8), U8(1),
|
||||||
B(Star), R(9),
|
B(Star), R(9),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(8), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(8), U8(1),
|
||||||
B(Star), R(10),
|
B(Star), R(10),
|
||||||
@ -394,7 +394,7 @@ bytecodes: [
|
|||||||
/* 44 S> */ B(Return),
|
/* 44 S> */ B(Return),
|
||||||
B(LdaSmi), U8(-2),
|
B(LdaSmi), U8(-2),
|
||||||
B(Star), R(3),
|
B(Star), R(3),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetInput), R(11), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(11), U8(1),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(11), U8(1),
|
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(11), U8(1),
|
||||||
B(Star), R(14),
|
B(Star), R(14),
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
// Flags: --expose-debug-as debug
|
// Flags: --expose-debug-as debug --ignition-generators
|
||||||
// Test the mirror object for functions.
|
// Test the mirror object for functions.
|
||||||
|
|
||||||
function *generator(f) {
|
function *generator(f) {
|
||||||
|
Loading…
Reference in New Issue
Block a user