| 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_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 GenerateTailCallToSharedCode(masm); | 117 GenerateTailCallToSharedCode(masm); |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 121 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 122 bool is_api_function) { | 122 bool is_api_function) { |
| 123 // ----------- S t a t e ------------- | 123 // ----------- S t a t e ------------- |
| 124 // -- rax: number of arguments | 124 // -- rax: number of arguments |
| 125 // -- rdi: constructor function | 125 // -- rdi: constructor function |
| 126 // -- rbx: allocation site or undefined | 126 // -- rbx: allocation site or undefined |
| 127 // -- rdx: original constructor | 127 // -- rdx: new target |
| 128 // ----------------------------------- | 128 // ----------------------------------- |
| 129 | 129 |
| 130 // Enter a construct frame. | 130 // Enter a construct frame. |
| 131 { | 131 { |
| 132 FrameScope scope(masm, StackFrame::CONSTRUCT); | 132 FrameScope scope(masm, StackFrame::CONSTRUCT); |
| 133 | 133 |
| 134 // Preserve the incoming parameters on the stack. | 134 // Preserve the incoming parameters on the stack. |
| 135 __ AssertUndefinedOrAllocationSite(rbx); | 135 __ AssertUndefinedOrAllocationSite(rbx); |
| 136 __ Push(rbx); | 136 __ Push(rbx); |
| 137 __ Integer32ToSmi(rax, rax); | 137 __ Integer32ToSmi(rax, rax); |
| 138 __ Push(rax); | 138 __ Push(rax); |
| 139 __ Push(rdi); | 139 __ Push(rdi); |
| 140 __ Push(rdx); | 140 __ Push(rdx); |
| 141 | 141 |
| 142 // Try to allocate the object without transitioning into C code. If any of | 142 // Try to allocate the object without transitioning into C code. If any of |
| 143 // the preconditions is not met, the code bails out to the runtime call. | 143 // the preconditions is not met, the code bails out to the runtime call. |
| 144 Label rt_call, allocated; | 144 Label rt_call, allocated; |
| 145 if (FLAG_inline_new) { | 145 if (FLAG_inline_new) { |
| 146 ExternalReference debug_step_in_fp = | 146 ExternalReference debug_step_in_fp = |
| 147 ExternalReference::debug_step_in_fp_address(masm->isolate()); | 147 ExternalReference::debug_step_in_fp_address(masm->isolate()); |
| 148 __ Move(kScratchRegister, debug_step_in_fp); | 148 __ Move(kScratchRegister, debug_step_in_fp); |
| 149 __ cmpp(Operand(kScratchRegister, 0), Immediate(0)); | 149 __ cmpp(Operand(kScratchRegister, 0), Immediate(0)); |
| 150 __ j(not_equal, &rt_call); | 150 __ j(not_equal, &rt_call); |
| 151 | 151 |
| 152 // Verify that the original constructor is a JSFunction. | 152 // Verify that the new target is a JSFunction. |
| 153 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rbx); | 153 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rbx); |
| 154 __ j(not_equal, &rt_call); | 154 __ j(not_equal, &rt_call); |
| 155 | 155 |
| 156 // Load the initial map and verify that it is in fact a map. | 156 // Load the initial map and verify that it is in fact a map. |
| 157 // rdx: original constructor | 157 // rdx: new target |
| 158 __ movp(rax, FieldOperand(rdx, JSFunction::kPrototypeOrInitialMapOffset)); | 158 __ movp(rax, FieldOperand(rdx, JSFunction::kPrototypeOrInitialMapOffset)); |
| 159 // Will both indicate a NULL and a Smi | 159 // Will both indicate a NULL and a Smi |
| 160 DCHECK(kSmiTag == 0); | 160 DCHECK(kSmiTag == 0); |
| 161 __ JumpIfSmi(rax, &rt_call); | 161 __ JumpIfSmi(rax, &rt_call); |
| 162 // rdi: constructor | 162 // rdi: constructor |
| 163 // rax: initial map (if proven valid below) | 163 // rax: initial map (if proven valid below) |
| 164 __ CmpObjectType(rax, MAP_TYPE, rbx); | 164 __ CmpObjectType(rax, MAP_TYPE, rbx); |
| 165 __ j(not_equal, &rt_call); | 165 __ j(not_equal, &rt_call); |
| 166 | 166 |
| 167 // Fall back to runtime if the expected base constructor and base | 167 // Fall back to runtime if the expected base constructor and base |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 // and jump into the continuation code at any time from now on. | 267 // and jump into the continuation code at any time from now on. |
| 268 // rbx: JSObject (untagged) | 268 // rbx: JSObject (untagged) |
| 269 __ orp(rbx, Immediate(kHeapObjectTag)); | 269 __ orp(rbx, Immediate(kHeapObjectTag)); |
| 270 | 270 |
| 271 // Continue with JSObject being successfully allocated | 271 // Continue with JSObject being successfully allocated |
| 272 // rbx: JSObject (tagged) | 272 // rbx: JSObject (tagged) |
| 273 __ jmp(&allocated); | 273 __ jmp(&allocated); |
| 274 } | 274 } |
| 275 | 275 |
| 276 // Allocate the new receiver object using the runtime call. | 276 // Allocate the new receiver object using the runtime call. |
| 277 // rdx: original constructor | 277 // rdx: new target |
| 278 __ bind(&rt_call); | 278 __ bind(&rt_call); |
| 279 int offset = kPointerSize; | 279 int offset = kPointerSize; |
| 280 | 280 |
| 281 // Must restore rsi (context) and rdi (constructor) before calling runtime. | 281 // Must restore rsi (context) and rdi (constructor) before calling runtime. |
| 282 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 282 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 283 __ movp(rdi, Operand(rsp, offset)); | 283 __ movp(rdi, Operand(rsp, offset)); |
| 284 __ Push(rdi); // constructor function | 284 __ Push(rdi); // constructor function |
| 285 __ Push(rdx); // original constructor | 285 __ Push(rdx); // new target |
| 286 __ CallRuntime(Runtime::kNewObject, 2); | 286 __ CallRuntime(Runtime::kNewObject, 2); |
| 287 __ movp(rbx, rax); // store result in rbx | 287 __ movp(rbx, rax); // store result in rbx |
| 288 | 288 |
| 289 // New object allocated. | 289 // New object allocated. |
| 290 // rbx: newly allocated object | 290 // rbx: newly allocated object |
| 291 __ bind(&allocated); | 291 __ bind(&allocated); |
| 292 | 292 |
| 293 // Restore the parameters. | 293 // Restore the parameters. |
| 294 __ Pop(rdx); | 294 __ Pop(rdx); |
| 295 __ Pop(rdi); | 295 __ Pop(rdi); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 385 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 386 Generate_JSConstructStubHelper(masm, true); | 386 Generate_JSConstructStubHelper(masm, true); |
| 387 } | 387 } |
| 388 | 388 |
| 389 | 389 |
| 390 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { | 390 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { |
| 391 // ----------- S t a t e ------------- | 391 // ----------- S t a t e ------------- |
| 392 // -- rax: number of arguments | 392 // -- rax: number of arguments |
| 393 // -- rdi: constructor function | 393 // -- rdi: constructor function |
| 394 // -- rbx: allocation site or undefined | 394 // -- rbx: allocation site or undefined |
| 395 // -- rdx: original constructor | 395 // -- rdx: new target |
| 396 // ----------------------------------- | 396 // ----------------------------------- |
| 397 | 397 |
| 398 { | 398 { |
| 399 FrameScope frame_scope(masm, StackFrame::CONSTRUCT); | 399 FrameScope frame_scope(masm, StackFrame::CONSTRUCT); |
| 400 | 400 |
| 401 // Preserve allocation site. | 401 // Preserve allocation site. |
| 402 __ AssertUndefinedOrAllocationSite(rbx); | 402 __ AssertUndefinedOrAllocationSite(rbx); |
| 403 __ Push(rbx); | 403 __ Push(rbx); |
| 404 | 404 |
| 405 // Store a smi-tagged arguments count on the stack. | 405 // Store a smi-tagged arguments count on the stack. |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 // Call the target. | 826 // Call the target. |
| 827 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. | 827 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. |
| 828 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 828 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 829 } | 829 } |
| 830 | 830 |
| 831 | 831 |
| 832 // static | 832 // static |
| 833 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 833 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
| 834 // ----------- S t a t e ------------- | 834 // ----------- S t a t e ------------- |
| 835 // -- rax : the number of arguments (not including the receiver) | 835 // -- rax : the number of arguments (not including the receiver) |
| 836 // -- rdx : the original constructor (either the same as the constructor or | 836 // -- rdx : the new target (either the same as the constructor or |
| 837 // the JSFunction on which new was invoked initially) | 837 // the JSFunction on which new was invoked initially) |
| 838 // -- rdi : the constructor to call (can be any Object) | 838 // -- rdi : the constructor to call (can be any Object) |
| 839 // -- rbx : the address of the first argument to be pushed. Subsequent | 839 // -- rbx : the address of the first argument to be pushed. Subsequent |
| 840 // arguments should be consecutive above this, in the same order as | 840 // arguments should be consecutive above this, in the same order as |
| 841 // they are to be pushed onto the stack. | 841 // they are to be pushed onto the stack. |
| 842 // ----------------------------------- | 842 // ----------------------------------- |
| 843 | 843 |
| 844 // Pop return address to allow tail-call after pushing arguments. | 844 // Pop return address to allow tail-call after pushing arguments. |
| 845 __ PopReturnAddressTo(kScratchRegister); | 845 __ PopReturnAddressTo(kScratchRegister); |
| 846 | 846 |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 } | 1206 } |
| 1207 | 1207 |
| 1208 | 1208 |
| 1209 // Used by ReflectConstruct | 1209 // Used by ReflectConstruct |
| 1210 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1210 static void Generate_ConstructHelper(MacroAssembler* masm) { |
| 1211 const int kFormalParameters = 3; | 1211 const int kFormalParameters = 3; |
| 1212 const int kStackSize = kFormalParameters + 1; | 1212 const int kStackSize = kFormalParameters + 1; |
| 1213 | 1213 |
| 1214 // Stack at entry: | 1214 // Stack at entry: |
| 1215 // rsp : return address | 1215 // rsp : return address |
| 1216 // rsp[8] : original constructor (new.target) | 1216 // rsp[8] : new target |
| 1217 // rsp[16] : arguments | 1217 // rsp[16] : arguments |
| 1218 // rsp[24] : constructor | 1218 // rsp[24] : constructor |
| 1219 { | 1219 { |
| 1220 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1220 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 1221 // Stack frame: | 1221 // Stack frame: |
| 1222 // rbp : Old base pointer | 1222 // rbp : Old base pointer |
| 1223 // rbp[8] : return address | 1223 // rbp[8] : return address |
| 1224 // rbp[16] : original constructor (new.target) | 1224 // rbp[16] : new target |
| 1225 // rbp[24] : arguments | 1225 // rbp[24] : arguments |
| 1226 // rbp[32] : constructor | 1226 // rbp[32] : constructor |
| 1227 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1227 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
| 1228 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1228 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
| 1229 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1229 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
| 1230 | 1230 |
| 1231 static const int kVectorOffset = | 1231 static const int kVectorOffset = |
| 1232 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; | 1232 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1233 | 1233 |
| 1234 // Push the vector. | 1234 // Push the vector. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); | 1417 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); |
| 1418 } | 1418 } |
| 1419 } | 1419 } |
| 1420 | 1420 |
| 1421 | 1421 |
| 1422 // static | 1422 // static |
| 1423 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1423 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
| 1424 // ----------- S t a t e ------------- | 1424 // ----------- S t a t e ------------- |
| 1425 // -- rax : number of arguments | 1425 // -- rax : number of arguments |
| 1426 // -- rdi : constructor function | 1426 // -- rdi : constructor function |
| 1427 // -- rdx : original constructor | 1427 // -- rdx : new target |
| 1428 // -- rsp[0] : return address | 1428 // -- rsp[0] : return address |
| 1429 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1429 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1430 // -- rsp[(argc + 1) * 8] : receiver | 1430 // -- rsp[(argc + 1) * 8] : receiver |
| 1431 // ----------------------------------- | 1431 // ----------------------------------- |
| 1432 | 1432 |
| 1433 // 1. Load the first argument into rbx and get rid of the rest (including the | 1433 // 1. Load the first argument into rbx and get rid of the rest (including the |
| 1434 // receiver). | 1434 // receiver). |
| 1435 { | 1435 { |
| 1436 StackArgumentsAccessor args(rsp, rax); | 1436 StackArgumentsAccessor args(rsp, rax); |
| 1437 Label no_arguments, done; | 1437 Label no_arguments, done; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1461 __ Push(rdi); | 1461 __ Push(rdi); |
| 1462 __ Move(rax, rbx); | 1462 __ Move(rax, rbx); |
| 1463 __ CallStub(&stub); | 1463 __ CallStub(&stub); |
| 1464 __ Move(rbx, rax); | 1464 __ Move(rbx, rax); |
| 1465 __ Pop(rdi); | 1465 __ Pop(rdi); |
| 1466 __ Pop(rdx); | 1466 __ Pop(rdx); |
| 1467 } | 1467 } |
| 1468 __ bind(&done_convert); | 1468 __ bind(&done_convert); |
| 1469 } | 1469 } |
| 1470 | 1470 |
| 1471 // 3. Check if original constructor and constructor differ. | 1471 // 3. Check if new target and constructor differ. |
| 1472 Label new_object; | 1472 Label new_object; |
| 1473 __ cmpp(rdx, rdi); | 1473 __ cmpp(rdx, rdi); |
| 1474 __ j(not_equal, &new_object); | 1474 __ j(not_equal, &new_object); |
| 1475 | 1475 |
| 1476 // 4. Allocate a JSValue wrapper for the string. | 1476 // 4. Allocate a JSValue wrapper for the string. |
| 1477 { | 1477 { |
| 1478 // ----------- S t a t e ------------- | 1478 // ----------- S t a t e ------------- |
| 1479 // -- rbx : the first argument | 1479 // -- rbx : the first argument |
| 1480 // -- rdi : constructor function | 1480 // -- rdi : constructor function |
| 1481 // -- rdx : original constructor | 1481 // -- rdx : new target |
| 1482 // ----------------------------------- | 1482 // ----------------------------------- |
| 1483 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &new_object, TAG_OBJECT); | 1483 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &new_object, TAG_OBJECT); |
| 1484 | 1484 |
| 1485 // Initialize the JSValue in rax. | 1485 // Initialize the JSValue in rax. |
| 1486 __ LoadGlobalFunctionInitialMap(rdi, rcx); | 1486 __ LoadGlobalFunctionInitialMap(rdi, rcx); |
| 1487 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); | 1487 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); |
| 1488 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); | 1488 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); |
| 1489 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); | 1489 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); |
| 1490 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); | 1490 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); |
| 1491 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); | 1491 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); |
| 1492 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1492 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
| 1493 __ Ret(); | 1493 __ Ret(); |
| 1494 } | 1494 } |
| 1495 | 1495 |
| 1496 // 5. Fallback to the runtime to create new object. | 1496 // 5. Fallback to the runtime to create new object. |
| 1497 __ bind(&new_object); | 1497 __ bind(&new_object); |
| 1498 { | 1498 { |
| 1499 FrameScope scope(masm, StackFrame::INTERNAL); | 1499 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1500 __ Push(rbx); // the first argument | 1500 __ Push(rbx); // the first argument |
| 1501 __ Push(rdi); // constructor function | 1501 __ Push(rdi); // constructor function |
| 1502 __ Push(rdx); // original constructor | 1502 __ Push(rdx); // new target |
| 1503 __ CallRuntime(Runtime::kNewObject, 2); | 1503 __ CallRuntime(Runtime::kNewObject, 2); |
| 1504 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); | 1504 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); |
| 1505 } | 1505 } |
| 1506 __ Ret(); | 1506 __ Ret(); |
| 1507 } | 1507 } |
| 1508 | 1508 |
| 1509 | 1509 |
| 1510 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1510 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
| 1511 Label* stack_overflow) { | 1511 Label* stack_overflow) { |
| 1512 // ----------- S t a t e ------------- | 1512 // ----------- S t a t e ------------- |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1861 __ Push(rdi); | 1861 __ Push(rdi); |
| 1862 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1862 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
| 1863 } | 1863 } |
| 1864 } | 1864 } |
| 1865 | 1865 |
| 1866 | 1866 |
| 1867 // static | 1867 // static |
| 1868 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 1868 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
| 1869 // ----------- S t a t e ------------- | 1869 // ----------- S t a t e ------------- |
| 1870 // -- rax : the number of arguments (not including the receiver) | 1870 // -- rax : the number of arguments (not including the receiver) |
| 1871 // -- rdx : the original constructor (checked to be a JSFunction) | 1871 // -- rdx : the new target (checked to be a JSFunction) |
| 1872 // -- rdi : the constructor to call (checked to be a JSFunction) | 1872 // -- rdi : the constructor to call (checked to be a JSFunction) |
| 1873 // ----------------------------------- | 1873 // ----------------------------------- |
| 1874 __ AssertFunction(rdx); | 1874 __ AssertFunction(rdx); |
| 1875 __ AssertFunction(rdi); | 1875 __ AssertFunction(rdi); |
| 1876 | 1876 |
| 1877 // Calling convention for function specific ConstructStubs require | 1877 // Calling convention for function specific ConstructStubs require |
| 1878 // rbx to contain either an AllocationSite or undefined. | 1878 // rbx to contain either an AllocationSite or undefined. |
| 1879 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 1879 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
| 1880 | 1880 |
| 1881 // Tail call to the function-specific construct stub (still in the caller | 1881 // Tail call to the function-specific construct stub (still in the caller |
| 1882 // context at this point). | 1882 // context at this point). |
| 1883 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 1883 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 1884 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); | 1884 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); |
| 1885 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 1885 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |
| 1886 __ jmp(rcx); | 1886 __ jmp(rcx); |
| 1887 } | 1887 } |
| 1888 | 1888 |
| 1889 | 1889 |
| 1890 // static | 1890 // static |
| 1891 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 1891 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
| 1892 // ----------- S t a t e ------------- | 1892 // ----------- S t a t e ------------- |
| 1893 // -- rax : the number of arguments (not including the receiver) | 1893 // -- rax : the number of arguments (not including the receiver) |
| 1894 // -- rdx : the original constructor (either the same as the constructor or | 1894 // -- rdx : the new target (either the same as the constructor or |
| 1895 // the JSFunction on which new was invoked initially) | 1895 // the JSFunction on which new was invoked initially) |
| 1896 // -- rdi : the constructor to call (checked to be a JSFunctionProxy) | 1896 // -- rdi : the constructor to call (checked to be a JSFunctionProxy) |
| 1897 // ----------------------------------- | 1897 // ----------------------------------- |
| 1898 | 1898 |
| 1899 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. | 1899 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. |
| 1900 __ movp(rdi, FieldOperand(rdi, JSFunctionProxy::kConstructTrapOffset)); | 1900 __ movp(rdi, FieldOperand(rdi, JSFunctionProxy::kConstructTrapOffset)); |
| 1901 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1901 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1902 } | 1902 } |
| 1903 | 1903 |
| 1904 | 1904 |
| 1905 // static | 1905 // static |
| 1906 void Builtins::Generate_Construct(MacroAssembler* masm) { | 1906 void Builtins::Generate_Construct(MacroAssembler* masm) { |
| 1907 // ----------- S t a t e ------------- | 1907 // ----------- S t a t e ------------- |
| 1908 // -- rax : the number of arguments (not including the receiver) | 1908 // -- rax : the number of arguments (not including the receiver) |
| 1909 // -- rdx : the original constructor (either the same as the constructor or | 1909 // -- rdx : the new target (either the same as the constructor or |
| 1910 // the JSFunction on which new was invoked initially) | 1910 // the JSFunction on which new was invoked initially) |
| 1911 // -- rdi : the constructor to call (can be any Object) | 1911 // -- rdi : the constructor to call (can be any Object) |
| 1912 // ----------------------------------- | 1912 // ----------------------------------- |
| 1913 StackArgumentsAccessor args(rsp, rax); | 1913 StackArgumentsAccessor args(rsp, rax); |
| 1914 | 1914 |
| 1915 // Check if target has a [[Construct]] internal method. | 1915 // Check if target has a [[Construct]] internal method. |
| 1916 Label non_constructor; | 1916 Label non_constructor; |
| 1917 __ JumpIfSmi(rdi, &non_constructor, Label::kNear); | 1917 __ JumpIfSmi(rdi, &non_constructor, Label::kNear); |
| 1918 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset)); | 1918 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset)); |
| 1919 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), | 1919 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2001 __ ret(0); | 2001 __ ret(0); |
| 2002 } | 2002 } |
| 2003 | 2003 |
| 2004 | 2004 |
| 2005 #undef __ | 2005 #undef __ |
| 2006 | 2006 |
| 2007 } // namespace internal | 2007 } // namespace internal |
| 2008 } // namespace v8 | 2008 } // namespace v8 |
| 2009 | 2009 |
| 2010 #endif // V8_TARGET_ARCH_X64 | 2010 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |