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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 } else if (FLAG_debug_code) { | 224 } else if (FLAG_debug_code) { |
225 Label done; | 225 Label done; |
226 __ JumpIfInNewSpace(esi, eax, &done, Label::kNear); | 226 __ JumpIfInNewSpace(esi, eax, &done, Label::kNear); |
227 __ Abort(kExpectedNewSpaceObject); | 227 __ Abort(kExpectedNewSpaceObject); |
228 __ bind(&done); | 228 __ bind(&done); |
229 } | 229 } |
230 } | 230 } |
231 } | 231 } |
232 } | 232 } |
233 | 233 |
| 234 Variable* home_object_var = scope()->home_object_var(); |
| 235 if (home_object_var != nullptr) { |
| 236 __ push(edi); |
| 237 } |
| 238 |
| 239 // Possibly set up a local binding to the this function which is used in |
| 240 // derived constructors with super calls. |
| 241 Variable* this_function_var = scope()->this_function_var(); |
| 242 if (this_function_var != nullptr) { |
| 243 Comment cmnt(masm_, "[ This function"); |
| 244 SetVar(this_function_var, edi, ebx, edx); |
| 245 } |
| 246 |
| 247 Variable* new_target_var = scope()->new_target_var(); |
| 248 if (new_target_var != nullptr) { |
| 249 Comment cmnt(masm_, "[ new.target"); |
| 250 // new.target is parameter -2. |
| 251 int offset = 2 * kPointerSize + kFPOnStackSize + kPCOnStackSize + |
| 252 (info_->scope()->num_parameters() - 1) * kPointerSize; |
| 253 __ mov(eax, Operand(ebp, offset)); |
| 254 SetVar(new_target_var, eax, ebx, edx); |
| 255 } |
| 256 |
234 ArgumentsAccessStub::HasNewTarget has_new_target = | 257 ArgumentsAccessStub::HasNewTarget has_new_target = |
235 IsSubclassConstructor(info->function()->kind()) | 258 IsSubclassConstructor(info->function()->kind()) |
236 ? ArgumentsAccessStub::HAS_NEW_TARGET | 259 ? ArgumentsAccessStub::HAS_NEW_TARGET |
237 : ArgumentsAccessStub::NO_NEW_TARGET; | 260 : ArgumentsAccessStub::NO_NEW_TARGET; |
238 | 261 |
239 // Possibly allocate RestParameters | 262 // Possibly allocate RestParameters |
240 int rest_index; | 263 int rest_index; |
241 Variable* rest_param = scope()->rest_parameter(&rest_index); | 264 Variable* rest_param = scope()->rest_parameter(&rest_index); |
242 if (rest_param) { | 265 if (rest_param) { |
243 Comment cmnt(masm_, "[ Allocate rest parameter array"); | 266 Comment cmnt(masm_, "[ Allocate rest parameter array"); |
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1883 | 1906 |
1884 Property* property = expr->target()->AsProperty(); | 1907 Property* property = expr->target()->AsProperty(); |
1885 LhsKind assign_type = Property::GetAssignType(property); | 1908 LhsKind assign_type = Property::GetAssignType(property); |
1886 | 1909 |
1887 // Evaluate LHS expression. | 1910 // Evaluate LHS expression. |
1888 switch (assign_type) { | 1911 switch (assign_type) { |
1889 case VARIABLE: | 1912 case VARIABLE: |
1890 // Nothing to do here. | 1913 // Nothing to do here. |
1891 break; | 1914 break; |
1892 case NAMED_SUPER_PROPERTY: | 1915 case NAMED_SUPER_PROPERTY: |
1893 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); | 1916 VisitForStackValue( |
| 1917 property->obj()->AsSuperPropertyReference()->this_var()); |
1894 VisitForAccumulatorValue( | 1918 VisitForAccumulatorValue( |
1895 property->obj()->AsSuperReference()->home_object()); | 1919 property->obj()->AsSuperPropertyReference()->home_object_var()); |
1896 __ push(result_register()); | 1920 __ push(result_register()); |
1897 if (expr->is_compound()) { | 1921 if (expr->is_compound()) { |
1898 __ push(MemOperand(esp, kPointerSize)); | 1922 __ push(MemOperand(esp, kPointerSize)); |
1899 __ push(result_register()); | 1923 __ push(result_register()); |
1900 } | 1924 } |
1901 break; | 1925 break; |
1902 case NAMED_PROPERTY: | 1926 case NAMED_PROPERTY: |
1903 if (expr->is_compound()) { | 1927 if (expr->is_compound()) { |
1904 // We need the receiver both on the stack and in the register. | 1928 // We need the receiver both on the stack and in the register. |
1905 VisitForStackValue(property->obj()); | 1929 VisitForStackValue(property->obj()); |
1906 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1930 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1907 } else { | 1931 } else { |
1908 VisitForStackValue(property->obj()); | 1932 VisitForStackValue(property->obj()); |
1909 } | 1933 } |
1910 break; | 1934 break; |
1911 case KEYED_SUPER_PROPERTY: | 1935 case KEYED_SUPER_PROPERTY: |
1912 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); | 1936 VisitForStackValue( |
1913 VisitForStackValue(property->obj()->AsSuperReference()->home_object()); | 1937 property->obj()->AsSuperPropertyReference()->this_var()); |
| 1938 VisitForStackValue( |
| 1939 property->obj()->AsSuperPropertyReference()->home_object_var()); |
1914 VisitForAccumulatorValue(property->key()); | 1940 VisitForAccumulatorValue(property->key()); |
1915 __ Push(result_register()); | 1941 __ Push(result_register()); |
1916 if (expr->is_compound()) { | 1942 if (expr->is_compound()) { |
1917 __ push(MemOperand(esp, 2 * kPointerSize)); | 1943 __ push(MemOperand(esp, 2 * kPointerSize)); |
1918 __ push(MemOperand(esp, 2 * kPointerSize)); | 1944 __ push(MemOperand(esp, 2 * kPointerSize)); |
1919 __ push(result_register()); | 1945 __ push(result_register()); |
1920 } | 1946 } |
1921 break; | 1947 break; |
1922 case KEYED_PROPERTY: { | 1948 case KEYED_PROPERTY: { |
1923 if (expr->is_compound()) { | 1949 if (expr->is_compound()) { |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2528 __ Move(StoreDescriptor::ReceiverRegister(), eax); | 2554 __ Move(StoreDescriptor::ReceiverRegister(), eax); |
2529 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2555 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
2530 __ mov(StoreDescriptor::NameRegister(), | 2556 __ mov(StoreDescriptor::NameRegister(), |
2531 prop->key()->AsLiteral()->value()); | 2557 prop->key()->AsLiteral()->value()); |
2532 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2558 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
2533 CallStoreIC(); | 2559 CallStoreIC(); |
2534 break; | 2560 break; |
2535 } | 2561 } |
2536 case NAMED_SUPER_PROPERTY: { | 2562 case NAMED_SUPER_PROPERTY: { |
2537 __ push(eax); | 2563 __ push(eax); |
2538 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2564 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2539 VisitForAccumulatorValue(prop->obj()->AsSuperReference()->home_object()); | 2565 VisitForAccumulatorValue( |
| 2566 prop->obj()->AsSuperPropertyReference()->home_object_var()); |
2540 // stack: value, this; eax: home_object | 2567 // stack: value, this; eax: home_object |
2541 Register scratch = ecx; | 2568 Register scratch = ecx; |
2542 Register scratch2 = edx; | 2569 Register scratch2 = edx; |
2543 __ mov(scratch, result_register()); // home_object | 2570 __ mov(scratch, result_register()); // home_object |
2544 __ mov(eax, MemOperand(esp, kPointerSize)); // value | 2571 __ mov(eax, MemOperand(esp, kPointerSize)); // value |
2545 __ mov(scratch2, MemOperand(esp, 0)); // this | 2572 __ mov(scratch2, MemOperand(esp, 0)); // this |
2546 __ mov(MemOperand(esp, kPointerSize), scratch2); // this | 2573 __ mov(MemOperand(esp, kPointerSize), scratch2); // this |
2547 __ mov(MemOperand(esp, 0), scratch); // home_object | 2574 __ mov(MemOperand(esp, 0), scratch); // home_object |
2548 // stack: this, home_object. eax: value | 2575 // stack: this, home_object. eax: value |
2549 EmitNamedSuperPropertyStore(prop); | 2576 EmitNamedSuperPropertyStore(prop); |
2550 break; | 2577 break; |
2551 } | 2578 } |
2552 case KEYED_SUPER_PROPERTY: { | 2579 case KEYED_SUPER_PROPERTY: { |
2553 __ push(eax); | 2580 __ push(eax); |
2554 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2581 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2555 VisitForStackValue(prop->obj()->AsSuperReference()->home_object()); | 2582 VisitForStackValue( |
| 2583 prop->obj()->AsSuperPropertyReference()->home_object_var()); |
2556 VisitForAccumulatorValue(prop->key()); | 2584 VisitForAccumulatorValue(prop->key()); |
2557 Register scratch = ecx; | 2585 Register scratch = ecx; |
2558 Register scratch2 = edx; | 2586 Register scratch2 = edx; |
2559 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value | 2587 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value |
2560 // stack: value, this, home_object; eax: key, edx: value | 2588 // stack: value, this, home_object; eax: key, edx: value |
2561 __ mov(scratch, MemOperand(esp, kPointerSize)); // this | 2589 __ mov(scratch, MemOperand(esp, kPointerSize)); // this |
2562 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); | 2590 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); |
2563 __ mov(scratch, MemOperand(esp, 0)); // home_object | 2591 __ mov(scratch, MemOperand(esp, 0)); // home_object |
2564 __ mov(MemOperand(esp, kPointerSize), scratch); | 2592 __ mov(MemOperand(esp, kPointerSize), scratch); |
2565 __ mov(MemOperand(esp, 0), eax); | 2593 __ mov(MemOperand(esp, 0), eax); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2767 void FullCodeGenerator::VisitProperty(Property* expr) { | 2795 void FullCodeGenerator::VisitProperty(Property* expr) { |
2768 Comment cmnt(masm_, "[ Property"); | 2796 Comment cmnt(masm_, "[ Property"); |
2769 Expression* key = expr->key(); | 2797 Expression* key = expr->key(); |
2770 | 2798 |
2771 if (key->IsPropertyName()) { | 2799 if (key->IsPropertyName()) { |
2772 if (!expr->IsSuperAccess()) { | 2800 if (!expr->IsSuperAccess()) { |
2773 VisitForAccumulatorValue(expr->obj()); | 2801 VisitForAccumulatorValue(expr->obj()); |
2774 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 2802 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
2775 EmitNamedPropertyLoad(expr); | 2803 EmitNamedPropertyLoad(expr); |
2776 } else { | 2804 } else { |
2777 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); | 2805 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2778 VisitForStackValue(expr->obj()->AsSuperReference()->home_object()); | 2806 VisitForStackValue( |
| 2807 expr->obj()->AsSuperPropertyReference()->home_object_var()); |
2779 EmitNamedSuperPropertyLoad(expr); | 2808 EmitNamedSuperPropertyLoad(expr); |
2780 } | 2809 } |
2781 } else { | 2810 } else { |
2782 if (!expr->IsSuperAccess()) { | 2811 if (!expr->IsSuperAccess()) { |
2783 VisitForStackValue(expr->obj()); | 2812 VisitForStackValue(expr->obj()); |
2784 VisitForAccumulatorValue(expr->key()); | 2813 VisitForAccumulatorValue(expr->key()); |
2785 __ pop(LoadDescriptor::ReceiverRegister()); // Object. | 2814 __ pop(LoadDescriptor::ReceiverRegister()); // Object. |
2786 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. | 2815 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. |
2787 EmitKeyedPropertyLoad(expr); | 2816 EmitKeyedPropertyLoad(expr); |
2788 } else { | 2817 } else { |
2789 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); | 2818 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2790 VisitForStackValue(expr->obj()->AsSuperReference()->home_object()); | 2819 VisitForStackValue( |
| 2820 expr->obj()->AsSuperPropertyReference()->home_object_var()); |
2791 VisitForStackValue(expr->key()); | 2821 VisitForStackValue(expr->key()); |
2792 EmitKeyedSuperPropertyLoad(expr); | 2822 EmitKeyedSuperPropertyLoad(expr); |
2793 } | 2823 } |
2794 } | 2824 } |
2795 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2825 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2796 context()->Plug(eax); | 2826 context()->Plug(eax); |
2797 } | 2827 } |
2798 | 2828 |
2799 | 2829 |
2800 void FullCodeGenerator::CallIC(Handle<Code> code, | 2830 void FullCodeGenerator::CallIC(Handle<Code> code, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2838 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2868 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2839 Expression* callee = expr->expression(); | 2869 Expression* callee = expr->expression(); |
2840 DCHECK(callee->IsProperty()); | 2870 DCHECK(callee->IsProperty()); |
2841 Property* prop = callee->AsProperty(); | 2871 Property* prop = callee->AsProperty(); |
2842 DCHECK(prop->IsSuperAccess()); | 2872 DCHECK(prop->IsSuperAccess()); |
2843 | 2873 |
2844 SetSourcePosition(prop->position()); | 2874 SetSourcePosition(prop->position()); |
2845 Literal* key = prop->key()->AsLiteral(); | 2875 Literal* key = prop->key()->AsLiteral(); |
2846 DCHECK(!key->value()->IsSmi()); | 2876 DCHECK(!key->value()->IsSmi()); |
2847 // Load the function from the receiver. | 2877 // Load the function from the receiver. |
2848 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); | 2878 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2849 VisitForStackValue(super_ref->home_object()); | 2879 VisitForStackValue(super_ref->home_object_var()); |
2850 VisitForAccumulatorValue(super_ref->this_var()); | 2880 VisitForAccumulatorValue(super_ref->this_var()); |
2851 __ push(eax); | 2881 __ push(eax); |
2852 __ push(eax); | 2882 __ push(eax); |
2853 __ push(Operand(esp, kPointerSize * 2)); | 2883 __ push(Operand(esp, kPointerSize * 2)); |
2854 __ push(Immediate(key->value())); | 2884 __ push(Immediate(key->value())); |
2855 // Stack here: | 2885 // Stack here: |
2856 // - home_object | 2886 // - home_object |
2857 // - this (receiver) | 2887 // - this (receiver) |
2858 // - this (receiver) <-- LoadFromSuper will pop here and below. | 2888 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2859 // - home_object | 2889 // - home_object |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 | 2924 |
2895 | 2925 |
2896 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2926 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2897 Expression* callee = expr->expression(); | 2927 Expression* callee = expr->expression(); |
2898 DCHECK(callee->IsProperty()); | 2928 DCHECK(callee->IsProperty()); |
2899 Property* prop = callee->AsProperty(); | 2929 Property* prop = callee->AsProperty(); |
2900 DCHECK(prop->IsSuperAccess()); | 2930 DCHECK(prop->IsSuperAccess()); |
2901 | 2931 |
2902 SetSourcePosition(prop->position()); | 2932 SetSourcePosition(prop->position()); |
2903 // Load the function from the receiver. | 2933 // Load the function from the receiver. |
2904 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); | 2934 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2905 VisitForStackValue(super_ref->home_object()); | 2935 VisitForStackValue(super_ref->home_object_var()); |
2906 VisitForAccumulatorValue(super_ref->this_var()); | 2936 VisitForAccumulatorValue(super_ref->this_var()); |
2907 __ push(eax); | 2937 __ push(eax); |
2908 __ push(eax); | 2938 __ push(eax); |
2909 __ push(Operand(esp, kPointerSize * 2)); | 2939 __ push(Operand(esp, kPointerSize * 2)); |
2910 VisitForStackValue(prop->key()); | 2940 VisitForStackValue(prop->key()); |
2911 // Stack here: | 2941 // Stack here: |
2912 // - home_object | 2942 // - home_object |
2913 // - this (receiver) | 2943 // - this (receiver) |
2914 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | 2944 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. |
2915 // - home_object | 2945 // - home_object |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2972 __ push(Immediate(Smi::FromInt(language_mode()))); | 3002 __ push(Immediate(Smi::FromInt(language_mode()))); |
2973 | 3003 |
2974 // Push the start position of the scope the calls resides in. | 3004 // Push the start position of the scope the calls resides in. |
2975 __ push(Immediate(Smi::FromInt(scope()->start_position()))); | 3005 __ push(Immediate(Smi::FromInt(scope()->start_position()))); |
2976 | 3006 |
2977 // Do the runtime call. | 3007 // Do the runtime call. |
2978 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 3008 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2979 } | 3009 } |
2980 | 3010 |
2981 | 3011 |
2982 void FullCodeGenerator::EmitLoadSuperConstructor() { | |
2983 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | |
2984 __ CallRuntime(Runtime::kGetPrototype, 1); | |
2985 } | |
2986 | |
2987 | |
2988 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3012 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
2989 SuperReference* super_ref, FeedbackVectorICSlot slot) { | 3013 SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) { |
2990 Variable* this_var = super_ref->this_var()->var(); | 3014 Variable* this_var = super_call_ref->this_var()->var(); |
2991 GetVar(ecx, this_var); | 3015 GetVar(ecx, this_var); |
2992 __ cmp(ecx, isolate()->factory()->the_hole_value()); | 3016 __ cmp(ecx, isolate()->factory()->the_hole_value()); |
2993 Label uninitialized_this; | 3017 Label uninitialized_this; |
2994 __ j(equal, &uninitialized_this); | 3018 __ j(equal, &uninitialized_this); |
2995 __ push(Immediate(this_var->name())); | 3019 __ push(Immediate(this_var->name())); |
2996 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3020 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2997 __ bind(&uninitialized_this); | 3021 __ bind(&uninitialized_this); |
2998 | 3022 |
2999 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3023 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
3000 } | 3024 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3129 | 3153 |
3130 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 3154 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
3131 Comment cmnt(masm_, "[ CallNew"); | 3155 Comment cmnt(masm_, "[ CallNew"); |
3132 // According to ECMA-262, section 11.2.2, page 44, the function | 3156 // According to ECMA-262, section 11.2.2, page 44, the function |
3133 // expression in new calls must be evaluated before the | 3157 // expression in new calls must be evaluated before the |
3134 // arguments. | 3158 // arguments. |
3135 | 3159 |
3136 // Push constructor on the stack. If it's not a function it's used as | 3160 // Push constructor on the stack. If it's not a function it's used as |
3137 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is | 3161 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is |
3138 // ignored. | 3162 // ignored. |
3139 DCHECK(!expr->expression()->IsSuperReference()); | 3163 DCHECK(!expr->expression()->IsSuperPropertyReference()); |
3140 VisitForStackValue(expr->expression()); | 3164 VisitForStackValue(expr->expression()); |
3141 | 3165 |
3142 // Push the arguments ("left-to-right") on the stack. | 3166 // Push the arguments ("left-to-right") on the stack. |
3143 ZoneList<Expression*>* args = expr->arguments(); | 3167 ZoneList<Expression*>* args = expr->arguments(); |
3144 int arg_count = args->length(); | 3168 int arg_count = args->length(); |
3145 for (int i = 0; i < arg_count; i++) { | 3169 for (int i = 0; i < arg_count; i++) { |
3146 VisitForStackValue(args->at(i)); | 3170 VisitForStackValue(args->at(i)); |
3147 } | 3171 } |
3148 | 3172 |
3149 // Call the construct call builtin that handles allocation and | 3173 // Call the construct call builtin that handles allocation and |
(...skipping 15 matching lines...) Expand all Loading... |
3165 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); | 3189 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); |
3166 | 3190 |
3167 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); | 3191 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); |
3168 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3192 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3169 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 3193 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
3170 context()->Plug(eax); | 3194 context()->Plug(eax); |
3171 } | 3195 } |
3172 | 3196 |
3173 | 3197 |
3174 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 3198 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
3175 Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); | 3199 SuperCallReference* super_call_ref = |
3176 GetVar(eax, new_target_var); | 3200 expr->expression()->AsSuperCallReference(); |
3177 __ push(eax); | 3201 DCHECK_NOT_NULL(super_call_ref); |
3178 | 3202 |
3179 EmitLoadSuperConstructor(); | 3203 VariableProxy* new_target_proxy = super_call_ref->new_target_var(); |
| 3204 VisitForStackValue(new_target_proxy); |
| 3205 |
| 3206 EmitLoadSuperConstructor(super_call_ref); |
3180 __ push(result_register()); | 3207 __ push(result_register()); |
3181 | 3208 |
3182 // Push the arguments ("left-to-right") on the stack. | 3209 // Push the arguments ("left-to-right") on the stack. |
3183 ZoneList<Expression*>* args = expr->arguments(); | 3210 ZoneList<Expression*>* args = expr->arguments(); |
3184 int arg_count = args->length(); | 3211 int arg_count = args->length(); |
3185 for (int i = 0; i < arg_count; i++) { | 3212 for (int i = 0; i < arg_count; i++) { |
3186 VisitForStackValue(args->at(i)); | 3213 VisitForStackValue(args->at(i)); |
3187 } | 3214 } |
3188 | 3215 |
3189 // Call the construct call builtin that handles allocation and | 3216 // Call the construct call builtin that handles allocation and |
(...skipping 17 matching lines...) Expand all Loading... |
3207 __ LoadHeapObject(ebx, FeedbackVector()); | 3234 __ LoadHeapObject(ebx, FeedbackVector()); |
3208 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); | 3235 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); |
3209 | 3236 |
3210 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3237 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3211 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3238 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3212 | 3239 |
3213 __ Drop(1); | 3240 __ Drop(1); |
3214 | 3241 |
3215 RecordJSReturnSite(expr); | 3242 RecordJSReturnSite(expr); |
3216 | 3243 |
3217 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), | 3244 EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); |
3218 expr->CallFeedbackICSlot()); | |
3219 context()->Plug(eax); | 3245 context()->Plug(eax); |
3220 } | 3246 } |
3221 | 3247 |
3222 | 3248 |
3223 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3249 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3224 ZoneList<Expression*>* args = expr->arguments(); | 3250 ZoneList<Expression*>* args = expr->arguments(); |
3225 DCHECK(args->length() == 1); | 3251 DCHECK(args->length() == 1); |
3226 | 3252 |
3227 VisitForAccumulatorValue(args->at(0)); | 3253 VisitForAccumulatorValue(args->at(0)); |
3228 | 3254 |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4084 __ bind(&runtime); | 4110 __ bind(&runtime); |
4085 __ push(eax); | 4111 __ push(eax); |
4086 __ CallRuntime(Runtime::kCall, args->length()); | 4112 __ CallRuntime(Runtime::kCall, args->length()); |
4087 __ bind(&done); | 4113 __ bind(&done); |
4088 | 4114 |
4089 context()->Plug(eax); | 4115 context()->Plug(eax); |
4090 } | 4116 } |
4091 | 4117 |
4092 | 4118 |
4093 void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { | 4119 void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { |
4094 Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); | 4120 ZoneList<Expression*>* args = expr->arguments(); |
4095 GetVar(eax, new_target_var); | 4121 DCHECK(args->length() == 2); |
4096 __ push(eax); | |
4097 | 4122 |
4098 EmitLoadSuperConstructor(); | 4123 // new.target |
| 4124 VisitForStackValue(args->at(0)); |
| 4125 |
| 4126 // .this_function |
| 4127 VisitForStackValue(args->at(1)); |
| 4128 __ CallRuntime(Runtime::kGetPrototype, 1); |
4099 __ push(result_register()); | 4129 __ push(result_register()); |
4100 | 4130 |
4101 // Check if the calling frame is an arguments adaptor frame. | 4131 // Check if the calling frame is an arguments adaptor frame. |
4102 Label adaptor_frame, args_set_up, runtime; | 4132 Label adaptor_frame, args_set_up, runtime; |
4103 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 4133 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
4104 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 4134 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
4105 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 4135 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
4106 __ j(equal, &adaptor_frame); | 4136 __ j(equal, &adaptor_frame); |
4107 // default constructor has no arguments, so no adaptor frame means no args. | 4137 // default constructor has no arguments, so no adaptor frame means no args. |
4108 __ mov(eax, Immediate(0)); | 4138 __ mov(eax, Immediate(0)); |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4511 ExternalReference debug_is_active = | 4541 ExternalReference debug_is_active = |
4512 ExternalReference::debug_is_active_address(isolate()); | 4542 ExternalReference::debug_is_active_address(isolate()); |
4513 __ movzx_b(eax, Operand::StaticVariable(debug_is_active)); | 4543 __ movzx_b(eax, Operand::StaticVariable(debug_is_active)); |
4514 __ SmiTag(eax); | 4544 __ SmiTag(eax); |
4515 context()->Plug(eax); | 4545 context()->Plug(eax); |
4516 } | 4546 } |
4517 | 4547 |
4518 | 4548 |
4519 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { | 4549 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { |
4520 // Assert: expr == CallRuntime("ReflectConstruct") | 4550 // Assert: expr == CallRuntime("ReflectConstruct") |
| 4551 DCHECK_EQ(1, expr->arguments()->length()); |
4521 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); | 4552 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); |
| 4553 |
4522 ZoneList<Expression*>* args = call->arguments(); | 4554 ZoneList<Expression*>* args = call->arguments(); |
4523 DCHECK_EQ(3, args->length()); | 4555 DCHECK_EQ(3, args->length()); |
4524 | 4556 |
4525 SuperReference* super_reference = args->at(0)->AsSuperReference(); | 4557 SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference(); |
| 4558 DCHECK_NOT_NULL(super_call_ref); |
4526 | 4559 |
4527 // Load ReflectConstruct function | 4560 // Load ReflectConstruct function |
4528 EmitLoadJSRuntimeFunction(call); | 4561 EmitLoadJSRuntimeFunction(call); |
4529 | 4562 |
4530 // Push the target function under the receiver | 4563 // Push the target function under the receiver |
4531 __ push(Operand(esp, 0)); | 4564 __ push(Operand(esp, 0)); |
4532 __ mov(Operand(esp, kPointerSize), eax); | 4565 __ mov(Operand(esp, kPointerSize), eax); |
4533 | 4566 |
4534 // Push super | 4567 // Push super constructor |
4535 EmitLoadSuperConstructor(); | 4568 EmitLoadSuperConstructor(super_call_ref); |
4536 __ Push(result_register()); | 4569 __ Push(result_register()); |
4537 | 4570 |
4538 // Push arguments array | 4571 // Push arguments array |
4539 VisitForStackValue(args->at(1)); | 4572 VisitForStackValue(args->at(1)); |
4540 | 4573 |
4541 // Push NewTarget | 4574 // Push NewTarget |
4542 DCHECK(args->at(2)->IsVariableProxy()); | 4575 DCHECK(args->at(2)->IsVariableProxy()); |
4543 VisitForStackValue(args->at(2)); | 4576 VisitForStackValue(args->at(2)); |
4544 | 4577 |
4545 EmitCallJSRuntimeFunction(call); | 4578 EmitCallJSRuntimeFunction(call); |
4546 | 4579 |
4547 // Restore context register. | 4580 // Restore context register. |
4548 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4581 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
4549 context()->DropAndPlug(1, eax); | 4582 context()->DropAndPlug(1, eax); |
4550 | 4583 |
4551 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. | 4584 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
4552 EmitInitializeThisAfterSuper(super_reference); | 4585 EmitInitializeThisAfterSuper(super_call_ref); |
4553 } | 4586 } |
4554 | 4587 |
4555 | 4588 |
4556 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4589 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4557 // Push the builtins object as receiver. | 4590 // Push the builtins object as receiver. |
4558 __ mov(eax, GlobalObjectOperand()); | 4591 __ mov(eax, GlobalObjectOperand()); |
4559 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | 4592 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
4560 | 4593 |
4561 // Load the function from the receiver. | 4594 // Load the function from the receiver. |
4562 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 4595 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4767 switch (assign_type) { | 4800 switch (assign_type) { |
4768 case NAMED_PROPERTY: { | 4801 case NAMED_PROPERTY: { |
4769 // Put the object both on the stack and in the register. | 4802 // Put the object both on the stack and in the register. |
4770 VisitForStackValue(prop->obj()); | 4803 VisitForStackValue(prop->obj()); |
4771 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 4804 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
4772 EmitNamedPropertyLoad(prop); | 4805 EmitNamedPropertyLoad(prop); |
4773 break; | 4806 break; |
4774 } | 4807 } |
4775 | 4808 |
4776 case NAMED_SUPER_PROPERTY: { | 4809 case NAMED_SUPER_PROPERTY: { |
4777 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 4810 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
4778 VisitForAccumulatorValue( | 4811 VisitForAccumulatorValue( |
4779 prop->obj()->AsSuperReference()->home_object()); | 4812 prop->obj()->AsSuperPropertyReference()->home_object_var()); |
4780 __ push(result_register()); | 4813 __ push(result_register()); |
4781 __ push(MemOperand(esp, kPointerSize)); | 4814 __ push(MemOperand(esp, kPointerSize)); |
4782 __ push(result_register()); | 4815 __ push(result_register()); |
4783 EmitNamedSuperPropertyLoad(prop); | 4816 EmitNamedSuperPropertyLoad(prop); |
4784 break; | 4817 break; |
4785 } | 4818 } |
4786 | 4819 |
4787 case KEYED_SUPER_PROPERTY: { | 4820 case KEYED_SUPER_PROPERTY: { |
4788 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 4821 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
4789 VisitForStackValue(prop->obj()->AsSuperReference()->home_object()); | 4822 VisitForStackValue( |
| 4823 prop->obj()->AsSuperPropertyReference()->home_object_var()); |
4790 VisitForAccumulatorValue(prop->key()); | 4824 VisitForAccumulatorValue(prop->key()); |
4791 __ push(result_register()); | 4825 __ push(result_register()); |
4792 __ push(MemOperand(esp, 2 * kPointerSize)); | 4826 __ push(MemOperand(esp, 2 * kPointerSize)); |
4793 __ push(MemOperand(esp, 2 * kPointerSize)); | 4827 __ push(MemOperand(esp, 2 * kPointerSize)); |
4794 __ push(result_register()); | 4828 __ push(result_register()); |
4795 EmitKeyedSuperPropertyLoad(prop); | 4829 EmitKeyedSuperPropertyLoad(prop); |
4796 break; | 4830 break; |
4797 } | 4831 } |
4798 | 4832 |
4799 case KEYED_PROPERTY: { | 4833 case KEYED_PROPERTY: { |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5404 Assembler::target_address_at(call_target_address, | 5438 Assembler::target_address_at(call_target_address, |
5405 unoptimized_code)); | 5439 unoptimized_code)); |
5406 return OSR_AFTER_STACK_CHECK; | 5440 return OSR_AFTER_STACK_CHECK; |
5407 } | 5441 } |
5408 | 5442 |
5409 | 5443 |
5410 } // namespace internal | 5444 } // namespace internal |
5411 } // namespace v8 | 5445 } // namespace v8 |
5412 | 5446 |
5413 #endif // V8_TARGET_ARCH_X87 | 5447 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |