[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:
neis 2016-06-21 05:12:47 -07:00 committed by Commit bot
parent 1f12208101
commit 7c57ffc1df
36 changed files with 121 additions and 88 deletions

View File

@ -693,8 +693,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(r1);
// Store input value into generator object.
__ str(r0, FieldMemOperand(r1, JSGeneratorObject::kInputOffset));
__ RecordWriteField(r1, JSGeneratorObject::kInputOffset, r0, r3,
__ str(r0, FieldMemOperand(r1, JSGeneratorObject::kInputOrDebugPosOffset));
__ RecordWriteField(r1, JSGeneratorObject::kInputOrDebugPosOffset, r0, r3,
kLRHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -700,8 +700,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(x1);
// Store input value into generator object.
__ Str(x0, FieldMemOperand(x1, JSGeneratorObject::kInputOffset));
__ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x0, x3,
__ Str(x0, FieldMemOperand(x1, JSGeneratorObject::kInputOrDebugPosOffset));
__ RecordWriteField(x1, JSGeneratorObject::kInputOrDebugPosOffset, x0, x3,
kLRHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -152,10 +152,13 @@ FieldAccess AccessBuilder::ForJSGeneratorObjectContinuation() {
}
// static
FieldAccess AccessBuilder::ForJSGeneratorObjectInput() {
FieldAccess access = {
kTaggedBase, JSGeneratorObject::kInputOffset, Handle<Name>(),
Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
FieldAccess AccessBuilder::ForJSGeneratorObjectInputOrDebugPos() {
FieldAccess access = {kTaggedBase,
JSGeneratorObject::kInputOrDebugPosOffset,
Handle<Name>(),
Type::Any(),
MachineType::AnyTagged(),
kFullWriteBarrier};
return access;
}

View File

@ -58,8 +58,8 @@ class AccessBuilder final : public AllStatic {
// Provides access to JSGeneratorObject::continuation() field.
static FieldAccess ForJSGeneratorObjectContinuation();
// Provides access to JSGeneratorObject::input() field.
static FieldAccess ForJSGeneratorObjectInput();
// Provides access to JSGeneratorObject::input_or_debug_pos() field.
static FieldAccess ForJSGeneratorObjectInputOrDebugPos();
// Provides access to JSGeneratorObject::operand_stack() field.
static FieldAccess ForJSGeneratorObjectOperandStack();

View File

@ -1419,15 +1419,21 @@ void BytecodeGraphBuilder::VisitSuspendGenerator() {
Node* state = environment()->LookupAccumulator();
Node* generator = environment()->LookupRegister(
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 value_input_count = 2 + register_count;
int value_input_count = 3 + register_count;
Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
value_inputs[0] = generator;
value_inputs[1] = state;
value_inputs[2] = offset;
for (int i = 0; i < register_count; ++i) {
value_inputs[2 + i] =
value_inputs[3 + i] =
environment()->LookupRegister(interpreter::Register(i));
}

View File

@ -40,8 +40,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceDoubleLo(node);
case Runtime::kInlineGeneratorClose:
return ReduceGeneratorClose(node);
case Runtime::kInlineGeneratorGetInput:
return ReduceGeneratorGetInput(node);
case Runtime::kInlineGeneratorGetInputOrDebugPos:
return ReduceGeneratorGetInputOrDebugPos(node);
case Runtime::kInlineGeneratorGetResumeMode:
return ReduceGeneratorGetResumeMode(node);
case Runtime::kInlineIsArray:
@ -157,12 +157,12 @@ Reduction JSIntrinsicLowering::ReduceGeneratorClose(Node* node) {
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 effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
Operator const* const op =
simplified()->LoadField(AccessBuilder::ForJSGeneratorObjectInput());
Operator const* const op = simplified()->LoadField(
AccessBuilder::ForJSGeneratorObjectInputOrDebugPos());
return Change(node, op, generator, effect, control);
}

View File

@ -42,7 +42,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
Reduction ReduceDoubleHi(Node* node);
Reduction ReduceDoubleLo(Node* node);
Reduction ReduceGeneratorClose(Node* node);
Reduction ReduceGeneratorGetInput(Node* node);
Reduction ReduceGeneratorGetInputOrDebugPos(Node* node);
Reduction ReduceGeneratorGetResumeMode(Node* node);
Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
Reduction ReduceIsJSReceiver(Node* node);

View File

@ -722,7 +722,7 @@ const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
return new (zone()) Operator1<int>( // --
IrOpcode::kJSGeneratorStore, Operator::kNoThrow, // opcode
"JSGeneratorStore", // name
2 + register_count, 1, 1, 0, 1, 0, // counts
3 + register_count, 1, 1, 0, 1, 0, // counts
register_count); // parameter
}

View File

@ -1743,6 +1743,7 @@ Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode());
Node* generator = NodeProperties::GetValueInput(node, 0);
Node* continuation = NodeProperties::GetValueInput(node, 1);
Node* offset = NodeProperties::GetValueInput(node, 2);
Node* context = NodeProperties::GetContextInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
@ -1752,12 +1753,14 @@ Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext();
FieldAccess continuation_field =
AccessBuilder::ForJSGeneratorObjectContinuation();
FieldAccess input_or_debug_pos_field =
AccessBuilder::ForJSGeneratorObjectInputOrDebugPos();
Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
generator, effect, control);
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(
simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array,
value, effect, control);
@ -1767,6 +1770,8 @@ Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
context, effect, control);
effect = graph()->NewNode(simplified()->StoreField(continuation_field),
generator, continuation, effect, control);
effect = graph()->NewNode(simplified()->StoreField(input_or_debug_pos_field),
generator, offset, effect, control);
ReplaceWithValue(node, effect, effect, control);
return Changed(effect);

View File

@ -1828,7 +1828,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, r0 holds the generator object.
__ RecordGeneratorContinuation();
__ 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::kThrow > JSGeneratorObject::kReturn);
__ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));

View File

@ -3567,7 +3567,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, x0 holds the generator object.
__ RecordGeneratorContinuation();
__ 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::kThrow > JSGeneratorObject::kReturn);
__ Cmp(x1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));

