| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 __ dec(ecx); | 363 __ dec(ecx); |
| 364 __ j(greater_equal, &loop); | 364 __ j(greater_equal, &loop); |
| 365 | 365 |
| 366 // Call the function. | 366 // Call the function. |
| 367 if (is_api_function) { | 367 if (is_api_function) { |
| 368 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 368 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 369 Handle<Code> code = | 369 Handle<Code> code = |
| 370 masm->isolate()->builtins()->HandleApiCallConstruct(); | 370 masm->isolate()->builtins()->HandleApiCallConstruct(); |
| 371 ParameterCount expected(0); | 371 ParameterCount expected(0); |
| 372 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET, | 372 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET, |
| 373 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 373 CALL_FUNCTION, NullCallWrapper()); |
| 374 } else { | 374 } else { |
| 375 ParameterCount actual(eax); | 375 ParameterCount actual(eax); |
| 376 __ InvokeFunction(edi, actual, CALL_FUNCTION, | 376 __ InvokeFunction(edi, actual, CALL_FUNCTION, |
| 377 NullCallWrapper(), CALL_AS_METHOD); | 377 NullCallWrapper()); |
| 378 } | 378 } |
| 379 | 379 |
| 380 // Store offset of return address for deoptimizer. | 380 // Store offset of return address for deoptimizer. |
| 381 if (!is_api_function && !count_constructions) { | 381 if (!is_api_function && !count_constructions) { |
| 382 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 382 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
| 383 } | 383 } |
| 384 | 384 |
| 385 // Restore context from the frame. | 385 // Restore context from the frame. |
| 386 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 386 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 387 | 387 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 if (is_construct) { | 480 if (is_construct) { |
| 481 // No type feedback cell is available | 481 // No type feedback cell is available |
| 482 Handle<Object> undefined_sentinel( | 482 Handle<Object> undefined_sentinel( |
| 483 masm->isolate()->heap()->undefined_value(), masm->isolate()); | 483 masm->isolate()->heap()->undefined_value(), masm->isolate()); |
| 484 __ mov(ebx, Immediate(undefined_sentinel)); | 484 __ mov(ebx, Immediate(undefined_sentinel)); |
| 485 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); | 485 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); |
| 486 __ CallStub(&stub); | 486 __ CallStub(&stub); |
| 487 } else { | 487 } else { |
| 488 ParameterCount actual(eax); | 488 ParameterCount actual(eax); |
| 489 __ InvokeFunction(edi, actual, CALL_FUNCTION, | 489 __ InvokeFunction(edi, actual, CALL_FUNCTION, |
| 490 NullCallWrapper(), CALL_AS_METHOD); | 490 NullCallWrapper()); |
| 491 } | 491 } |
| 492 | 492 |
| 493 // Exit the internal frame. Notice that this also removes the empty. | 493 // Exit the internal frame. Notice that this also removes the empty. |
| 494 // context and the function left on the stack by the code | 494 // context and the function left on the stack by the code |
| 495 // invocation. | 495 // invocation. |
| 496 } | 496 } |
| 497 __ ret(kPointerSize); // Remove receiver. | 497 __ ret(kPointerSize); // Remove receiver. |
| 498 } | 498 } |
| 499 | 499 |
| 500 | 500 |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 __ test(edx, edx); | 827 __ test(edx, edx); |
| 828 __ j(zero, &function); | 828 __ j(zero, &function); |
| 829 __ Set(ebx, Immediate(0)); | 829 __ Set(ebx, Immediate(0)); |
| 830 __ cmp(edx, Immediate(1)); | 830 __ cmp(edx, Immediate(1)); |
| 831 __ j(not_equal, &non_proxy); | 831 __ j(not_equal, &non_proxy); |
| 832 | 832 |
| 833 __ pop(edx); // return address | 833 __ pop(edx); // return address |
| 834 __ push(edi); // re-add proxy object as additional argument | 834 __ push(edi); // re-add proxy object as additional argument |
| 835 __ push(edx); | 835 __ push(edx); |
| 836 __ inc(eax); | 836 __ inc(eax); |
| 837 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 838 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 837 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); |
| 839 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 838 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 840 RelocInfo::CODE_TARGET); | 839 RelocInfo::CODE_TARGET); |
| 841 | 840 |
| 842 __ bind(&non_proxy); | 841 __ bind(&non_proxy); |
| 843 __ SetCallKind(ecx, CALL_AS_METHOD); | |
| 844 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 842 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| 845 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 843 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 846 RelocInfo::CODE_TARGET); | 844 RelocInfo::CODE_TARGET); |
| 847 __ bind(&function); | 845 __ bind(&function); |
| 848 } | 846 } |
| 849 | 847 |
| 850 // 5b. Get the code to call from the function and check that the number of | 848 // 5b. Get the code to call from the function and check that the number of |
| 851 // expected arguments matches what we're providing. If so, jump | 849 // expected arguments matches what we're providing. If so, jump |
| 852 // (tail-call) to the code in register edx without checking arguments. | 850 // (tail-call) to the code in register edx without checking arguments. |
| 853 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 851 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 854 __ mov(ebx, | 852 __ mov(ebx, |
| 855 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 853 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 856 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 854 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 857 __ SmiUntag(ebx); | 855 __ SmiUntag(ebx); |
| 858 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 859 __ cmp(eax, ebx); | 856 __ cmp(eax, ebx); |
| 860 __ j(not_equal, | 857 __ j(not_equal, |
| 861 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); | 858 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); |
| 862 | 859 |
| 863 ParameterCount expected(0); | 860 ParameterCount expected(0); |
| 864 __ InvokeCode(edx, expected, expected, JUMP_FUNCTION, NullCallWrapper(), | 861 __ InvokeCode(edx, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
| 865 CALL_AS_FUNCTION); | |
| 866 } | 862 } |
| 867 | 863 |
| 868 | 864 |
| 869 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 865 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
| 870 static const int kArgumentsOffset = 2 * kPointerSize; | 866 static const int kArgumentsOffset = 2 * kPointerSize; |
| 871 static const int kReceiverOffset = 3 * kPointerSize; | 867 static const int kReceiverOffset = 3 * kPointerSize; |
| 872 static const int kFunctionOffset = 4 * kPointerSize; | 868 static const int kFunctionOffset = 4 * kPointerSize; |
| 873 { | 869 { |
| 874 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 870 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 875 | 871 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 __ j(not_equal, &loop); | 988 __ j(not_equal, &loop); |
| 993 | 989 |
| 994 // Call the function. | 990 // Call the function. |
| 995 Label call_proxy; | 991 Label call_proxy; |
| 996 __ mov(eax, ecx); | 992 __ mov(eax, ecx); |
| 997 ParameterCount actual(eax); | 993 ParameterCount actual(eax); |
| 998 __ SmiUntag(eax); | 994 __ SmiUntag(eax); |
| 999 __ mov(edi, Operand(ebp, kFunctionOffset)); | 995 __ mov(edi, Operand(ebp, kFunctionOffset)); |
| 1000 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 996 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 1001 __ j(not_equal, &call_proxy); | 997 __ j(not_equal, &call_proxy); |
| 1002 __ InvokeFunction(edi, actual, CALL_FUNCTION, | 998 __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper()); |
| 1003 NullCallWrapper(), CALL_AS_FUNCTION); | |
| 1004 | 999 |
| 1005 frame_scope.GenerateLeaveFrame(); | 1000 frame_scope.GenerateLeaveFrame(); |
| 1006 __ ret(3 * kPointerSize); // remove this, receiver, and arguments | 1001 __ ret(3 * kPointerSize); // remove this, receiver, and arguments |
| 1007 | 1002 |
| 1008 // Call the function proxy. | 1003 // Call the function proxy. |
| 1009 __ bind(&call_proxy); | 1004 __ bind(&call_proxy); |
| 1010 __ push(edi); // add function proxy as last argument | 1005 __ push(edi); // add function proxy as last argument |
| 1011 __ inc(eax); | 1006 __ inc(eax); |
| 1012 __ Set(ebx, Immediate(0)); | 1007 __ Set(ebx, Immediate(0)); |
| 1013 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 1014 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 1008 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); |
| 1015 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1009 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 1016 RelocInfo::CODE_TARGET); | 1010 RelocInfo::CODE_TARGET); |
| 1017 | 1011 |
| 1018 // Leave internal frame. | 1012 // Leave internal frame. |
| 1019 } | 1013 } |
| 1020 __ ret(3 * kPointerSize); // remove this, receiver, and arguments | 1014 __ ret(3 * kPointerSize); // remove this, receiver, and arguments |
| 1021 } | 1015 } |
| 1022 | 1016 |
| 1023 | 1017 |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 | 1375 |
| 1382 __ bind(&ok); | 1376 __ bind(&ok); |
| 1383 __ ret(0); | 1377 __ ret(0); |
| 1384 } | 1378 } |
| 1385 | 1379 |
| 1386 #undef __ | 1380 #undef __ |
| 1387 } | 1381 } |
| 1388 } // namespace v8::internal | 1382 } // namespace v8::internal |
| 1389 | 1383 |
| 1390 #endif // V8_TARGET_ARCH_IA32 | 1384 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |