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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 2925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2936 __ push(Immediate(Smi::FromInt(language_mode()))); | 2936 __ push(Immediate(Smi::FromInt(language_mode()))); |
2937 | 2937 |
2938 // Push the start position of the scope the calls resides in. | 2938 // Push the start position of the scope the calls resides in. |
2939 __ push(Immediate(Smi::FromInt(scope()->start_position()))); | 2939 __ push(Immediate(Smi::FromInt(scope()->start_position()))); |
2940 | 2940 |
2941 // Do the runtime call. | 2941 // Do the runtime call. |
2942 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2942 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2943 } | 2943 } |
2944 | 2944 |
2945 | 2945 |
2946 void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) { | 2946 void FullCodeGenerator::EmitLoadSuperConstructor() { |
2947 DCHECK(super_ref != NULL); | |
2948 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 2947 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
2949 __ CallRuntime(Runtime::kGetPrototype, 1); | 2948 __ CallRuntime(Runtime::kGetPrototype, 1); |
2950 } | 2949 } |
2951 | 2950 |
2952 | 2951 |
2953 void FullCodeGenerator::VisitCall(Call* expr) { | 2952 void FullCodeGenerator::VisitCall(Call* expr) { |
2954 #ifdef DEBUG | 2953 #ifdef DEBUG |
2955 // We want to verify that RecordJSReturnSite gets called on all paths | 2954 // We want to verify that RecordJSReturnSite gets called on all paths |
2956 // through this function. Avoid early returns. | 2955 // through this function. Avoid early returns. |
2957 expr->return_is_recorded_ = false; | 2956 expr->return_is_recorded_ = false; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3055 EmitCallWithLoadIC(expr); | 3054 EmitCallWithLoadIC(expr); |
3056 } else { | 3055 } else { |
3057 EmitKeyedCallWithLoadIC(expr, property->key()); | 3056 EmitKeyedCallWithLoadIC(expr, property->key()); |
3058 } | 3057 } |
3059 } | 3058 } |
3060 } else if (call_type == Call::SUPER_CALL) { | 3059 } else if (call_type == Call::SUPER_CALL) { |
3061 if (FLAG_experimental_classes) { | 3060 if (FLAG_experimental_classes) { |
3062 EmitSuperConstructorCall(expr); | 3061 EmitSuperConstructorCall(expr); |
3063 } else { | 3062 } else { |
3064 SuperReference* super_ref = callee->AsSuperReference(); | 3063 SuperReference* super_ref = callee->AsSuperReference(); |
3065 EmitLoadSuperConstructor(super_ref); | 3064 EmitLoadSuperConstructor(); |
3066 __ push(result_register()); | 3065 __ push(result_register()); |
3067 VisitForStackValue(super_ref->this_var()); | 3066 VisitForStackValue(super_ref->this_var()); |
3068 EmitCall(expr, CallICState::METHOD); | 3067 EmitCall(expr, CallICState::METHOD); |
3069 } | 3068 } |
3070 } else { | 3069 } else { |
3071 DCHECK(call_type == Call::OTHER_CALL); | 3070 DCHECK(call_type == Call::OTHER_CALL); |
3072 // Call to an arbitrary expression not handled specially above. | 3071 // Call to an arbitrary expression not handled specially above. |
3073 { PreservePositionScope scope(masm()->positions_recorder()); | 3072 { PreservePositionScope scope(masm()->positions_recorder()); |
3074 VisitForStackValue(callee); | 3073 VisitForStackValue(callee); |
3075 } | 3074 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3128 context()->Plug(eax); | 3127 context()->Plug(eax); |
3129 } | 3128 } |
3130 | 3129 |
3131 | 3130 |
3132 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 3131 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
3133 Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); | 3132 Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); |
3134 GetVar(eax, new_target_var); | 3133 GetVar(eax, new_target_var); |
3135 __ push(eax); | 3134 __ push(eax); |
3136 | 3135 |
3137 SuperReference* super_ref = expr->expression()->AsSuperReference(); | 3136 SuperReference* super_ref = expr->expression()->AsSuperReference(); |
3138 EmitLoadSuperConstructor(super_ref); | 3137 EmitLoadSuperConstructor(); |
3139 __ push(result_register()); | 3138 __ push(result_register()); |
3140 | 3139 |
3141 Variable* this_var = super_ref->this_var()->var(); | 3140 Variable* this_var = super_ref->this_var()->var(); |
3142 GetVar(eax, this_var); | 3141 GetVar(eax, this_var); |
3143 __ cmp(eax, isolate()->factory()->the_hole_value()); | 3142 __ cmp(eax, isolate()->factory()->the_hole_value()); |
3144 Label uninitialized_this; | 3143 Label uninitialized_this; |
3145 __ j(equal, &uninitialized_this); | 3144 __ j(equal, &uninitialized_this); |
3146 __ push(Immediate(this_var->name())); | 3145 __ push(Immediate(this_var->name())); |
3147 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3146 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
3148 __ bind(&uninitialized_this); | 3147 __ bind(&uninitialized_this); |
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4050 | 4049 |
4051 __ bind(&runtime); | 4050 __ bind(&runtime); |
4052 __ push(eax); | 4051 __ push(eax); |
4053 __ CallRuntime(Runtime::kCall, args->length()); | 4052 __ CallRuntime(Runtime::kCall, args->length()); |
4054 __ bind(&done); | 4053 __ bind(&done); |
4055 | 4054 |
4056 context()->Plug(eax); | 4055 context()->Plug(eax); |
4057 } | 4056 } |
4058 | 4057 |
4059 | 4058 |
| 4059 void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { |
| 4060 Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); |
| 4061 GetVar(eax, new_target_var); |
| 4062 __ push(eax); |
| 4063 |
| 4064 EmitLoadSuperConstructor(); |
| 4065 __ push(result_register()); |
| 4066 |
| 4067 // Check if the calling frame is an arguments adaptor frame. |
| 4068 Label adaptor_frame, args_set_up, runtime; |
| 4069 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 4070 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
| 4071 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 4072 __ j(equal, &adaptor_frame); |
| 4073 // default constructor has no arguments, so no adaptor frame means no args. |
| 4074 __ mov(eax, Immediate(0)); |
| 4075 __ jmp(&args_set_up); |
| 4076 |
| 4077 // Copy arguments from adaptor frame. |
| 4078 { |
| 4079 __ bind(&adaptor_frame); |
| 4080 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 4081 __ SmiUntag(ecx); |
| 4082 |
| 4083 // Subtract 1 from arguments count, for new.target. |
| 4084 __ sub(ecx, Immediate(1)); |
| 4085 __ mov(eax, ecx); |
| 4086 __ lea(edx, Operand(edx, ecx, times_pointer_size, |
| 4087 StandardFrameConstants::kCallerSPOffset)); |
| 4088 Label loop; |
| 4089 __ bind(&loop); |
| 4090 __ push(Operand(edx, -1 * kPointerSize)); |
| 4091 __ sub(edx, Immediate(kPointerSize)); |
| 4092 __ dec(ecx); |
| 4093 __ j(not_zero, &loop); |
| 4094 } |
| 4095 |
| 4096 __ bind(&args_set_up); |
| 4097 __ mov(edi, Operand(esp, eax, times_pointer_size, 0)); |
| 4098 |
| 4099 CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL); |
| 4100 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 4101 |
| 4102 __ Drop(1); |
| 4103 |
| 4104 context()->Plug(eax); |
| 4105 } |
| 4106 |
| 4107 |
4060 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { | 4108 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
4061 // Load the arguments on the stack and call the stub. | 4109 // Load the arguments on the stack and call the stub. |
4062 RegExpConstructResultStub stub(isolate()); | 4110 RegExpConstructResultStub stub(isolate()); |
4063 ZoneList<Expression*>* args = expr->arguments(); | 4111 ZoneList<Expression*>* args = expr->arguments(); |
4064 DCHECK(args->length() == 3); | 4112 DCHECK(args->length() == 3); |
4065 VisitForStackValue(args->at(0)); | 4113 VisitForStackValue(args->at(0)); |
4066 VisitForStackValue(args->at(1)); | 4114 VisitForStackValue(args->at(1)); |
4067 VisitForAccumulatorValue(args->at(2)); | 4115 VisitForAccumulatorValue(args->at(2)); |
4068 __ pop(ebx); | 4116 __ pop(ebx); |
4069 __ pop(ecx); | 4117 __ pop(ecx); |
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5289 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5337 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5290 Assembler::target_address_at(call_target_address, | 5338 Assembler::target_address_at(call_target_address, |
5291 unoptimized_code)); | 5339 unoptimized_code)); |
5292 return OSR_AFTER_STACK_CHECK; | 5340 return OSR_AFTER_STACK_CHECK; |
5293 } | 5341 } |
5294 | 5342 |
5295 | 5343 |
5296 } } // namespace v8::internal | 5344 } } // namespace v8::internal |
5297 | 5345 |
5298 #endif // V8_TARGET_ARCH_X87 | 5346 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |