Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Unified Diff: src/builtins/x64/builtins-x64.cc

Issue 2622833002: WIP [esnext] implement async iteration proposal (Closed)
Patch Set: Fix minor parsing bug, add some local test262 tests Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/builtins/x64/builtins-x64.cc
diff --git a/src/builtins/x64/builtins-x64.cc b/src/builtins/x64/builtins-x64.cc
index 87dfc7d3a6b6305a4d7ec63c05c36e47b5418a7c..16e9d00cf56e96ca24953e9f5558c5f67f5844a8 100644
--- a/src/builtins/x64/builtins-x64.cc
+++ b/src/builtins/x64/builtins-x64.cc
@@ -559,6 +559,132 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ jmp(&stepping_prepared);
}
+// static
+void Builtins::Generate_ResumeAwaitedGeneratorTrampoline(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- rax : the value to pass to the generator
+ // -- rbx : the JSGeneratorObject to resume
Dan Ehrenberg 2017/01/13 19:41:09 Presumably this would only be called on JSAsyncGen
caitp 2017/01/13 20:11:52 Yes, will update the comment. I don't think it's w
+ // -- rdx : the resume mode (tagged)
+ // -- rsp[0] : return address
+ // -----------------------------------
+ __ AssertGeneratorObject(rbx);
+
+ // Restore saved input
+ __ movp(rcx, FieldOperand(rbx, JSGeneratorObject::kAwaitInputOffset));
+ __ movp(FieldOperand(rbx, JSGeneratorObject::kInputOrDebugPosOffset), rcx);
+ __ RecordWriteField(rbx, JSGeneratorObject::kInputOrDebugPosOffset, rcx, rsi,
+ kDontSaveFPRegs);
+
+ // Store input value into generator object.
+ __ movp(FieldOperand(rbx, JSGeneratorObject::kAwaitInputOffset), rax);
+ __ RecordWriteField(rbx, JSGeneratorObject::kAwaitInputOffset, rax, rcx,
+ kDontSaveFPRegs);
Dan Ehrenberg 2017/01/13 19:41:09 Is the only difference here vs Generate_ResumeGene
caitp 2017/01/13 20:11:52 I agree :D but... I kind of want to avoid adding a
+
+ // Store resume mode into generator object.
+ __ movp(FieldOperand(rbx, JSGeneratorObject::kResumeModeOffset), rdx);
+
+ // Load suspended function and context.
+ __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset));
+ __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
+
+ // Flood function if we are stepping.
+ Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
+ Label stepping_prepared;
+ ExternalReference last_step_action =
+ ExternalReference::debug_last_step_action_address(masm->isolate());
+ Operand last_step_action_operand = masm->ExternalOperand(last_step_action);
+ STATIC_ASSERT(StepFrame > StepIn);
+ __ cmpb(last_step_action_operand, Immediate(StepIn));
+ __ j(greater_equal, &prepare_step_in_if_stepping);
+
+ // Flood function if we need to continue stepping in the suspended generator.
+ ExternalReference debug_suspended_generator =
+ ExternalReference::debug_suspended_generator_address(masm->isolate());
+ Operand debug_suspended_generator_operand =
+ masm->ExternalOperand(debug_suspended_generator);
+ __ cmpp(rbx, debug_suspended_generator_operand);
+ __ j(equal, &prepare_step_in_suspended_generator);
+ __ bind(&stepping_prepared);
+
+ // Pop return address.
+ __ PopReturnAddressTo(rax);
+
+ // Push receiver.
+ __ Push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset));
+
+ // ----------- S t a t e -------------
+ // -- rax : return address
+ // -- rbx : the JSGeneratorObject to resume
+ // -- rdx : the resume mode (tagged)
+ // -- rdi : generator function
+ // -- rsi : generator context
+ // -- rsp[0] : generator receiver
+ // -----------------------------------
+
+ // 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.
+ __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+ __ LoadSharedFunctionInfoSpecialField(
+ rcx, rcx, SharedFunctionInfo::kFormalParameterCountOffset);
+ {
+ Label done_loop, loop;
+ __ bind(&loop);
+ __ subl(rcx, Immediate(1));
+ __ j(carry, &done_loop, Label::kNear);
+ __ PushRoot(Heap::kTheHoleValueRootIndex);
+ __ jmp(&loop);
+ __ bind(&done_loop);
+ }
+
+ // Underlying function needs to have bytecode available.
+ if (FLAG_debug_code) {
+ __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+ __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kFunctionDataOffset));
+ __ CmpObjectType(rcx, BYTECODE_ARRAY_TYPE, rcx);
+ __ Assert(equal, kMissingBytecodeArray);
+ }
+
+ // Resume (Ignition/TurboFan) generator object.
+ {
+ __ PushReturnAddressFrom(rax);
+ __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+ __ LoadSharedFunctionInfoSpecialField(
+ rax, rax, SharedFunctionInfo::kFormalParameterCountOffset);
+ // We abuse new.target both to indicate that this is a resume call and to
+ // pass in the generator object. In ordinary calls, new.target is always
+ // undefined because generator functions are non-constructable.
+ __ movp(rdx, rbx);
+ __ jmp(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
+ }
+
+ __ bind(&prepare_step_in_if_stepping);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(rbx);
+ __ Push(rdx);
+ __ Push(rdi);
+ __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
+ __ Pop(rdx);
+ __ Pop(rbx);
+ __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
+ }
+ __ jmp(&stepping_prepared);
+
+ __ bind(&prepare_step_in_suspended_generator);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(rbx);
+ __ Push(rdx);
+ __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
+ __ Pop(rdx);
+ __ Pop(rbx);
+ __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
+ }
+ __ jmp(&stepping_prepared);
+}
+
static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
Register scratch2) {
Register args_count = scratch1;

Powered by Google App Engine
This is Rietveld 408576698