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 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 GenerateTailCallToSharedCode(masm); | 120 GenerateTailCallToSharedCode(masm); |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 124 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
125 bool is_api_function) { | 125 bool is_api_function) { |
126 // ----------- S t a t e ------------- | 126 // ----------- S t a t e ------------- |
127 // -- eax: number of arguments | 127 // -- eax: number of arguments |
128 // -- edi: constructor function | 128 // -- edi: constructor function |
129 // -- ebx: allocation site or undefined | 129 // -- ebx: allocation site or undefined |
130 // -- edx: original constructor | 130 // -- edx: new target |
131 // ----------------------------------- | 131 // ----------------------------------- |
132 | 132 |
133 // Enter a construct frame. | 133 // Enter a construct frame. |
134 { | 134 { |
135 FrameScope scope(masm, StackFrame::CONSTRUCT); | 135 FrameScope scope(masm, StackFrame::CONSTRUCT); |
136 | 136 |
137 // Preserve the incoming parameters on the stack. | 137 // Preserve the incoming parameters on the stack. |
138 __ AssertUndefinedOrAllocationSite(ebx); | 138 __ AssertUndefinedOrAllocationSite(ebx); |
139 __ push(ebx); | 139 __ push(ebx); |
140 __ SmiTag(eax); | 140 __ SmiTag(eax); |
141 __ push(eax); | 141 __ push(eax); |
142 __ push(edi); | 142 __ push(edi); |
143 __ push(edx); | 143 __ push(edx); |
144 | 144 |
145 // Try to allocate the object without transitioning into C code. If any of | 145 // Try to allocate the object without transitioning into C code. If any of |
146 // the preconditions is not met, the code bails out to the runtime call. | 146 // the preconditions is not met, the code bails out to the runtime call. |
147 Label rt_call, allocated; | 147 Label rt_call, allocated; |
148 if (FLAG_inline_new) { | 148 if (FLAG_inline_new) { |
149 ExternalReference debug_step_in_fp = | 149 ExternalReference debug_step_in_fp = |
150 ExternalReference::debug_step_in_fp_address(masm->isolate()); | 150 ExternalReference::debug_step_in_fp_address(masm->isolate()); |
151 __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0)); | 151 __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0)); |
152 __ j(not_equal, &rt_call); | 152 __ j(not_equal, &rt_call); |
153 | 153 |
154 // Verify that the original constructor is a JSFunction. | 154 // Verify that the new target is a JSFunction. |
155 __ CmpObjectType(edx, JS_FUNCTION_TYPE, ebx); | 155 __ CmpObjectType(edx, JS_FUNCTION_TYPE, ebx); |
156 __ j(not_equal, &rt_call); | 156 __ j(not_equal, &rt_call); |
157 | 157 |
158 // Load the initial map and verify that it is in fact a map. | 158 // Load the initial map and verify that it is in fact a map. |
159 // edx: original constructor | 159 // edx: new target |
160 __ mov(eax, FieldOperand(edx, JSFunction::kPrototypeOrInitialMapOffset)); | 160 __ mov(eax, FieldOperand(edx, JSFunction::kPrototypeOrInitialMapOffset)); |
161 // Will both indicate a NULL and a Smi | 161 // Will both indicate a NULL and a Smi |
162 __ JumpIfSmi(eax, &rt_call); | 162 __ JumpIfSmi(eax, &rt_call); |
163 // edi: constructor | 163 // edi: constructor |
164 // eax: initial map (if proven valid below) | 164 // eax: initial map (if proven valid below) |
165 __ CmpObjectType(eax, MAP_TYPE, ebx); | 165 __ CmpObjectType(eax, MAP_TYPE, ebx); |
166 __ j(not_equal, &rt_call); | 166 __ j(not_equal, &rt_call); |
167 | 167 |
168 // Fall back to runtime if the expected base constructor and base | 168 // Fall back to runtime if the expected base constructor and base |
169 // constructor differ. | 169 // constructor differ. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 // and jump into the continuation code at any time from now on. | 269 // and jump into the continuation code at any time from now on. |
270 // ebx: JSObject (untagged) | 270 // ebx: JSObject (untagged) |
271 __ or_(ebx, Immediate(kHeapObjectTag)); | 271 __ or_(ebx, Immediate(kHeapObjectTag)); |
272 | 272 |
273 // Continue with JSObject being successfully allocated | 273 // Continue with JSObject being successfully allocated |
274 // ebx: JSObject (tagged) | 274 // ebx: JSObject (tagged) |
275 __ jmp(&allocated); | 275 __ jmp(&allocated); |
276 } | 276 } |
277 | 277 |
278 // Allocate the new receiver object using the runtime call. | 278 // Allocate the new receiver object using the runtime call. |
279 // edx: original constructor | 279 // edx: new target |
280 __ bind(&rt_call); | 280 __ bind(&rt_call); |
281 int offset = kPointerSize; | 281 int offset = kPointerSize; |
282 | 282 |
283 // Must restore esi (context) and edi (constructor) before calling | 283 // Must restore esi (context) and edi (constructor) before calling |
284 // runtime. | 284 // runtime. |
285 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 285 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
286 __ mov(edi, Operand(esp, offset)); | 286 __ mov(edi, Operand(esp, offset)); |
287 __ push(edi); // constructor function | 287 __ push(edi); // constructor function |
288 __ push(edx); // original constructor | 288 __ push(edx); // new target |
289 __ CallRuntime(Runtime::kNewObject, 2); | 289 __ CallRuntime(Runtime::kNewObject, 2); |
290 __ mov(ebx, eax); // store result in ebx | 290 __ mov(ebx, eax); // store result in ebx |
291 | 291 |
292 // New object allocated. | 292 // New object allocated. |
293 // ebx: newly allocated object | 293 // ebx: newly allocated object |
294 __ bind(&allocated); | 294 __ bind(&allocated); |
295 | 295 |
296 // Restore the parameters. | 296 // Restore the parameters. |
297 __ pop(edx); // new.target | 297 __ pop(edx); // new.target |
298 __ pop(edi); // Constructor function. | 298 __ pop(edi); // Constructor function. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 388 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
389 Generate_JSConstructStubHelper(masm, true); | 389 Generate_JSConstructStubHelper(masm, true); |
390 } | 390 } |
391 | 391 |
392 | 392 |
393 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { | 393 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { |
394 // ----------- S t a t e ------------- | 394 // ----------- S t a t e ------------- |
395 // -- eax: number of arguments | 395 // -- eax: number of arguments |
396 // -- edi: constructor function | 396 // -- edi: constructor function |
397 // -- ebx: allocation site or undefined | 397 // -- ebx: allocation site or undefined |
398 // -- edx: original constructor | 398 // -- edx: new target |
399 // ----------------------------------- | 399 // ----------------------------------- |
400 | 400 |
401 { | 401 { |
402 FrameScope frame_scope(masm, StackFrame::CONSTRUCT); | 402 FrameScope frame_scope(masm, StackFrame::CONSTRUCT); |
403 | 403 |
404 // Preserve allocation site. | 404 // Preserve allocation site. |
405 __ AssertUndefinedOrAllocationSite(ebx); | 405 __ AssertUndefinedOrAllocationSite(ebx); |
406 __ push(ebx); | 406 __ push(ebx); |
407 | 407 |
408 // Preserve actual arguments count. | 408 // Preserve actual arguments count. |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 // Call the target. | 759 // Call the target. |
760 __ Push(edx); // Re-push return address. | 760 __ Push(edx); // Re-push return address. |
761 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 761 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
762 } | 762 } |
763 | 763 |
764 | 764 |
765 // static | 765 // static |
766 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 766 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
767 // ----------- S t a t e ------------- | 767 // ----------- S t a t e ------------- |
768 // -- eax : the number of arguments (not including the receiver) | 768 // -- eax : the number of arguments (not including the receiver) |
769 // -- edx : the original constructor | 769 // -- edx : the new target |
770 // -- edi : the constructor | 770 // -- edi : the constructor |
771 // -- ebx : the address of the first argument to be pushed. Subsequent | 771 // -- ebx : the address of the first argument to be pushed. Subsequent |
772 // arguments should be consecutive above this, in the same order as | 772 // arguments should be consecutive above this, in the same order as |
773 // they are to be pushed onto the stack. | 773 // they are to be pushed onto the stack. |
774 // ----------------------------------- | 774 // ----------------------------------- |
775 | 775 |
776 // Save number of arguments on the stack below where arguments are going | 776 // Save number of arguments on the stack below where arguments are going |
777 // to be pushed. | 777 // to be pushed. |
778 __ mov(ecx, eax); | 778 __ mov(ecx, eax); |
779 __ neg(ecx); | 779 __ neg(ecx); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1150 } | 1150 } |
1151 | 1151 |
1152 | 1152 |
1153 // Used by ReflectConstruct | 1153 // Used by ReflectConstruct |
1154 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1154 static void Generate_ConstructHelper(MacroAssembler* masm) { |
1155 const int kFormalParameters = 3; | 1155 const int kFormalParameters = 3; |
1156 const int kStackSize = kFormalParameters + 1; | 1156 const int kStackSize = kFormalParameters + 1; |
1157 | 1157 |
1158 // Stack at entry: | 1158 // Stack at entry: |
1159 // esp : return address | 1159 // esp : return address |
1160 // esp[4] : original constructor (new.target) | 1160 // esp[4] : new target |
1161 // esp[8] : arguments | 1161 // esp[8] : arguments |
1162 // esp[16] : constructor | 1162 // esp[16] : constructor |
1163 { | 1163 { |
1164 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1164 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1165 // Stack frame: | 1165 // Stack frame: |
1166 // ebp : Old base pointer | 1166 // ebp : Old base pointer |
1167 // ebp[4] : return address | 1167 // ebp[4] : return address |
1168 // ebp[8] : original constructor (new.target) | 1168 // ebp[8] : new target |
1169 // ebp[12] : arguments | 1169 // ebp[12] : arguments |
1170 // ebp[16] : constructor | 1170 // ebp[16] : constructor |
1171 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1171 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1172 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1172 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1173 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1173 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
1174 static const int kVectorOffset = | 1174 static const int kVectorOffset = |
1175 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; | 1175 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
1176 | 1176 |
1177 // Push the vector. | 1177 // Push the vector. |
1178 __ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 1178 __ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); | 1357 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); |
1358 } | 1358 } |
1359 } | 1359 } |
1360 | 1360 |
1361 | 1361 |
1362 // static | 1362 // static |
1363 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1363 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1364 // ----------- S t a t e ------------- | 1364 // ----------- S t a t e ------------- |
1365 // -- eax : number of arguments | 1365 // -- eax : number of arguments |
1366 // -- edi : constructor function | 1366 // -- edi : constructor function |
1367 // -- edx : original constructor | 1367 // -- edx : new target |
1368 // -- esp[0] : return address | 1368 // -- esp[0] : return address |
1369 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1369 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1370 // -- esp[(argc + 1) * 4] : receiver | 1370 // -- esp[(argc + 1) * 4] : receiver |
1371 // ----------------------------------- | 1371 // ----------------------------------- |
1372 | 1372 |
1373 // 1. Load the first argument into ebx and get rid of the rest (including the | 1373 // 1. Load the first argument into ebx and get rid of the rest (including the |
1374 // receiver). | 1374 // receiver). |
1375 { | 1375 { |
1376 Label no_arguments, done; | 1376 Label no_arguments, done; |
1377 __ test(eax, eax); | 1377 __ test(eax, eax); |
(...skipping 22 matching lines...) Expand all Loading... |
1400 __ Push(edx); | 1400 __ Push(edx); |
1401 __ Move(eax, ebx); | 1401 __ Move(eax, ebx); |
1402 __ CallStub(&stub); | 1402 __ CallStub(&stub); |
1403 __ Move(ebx, eax); | 1403 __ Move(ebx, eax); |
1404 __ Pop(edx); | 1404 __ Pop(edx); |
1405 __ Pop(edi); | 1405 __ Pop(edi); |
1406 } | 1406 } |
1407 __ bind(&done_convert); | 1407 __ bind(&done_convert); |
1408 } | 1408 } |
1409 | 1409 |
1410 // 3. Check if original constructor and constructor differ. | 1410 // 3. Check if new target and constructor differ. |
1411 Label new_object; | 1411 Label new_object; |
1412 __ cmp(edx, edi); | 1412 __ cmp(edx, edi); |
1413 __ j(not_equal, &new_object); | 1413 __ j(not_equal, &new_object); |
1414 | 1414 |
1415 // 4. Allocate a JSValue wrapper for the string. | 1415 // 4. Allocate a JSValue wrapper for the string. |
1416 { | 1416 { |
1417 // ----------- S t a t e ------------- | 1417 // ----------- S t a t e ------------- |
1418 // -- ebx : the first argument | 1418 // -- ebx : the first argument |
1419 // -- edi : constructor function | 1419 // -- edi : constructor function |
1420 // -- edx : original constructor | 1420 // -- edx : new target |
1421 // ----------------------------------- | 1421 // ----------------------------------- |
1422 __ Allocate(JSValue::kSize, eax, ecx, no_reg, &new_object, TAG_OBJECT); | 1422 __ Allocate(JSValue::kSize, eax, ecx, no_reg, &new_object, TAG_OBJECT); |
1423 | 1423 |
1424 // Initialize the JSValue in eax. | 1424 // Initialize the JSValue in eax. |
1425 __ LoadGlobalFunctionInitialMap(edi, ecx); | 1425 __ LoadGlobalFunctionInitialMap(edi, ecx); |
1426 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx); | 1426 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx); |
1427 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | 1427 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
1428 masm->isolate()->factory()->empty_fixed_array()); | 1428 masm->isolate()->factory()->empty_fixed_array()); |
1429 __ mov(FieldOperand(eax, JSObject::kElementsOffset), | 1429 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
1430 masm->isolate()->factory()->empty_fixed_array()); | 1430 masm->isolate()->factory()->empty_fixed_array()); |
1431 __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); | 1431 __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); |
1432 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1432 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
1433 __ Ret(); | 1433 __ Ret(); |
1434 } | 1434 } |
1435 | 1435 |
1436 // 5. Fallback to the runtime to create new object. | 1436 // 5. Fallback to the runtime to create new object. |
1437 __ bind(&new_object); | 1437 __ bind(&new_object); |
1438 { | 1438 { |
1439 FrameScope scope(masm, StackFrame::INTERNAL); | 1439 FrameScope scope(masm, StackFrame::INTERNAL); |
1440 __ Push(ebx); // the first argument | 1440 __ Push(ebx); // the first argument |
1441 __ Push(edi); // constructor function | 1441 __ Push(edi); // constructor function |
1442 __ Push(edx); // original constructor | 1442 __ Push(edx); // new target |
1443 __ CallRuntime(Runtime::kNewObject, 2); | 1443 __ CallRuntime(Runtime::kNewObject, 2); |
1444 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); | 1444 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |
1445 } | 1445 } |
1446 __ Ret(); | 1446 __ Ret(); |
1447 } | 1447 } |
1448 | 1448 |
1449 | 1449 |
1450 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1450 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
1451 Label* stack_overflow) { | 1451 Label* stack_overflow) { |
1452 // ----------- S t a t e ------------- | 1452 // ----------- S t a t e ------------- |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 __ Push(edi); | 1659 __ Push(edi); |
1660 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1660 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
1661 } | 1661 } |
1662 } | 1662 } |
1663 | 1663 |
1664 | 1664 |
1665 // static | 1665 // static |
1666 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 1666 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
1667 // ----------- S t a t e ------------- | 1667 // ----------- S t a t e ------------- |
1668 // -- eax : the number of arguments (not including the receiver) | 1668 // -- eax : the number of arguments (not including the receiver) |
1669 // -- edx : the original constructor (checked to be a JSFunction) | 1669 // -- edx : the new target (checked to be a JSFunction) |
1670 // -- edi : the constructor to call (checked to be a JSFunction) | 1670 // -- edi : the constructor to call (checked to be a JSFunction) |
1671 // ----------------------------------- | 1671 // ----------------------------------- |
1672 __ AssertFunction(edx); | 1672 __ AssertFunction(edx); |
1673 __ AssertFunction(edi); | 1673 __ AssertFunction(edi); |
1674 | 1674 |
1675 // Calling convention for function specific ConstructStubs require | 1675 // Calling convention for function specific ConstructStubs require |
1676 // ebx to contain either an AllocationSite or undefined. | 1676 // ebx to contain either an AllocationSite or undefined. |
1677 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); | 1677 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); |
1678 | 1678 |
1679 // Tail call to the function-specific construct stub (still in the caller | 1679 // Tail call to the function-specific construct stub (still in the caller |
1680 // context at this point). | 1680 // context at this point). |
1681 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 1681 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
1682 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); | 1682 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); |
1683 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 1683 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
1684 __ jmp(ecx); | 1684 __ jmp(ecx); |
1685 } | 1685 } |
1686 | 1686 |
1687 | 1687 |
1688 // static | 1688 // static |
1689 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 1689 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
1690 // ----------- S t a t e ------------- | 1690 // ----------- S t a t e ------------- |
1691 // -- eax : the number of arguments (not including the receiver) | 1691 // -- eax : the number of arguments (not including the receiver) |
1692 // -- edx : the original constructor (either the same as the constructor or | 1692 // -- edx : the new target (either the same as the constructor or |
1693 // the JSFunction on which new was invoked initially) | 1693 // the JSFunction on which new was invoked initially) |
1694 // -- edi : the constructor to call (checked to be a JSFunctionProxy) | 1694 // -- edi : the constructor to call (checked to be a JSFunctionProxy) |
1695 // ----------------------------------- | 1695 // ----------------------------------- |
1696 | 1696 |
1697 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. | 1697 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. |
1698 __ mov(edi, FieldOperand(edi, JSFunctionProxy::kConstructTrapOffset)); | 1698 __ mov(edi, FieldOperand(edi, JSFunctionProxy::kConstructTrapOffset)); |
1699 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1699 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1700 } | 1700 } |
1701 | 1701 |
1702 | 1702 |
1703 // static | 1703 // static |
1704 void Builtins::Generate_Construct(MacroAssembler* masm) { | 1704 void Builtins::Generate_Construct(MacroAssembler* masm) { |
1705 // ----------- S t a t e ------------- | 1705 // ----------- S t a t e ------------- |
1706 // -- eax : the number of arguments (not including the receiver) | 1706 // -- eax : the number of arguments (not including the receiver) |
1707 // -- edx : the original constructor (either the same as the constructor or | 1707 // -- edx : the new target (either the same as the constructor or |
1708 // the JSFunction on which new was invoked initially) | 1708 // the JSFunction on which new was invoked initially) |
1709 // -- edi : the constructor to call (can be any Object) | 1709 // -- edi : the constructor to call (can be any Object) |
1710 // ----------------------------------- | 1710 // ----------------------------------- |
1711 | 1711 |
1712 // Check if target has a [[Construct]] internal method. | 1712 // Check if target has a [[Construct]] internal method. |
1713 Label non_constructor; | 1713 Label non_constructor; |
1714 __ JumpIfSmi(edi, &non_constructor, Label::kNear); | 1714 __ JumpIfSmi(edi, &non_constructor, Label::kNear); |
1715 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); | 1715 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); |
1716 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); | 1716 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); |
1717 __ j(zero, &non_constructor, Label::kNear); | 1717 __ j(zero, &non_constructor, Label::kNear); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1926 | 1926 |
1927 __ bind(&ok); | 1927 __ bind(&ok); |
1928 __ ret(0); | 1928 __ ret(0); |
1929 } | 1929 } |
1930 | 1930 |
1931 #undef __ | 1931 #undef __ |
1932 } // namespace internal | 1932 } // namespace internal |
1933 } // namespace v8 | 1933 } // namespace v8 |
1934 | 1934 |
1935 #endif // V8_TARGET_ARCH_IA32 | 1935 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |