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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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 2987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2998 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2998 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2999 } | 2999 } |
3000 | 3000 |
3001 | 3001 |
3002 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3002 void FullCodeGenerator::EmitLoadSuperConstructor() { |
3003 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3003 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
3004 __ CallRuntime(Runtime::kGetPrototype, 1); | 3004 __ CallRuntime(Runtime::kGetPrototype, 1); |
3005 } | 3005 } |
3006 | 3006 |
3007 | 3007 |
| 3008 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 3009 SuperReference* super_ref) { |
| 3010 Variable* this_var = super_ref->this_var()->var(); |
| 3011 GetVar(ecx, this_var); |
| 3012 __ cmp(ecx, isolate()->factory()->the_hole_value()); |
| 3013 Label uninitialized_this; |
| 3014 __ j(equal, &uninitialized_this); |
| 3015 __ push(Immediate(this_var->name())); |
| 3016 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 3017 __ bind(&uninitialized_this); |
| 3018 |
| 3019 EmitVariableAssignment(this_var, Token::INIT_CONST); |
| 3020 } |
| 3021 |
| 3022 |
3008 void FullCodeGenerator::VisitCall(Call* expr) { | 3023 void FullCodeGenerator::VisitCall(Call* expr) { |
3009 #ifdef DEBUG | 3024 #ifdef DEBUG |
3010 // We want to verify that RecordJSReturnSite gets called on all paths | 3025 // We want to verify that RecordJSReturnSite gets called on all paths |
3011 // through this function. Avoid early returns. | 3026 // through this function. Avoid early returns. |
3012 expr->return_is_recorded_ = false; | 3027 expr->return_is_recorded_ = false; |
3013 #endif | 3028 #endif |
3014 | 3029 |
3015 Comment cmnt(masm_, "[ Call"); | 3030 Comment cmnt(masm_, "[ Call"); |
3016 Expression* callee = expr->expression(); | 3031 Expression* callee = expr->expression(); |
3017 Call::CallType call_type = expr->GetCallType(isolate()); | 3032 Call::CallType call_type = expr->GetCallType(isolate()); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3212 __ LoadHeapObject(ebx, FeedbackVector()); | 3227 __ LoadHeapObject(ebx, FeedbackVector()); |
3213 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); | 3228 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); |
3214 | 3229 |
3215 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3230 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3216 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3231 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3217 | 3232 |
3218 __ Drop(1); | 3233 __ Drop(1); |
3219 | 3234 |
3220 RecordJSReturnSite(expr); | 3235 RecordJSReturnSite(expr); |
3221 | 3236 |
3222 SuperReference* super_ref = expr->expression()->AsSuperReference(); | 3237 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); |
3223 Variable* this_var = super_ref->this_var()->var(); | |
3224 GetVar(ecx, this_var); | |
3225 __ cmp(ecx, isolate()->factory()->the_hole_value()); | |
3226 Label uninitialized_this; | |
3227 __ j(equal, &uninitialized_this); | |
3228 __ push(Immediate(this_var->name())); | |
3229 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3230 __ bind(&uninitialized_this); | |
3231 | |
3232 EmitVariableAssignment(this_var, Token::INIT_CONST); | |
3233 context()->Plug(eax); | 3238 context()->Plug(eax); |
3234 } | 3239 } |
3235 | 3240 |
3236 | 3241 |
3237 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3242 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3238 ZoneList<Expression*>* args = expr->arguments(); | 3243 ZoneList<Expression*>* args = expr->arguments(); |
3239 DCHECK(args->length() == 1); | 3244 DCHECK(args->length() == 1); |
3240 | 3245 |
3241 VisitForAccumulatorValue(args->at(0)); | 3246 VisitForAccumulatorValue(args->at(0)); |
3242 | 3247 |
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4524 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { | 4529 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { |
4525 DCHECK(expr->arguments()->length() == 0); | 4530 DCHECK(expr->arguments()->length() == 0); |
4526 ExternalReference debug_is_active = | 4531 ExternalReference debug_is_active = |
4527 ExternalReference::debug_is_active_address(isolate()); | 4532 ExternalReference::debug_is_active_address(isolate()); |
4528 __ movzx_b(eax, Operand::StaticVariable(debug_is_active)); | 4533 __ movzx_b(eax, Operand::StaticVariable(debug_is_active)); |
4529 __ SmiTag(eax); | 4534 __ SmiTag(eax); |
4530 context()->Plug(eax); | 4535 context()->Plug(eax); |
4531 } | 4536 } |
4532 | 4537 |
4533 | 4538 |
| 4539 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { |
| 4540 // Assert: expr == CallRuntime("ReflectConstruct") |
| 4541 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); |
| 4542 ZoneList<Expression*>* args = call->arguments(); |
| 4543 DCHECK_EQ(3, args->length()); |
| 4544 |
| 4545 SuperReference* super_reference = args->at(0)->AsSuperReference(); |
| 4546 |
| 4547 // Load ReflectConstruct function |
| 4548 EmitLoadJSRuntimeFunction(call); |
| 4549 |
| 4550 // Push the target function under the receiver |
| 4551 __ push(Operand(esp, 0)); |
| 4552 __ mov(Operand(esp, kPointerSize), eax); |
| 4553 |
| 4554 // Push super |
| 4555 EmitLoadSuperConstructor(); |
| 4556 __ Push(result_register()); |
| 4557 |
| 4558 // Push arguments array |
| 4559 VisitForStackValue(args->at(1)); |
| 4560 |
| 4561 // Push NewTarget |
| 4562 DCHECK(args->at(2)->IsVariableProxy()); |
| 4563 VisitForStackValue(args->at(2)); |
| 4564 |
| 4565 EmitCallJSRuntimeFunction(call); |
| 4566 |
| 4567 // Restore context register. |
| 4568 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 4569 context()->DropAndPlug(1, eax); |
| 4570 |
| 4571 EmitInitializeThisAfterSuper(super_reference); |
| 4572 } |
| 4573 |
| 4574 |
| 4575 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4576 // Push the builtins object as receiver. |
| 4577 __ mov(eax, GlobalObjectOperand()); |
| 4578 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
| 4579 |
| 4580 // Load the function from the receiver. |
| 4581 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 4582 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); |
| 4583 if (FLAG_vector_ics) { |
| 4584 __ mov(VectorLoadICDescriptor::SlotRegister(), |
| 4585 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); |
| 4586 CallLoadIC(NOT_CONTEXTUAL); |
| 4587 } else { |
| 4588 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4589 } |
| 4590 } |
| 4591 |
| 4592 |
| 4593 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 4594 ZoneList<Expression*>* args = expr->arguments(); |
| 4595 int arg_count = args->length(); |
| 4596 |
| 4597 // Record source position of the IC call. |
| 4598 SetSourcePosition(expr->position()); |
| 4599 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4600 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 4601 __ CallStub(&stub); |
| 4602 } |
| 4603 |
| 4604 |
4534 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4605 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4535 ZoneList<Expression*>* args = expr->arguments(); | 4606 ZoneList<Expression*>* args = expr->arguments(); |
4536 int arg_count = args->length(); | 4607 int arg_count = args->length(); |
4537 | 4608 |
4538 if (expr->is_jsruntime()) { | 4609 if (expr->is_jsruntime()) { |
4539 Comment cmnt(masm_, "[ CallRuntime"); | 4610 Comment cmnt(masm_, "[ CallRuntime"); |
4540 // Push the builtins object as receiver. | 4611 EmitLoadJSRuntimeFunction(expr); |
4541 __ mov(eax, GlobalObjectOperand()); | |
4542 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | |
4543 | |
4544 // Load the function from the receiver. | |
4545 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | |
4546 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); | |
4547 if (FLAG_vector_ics) { | |
4548 __ mov(VectorLoadICDescriptor::SlotRegister(), | |
4549 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); | |
4550 CallLoadIC(NOT_CONTEXTUAL); | |
4551 } else { | |
4552 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | |
4553 } | |
4554 | 4612 |
4555 // Push the target function under the receiver. | 4613 // Push the target function under the receiver. |
4556 __ push(Operand(esp, 0)); | 4614 __ push(Operand(esp, 0)); |
4557 __ mov(Operand(esp, kPointerSize), eax); | 4615 __ mov(Operand(esp, kPointerSize), eax); |
4558 | 4616 |
4559 // Push the arguments ("left-to-right"). | 4617 // Push the arguments ("left-to-right"). |
4560 for (int i = 0; i < arg_count; i++) { | 4618 for (int i = 0; i < arg_count; i++) { |
4561 VisitForStackValue(args->at(i)); | 4619 VisitForStackValue(args->at(i)); |
4562 } | 4620 } |
4563 | 4621 |
4564 // Record source position of the IC call. | 4622 EmitCallJSRuntimeFunction(expr); |
4565 SetSourcePosition(expr->position()); | |
4566 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
4567 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | |
4568 __ CallStub(&stub); | |
4569 | 4623 |
4570 // Restore context register. | 4624 // Restore context register. |
4571 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4625 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4572 context()->DropAndPlug(1, eax); | 4626 context()->DropAndPlug(1, eax); |
4573 | 4627 |
4574 } else { | 4628 } else { |
4575 const Runtime::Function* function = expr->function(); | 4629 const Runtime::Function* function = expr->function(); |
4576 switch (function->function_id) { | 4630 switch (function->function_id) { |
4577 #define CALL_INTRINSIC_GENERATOR(Name) \ | 4631 #define CALL_INTRINSIC_GENERATOR(Name) \ |
4578 case Runtime::kInline##Name: { \ | 4632 case Runtime::kInline##Name: { \ |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5342 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5396 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5343 Assembler::target_address_at(call_target_address, | 5397 Assembler::target_address_at(call_target_address, |
5344 unoptimized_code)); | 5398 unoptimized_code)); |
5345 return OSR_AFTER_STACK_CHECK; | 5399 return OSR_AFTER_STACK_CHECK; |
5346 } | 5400 } |
5347 | 5401 |
5348 | 5402 |
5349 } } // namespace v8::internal | 5403 } } // namespace v8::internal |
5350 | 5404 |
5351 #endif // V8_TARGET_ARCH_IA32 | 5405 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |