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