View File

@ -1744,7 +1744,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, eax holds the generator object.
__ RecordGeneratorContinuation();
__ 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::kThrow > JSGeneratorObject::kReturn);
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));

View File

@ -1823,7 +1823,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, v0 holds the generator object.
__ RecordGeneratorContinuation();
__ 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)));
__ Push(result_register());
__ Branch(&exception, eq, a1,

View File

@ -1824,7 +1824,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, v0 holds the generator object.
__ RecordGeneratorContinuation();
__ 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)));
__ Push(result_register());
__ Branch(&exception, eq, a1,

View File

@ -1786,7 +1786,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, r3 holds the generator object.
__ RecordGeneratorContinuation();
__ 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::kThrow > JSGeneratorObject::kReturn);
__ CmpSmiLiteral(r4, Smi::FromInt(JSGeneratorObject::kReturn), r0);

View File

@ -1744,7 +1744,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, r2 holds the generator object.
__ RecordGeneratorContinuation();
__ 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::kThrow > JSGeneratorObject::kReturn);
__ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::kReturn), r0);

View File

@ -1768,7 +1768,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, rax holds the generator object.
__ RecordGeneratorContinuation();
__ 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::kThrow > JSGeneratorObject::kReturn);
__ SmiCompare(rbx, Smi::FromInt(JSGeneratorObject::kReturn));

View File

@ -1741,7 +1741,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// When we arrive here, eax holds the generator object.
__ RecordGeneratorContinuation();
__ 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::kThrow > JSGeneratorObject::kReturn);
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));

View File

@ -384,8 +384,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(ebx);
// Store input value into generator object.
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), eax);
__ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, eax, ecx,
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
__ RecordWriteField(ebx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -2234,7 +2234,7 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
Register input = register_allocator()->NewRegister();
builder()
->CallRuntime(Runtime::kInlineGeneratorGetInput, generator, 1)
->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, generator, 1)
.StoreAccumulatorInRegister(input);
Register resume_mode = register_allocator()->NewRegister();

View File

