| 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 } else if (FLAG_debug_code) { | 227 } else if (FLAG_debug_code) { |
| 228 Label done; | 228 Label done; |
| 229 __ JumpIfInNewSpace(rsi, rax, &done, Label::kNear); | 229 __ JumpIfInNewSpace(rsi, rax, &done, Label::kNear); |
| 230 __ Abort(kExpectedNewSpaceObject); | 230 __ Abort(kExpectedNewSpaceObject); |
| 231 __ bind(&done); | 231 __ bind(&done); |
| 232 } | 232 } |
| 233 } | 233 } |
| 234 } | 234 } |
| 235 } | 235 } |
| 236 | 236 |
| 237 // Possibly set up a local binding to the this function which is used in | |
| 238 // derived constructors with super calls. | |
| 239 Variable* this_function_var = scope()->this_function_var(); | |
| 240 if (this_function_var != nullptr) { | |
| 241 Comment cmnt(masm_, "[ This function"); | |
| 242 SetVar(this_function_var, rdi, rbx, rdx); | |
| 243 } | |
| 244 | |
| 245 Variable* new_target_var = scope()->new_target_var(); | |
| 246 if (new_target_var != nullptr) { | |
| 247 Comment cmnt(masm_, "[ new.target"); | |
| 248 // new.target is parameter -2. | |
| 249 int offset = 2 * kPointerSize + kFPOnStackSize + kPCOnStackSize + | |
| 250 (info_->scope()->num_parameters() - 1) * kPointerSize; | |
| 251 __ movp(rax, Operand(rbp, offset)); | |
| 252 SetVar(new_target_var, rax, rbx, rdx); | |
| 253 } | |
| 254 | |
| 255 Variable* home_object_var = scope()->home_object_var(); | 237 Variable* home_object_var = scope()->home_object_var(); |
| 256 if (home_object_var != nullptr) { | 238 if (home_object_var != nullptr) { |
| 257 __ Push(rdi); | 239 __ Push(rdi); |
| 258 } | 240 } |
| 259 | 241 |
| 260 ArgumentsAccessStub::HasNewTarget has_new_target = | 242 ArgumentsAccessStub::HasNewTarget has_new_target = |
| 261 IsSubclassConstructor(info->function()->kind()) | 243 IsSubclassConstructor(info->function()->kind()) |
| 262 ? ArgumentsAccessStub::HAS_NEW_TARGET | 244 ? ArgumentsAccessStub::HAS_NEW_TARGET |
| 263 : ArgumentsAccessStub::NO_NEW_TARGET; | 245 : ArgumentsAccessStub::NO_NEW_TARGET; |
| 264 | 246 |
| (...skipping 1705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1970 case NAMED_PROPERTY: | 1952 case NAMED_PROPERTY: |
| 1971 if (expr->is_compound()) { | 1953 if (expr->is_compound()) { |
| 1972 // We need the receiver both on the stack and in the register. | 1954 // We need the receiver both on the stack and in the register. |
| 1973 VisitForStackValue(property->obj()); | 1955 VisitForStackValue(property->obj()); |
| 1974 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1956 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1975 } else { | 1957 } else { |
| 1976 VisitForStackValue(property->obj()); | 1958 VisitForStackValue(property->obj()); |
| 1977 } | 1959 } |
| 1978 break; | 1960 break; |
| 1979 case NAMED_SUPER_PROPERTY: | 1961 case NAMED_SUPER_PROPERTY: |
| 1980 VisitForStackValue( | 1962 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1981 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1982 VisitForAccumulatorValue( | 1963 VisitForAccumulatorValue( |
| 1983 property->obj()->AsSuperPropertyReference()->home_object_var()); | 1964 property->obj()->AsSuperReference()->home_object_var()); |
| 1984 __ Push(result_register()); | 1965 __ Push(result_register()); |
| 1985 if (expr->is_compound()) { | 1966 if (expr->is_compound()) { |
| 1986 __ Push(MemOperand(rsp, kPointerSize)); | 1967 __ Push(MemOperand(rsp, kPointerSize)); |
| 1987 __ Push(result_register()); | 1968 __ Push(result_register()); |
| 1988 } | 1969 } |
| 1989 break; | 1970 break; |
| 1990 case KEYED_SUPER_PROPERTY: | 1971 case KEYED_SUPER_PROPERTY: |
| 1972 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1991 VisitForStackValue( | 1973 VisitForStackValue( |
| 1992 property->obj()->AsSuperPropertyReference()->this_var()); | 1974 property->obj()->AsSuperReference()->home_object_var()); |
| 1993 VisitForStackValue( | |
| 1994 property->obj()->AsSuperPropertyReference()->home_object_var()); | |
| 1995 VisitForAccumulatorValue(property->key()); | 1975 VisitForAccumulatorValue(property->key()); |
| 1996 __ Push(result_register()); | 1976 __ Push(result_register()); |
| 1997 if (expr->is_compound()) { | 1977 if (expr->is_compound()) { |
| 1998 __ Push(MemOperand(rsp, 2 * kPointerSize)); | 1978 __ Push(MemOperand(rsp, 2 * kPointerSize)); |
| 1999 __ Push(MemOperand(rsp, 2 * kPointerSize)); | 1979 __ Push(MemOperand(rsp, 2 * kPointerSize)); |
| 2000 __ Push(result_register()); | 1980 __ Push(result_register()); |
| 2001 } | 1981 } |
| 2002 break; | 1982 break; |
| 2003 case KEYED_PROPERTY: { | 1983 case KEYED_PROPERTY: { |
| 2004 if (expr->is_compound()) { | 1984 if (expr->is_compound()) { |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2576 __ Move(StoreDescriptor::ReceiverRegister(), rax); | 2556 __ Move(StoreDescriptor::ReceiverRegister(), rax); |
| 2577 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. | 2557 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2578 __ Move(StoreDescriptor::NameRegister(), | 2558 __ Move(StoreDescriptor::NameRegister(), |
| 2579 prop->key()->AsLiteral()->value()); | 2559 prop->key()->AsLiteral()->value()); |
| 2580 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2560 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2581 CallStoreIC(); | 2561 CallStoreIC(); |
| 2582 break; | 2562 break; |
| 2583 } | 2563 } |
| 2584 case NAMED_SUPER_PROPERTY: { | 2564 case NAMED_SUPER_PROPERTY: { |
| 2585 __ Push(rax); | 2565 __ Push(rax); |
| 2586 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2566 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2587 VisitForAccumulatorValue( | 2567 VisitForAccumulatorValue( |
| 2588 prop->obj()->AsSuperPropertyReference()->home_object_var()); | 2568 prop->obj()->AsSuperReference()->home_object_var()); |
| 2589 // stack: value, this; rax: home_object | 2569 // stack: value, this; rax: home_object |
| 2590 Register scratch = rcx; | 2570 Register scratch = rcx; |
| 2591 Register scratch2 = rdx; | 2571 Register scratch2 = rdx; |
| 2592 __ Move(scratch, result_register()); // home_object | 2572 __ Move(scratch, result_register()); // home_object |
| 2593 __ movp(rax, MemOperand(rsp, kPointerSize)); // value | 2573 __ movp(rax, MemOperand(rsp, kPointerSize)); // value |
| 2594 __ movp(scratch2, MemOperand(rsp, 0)); // this | 2574 __ movp(scratch2, MemOperand(rsp, 0)); // this |
| 2595 __ movp(MemOperand(rsp, kPointerSize), scratch2); // this | 2575 __ movp(MemOperand(rsp, kPointerSize), scratch2); // this |
| 2596 __ movp(MemOperand(rsp, 0), scratch); // home_object | 2576 __ movp(MemOperand(rsp, 0), scratch); // home_object |
| 2597 // stack: this, home_object; rax: value | 2577 // stack: this, home_object; rax: value |
| 2598 EmitNamedSuperPropertyStore(prop); | 2578 EmitNamedSuperPropertyStore(prop); |
| 2599 break; | 2579 break; |
| 2600 } | 2580 } |
| 2601 case KEYED_SUPER_PROPERTY: { | 2581 case KEYED_SUPER_PROPERTY: { |
| 2602 __ Push(rax); | 2582 __ Push(rax); |
| 2603 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2583 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2604 VisitForStackValue( | 2584 VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var()); |
| 2605 prop->obj()->AsSuperPropertyReference()->home_object_var()); | |
| 2606 VisitForAccumulatorValue(prop->key()); | 2585 VisitForAccumulatorValue(prop->key()); |
| 2607 Register scratch = rcx; | 2586 Register scratch = rcx; |
| 2608 Register scratch2 = rdx; | 2587 Register scratch2 = rdx; |
| 2609 __ movp(scratch2, MemOperand(rsp, 2 * kPointerSize)); // value | 2588 __ movp(scratch2, MemOperand(rsp, 2 * kPointerSize)); // value |
| 2610 // stack: value, this, home_object; rax: key, rdx: value | 2589 // stack: value, this, home_object; rax: key, rdx: value |
| 2611 __ movp(scratch, MemOperand(rsp, kPointerSize)); // this | 2590 __ movp(scratch, MemOperand(rsp, kPointerSize)); // this |
| 2612 __ movp(MemOperand(rsp, 2 * kPointerSize), scratch); | 2591 __ movp(MemOperand(rsp, 2 * kPointerSize), scratch); |
| 2613 __ movp(scratch, MemOperand(rsp, 0)); // home_object | 2592 __ movp(scratch, MemOperand(rsp, 0)); // home_object |
| 2614 __ movp(MemOperand(rsp, kPointerSize), scratch); | 2593 __ movp(MemOperand(rsp, kPointerSize), scratch); |
| 2615 __ movp(MemOperand(rsp, 0), rax); | 2594 __ movp(MemOperand(rsp, 0), rax); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2814 Comment cmnt(masm_, "[ Property"); | 2793 Comment cmnt(masm_, "[ Property"); |
| 2815 Expression* key = expr->key(); | 2794 Expression* key = expr->key(); |
| 2816 | 2795 |
| 2817 if (key->IsPropertyName()) { | 2796 if (key->IsPropertyName()) { |
| 2818 if (!expr->IsSuperAccess()) { | 2797 if (!expr->IsSuperAccess()) { |
| 2819 VisitForAccumulatorValue(expr->obj()); | 2798 VisitForAccumulatorValue(expr->obj()); |
| 2820 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister())); | 2799 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister())); |
| 2821 __ movp(LoadDescriptor::ReceiverRegister(), rax); | 2800 __ movp(LoadDescriptor::ReceiverRegister(), rax); |
| 2822 EmitNamedPropertyLoad(expr); | 2801 EmitNamedPropertyLoad(expr); |
| 2823 } else { | 2802 } else { |
| 2824 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2803 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); |
| 2825 VisitForStackValue( | 2804 VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var()); |
| 2826 expr->obj()->AsSuperPropertyReference()->home_object_var()); | |
| 2827 EmitNamedSuperPropertyLoad(expr); | 2805 EmitNamedSuperPropertyLoad(expr); |
| 2828 } | 2806 } |
| 2829 } else { | 2807 } else { |
| 2830 if (!expr->IsSuperAccess()) { | 2808 if (!expr->IsSuperAccess()) { |
| 2831 VisitForStackValue(expr->obj()); | 2809 VisitForStackValue(expr->obj()); |
| 2832 VisitForAccumulatorValue(expr->key()); | 2810 VisitForAccumulatorValue(expr->key()); |
| 2833 __ Move(LoadDescriptor::NameRegister(), rax); | 2811 __ Move(LoadDescriptor::NameRegister(), rax); |
| 2834 __ Pop(LoadDescriptor::ReceiverRegister()); | 2812 __ Pop(LoadDescriptor::ReceiverRegister()); |
| 2835 EmitKeyedPropertyLoad(expr); | 2813 EmitKeyedPropertyLoad(expr); |
| 2836 } else { | 2814 } else { |
| 2837 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2815 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); |
| 2838 VisitForStackValue( | 2816 VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var()); |
| 2839 expr->obj()->AsSuperPropertyReference()->home_object_var()); | |
| 2840 VisitForStackValue(expr->key()); | 2817 VisitForStackValue(expr->key()); |
| 2841 EmitKeyedSuperPropertyLoad(expr); | 2818 EmitKeyedSuperPropertyLoad(expr); |
| 2842 } | 2819 } |
| 2843 } | 2820 } |
| 2844 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2821 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2845 context()->Plug(rax); | 2822 context()->Plug(rax); |
| 2846 } | 2823 } |
| 2847 | 2824 |
| 2848 | 2825 |
| 2849 void FullCodeGenerator::CallIC(Handle<Code> code, | 2826 void FullCodeGenerator::CallIC(Handle<Code> code, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2887 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2864 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2888 Expression* callee = expr->expression(); | 2865 Expression* callee = expr->expression(); |
| 2889 DCHECK(callee->IsProperty()); | 2866 DCHECK(callee->IsProperty()); |
| 2890 Property* prop = callee->AsProperty(); | 2867 Property* prop = callee->AsProperty(); |
| 2891 DCHECK(prop->IsSuperAccess()); | 2868 DCHECK(prop->IsSuperAccess()); |
| 2892 | 2869 |
| 2893 SetSourcePosition(prop->position()); | 2870 SetSourcePosition(prop->position()); |
| 2894 Literal* key = prop->key()->AsLiteral(); | 2871 Literal* key = prop->key()->AsLiteral(); |
| 2895 DCHECK(!key->value()->IsSmi()); | 2872 DCHECK(!key->value()->IsSmi()); |
| 2896 // Load the function from the receiver. | 2873 // Load the function from the receiver. |
| 2897 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2874 SuperReference* super_ref = prop->obj()->AsSuperReference(); |
| 2898 VisitForStackValue(super_ref->home_object_var()); | 2875 VisitForStackValue(super_ref->home_object_var()); |
| 2899 VisitForAccumulatorValue(super_ref->this_var()); | 2876 VisitForAccumulatorValue(super_ref->this_var()); |
| 2900 __ Push(rax); | 2877 __ Push(rax); |
| 2901 __ Push(rax); | 2878 __ Push(rax); |
| 2902 __ Push(Operand(rsp, kPointerSize * 2)); | 2879 __ Push(Operand(rsp, kPointerSize * 2)); |
| 2903 __ Push(key->value()); | 2880 __ Push(key->value()); |
| 2904 | 2881 |
| 2905 // Stack here: | 2882 // Stack here: |
| 2906 // - home_object | 2883 // - home_object |
| 2907 // - this (receiver) | 2884 // - this (receiver) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2944 | 2921 |
| 2945 | 2922 |
| 2946 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2923 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
| 2947 Expression* callee = expr->expression(); | 2924 Expression* callee = expr->expression(); |
| 2948 DCHECK(callee->IsProperty()); | 2925 DCHECK(callee->IsProperty()); |
| 2949 Property* prop = callee->AsProperty(); | 2926 Property* prop = callee->AsProperty(); |
| 2950 DCHECK(prop->IsSuperAccess()); | 2927 DCHECK(prop->IsSuperAccess()); |
| 2951 | 2928 |
| 2952 SetSourcePosition(prop->position()); | 2929 SetSourcePosition(prop->position()); |
| 2953 // Load the function from the receiver. | 2930 // Load the function from the receiver. |
| 2954 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2931 SuperReference* super_ref = prop->obj()->AsSuperReference(); |
| 2955 VisitForStackValue(super_ref->home_object_var()); | 2932 VisitForStackValue(super_ref->home_object_var()); |
| 2956 VisitForAccumulatorValue(super_ref->this_var()); | 2933 VisitForAccumulatorValue(super_ref->this_var()); |
| 2957 __ Push(rax); | 2934 __ Push(rax); |
| 2958 __ Push(rax); | 2935 __ Push(rax); |
| 2959 __ Push(Operand(rsp, kPointerSize * 2)); | 2936 __ Push(Operand(rsp, kPointerSize * 2)); |
| 2960 VisitForStackValue(prop->key()); | 2937 VisitForStackValue(prop->key()); |
| 2961 | 2938 |
| 2962 // Stack here: | 2939 // Stack here: |
| 2963 // - home_object | 2940 // - home_object |
| 2964 // - this (receiver) | 2941 // - this (receiver) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3025 __ Push(Smi::FromInt(language_mode())); | 3002 __ Push(Smi::FromInt(language_mode())); |
| 3026 | 3003 |
| 3027 // Push the start position of the scope the calls resides in. | 3004 // Push the start position of the scope the calls resides in. |
| 3028 __ Push(Smi::FromInt(scope()->start_position())); | 3005 __ Push(Smi::FromInt(scope()->start_position())); |
| 3029 | 3006 |
| 3030 // Do the runtime call. | 3007 // Do the runtime call. |
| 3031 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 3008 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
| 3032 } | 3009 } |
| 3033 | 3010 |
| 3034 | 3011 |
| 3012 void FullCodeGenerator::EmitLoadSuperConstructor() { |
| 3013 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3014 __ CallRuntime(Runtime::kGetPrototype, 1); |
| 3015 } |
| 3016 |
| 3017 |
| 3035 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3018 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 3036 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { | 3019 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
| 3037 Variable* this_var = super_ref->this_var()->var(); | 3020 Variable* this_var = super_ref->this_var()->var(); |
| 3038 GetVar(rcx, this_var); | 3021 GetVar(rcx, this_var); |
| 3039 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); | 3022 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); |
| 3040 Label uninitialized_this; | 3023 Label uninitialized_this; |
| 3041 __ j(equal, &uninitialized_this); | 3024 __ j(equal, &uninitialized_this); |
| 3042 __ Push(this_var->name()); | 3025 __ Push(this_var->name()); |
| 3043 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3026 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 3044 __ bind(&uninitialized_this); | 3027 __ bind(&uninitialized_this); |
| 3045 | 3028 |
| 3046 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3029 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3176 | 3159 |
| 3177 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 3160 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
| 3178 Comment cmnt(masm_, "[ CallNew"); | 3161 Comment cmnt(masm_, "[ CallNew"); |
| 3179 // According to ECMA-262, section 11.2.2, page 44, the function | 3162 // According to ECMA-262, section 11.2.2, page 44, the function |
| 3180 // expression in new calls must be evaluated before the | 3163 // expression in new calls must be evaluated before the |
| 3181 // arguments. | 3164 // arguments. |
| 3182 | 3165 |
| 3183 // Push constructor on the stack. If it's not a function it's used as | 3166 // Push constructor on the stack. If it's not a function it's used as |
| 3184 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is | 3167 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is |
| 3185 // ignored. | 3168 // ignored. |
| 3186 DCHECK(!expr->expression()->IsSuperPropertyReference()); | 3169 DCHECK(!expr->expression()->IsSuperReference()); |
| 3187 VisitForStackValue(expr->expression()); | 3170 VisitForStackValue(expr->expression()); |
| 3188 | 3171 |
| 3189 // Push the arguments ("left-to-right") on the stack. | 3172 // Push the arguments ("left-to-right") on the stack. |
| 3190 ZoneList<Expression*>* args = expr->arguments(); | 3173 ZoneList<Expression*>* args = expr->arguments(); |
| 3191 int arg_count = args->length(); | 3174 int arg_count = args->length(); |
| 3192 for (int i = 0; i < arg_count; i++) { | 3175 for (int i = 0; i < arg_count; i++) { |
| 3193 VisitForStackValue(args->at(i)); | 3176 VisitForStackValue(args->at(i)); |
| 3194 } | 3177 } |
| 3195 | 3178 |
| 3196 // Call the construct call builtin that handles allocation and | 3179 // Call the construct call builtin that handles allocation and |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3212 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot())); | 3195 __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot())); |
| 3213 | 3196 |
| 3214 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); | 3197 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); |
| 3215 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3198 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3216 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 3199 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 3217 context()->Plug(rax); | 3200 context()->Plug(rax); |
| 3218 } | 3201 } |
| 3219 | 3202 |
| 3220 | 3203 |
| 3221 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 3204 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
| 3222 SuperCallReference* super_call_ref = | 3205 Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); |
| 3223 expr->expression()->AsSuperCallReference(); | 3206 GetVar(result_register(), new_target_var); |
| 3224 DCHECK_NOT_NULL(super_call_ref); | 3207 __ Push(result_register()); |
| 3225 | 3208 |
| 3226 VariableProxy* new_target_proxy = super_call_ref->new_target_var(); | 3209 EmitLoadSuperConstructor(); |
| 3227 VisitForStackValue(new_target_proxy); | |
| 3228 | |
| 3229 EmitLoadSuperConstructor(super_call_ref); | |
| 3230 __ Push(result_register()); | 3210 __ Push(result_register()); |
| 3231 | 3211 |
| 3232 // Push the arguments ("left-to-right") on the stack. | 3212 // Push the arguments ("left-to-right") on the stack. |
| 3233 ZoneList<Expression*>* args = expr->arguments(); | 3213 ZoneList<Expression*>* args = expr->arguments(); |
| 3234 int arg_count = args->length(); | 3214 int arg_count = args->length(); |
| 3235 for (int i = 0; i < arg_count; i++) { | 3215 for (int i = 0; i < arg_count; i++) { |
| 3236 VisitForStackValue(args->at(i)); | 3216 VisitForStackValue(args->at(i)); |
| 3237 } | 3217 } |
| 3238 | 3218 |
| 3239 // Call the construct call builtin that handles allocation and | 3219 // Call the construct call builtin that handles allocation and |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3257 __ Move(rbx, FeedbackVector()); | 3237 __ Move(rbx, FeedbackVector()); |
| 3258 __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); | 3238 __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); |
| 3259 | 3239 |
| 3260 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3240 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3261 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3241 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3262 | 3242 |
| 3263 __ Drop(1); | 3243 __ Drop(1); |
| 3264 | 3244 |
| 3265 RecordJSReturnSite(expr); | 3245 RecordJSReturnSite(expr); |
| 3266 | 3246 |
| 3267 EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); | 3247 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3248 expr->CallFeedbackICSlot()); |
| 3268 context()->Plug(rax); | 3249 context()->Plug(rax); |
| 3269 } | 3250 } |
| 3270 | 3251 |
| 3271 | 3252 |
| 3272 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3253 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 3273 ZoneList<Expression*>* args = expr->arguments(); | 3254 ZoneList<Expression*>* args = expr->arguments(); |
| 3274 DCHECK(args->length() == 1); | 3255 DCHECK(args->length() == 1); |
| 3275 | 3256 |
| 3276 VisitForAccumulatorValue(args->at(0)); | 3257 VisitForAccumulatorValue(args->at(0)); |
| 3277 | 3258 |
| (...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4124 __ bind(&runtime); | 4105 __ bind(&runtime); |
| 4125 __ Push(rax); | 4106 __ Push(rax); |
| 4126 __ CallRuntime(Runtime::kCall, args->length()); | 4107 __ CallRuntime(Runtime::kCall, args->length()); |
| 4127 __ bind(&done); | 4108 __ bind(&done); |
| 4128 | 4109 |
| 4129 context()->Plug(rax); | 4110 context()->Plug(rax); |
| 4130 } | 4111 } |
| 4131 | 4112 |
| 4132 | 4113 |
| 4133 void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { | 4114 void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { |
| 4134 ZoneList<Expression*>* args = expr->arguments(); | 4115 Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); |
| 4135 DCHECK(args->length() == 2); | 4116 GetVar(result_register(), new_target_var); |
| 4117 __ Push(result_register()); |
| 4136 | 4118 |
| 4137 // new.target | 4119 EmitLoadSuperConstructor(); |
| 4138 VisitForStackValue(args->at(0)); | |
| 4139 | |
| 4140 // .this_function | |
| 4141 VisitForStackValue(args->at(1)); | |
| 4142 __ CallRuntime(Runtime::kGetPrototype, 1); | |
| 4143 __ Push(result_register()); | 4120 __ Push(result_register()); |
| 4144 | 4121 |
| 4145 // Check if the calling frame is an arguments adaptor frame. | 4122 // Check if the calling frame is an arguments adaptor frame. |
| 4146 Label adaptor_frame, args_set_up, runtime; | 4123 Label adaptor_frame, args_set_up, runtime; |
| 4147 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 4124 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 4148 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); | 4125 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); |
| 4149 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 4126 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 4150 __ j(equal, &adaptor_frame); | 4127 __ j(equal, &adaptor_frame); |
| 4151 // default constructor has no arguments, so no adaptor frame means no args. | 4128 // default constructor has no arguments, so no adaptor frame means no args. |
| 4152 __ movp(rax, Immediate(0)); | 4129 __ movp(rax, Immediate(0)); |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4584 ExternalReference::debug_is_active_address(isolate()); | 4561 ExternalReference::debug_is_active_address(isolate()); |
| 4585 __ Move(kScratchRegister, debug_is_active); | 4562 __ Move(kScratchRegister, debug_is_active); |
| 4586 __ movzxbp(rax, Operand(kScratchRegister, 0)); | 4563 __ movzxbp(rax, Operand(kScratchRegister, 0)); |
| 4587 __ Integer32ToSmi(rax, rax); | 4564 __ Integer32ToSmi(rax, rax); |
| 4588 context()->Plug(rax); | 4565 context()->Plug(rax); |
| 4589 } | 4566 } |
| 4590 | 4567 |
| 4591 | 4568 |
| 4592 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { | 4569 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { |
| 4593 // Assert: expr === CallRuntime("ReflectConstruct") | 4570 // Assert: expr === CallRuntime("ReflectConstruct") |
| 4594 DCHECK_EQ(1, expr->arguments()->length()); | |
| 4595 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); | 4571 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); |
| 4596 | |
| 4597 ZoneList<Expression*>* args = call->arguments(); | 4572 ZoneList<Expression*>* args = call->arguments(); |
| 4598 DCHECK_EQ(3, args->length()); | 4573 DCHECK_EQ(3, args->length()); |
| 4599 | 4574 |
| 4600 SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference(); | 4575 SuperReference* super_reference = args->at(0)->AsSuperReference(); |
| 4601 DCHECK_NOT_NULL(super_call_ref); | |
| 4602 | 4576 |
| 4603 // Load ReflectConstruct function | 4577 // Load ReflectConstruct function |
| 4604 EmitLoadJSRuntimeFunction(call); | 4578 EmitLoadJSRuntimeFunction(call); |
| 4605 | 4579 |
| 4606 // Push the target function under the receiver. | 4580 // Push the target function under the receiver. |
| 4607 __ Push(Operand(rsp, 0)); | 4581 __ Push(Operand(rsp, 0)); |
| 4608 __ movp(Operand(rsp, kPointerSize), rax); | 4582 __ movp(Operand(rsp, kPointerSize), rax); |
| 4609 | 4583 |
| 4610 // Push super constructor | 4584 // Push super |
| 4611 EmitLoadSuperConstructor(super_call_ref); | 4585 EmitLoadSuperConstructor(); |
| 4612 __ Push(result_register()); | 4586 __ Push(result_register()); |
| 4613 | 4587 |
| 4614 // Push arguments array | 4588 // Push arguments array |
| 4615 VisitForStackValue(args->at(1)); | 4589 VisitForStackValue(args->at(1)); |
| 4616 | 4590 |
| 4617 // Push NewTarget | 4591 // Push NewTarget |
| 4618 DCHECK(args->at(2)->IsVariableProxy()); | 4592 DCHECK(args->at(2)->IsVariableProxy()); |
| 4619 VisitForStackValue(args->at(2)); | 4593 VisitForStackValue(args->at(2)); |
| 4620 | 4594 |
| 4621 EmitCallJSRuntimeFunction(call); | 4595 EmitCallJSRuntimeFunction(call); |
| 4622 | 4596 |
| 4623 // Restore context register. | 4597 // Restore context register. |
| 4624 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 4598 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 4625 context()->DropAndPlug(1, rax); | 4599 context()->DropAndPlug(1, rax); |
| 4626 | 4600 |
| 4627 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. | 4601 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
| 4628 EmitInitializeThisAfterSuper(super_call_ref); | 4602 EmitInitializeThisAfterSuper(super_reference); |
| 4629 } | 4603 } |
| 4630 | 4604 |
| 4631 | 4605 |
| 4632 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4606 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4633 // Push the builtins object as receiver. | 4607 // Push the builtins object as receiver. |
| 4634 __ movp(rax, GlobalObjectOperand()); | 4608 __ movp(rax, GlobalObjectOperand()); |
| 4635 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 4609 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
| 4636 | 4610 |
| 4637 // Load the function from the receiver. | 4611 // Load the function from the receiver. |
| 4638 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 4612 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4843 } | 4817 } |
| 4844 switch (assign_type) { | 4818 switch (assign_type) { |
| 4845 case NAMED_PROPERTY: { | 4819 case NAMED_PROPERTY: { |
| 4846 VisitForStackValue(prop->obj()); | 4820 VisitForStackValue(prop->obj()); |
| 4847 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 4821 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 4848 EmitNamedPropertyLoad(prop); | 4822 EmitNamedPropertyLoad(prop); |
| 4849 break; | 4823 break; |
| 4850 } | 4824 } |
| 4851 | 4825 |
| 4852 case NAMED_SUPER_PROPERTY: { | 4826 case NAMED_SUPER_PROPERTY: { |
| 4853 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 4827 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 4854 VisitForAccumulatorValue( | 4828 VisitForAccumulatorValue( |
| 4855 prop->obj()->AsSuperPropertyReference()->home_object_var()); | 4829 prop->obj()->AsSuperReference()->home_object_var()); |
| 4856 __ Push(result_register()); | 4830 __ Push(result_register()); |
| 4857 __ Push(MemOperand(rsp, kPointerSize)); | 4831 __ Push(MemOperand(rsp, kPointerSize)); |
| 4858 __ Push(result_register()); | 4832 __ Push(result_register()); |
| 4859 EmitNamedSuperPropertyLoad(prop); | 4833 EmitNamedSuperPropertyLoad(prop); |
| 4860 break; | 4834 break; |
| 4861 } | 4835 } |
| 4862 | 4836 |
| 4863 case KEYED_SUPER_PROPERTY: { | 4837 case KEYED_SUPER_PROPERTY: { |
| 4864 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 4838 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 4865 VisitForStackValue( | 4839 VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var()); |
| 4866 prop->obj()->AsSuperPropertyReference()->home_object_var()); | |
| 4867 VisitForAccumulatorValue(prop->key()); | 4840 VisitForAccumulatorValue(prop->key()); |
| 4868 __ Push(result_register()); | 4841 __ Push(result_register()); |
| 4869 __ Push(MemOperand(rsp, 2 * kPointerSize)); | 4842 __ Push(MemOperand(rsp, 2 * kPointerSize)); |
| 4870 __ Push(MemOperand(rsp, 2 * kPointerSize)); | 4843 __ Push(MemOperand(rsp, 2 * kPointerSize)); |
| 4871 __ Push(result_register()); | 4844 __ Push(result_register()); |
| 4872 EmitKeyedSuperPropertyLoad(prop); | 4845 EmitKeyedSuperPropertyLoad(prop); |
| 4873 break; | 4846 break; |
| 4874 } | 4847 } |
| 4875 | 4848 |
| 4876 case KEYED_PROPERTY: { | 4849 case KEYED_PROPERTY: { |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5478 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5451 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 5479 Assembler::target_address_at(call_target_address, | 5452 Assembler::target_address_at(call_target_address, |
| 5480 unoptimized_code)); | 5453 unoptimized_code)); |
| 5481 return OSR_AFTER_STACK_CHECK; | 5454 return OSR_AFTER_STACK_CHECK; |
| 5482 } | 5455 } |
| 5483 | 5456 |
| 5484 | 5457 |
| 5485 } } // namespace v8::internal | 5458 } } // namespace v8::internal |
| 5486 | 5459 |
| 5487 #endif // V8_TARGET_ARCH_X64 | 5460 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |