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 |