@ -146,6 +146,9 @@ class InterpreterAssembler : public CodeStubAssembler {
void AbortIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
BailoutReason bailout_reason);
// Returns the offset from the BytecodeArrayPointer of the current bytecode.
compiler::Node* BytecodeOffset();
protected:
Bytecode bytecode() const { return bytecode_; }
static bool TargetSupportsUnalignedAccess();
@ -153,8 +156,6 @@ class InterpreterAssembler : public CodeStubAssembler {
private:
// Returns a tagged pointer to the current function's BytecodeArray object.
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.
compiler::Node* DispatchTableRawPointer();

View File

@ -1791,7 +1791,8 @@ void Interpreter::DoNop(InterpreterAssembler* assembler) { __ Dispatch(); }
// SuspendGenerator <generator>
//
// 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) {
Node* generator_reg = __ BytecodeOperandReg(0);
Node* generator = __ LoadRegister(generator_reg);
@ -1816,6 +1817,10 @@ void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) {
__ StoreObjectField(generator, JSGeneratorObject::kContextOffset, context);
__ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, state);
Node* offset = __ SmiTag(__ BytecodeOffset());
__ StoreObjectField(generator, JSGeneratorObject::kInputOrDebugPosOffset,
offset);
__ Dispatch();
__ Bind(&if_stepping);

View File

