OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 7689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7700 __ cmp(ebp, 0); | 7700 __ cmp(ebp, 0); |
7701 __ j(equal, &skip, not_taken); | 7701 __ j(equal, &skip, not_taken); |
7702 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 7702 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
7703 __ bind(&skip); | 7703 __ bind(&skip); |
7704 | 7704 |
7705 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 7705 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
7706 __ ret(0); | 7706 __ ret(0); |
7707 } | 7707 } |
7708 | 7708 |
7709 | 7709 |
| 7710 // If true, a Handle<T> passed by value is passed and returned by |
| 7711 // using the location_ field directly. If false, it is passed and |
| 7712 // returned as a pointer to a handle. |
| 7713 #ifdef USING_MAC_ABI |
| 7714 static const bool kPassHandlesDirectly = true; |
| 7715 #else |
| 7716 static const bool kPassHandlesDirectly = false; |
| 7717 #endif |
| 7718 |
| 7719 |
| 7720 void ApiGetterEntryStub::Generate(MacroAssembler* masm) { |
| 7721 Label get_result; |
| 7722 Label prologue; |
| 7723 Label promote_scheduled_exception; |
| 7724 __ EnterApiExitFrame(ExitFrame::MODE_NORMAL, kStackSpace, kArgc); |
| 7725 ASSERT_EQ(kArgc, 4); |
| 7726 if (kPassHandlesDirectly) { |
| 7727 // When handles as passed directly we don't have to allocate extra |
| 7728 // space for and pass an out parameter. |
| 7729 __ mov(Operand(esp, 0 * kPointerSize), ebx); // name. |
| 7730 __ mov(Operand(esp, 1 * kPointerSize), eax); // arguments pointer. |
| 7731 } else { |
| 7732 // The function expects three arguments to be passed but we allocate |
| 7733 // four to get space for the output cell. The argument slots are filled |
| 7734 // as follows: |
| 7735 // |
| 7736 // 3: output cell |
| 7737 // 2: arguments pointer |
| 7738 // 1: name |
| 7739 // 0: pointer to the output cell |
| 7740 // |
| 7741 // Note that this is one more "argument" than the function expects |
| 7742 // so the out cell will have to be popped explicitly after returning |
| 7743 // from the function. |
| 7744 __ mov(Operand(esp, 1 * kPointerSize), ebx); // name. |
| 7745 __ mov(Operand(esp, 2 * kPointerSize), eax); // arguments pointer. |
| 7746 __ mov(ebx, esp); |
| 7747 __ add(Operand(ebx), Immediate(3 * kPointerSize)); |
| 7748 __ mov(Operand(esp, 0 * kPointerSize), ebx); // output |
| 7749 __ mov(Operand(esp, 3 * kPointerSize), Immediate(0)); // out cell. |
| 7750 } |
| 7751 __ mov(eax, Immediate(ExternalReference(fun()))); |
| 7752 // Call the api function! |
| 7753 __ call(Operand(eax)); |
| 7754 // Check if the function scheduled an exception. |
| 7755 ExternalReference scheduled_exception_address = |
| 7756 ExternalReference::scheduled_exception_address(); |
| 7757 __ cmp(Operand::StaticVariable(scheduled_exception_address), |
| 7758 Immediate(Factory::the_hole_value())); |
| 7759 __ j(not_equal, &promote_scheduled_exception, not_taken); |
| 7760 if (!kPassHandlesDirectly) { |
| 7761 // The returned value is a pointer to the handle holding the result. |
| 7762 // Dereference this to get to the location. |
| 7763 __ mov(eax, Operand(eax, 0)); |
| 7764 } |
| 7765 // Check if the result handle holds 0 |
| 7766 __ test(eax, Operand(eax)); |
| 7767 __ j(not_zero, &get_result, taken); |
| 7768 // It was zero; the result is undefined. |
| 7769 __ mov(eax, Factory::undefined_value()); |
| 7770 __ jmp(&prologue); |
| 7771 // It was non-zero. Dereference to get the result value. |
| 7772 __ bind(&get_result); |
| 7773 __ mov(eax, Operand(eax, 0)); |
| 7774 __ bind(&prologue); |
| 7775 __ LeaveExitFrame(ExitFrame::MODE_NORMAL); |
| 7776 __ ret(0); |
| 7777 __ bind(&promote_scheduled_exception); |
| 7778 __ TailCallRuntime(ExternalReference(Runtime::kPromoteScheduledException), |
| 7779 0, |
| 7780 1); |
| 7781 } |
| 7782 |
| 7783 |
7710 void CEntryStub::GenerateCore(MacroAssembler* masm, | 7784 void CEntryStub::GenerateCore(MacroAssembler* masm, |
7711 Label* throw_normal_exception, | 7785 Label* throw_normal_exception, |
7712 Label* throw_termination_exception, | 7786 Label* throw_termination_exception, |
7713 Label* throw_out_of_memory_exception, | 7787 Label* throw_out_of_memory_exception, |
7714 StackFrame::Type frame_type, | 7788 ExitFrame::Mode mode, |
7715 bool do_gc, | 7789 bool do_gc, |
7716 bool always_allocate_scope) { | 7790 bool always_allocate_scope) { |
7717 // eax: result parameter for PerformGC, if any | 7791 // eax: result parameter for PerformGC, if any |
7718 // ebx: pointer to C function (C callee-saved) | 7792 // ebx: pointer to C function (C callee-saved) |
7719 // ebp: frame pointer (restored after C call) | 7793 // ebp: frame pointer (restored after C call) |
7720 // esp: stack pointer (restored after C call) | 7794 // esp: stack pointer (restored after C call) |
7721 // edi: number of arguments including receiver (C callee-saved) | 7795 // edi: number of arguments including receiver (C callee-saved) |
7722 // esi: pointer to the first argument (C callee-saved) | 7796 // esi: pointer to the first argument (C callee-saved) |
7723 | 7797 |
7724 if (do_gc) { | 7798 if (do_gc) { |
(...skipping 29 matching lines...) Expand all Loading... |
7754 | 7828 |
7755 // Check for failure result. | 7829 // Check for failure result. |
7756 Label failure_returned; | 7830 Label failure_returned; |
7757 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); | 7831 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); |
7758 __ lea(ecx, Operand(eax, 1)); | 7832 __ lea(ecx, Operand(eax, 1)); |
7759 // Lower 2 bits of ecx are 0 iff eax has failure tag. | 7833 // Lower 2 bits of ecx are 0 iff eax has failure tag. |
7760 __ test(ecx, Immediate(kFailureTagMask)); | 7834 __ test(ecx, Immediate(kFailureTagMask)); |
7761 __ j(zero, &failure_returned, not_taken); | 7835 __ j(zero, &failure_returned, not_taken); |
7762 | 7836 |
7763 // Exit the JavaScript to C++ exit frame. | 7837 // Exit the JavaScript to C++ exit frame. |
7764 __ LeaveExitFrame(frame_type); | 7838 __ LeaveExitFrame(mode); |
7765 __ ret(0); | 7839 __ ret(0); |
7766 | 7840 |
7767 // Handling of failure. | 7841 // Handling of failure. |
7768 __ bind(&failure_returned); | 7842 __ bind(&failure_returned); |
7769 | 7843 |
7770 Label retry; | 7844 Label retry; |
7771 // If the returned exception is RETRY_AFTER_GC continue at retry label | 7845 // If the returned exception is RETRY_AFTER_GC continue at retry label |
7772 ASSERT(Failure::RETRY_AFTER_GC == 0); | 7846 ASSERT(Failure::RETRY_AFTER_GC == 0); |
7773 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 7847 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
7774 __ j(zero, &retry, taken); | 7848 __ j(zero, &retry, taken); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7853 // ebx: pointer to C function (C callee-saved) | 7927 // ebx: pointer to C function (C callee-saved) |
7854 // ebp: frame pointer (restored after C call) | 7928 // ebp: frame pointer (restored after C call) |
7855 // esp: stack pointer (restored after C call) | 7929 // esp: stack pointer (restored after C call) |
7856 // esi: current context (C callee-saved) | 7930 // esi: current context (C callee-saved) |
7857 // edi: JS function of the caller (C callee-saved) | 7931 // edi: JS function of the caller (C callee-saved) |
7858 | 7932 |
7859 // NOTE: Invocations of builtins may return failure objects instead | 7933 // NOTE: Invocations of builtins may return failure objects instead |
7860 // of a proper result. The builtin entry handles this by performing | 7934 // of a proper result. The builtin entry handles this by performing |
7861 // a garbage collection and retrying the builtin (twice). | 7935 // a garbage collection and retrying the builtin (twice). |
7862 | 7936 |
7863 StackFrame::Type frame_type = is_debug_break ? | 7937 ExitFrame::Mode mode = is_debug_break |
7864 StackFrame::EXIT_DEBUG : | 7938 ? ExitFrame::MODE_DEBUG |
7865 StackFrame::EXIT; | 7939 : ExitFrame::MODE_NORMAL; |
7866 | 7940 |
7867 // Enter the exit frame that transitions from JavaScript to C++. | 7941 // Enter the exit frame that transitions from JavaScript to C++. |
7868 __ EnterExitFrame(frame_type); | 7942 __ EnterExitFrame(mode); |
7869 | 7943 |
7870 // eax: result parameter for PerformGC, if any (setup below) | 7944 // eax: result parameter for PerformGC, if any (setup below) |
7871 // ebx: pointer to builtin function (C callee-saved) | 7945 // ebx: pointer to builtin function (C callee-saved) |
7872 // ebp: frame pointer (restored after C call) | 7946 // ebp: frame pointer (restored after C call) |
7873 // esp: stack pointer (restored after C call) | 7947 // esp: stack pointer (restored after C call) |
7874 // edi: number of arguments including receiver (C callee-saved) | 7948 // edi: number of arguments including receiver (C callee-saved) |
7875 // esi: argv pointer (C callee-saved) | 7949 // esi: argv pointer (C callee-saved) |
7876 | 7950 |
7877 Label throw_normal_exception; | 7951 Label throw_normal_exception; |
7878 Label throw_termination_exception; | 7952 Label throw_termination_exception; |
7879 Label throw_out_of_memory_exception; | 7953 Label throw_out_of_memory_exception; |
7880 | 7954 |
7881 // Call into the runtime system. | 7955 // Call into the runtime system. |
7882 GenerateCore(masm, | 7956 GenerateCore(masm, |
7883 &throw_normal_exception, | 7957 &throw_normal_exception, |
7884 &throw_termination_exception, | 7958 &throw_termination_exception, |
7885 &throw_out_of_memory_exception, | 7959 &throw_out_of_memory_exception, |
7886 frame_type, | 7960 mode, |
7887 false, | 7961 false, |
7888 false); | 7962 false); |
7889 | 7963 |
7890 // Do space-specific GC and retry runtime call. | 7964 // Do space-specific GC and retry runtime call. |
7891 GenerateCore(masm, | 7965 GenerateCore(masm, |
7892 &throw_normal_exception, | 7966 &throw_normal_exception, |
7893 &throw_termination_exception, | 7967 &throw_termination_exception, |
7894 &throw_out_of_memory_exception, | 7968 &throw_out_of_memory_exception, |
7895 frame_type, | 7969 mode, |
7896 true, | 7970 true, |
7897 false); | 7971 false); |
7898 | 7972 |
7899 // Do full GC and retry runtime call one final time. | 7973 // Do full GC and retry runtime call one final time. |
7900 Failure* failure = Failure::InternalError(); | 7974 Failure* failure = Failure::InternalError(); |
7901 __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure))); | 7975 __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure))); |
7902 GenerateCore(masm, | 7976 GenerateCore(masm, |
7903 &throw_normal_exception, | 7977 &throw_normal_exception, |
7904 &throw_termination_exception, | 7978 &throw_termination_exception, |
7905 &throw_out_of_memory_exception, | 7979 &throw_out_of_memory_exception, |
7906 frame_type, | 7980 mode, |
7907 true, | 7981 true, |
7908 true); | 7982 true); |
7909 | 7983 |
7910 __ bind(&throw_out_of_memory_exception); | 7984 __ bind(&throw_out_of_memory_exception); |
7911 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); | 7985 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); |
7912 | 7986 |
7913 __ bind(&throw_termination_exception); | 7987 __ bind(&throw_termination_exception); |
7914 GenerateThrowUncatchable(masm, TERMINATION); | 7988 GenerateThrowUncatchable(masm, TERMINATION); |
7915 | 7989 |
7916 __ bind(&throw_normal_exception); | 7990 __ bind(&throw_normal_exception); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8076 | 8150 |
8077 int CompareStub::MinorKey() { | 8151 int CompareStub::MinorKey() { |
8078 // Encode the two parameters in a unique 16 bit value. | 8152 // Encode the two parameters in a unique 16 bit value. |
8079 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 8153 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
8080 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 8154 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
8081 } | 8155 } |
8082 | 8156 |
8083 #undef __ | 8157 #undef __ |
8084 | 8158 |
8085 } } // namespace v8::internal | 8159 } } // namespace v8::internal |
OLD | NEW |