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

Unified Diff: src/x64/full-codegen-x64.cc

Issue 919703003: WIP: Implement ES6 Spread-calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: AssignmentExpressions are not spreadable, add cctests for parsing Created 5 years, 10 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/x64/full-codegen-x64.cc
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 8fe07975c225d1cf34c47d629907afc3ccb49609..292f7e6e20954dac38f99952b839b68a3b4fdbd7 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -2912,20 +2912,40 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
+ if (expr->HasSpreadArguments()) {
+ __ movp(rax, Immediate(arg_count));
+ }
+
{ PreservePositionScope scope(masm()->positions_recorder());
for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
+ Expression* e = args->at(i);
+ if (e->IsSpreadOperation()) {
+ DoSpreadArgument(e->AsSpreadOperation(), rax);
+ } else {
+ VisitForStackValue(args->at(i));
+ }
}
}
// Record source position of the IC call.
SetSourcePosition(expr->position());
- Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
- __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
- __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
- // Don't assign a type feedback id to the IC, since type feedback is provided
- // by the vector above.
- CallIC(ic);
+ if (expr->HasSpreadArguments()) {
+ CallFunctionFlags flags = call_type == CallICState::METHOD ?
+ CALL_AS_METHOD : NO_CALL_FUNCTION_FLAGS;
+ CallFunctionStub stub(isolate(), arg_count, flags, true);
+ __ movp(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize));
+ __ CallStub(&stub);
+ } else {
+ Handle<Code> ic =
+ CodeFactory::CallIC(isolate(), arg_count, call_type).code();
+ __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
+
+ __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
+
+ // Don't assign a type feedback id to the IC, since type feedback is
+ // provided by the vector above.
+ CallIC(ic);
+ }
RecordJSReturnSite(expr);
@@ -5109,6 +5129,47 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
}
+void FullCodeGenerator::DoSpreadArgument(SpreadOperation* expr,
+ Register arg_count) {
+ Comment cmnt(masm_, "[ SpreadArgument");
+
+ Label loop, not_done, done;
+
+ __ decp(arg_count);
+ __ pushq(arg_count);
+
+ // var iterator = iterable[Symbol.iterator]();
+ VisitForEffect(expr->assign_iterator());
+
+ // Loop entry.
+ __ bind(&loop);
+
+ // result = iterator.next()
+ VisitForEffect(expr->next_result());
+
+ // if (result.done) break;
+ VisitForControl(expr->result_done(), &done, &not_done, &not_done);
+ __ bind(&not_done);
+
+ // %rax = result.value
+ VisitForAccumulatorValue(expr->result_value());
arv (Not doing code reviews) 2015/02/12 21:41:34 Why not VisitForStackValue?
caitp (gmail) 2015/02/12 21:58:54 right now, it's sort of like this: before first v
+ __ pushq(Operand(rsp, 0));
+ __ incp(Operand(rsp, 0));
+ __ movp(Operand(rsp, 1 * kPointerSize), rax);
+
+ // loop
+ __ jmp(&loop);
+
+ __ bind(&done);
+ __ popq(arg_count);
+}
+
+
+void FullCodeGenerator::VisitSpreadOperation(SpreadOperation* expr) {
+ UNREACHABLE();
+}
+
+
void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
__ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
context()->Plug(rax);

Powered by Google App Engine
This is Rietveld 408576698