@ -815,8 +815,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(a1);
// Store input value into generator object.
__ sw(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
__ RecordWriteField(a1, JSGeneratorObject::kInputOffset, v0, a3,
__ sw(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOrDebugPosOffset));
__ RecordWriteField(a1, JSGeneratorObject::kInputOrDebugPosOffset, v0, a3,
kRAHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -680,8 +680,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(a1);
// Store input value into generator object.
__ sd(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
__ RecordWriteField(a1, JSGeneratorObject::kInputOffset, v0, a3,
__ sd(v0, FieldMemOperand(a1, JSGeneratorObject::kInputOrDebugPosOffset));
__ RecordWriteField(a1, JSGeneratorObject::kInputOrDebugPosOffset, v0, a3,
kRAHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -6343,22 +6343,22 @@ void Foreign::set_foreign_address(Address value) {
ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
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, continuation, kContinuationOffset)
ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
bool JSGeneratorObject::is_suspended() {
bool JSGeneratorObject::is_suspended() const {
DCHECK_LT(kGeneratorExecuting, 0);
DCHECK_LT(kGeneratorClosed, 0);
return continuation() >= 0;
}
bool JSGeneratorObject::is_closed() {
bool JSGeneratorObject::is_closed() const {
return continuation() == kGeneratorClosed;
}
bool JSGeneratorObject::is_executing() {
bool JSGeneratorObject::is_executing() const {
return continuation() == kGeneratorExecuting;
}

View File

@ -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 v8

View File

@ -7363,23 +7363,32 @@ class JSGeneratorObject: public JSObject {
// [receiver]: The receiver of the suspended computation.
DECL_ACCESSORS(receiver, Object)
// [input]: The most recent input value.
DECL_ACCESSORS(input, Object)
// [input_or_debug_pos]
// 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.
enum ResumeMode { kNext, kReturn, kThrow };
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
// cannot be resumed.
inline int continuation() const;
inline void set_continuation(int continuation);
inline bool is_closed();
inline bool is_executing();
inline bool is_suspended();
inline bool is_closed() const;
inline bool is_executing() const;
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.
DECL_ACCESSORS(operand_stack, FixedArray)
@ -7397,8 +7406,8 @@ class JSGeneratorObject: public JSObject {
static const int kFunctionOffset = JSObject::kHeaderSize;
static const int kContextOffset = kFunctionOffset + kPointerSize;
static const int kReceiverOffset = kContextOffset + kPointerSize;
static const int kInputOffset = kReceiverOffset + kPointerSize;
static const int kResumeModeOffset = kInputOffset + kPointerSize;
static const int kInputOrDebugPosOffset = kReceiverOffset + kPointerSize;
static const int kResumeModeOffset = kInputOrDebugPosOffset + kPointerSize;
static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
static const int kSize = kOperandStackOffset + kPointerSize;

View File

@ -680,13 +680,14 @@ Expression* ParserTraits::NewTargetExpression(Scope* scope,
Expression* ParserTraits::FunctionSentExpression(Scope* scope,
AstNodeFactory* factory,
int pos) {
// We desugar function.sent into %_GeneratorGetInput(generator).
// We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
Zone* zone = parser_->zone();
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
VariableProxy* generator = factory->NewVariableProxy(
parser_->function_state_->generator_object_variable());
args->Add(generator, zone);
return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInput, args, pos);
return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
args, pos);
}

View File

@ -691,8 +691,9 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(r4);
// Store input value into generator object.
__ StoreP(r3, FieldMemOperand(r4, JSGeneratorObject::kInputOffset), r0);
__ RecordWriteField(r4, JSGeneratorObject::kInputOffset, r3, r6,
__ StoreP(r3, FieldMemOperand(r4, JSGeneratorObject::kInputOrDebugPosOffset),
r0);
__ RecordWriteField(r4, JSGeneratorObject::kInputOrDebugPosOffset, r3, r6,
kLRHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -40,7 +40,6 @@ RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
return *generator;
}
RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
HandleScope handle_scope(isolate);
DCHECK(args.length() == 1);
@ -91,8 +90,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);
@ -101,8 +98,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
return generator->function();
}
// Returns receiver of generator activation.
RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
@ -111,17 +106,14 @@ 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();
}
// Returns resume mode of generator activation.
RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
@ -130,7 +122,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) {
return Smi::FromInt(generator->resume_mode());
}
RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
@ -139,20 +130,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()) return isolate->heap()->undefined_value();
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));
return Smi::FromInt(generator->source_position());
}
} // namespace internal

View File

@ -236,7 +236,7 @@ namespace internal {
F(GeneratorClose, 1, 1) \
F(GeneratorGetFunction, 1, 1) \
F(GeneratorGetReceiver, 1, 1) \
F(GeneratorGetInput, 1, 1) \
F(GeneratorGetInputOrDebugPos, 1, 1) \
F(GeneratorGetContinuation, 1, 1) \
F(GeneratorGetSourcePosition, 1, 1) \
F(GeneratorGetResumeMode, 1, 1)

View File

@ -679,8 +679,9 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(r3);
// Store input value into generator object.
__ StoreP(r2, FieldMemOperand(r3, JSGeneratorObject::kInputOffset), r0);
__ RecordWriteField(r3, JSGeneratorObject::kInputOffset, r2, r5,
__ StoreP(r2, FieldMemOperand(r3, JSGeneratorObject::kInputOrDebugPosOffset),
r0);
__ RecordWriteField(r3, JSGeneratorObject::kInputOrDebugPosOffset, r2, r5,
kLRHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -458,8 +458,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(rbx);
// Store input value into generator object.
__ movp(FieldOperand(rbx, JSGeneratorObject::kInputOffset), rax);
__ RecordWriteField(rbx, JSGeneratorObject::kInputOffset, rax, rcx,
__ movp(FieldOperand(rbx, JSGeneratorObject::kInputOrDebugPosOffset), rax);
__ RecordWriteField(rbx, JSGeneratorObject::kInputOrDebugPosOffset, rax, rcx,
kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -396,8 +396,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ AssertGeneratorObject(ebx);
// Store input value into generator object.
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), eax);
__ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, eax, ecx,
__ mov(FieldOperand(ebx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
__ RecordWriteField(ebx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
kDontSaveFPRegs);
// Store resume mode into generator object.

View File

@ -47,7 +47,7 @@ bytecodes: [
/* 16 S> */ B(Return),
B(LdaSmi), U8(-2),
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(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
B(Star), R(8),
@ -153,7 +153,7 @@ bytecodes: [
/* 25 S> */ B(Return),
B(LdaSmi), U8(-2),
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(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
B(Star), R(8),
@ -187,7 +187,7 @@ bytecodes: [
/* 25 S> */ B(Return),
B(LdaSmi), U8(-2),
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(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(5), U8(1),
B(Star), R(8),
@ -299,7 +299,7 @@ bytecodes: [
/* 44 S> */ B(Return),
B(LdaSmi), U8(-2),
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(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(8), U8(1),
B(Star), R(10),
@ -394,7 +394,7 @@ bytecodes: [
/* 44 S> */ B(Return),
B(LdaSmi), U8(-2),
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(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(11), U8(1),
B(Star), R(14),

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-debug-as debug
// Flags: --expose-debug-as debug --ignition-generators
// Test the mirror object for functions.
function *generator(f) {