Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 } | 305 } |
| 306 | 306 |
| 307 // Visit the declarations and body unless there is an illegal | 307 // Visit the declarations and body unless there is an illegal |
| 308 // redeclaration. | 308 // redeclaration. |
| 309 if (scope()->HasIllegalRedeclaration()) { | 309 if (scope()->HasIllegalRedeclaration()) { |
| 310 Comment cmnt(masm_, "[ Declarations"); | 310 Comment cmnt(masm_, "[ Declarations"); |
| 311 scope()->VisitIllegalRedeclaration(this); | 311 scope()->VisitIllegalRedeclaration(this); |
| 312 | 312 |
| 313 } else { | 313 } else { |
| 314 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); | 314 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
| 315 | |
| 315 { Comment cmnt(masm_, "[ Declarations"); | 316 { Comment cmnt(masm_, "[ Declarations"); |
| 316 // For named function expressions, declare the function name as a | 317 // For named function expressions, declare the function name as a |
| 317 // constant. | 318 // constant. |
| 318 if (scope()->is_function_scope() && scope()->function() != NULL) { | 319 if (scope()->is_function_scope() && scope()->function() != NULL) { |
| 319 VariableDeclaration* function = scope()->function(); | 320 VariableDeclaration* function = scope()->function(); |
| 320 DCHECK(function->proxy()->var()->mode() == CONST || | 321 DCHECK(function->proxy()->var()->mode() == CONST || |
| 321 function->proxy()->var()->mode() == CONST_LEGACY); | 322 function->proxy()->var()->mode() == CONST_LEGACY); |
| 322 DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED); | 323 DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED); |
| 323 VisitVariableDeclaration(function); | 324 VisitVariableDeclaration(function); |
| 324 } | 325 } |
| 325 VisitDeclarations(scope()->declarations()); | 326 VisitDeclarations(scope()->declarations()); |
| 326 } | 327 } |
| 327 | 328 |
| 328 { Comment cmnt(masm_, "[ Stack check"); | 329 { Comment cmnt(masm_, "[ Stack check"); |
| 329 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); | 330 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
| 330 Label ok; | 331 Label ok; |
| 331 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 332 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
| 332 __ j(above_equal, &ok, Label::kNear); | 333 __ j(above_equal, &ok, Label::kNear); |
| 333 __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); | 334 __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); |
| 334 __ bind(&ok); | 335 __ bind(&ok); |
| 335 } | 336 } |
| 336 | 337 |
| 338 if (info->function()->default_values()->length()) { | |
| 339 Comment cmnt(masm_, "[ Optional parameters"); | |
| 340 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
| |
| 341 } | |
| 342 | |
| 337 { Comment cmnt(masm_, "[ Body"); | 343 { Comment cmnt(masm_, "[ Body"); |
| 338 DCHECK(loop_depth() == 0); | 344 DCHECK(loop_depth() == 0); |
| 339 VisitStatements(function()->body()); | 345 VisitStatements(function()->body()); |
| 340 DCHECK(loop_depth() == 0); | 346 DCHECK(loop_depth() == 0); |
| 341 } | 347 } |
| 342 } | 348 } |
| 343 | 349 |
| 344 // Always emit a 'return undefined' in case control fell off the end of | 350 // Always emit a 'return undefined' in case control fell off the end of |
| 345 // the body. | 351 // the body. |
| 346 { Comment cmnt(masm_, "[ return <undefined>;"); | 352 { Comment cmnt(masm_, "[ return <undefined>;"); |
| (...skipping 4270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4617 int arg_count = args->length(); | 4623 int arg_count = args->length(); |
| 4618 | 4624 |
| 4619 // Record source position of the IC call. | 4625 // Record source position of the IC call. |
| 4620 SetSourcePosition(expr->position()); | 4626 SetSourcePosition(expr->position()); |
| 4621 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 4627 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4622 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 4628 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
| 4623 __ CallStub(&stub); | 4629 __ CallStub(&stub); |
| 4624 } | 4630 } |
| 4625 | 4631 |
| 4626 | 4632 |
| 4633 void FullCodeGenerator::EmitInitializeOptionalParameters(Scope* scope, | |
| 4634 FunctionLiteral* fn) { | |
| 4635 ZoneList<Expression*>* defaults = fn->default_values(); | |
| 4636 if (defaults->is_empty()) return; | |
| 4637 | |
| 4638 int num_parameters = scope->num_parameters(); | |
| 4639 int heap_slots = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | |
| 4640 | |
| 4641 int current_default = 0; | |
| 4642 | |
| 4643 for (int i = 0; i < num_parameters; ++i) { | |
| 4644 Variable* param = scope->parameter(i); | |
| 4645 | |
| 4646 if (param->isRestParameter()) break; | |
| 4647 | |
| 4648 if (param->isOptionalParameter()) { | |
| 4649 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
| |
| 4650 | |
| 4651 // If the default value is undefined, there is no point initializing it. | |
| 4652 if (default_value->IsLiteral() && | |
| 4653 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
| |
| 4654 | |
| 4655 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | |
| 4656 (num_parameters - 1 - i) * kPointerSize; | |
| 4657 | |
| 4658 Label next; | |
| 4659 | |
| 4660 __ movp(rax, Operand(rbp, parameter_offset)); | |
| 4661 | |
| 4662 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | |
| 4663 __ j(not_equal, &next); | |
| 4664 | |
| 4665 { | |
| 4666 AccumulatorValueContext context(this); | |
| 4667 Visit(default_value); | |
| 4668 } | |
| 4669 | |
| 4670 if (param->IsContextSlot() && heap_slots > 0) { | |
| 4671 bool write_barrier = heap_slots > FastNewContextStub::kMaximumSlots; | |
| 4672 int context_offset = Context::SlotOffset(param->index()); | |
| 4673 __ movp(Operand(rsi, context_offset), rax); | |
| 4674 if (write_barrier) { | |
| 4675 __ RecordWriteContextSlot( | |
| 4676 rsi, context_offset, rax, rbx, kDontSaveFPRegs); | |
| 4677 } | |
| 4678 } else { | |
| 4679 SetVar(param, rax, rbx, rdx); | |
| 4680 } | |
| 4681 | |
| 4682 __ bind(&next); | |
| 4683 } | |
| 4684 } | |
| 4685 } | |
| 4686 | |
| 4687 | |
| 4627 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4688 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 4628 ZoneList<Expression*>* args = expr->arguments(); | 4689 ZoneList<Expression*>* args = expr->arguments(); |
| 4629 int arg_count = args->length(); | 4690 int arg_count = args->length(); |
| 4630 | 4691 |
| 4631 if (expr->is_jsruntime()) { | 4692 if (expr->is_jsruntime()) { |
| 4632 Comment cmnt(masm_, "[ CallRuntime"); | 4693 Comment cmnt(masm_, "[ CallRuntime"); |
| 4633 | 4694 |
| 4634 EmitLoadJSRuntimeFunction(expr); | 4695 EmitLoadJSRuntimeFunction(expr); |
| 4635 | 4696 |
| 4636 // Push the target function under the receiver. | 4697 // Push the target function under the receiver. |
| (...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5417 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5478 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 5418 Assembler::target_address_at(call_target_address, | 5479 Assembler::target_address_at(call_target_address, |
| 5419 unoptimized_code)); | 5480 unoptimized_code)); |
| 5420 return OSR_AFTER_STACK_CHECK; | 5481 return OSR_AFTER_STACK_CHECK; |
| 5421 } | 5482 } |
| 5422 | 5483 |
| 5423 | 5484 |
| 5424 } } // namespace v8::internal | 5485 } } // namespace v8::internal |
| 5425 | 5486 |
| 5426 #endif // V8_TARGET_ARCH_X64 | 5487 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |