| 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_X87 | 5 #if V8_TARGET_ARCH_X87 |
| 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_X87 | 1935 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |