| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 NoHandleAllocation ha; | 912 NoHandleAllocation ha; |
| 913 ASSERT(args.length() == 2); | 913 ASSERT(args.length() == 2); |
| 914 | 914 |
| 915 CONVERT_CHECKED(JSFunction, fun, args[0]); | 915 CONVERT_CHECKED(JSFunction, fun, args[0]); |
| 916 Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL); | 916 Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL); |
| 917 if (obj->IsFailure()) return obj; | 917 if (obj->IsFailure()) return obj; |
| 918 return args[0]; // return TOS | 918 return args[0]; // return TOS |
| 919 } | 919 } |
| 920 | 920 |
| 921 | 921 |
| 922 static Object* Runtime_FunctionIsAPIFunction(Arguments args) { |
| 923 NoHandleAllocation ha; |
| 924 ASSERT(args.length() == 1); |
| 925 |
| 926 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 927 // The function_data field of the shared function info is used exclusively by |
| 928 // the API. |
| 929 return !f->shared()->function_data()->IsUndefined() ? Heap::true_value() |
| 930 : Heap::false_value(); |
| 931 } |
| 932 |
| 933 |
| 922 static Object* Runtime_SetCode(Arguments args) { | 934 static Object* Runtime_SetCode(Arguments args) { |
| 923 HandleScope scope; | 935 HandleScope scope; |
| 924 ASSERT(args.length() == 2); | 936 ASSERT(args.length() == 2); |
| 925 | 937 |
| 926 CONVERT_CHECKED(JSFunction, raw_target, args[0]); | 938 CONVERT_CHECKED(JSFunction, raw_target, args[0]); |
| 927 Handle<JSFunction> target(raw_target); | 939 Handle<JSFunction> target(raw_target); |
| 928 Handle<Object> code = args.at<Object>(1); | 940 Handle<Object> code = args.at<Object>(1); |
| 929 | 941 |
| 930 Handle<Context> context(target->context()); | 942 Handle<Context> context(target->context()); |
| 931 | 943 |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1726 } | 1738 } |
| 1727 | 1739 |
| 1728 | 1740 |
| 1729 | 1741 |
| 1730 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 1742 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
| 1731 static Object* Runtime_KeyedGetProperty(Arguments args) { | 1743 static Object* Runtime_KeyedGetProperty(Arguments args) { |
| 1732 NoHandleAllocation ha; | 1744 NoHandleAllocation ha; |
| 1733 ASSERT(args.length() == 2); | 1745 ASSERT(args.length() == 2); |
| 1734 | 1746 |
| 1735 // Fast cases for getting named properties of the receiver JSObject | 1747 // Fast cases for getting named properties of the receiver JSObject |
| 1736 // itself. The global proxy objects has to be excluded since | 1748 // itself. |
| 1737 // LocalLookup on the global proxy object can return a valid result | 1749 // |
| 1738 // eventhough the global proxy object never has properties. This is | 1750 // The global proxy objects has to be excluded since LocalLookup on |
| 1739 // the case because the global proxy object forwards everything to | 1751 // the global proxy object can return a valid result eventhough the |
| 1740 // its hidden prototype including local lookups. | 1752 // global proxy object never has properties. This is the case |
| 1753 // because the global proxy object forwards everything to its hidden |
| 1754 // prototype including local lookups. |
| 1755 // |
| 1756 // Additionally, we need to make sure that we do not cache results |
| 1757 // for objects that require access checks. |
| 1741 if (args[0]->IsJSObject() && | 1758 if (args[0]->IsJSObject() && |
| 1742 !args[0]->IsJSGlobalProxy() && | 1759 !args[0]->IsJSGlobalProxy() && |
| 1760 !args[0]->IsAccessCheckNeeded() && |
| 1743 args[1]->IsString()) { | 1761 args[1]->IsString()) { |
| 1744 JSObject* receiver = JSObject::cast(args[0]); | 1762 JSObject* receiver = JSObject::cast(args[0]); |
| 1745 String* key = String::cast(args[1]); | 1763 String* key = String::cast(args[1]); |
| 1746 if (receiver->HasFastProperties()) { | 1764 if (receiver->HasFastProperties()) { |
| 1747 // Attempt to use lookup cache. | 1765 // Attempt to use lookup cache. |
| 1748 Object* obj = Heap::GetKeyedLookupCache(); | 1766 Object* obj = Heap::GetKeyedLookupCache(); |
| 1749 if (obj->IsFailure()) return obj; | 1767 if (obj->IsFailure()) return obj; |
| 1750 LookupCache* cache = LookupCache::cast(obj); | 1768 LookupCache* cache = LookupCache::cast(obj); |
| 1751 Map* receiver_map = receiver->map(); | 1769 Map* receiver_map = receiver->map(); |
| 1752 int offset = cache->Lookup(receiver_map, key); | 1770 int offset = cache->Lookup(receiver_map, key); |
| (...skipping 1898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3651 return Top::Throw(*reference_error); | 3669 return Top::Throw(*reference_error); |
| 3652 } | 3670 } |
| 3653 | 3671 |
| 3654 | 3672 |
| 3655 static Object* Runtime_StackOverflow(Arguments args) { | 3673 static Object* Runtime_StackOverflow(Arguments args) { |
| 3656 NoHandleAllocation na; | 3674 NoHandleAllocation na; |
| 3657 return Top::StackOverflow(); | 3675 return Top::StackOverflow(); |
| 3658 } | 3676 } |
| 3659 | 3677 |
| 3660 | 3678 |
| 3661 static Object* RuntimePreempt(Arguments args) { | |
| 3662 // Clear the preempt request flag. | |
| 3663 StackGuard::Continue(PREEMPT); | |
| 3664 | |
| 3665 ContextSwitcher::PreemptionReceived(); | |
| 3666 | |
| 3667 { | |
| 3668 v8::Unlocker unlocker; | |
| 3669 Thread::YieldCPU(); | |
| 3670 } | |
| 3671 | |
| 3672 return Heap::undefined_value(); | |
| 3673 } | |
| 3674 | |
| 3675 | |
| 3676 static Object* DebugBreakHelper() { | |
| 3677 // Just continue if breaks are disabled. | |
| 3678 if (Debug::disable_break()) { | |
| 3679 return Heap::undefined_value(); | |
| 3680 } | |
| 3681 | |
| 3682 // Don't break in system functions. If the current function is | |
| 3683 // either in the builtins object of some context or is in the debug | |
| 3684 // context just return with the debug break stack guard active. | |
| 3685 JavaScriptFrameIterator it; | |
| 3686 JavaScriptFrame* frame = it.frame(); | |
| 3687 Object* fun = frame->function(); | |
| 3688 if (fun->IsJSFunction()) { | |
| 3689 GlobalObject* global = JSFunction::cast(fun)->context()->global(); | |
| 3690 if (global->IsJSBuiltinsObject() || Debug::IsDebugGlobal(global)) { | |
| 3691 return Heap::undefined_value(); | |
| 3692 } | |
| 3693 } | |
| 3694 | |
| 3695 // Clear the debug request flag. | |
| 3696 StackGuard::Continue(DEBUGBREAK); | |
| 3697 | |
| 3698 HandleScope scope; | |
| 3699 // Enter the debugger. Just continue if we fail to enter the debugger. | |
| 3700 EnterDebugger debugger; | |
| 3701 if (debugger.FailedToEnter()) { | |
| 3702 return Heap::undefined_value(); | |
| 3703 } | |
| 3704 | |
| 3705 // Notify the debug event listeners. | |
| 3706 Debugger::OnDebugBreak(Factory::undefined_value()); | |
| 3707 | |
| 3708 // Return to continue execution. | |
| 3709 return Heap::undefined_value(); | |
| 3710 } | |
| 3711 | |
| 3712 | |
| 3713 static Object* Runtime_DebugBreak(Arguments args) { | 3679 static Object* Runtime_DebugBreak(Arguments args) { |
| 3714 ASSERT(args.length() == 0); | 3680 ASSERT(args.length() == 0); |
| 3715 return DebugBreakHelper(); | 3681 return Execution::DebugBreakHelper(); |
| 3716 } | 3682 } |
| 3717 | 3683 |
| 3718 | 3684 |
| 3719 static Object* Runtime_StackGuard(Arguments args) { | 3685 static Object* Runtime_StackGuard(Arguments args) { |
| 3720 ASSERT(args.length() == 1); | 3686 ASSERT(args.length() == 1); |
| 3721 | 3687 |
| 3722 // First check if this is a real stack overflow. | 3688 // First check if this is a real stack overflow. |
| 3723 if (StackGuard::IsStackOverflow()) return Runtime_StackOverflow(args); | 3689 if (StackGuard::IsStackOverflow()) return Runtime_StackOverflow(args); |
| 3724 | 3690 |
| 3725 // If not real stack overflow the stack guard was used to interrupt | 3691 return Execution::HandleStackGuardInterrupt(); |
| 3726 // execution for another purpose. | |
| 3727 if (StackGuard::IsDebugBreak()) DebugBreakHelper(); | |
| 3728 if (StackGuard::IsPreempted()) RuntimePreempt(args); | |
| 3729 if (StackGuard::IsInterrupted()) { | |
| 3730 // interrupt | |
| 3731 StackGuard::Continue(INTERRUPT); | |
| 3732 return Top::StackOverflow(); | |
| 3733 } | |
| 3734 return Heap::undefined_value(); | |
| 3735 } | 3692 } |
| 3736 | 3693 |
| 3737 | 3694 |
| 3738 // NOTE: These PrintXXX functions are defined for all builds (not just | 3695 // NOTE: These PrintXXX functions are defined for all builds (not just |
| 3739 // DEBUG builds) because we may want to be able to trace function | 3696 // DEBUG builds) because we may want to be able to trace function |
| 3740 // calls in all modes. | 3697 // calls in all modes. |
| 3741 static void PrintString(String* str) { | 3698 static void PrintString(String* str) { |
| 3742 // not uncommon to have empty strings | 3699 // not uncommon to have empty strings |
| 3743 if (str->length() > 0) { | 3700 if (str->length() > 0) { |
| 3744 SmartPointer<char> s = | 3701 SmartPointer<char> s = |
| (...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4751 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); | 4708 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); |
| 4752 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); | 4709 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); |
| 4753 | 4710 |
| 4754 return obj->GetElementWithInterceptor(*obj, index); | 4711 return obj->GetElementWithInterceptor(*obj, index); |
| 4755 } | 4712 } |
| 4756 | 4713 |
| 4757 | 4714 |
| 4758 static Object* Runtime_CheckExecutionState(Arguments args) { | 4715 static Object* Runtime_CheckExecutionState(Arguments args) { |
| 4759 ASSERT(args.length() >= 1); | 4716 ASSERT(args.length() >= 1); |
| 4760 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 4717 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
| 4761 // Check that the break id is valid and that there is a valid frame | 4718 // Check that the break id is valid. |
| 4762 // where execution is broken. | 4719 if (Top::break_id() == 0 || break_id != Top::break_id()) { |
| 4763 if (break_id != Top::break_id() || | |
| 4764 Top::break_frame_id() == StackFrame::NO_ID) { | |
| 4765 return Top::Throw(Heap::illegal_execution_state_symbol()); | 4720 return Top::Throw(Heap::illegal_execution_state_symbol()); |
| 4766 } | 4721 } |
| 4767 | 4722 |
| 4768 return Heap::true_value(); | 4723 return Heap::true_value(); |
| 4769 } | 4724 } |
| 4770 | 4725 |
| 4771 | 4726 |
| 4772 static Object* Runtime_GetFrameCount(Arguments args) { | 4727 static Object* Runtime_GetFrameCount(Arguments args) { |
| 4773 HandleScope scope; | 4728 HandleScope scope; |
| 4774 ASSERT(args.length() == 1); | 4729 ASSERT(args.length() == 1); |
| 4775 | 4730 |
| 4776 // Check arguments. | 4731 // Check arguments. |
| 4777 Object* result = Runtime_CheckExecutionState(args); | 4732 Object* result = Runtime_CheckExecutionState(args); |
| 4778 if (result->IsFailure()) return result; | 4733 if (result->IsFailure()) return result; |
| 4779 | 4734 |
| 4780 // Count all frames which are relevant to debugging stack trace. | 4735 // Count all frames which are relevant to debugging stack trace. |
| 4781 int n = 0; | 4736 int n = 0; |
| 4782 StackFrame::Id id = Top::break_frame_id(); | 4737 StackFrame::Id id = Top::break_frame_id(); |
| 4738 if (id == StackFrame::NO_ID) { |
| 4739 // If there is no JavaScript stack frame count is 0. |
| 4740 return Smi::FromInt(0); |
| 4741 } |
| 4783 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; | 4742 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; |
| 4784 return Smi::FromInt(n); | 4743 return Smi::FromInt(n); |
| 4785 } | 4744 } |
| 4786 | 4745 |
| 4787 | 4746 |
| 4788 static const int kFrameDetailsFrameIdIndex = 0; | 4747 static const int kFrameDetailsFrameIdIndex = 0; |
| 4789 static const int kFrameDetailsReceiverIndex = 1; | 4748 static const int kFrameDetailsReceiverIndex = 1; |
| 4790 static const int kFrameDetailsFunctionIndex = 2; | 4749 static const int kFrameDetailsFunctionIndex = 2; |
| 4791 static const int kFrameDetailsArgumentCountIndex = 3; | 4750 static const int kFrameDetailsArgumentCountIndex = 3; |
| 4792 static const int kFrameDetailsLocalCountIndex = 4; | 4751 static const int kFrameDetailsLocalCountIndex = 4; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4814 HandleScope scope; | 4773 HandleScope scope; |
| 4815 ASSERT(args.length() == 2); | 4774 ASSERT(args.length() == 2); |
| 4816 | 4775 |
| 4817 // Check arguments. | 4776 // Check arguments. |
| 4818 Object* check = Runtime_CheckExecutionState(args); | 4777 Object* check = Runtime_CheckExecutionState(args); |
| 4819 if (check->IsFailure()) return check; | 4778 if (check->IsFailure()) return check; |
| 4820 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 4779 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 4821 | 4780 |
| 4822 // Find the relevant frame with the requested index. | 4781 // Find the relevant frame with the requested index. |
| 4823 StackFrame::Id id = Top::break_frame_id(); | 4782 StackFrame::Id id = Top::break_frame_id(); |
| 4783 if (id == StackFrame::NO_ID) { |
| 4784 // If there are no JavaScript stack frames return undefined. |
| 4785 return Heap::undefined_value(); |
| 4786 } |
| 4824 int count = 0; | 4787 int count = 0; |
| 4825 JavaScriptFrameIterator it(id); | 4788 JavaScriptFrameIterator it(id); |
| 4826 for (; !it.done(); it.Advance()) { | 4789 for (; !it.done(); it.Advance()) { |
| 4827 if (count == index) break; | 4790 if (count == index) break; |
| 4828 count++; | 4791 count++; |
| 4829 } | 4792 } |
| 4830 if (it.done()) return Heap::undefined_value(); | 4793 if (it.done()) return Heap::undefined_value(); |
| 4831 | 4794 |
| 4832 // Traverse the saved contexts chain to find the active context for the | 4795 // Traverse the saved contexts chain to find the active context for the |
| 4833 // selected frame. | 4796 // selected frame. |
| (...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5908 } else { | 5871 } else { |
| 5909 // Handle last resort GC and make sure to allow future allocations | 5872 // Handle last resort GC and make sure to allow future allocations |
| 5910 // to grow the heap without causing GCs (if possible). | 5873 // to grow the heap without causing GCs (if possible). |
| 5911 Counters::gc_last_resort_from_js.Increment(); | 5874 Counters::gc_last_resort_from_js.Increment(); |
| 5912 Heap::CollectAllGarbage(); | 5875 Heap::CollectAllGarbage(); |
| 5913 } | 5876 } |
| 5914 } | 5877 } |
| 5915 | 5878 |
| 5916 | 5879 |
| 5917 } } // namespace v8::internal | 5880 } } // namespace v8::internal |
| OLD | NEW |