Chromium Code Reviews| Index: src/x64/full-codegen-x64.cc |
| diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc |
| index 9c7a41f44906a2e4c326d9b52d40f9fbc496899d..06ce9420f2926ce1254c43a7cf56e9ea98f9f4d5 100644 |
| --- a/src/x64/full-codegen-x64.cc |
| +++ b/src/x64/full-codegen-x64.cc |
| @@ -312,6 +312,7 @@ void FullCodeGenerator::Generate() { |
| } else { |
| PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
| + |
| { Comment cmnt(masm_, "[ Declarations"); |
| // For named function expressions, declare the function name as a |
| // constant. |
| @@ -334,6 +335,11 @@ void FullCodeGenerator::Generate() { |
| __ bind(&ok); |
| } |
| + if (info->function()->default_values()->length()) { |
| + Comment cmnt(masm_, "[ Optional parameters"); |
| + EmitInitializeOptionalParameters(info->scope(), info->function()); |
|
arv (Not doing code reviews)
2015/04/10 15:08:48
I'm not sure this gets the TDZ right... maybe the
caitp (gmail)
2015/04/10 15:28:00
I think it's mostly right, actually
1 thing I'm n
arv (Not doing code reviews)
2015/04/10 15:58:16
This looks wrong
|
| + } |
| + |
| { Comment cmnt(masm_, "[ Body"); |
| DCHECK(loop_depth() == 0); |
| VisitStatements(function()->body()); |
| @@ -4624,6 +4630,61 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| } |
| +void FullCodeGenerator::EmitInitializeOptionalParameters(Scope* scope, |
| + FunctionLiteral* fn) { |
| + ZoneList<Expression*>* defaults = fn->default_values(); |
| + if (defaults->is_empty()) return; |
| + |
| + int num_parameters = scope->num_parameters(); |
| + int heap_slots = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| + |
| + int current_default = 0; |
| + |
| + for (int i = 0; i < num_parameters; ++i) { |
| + Variable* param = scope->parameter(i); |
| + |
| + if (param->isRestParameter()) break; |
| + |
| + if (param->isOptionalParameter()) { |
| + Expression* default_value = defaults->at(current_default++); |
|
arv (Not doing code reviews)
2015/04/10 15:08:48
So the default list is not a direct mapping from t
caitp (gmail)
2015/04/10 15:28:00
I think we will want to combine them into one list
|
| + |
| + // If the default value is undefined, there is no point initializing it. |
| + if (default_value->IsLiteral() && |
| + default_value->AsLiteral()->IsUndefined()) continue; |
|
arv (Not doing code reviews)
2015/04/10 15:08:49
undefined is a mutable global binding. We cannot m
caitp (gmail)
2015/04/10 15:28:00
hmm :( that's true
|
| + |
| + int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
| + (num_parameters - 1 - i) * kPointerSize; |
| + |
| + Label next; |
| + |
| + __ movp(rax, Operand(rbp, parameter_offset)); |
| + |
| + __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
| + __ j(not_equal, &next); |
| + |
| + { |
| + AccumulatorValueContext context(this); |
| + Visit(default_value); |
| + } |
| + |
| + if (param->IsContextSlot() && heap_slots > 0) { |
| + bool write_barrier = heap_slots > FastNewContextStub::kMaximumSlots; |
| + int context_offset = Context::SlotOffset(param->index()); |
| + __ movp(Operand(rsi, context_offset), rax); |
| + if (write_barrier) { |
| + __ RecordWriteContextSlot( |
| + rsi, context_offset, rax, rbx, kDontSaveFPRegs); |
| + } |
| + } else { |
| + SetVar(param, rax, rbx, rdx); |
| + } |
| + |
| + __ bind(&next); |
| + } |
| + } |
| +} |
| + |
| + |
| void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| ZoneList<Expression*>* args = expr->arguments(); |
| int arg_count = args->length(); |