| 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 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 // Support function for computing call IC miss stubs. | 649 // Support function for computing call IC miss stubs. |
| 650 Handle<Code> ComputeCallMiss(int argc) { | 650 Handle<Code> ComputeCallMiss(int argc) { |
| 651 CALL_HEAP_FUNCTION(StubCache::ComputeCallMiss(argc), Code); | 651 CALL_HEAP_FUNCTION(StubCache::ComputeCallMiss(argc), Code); |
| 652 } | 652 } |
| 653 | 653 |
| 654 | 654 |
| 655 | 655 |
| 656 Object* LoadCallbackProperty(Arguments args) { | 656 Object* LoadCallbackProperty(Arguments args) { |
| 657 Handle<JSObject> recv = args.at<JSObject>(0); | 657 Handle<JSObject> recv = args.at<JSObject>(0); |
| 658 AccessorInfo* callback = AccessorInfo::cast(args[1]); | 658 AccessorInfo* callback = AccessorInfo::cast(args[1]); |
| 659 v8::AccessorGetter fun = | 659 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 660 FUNCTION_CAST<v8::AccessorGetter>( | 660 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); |
| 661 v8::ToCData<Address>(callback->getter())); | |
| 662 ASSERT(fun != NULL); | 661 ASSERT(fun != NULL); |
| 663 Handle<String> name = args.at<String>(2); | 662 Handle<String> name = args.at<String>(2); |
| 664 Handle<JSObject> holder = args.at<JSObject>(3); | 663 Handle<JSObject> holder = args.at<JSObject>(3); |
| 665 HandleScope scope; | 664 HandleScope scope; |
| 666 Handle<Object> data(callback->data()); | 665 Handle<Object> data(callback->data()); |
| 667 LOG(ApiNamedPropertyAccess("load", *recv, *name)); | 666 LOG(ApiNamedPropertyAccess("load", *recv, *name)); |
| 668 // NOTE: If we can align the structure of an AccessorInfo with the | 667 // NOTE: If we can align the structure of an AccessorInfo with the |
| 669 // locations of the arguments to this function maybe we don't have | 668 // locations of the arguments to this function maybe we don't have |
| 670 // to explicitly create the structure but can just pass a pointer | 669 // to explicitly create the structure but can just pass a pointer |
| 671 // into the stack. | 670 // into the stack. |
| 672 v8::AccessorInfo info( | 671 v8::AccessorInfo info(v8::Utils::ToLocal(recv), |
| 673 v8::Utils::ToLocal(recv), | 672 v8::Utils::ToLocal(data), |
| 674 v8::Utils::ToLocal(data), | 673 v8::Utils::ToLocal(holder)); |
| 675 v8::Utils::ToLocal(holder)); | |
| 676 v8::Handle<v8::Value> result; | 674 v8::Handle<v8::Value> result; |
| 677 { | 675 { |
| 678 // Leaving JavaScript. | 676 // Leaving JavaScript. |
| 679 VMState state(OTHER); | 677 VMState state(OTHER); |
| 680 result = fun(v8::Utils::ToLocal(name), info); | 678 result = fun(v8::Utils::ToLocal(name), info); |
| 681 } | 679 } |
| 682 RETURN_IF_SCHEDULED_EXCEPTION(); | 680 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 683 if (result.IsEmpty()) { | 681 if (result.IsEmpty()) return Heap::undefined_value(); |
| 684 return Heap::undefined_value(); | 682 return *v8::Utils::OpenHandle(*result); |
| 685 } else { | |
| 686 return *v8::Utils::OpenHandle(*result); | |
| 687 } | |
| 688 } | 683 } |
| 689 | 684 |
| 690 | 685 |
| 691 Object* StoreCallbackProperty(Arguments args) { | 686 Object* StoreCallbackProperty(Arguments args) { |
| 692 Handle<JSObject> recv = args.at<JSObject>(0); | 687 Handle<JSObject> recv = args.at<JSObject>(0); |
| 693 AccessorInfo* callback = AccessorInfo::cast(args[1]); | 688 AccessorInfo* callback = AccessorInfo::cast(args[1]); |
| 694 v8::AccessorSetter fun = | 689 Address setter_address = v8::ToCData<Address>(callback->setter()); |
| 695 FUNCTION_CAST<v8::AccessorSetter>( | 690 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); |
| 696 v8::ToCData<Address>(callback->setter())); | |
| 697 ASSERT(fun != NULL); | 691 ASSERT(fun != NULL); |
| 698 Handle<String> name = args.at<String>(2); | 692 Handle<String> name = args.at<String>(2); |
| 699 Handle<Object> value = args.at<Object>(3); | 693 Handle<Object> value = args.at<Object>(3); |
| 700 HandleScope scope; | 694 HandleScope scope; |
| 701 Handle<Object> data(callback->data()); | 695 Handle<Object> data(callback->data()); |
| 702 LOG(ApiNamedPropertyAccess("store", *recv, *name)); | 696 LOG(ApiNamedPropertyAccess("store", *recv, *name)); |
| 703 v8::AccessorInfo info( | 697 v8::AccessorInfo info(v8::Utils::ToLocal(recv), |
| 704 v8::Utils::ToLocal(recv), | 698 v8::Utils::ToLocal(data), |
| 705 v8::Utils::ToLocal(data), | 699 v8::Utils::ToLocal(recv)); |
| 706 v8::Utils::ToLocal(recv)); | |
| 707 { | 700 { |
| 708 // Leaving JavaScript. | 701 // Leaving JavaScript. |
| 709 VMState state(OTHER); | 702 VMState state(OTHER); |
| 710 fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); | 703 fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); |
| 711 } | 704 } |
| 712 RETURN_IF_SCHEDULED_EXCEPTION(); | 705 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 713 return *value; | 706 return *value; |
| 714 } | 707 } |
| 715 | 708 |
| 716 | 709 |
| 717 Object* LoadInterceptorProperty(Arguments args) { | 710 Object* LoadInterceptorProperty(Arguments args) { |
| 718 HandleScope scope; | 711 JSObject* recv = JSObject::cast(args[0]); |
| 719 Handle<JSObject> recv = args.at<JSObject>(0); | 712 JSObject* holder = JSObject::cast(args[1]); |
| 720 Handle<JSObject> holder = args.at<JSObject>(1); | 713 String* name = String::cast(args[2]); |
| 721 Handle<String> name = args.at<String>(2); | |
| 722 ASSERT(holder->HasNamedInterceptor()); | 714 ASSERT(holder->HasNamedInterceptor()); |
| 723 PropertyAttributes attr = NONE; | 715 PropertyAttributes attr = NONE; |
| 724 Handle<Object> result = GetPropertyWithInterceptor(recv, holder, name, &attr); | 716 Object* result = holder->GetPropertyWithInterceptor(recv, name, &attr); |
| 725 | 717 |
| 726 // GetPropertyWithInterceptor already converts a scheduled exception | 718 if (result->IsFailure()) return result; |
| 727 // to a pending one if any. Don't use RETURN_IF_SCHEDULED_EXCEPTION() here. | |
| 728 | |
| 729 // Make sure to propagate exceptions. | |
| 730 if (result.is_null()) { | |
| 731 // Failure::Exception is converted to a null handle in the | |
| 732 // handle-based methods such as SetProperty. We therefore need | |
| 733 // to convert null handles back to exceptions. | |
| 734 ASSERT(Top::has_pending_exception()); | |
| 735 return Failure::Exception(); | |
| 736 } | |
| 737 | 719 |
| 738 // If the property is present, return it. | 720 // If the property is present, return it. |
| 739 if (attr != ABSENT) return *result; | 721 if (attr != ABSENT) return result; |
| 740 | 722 |
| 741 // If the top frame is an internal frame, this is really a call | 723 // If the top frame is an internal frame, this is really a call |
| 742 // IC. In this case, we simply return the undefined result which | 724 // IC. In this case, we simply return the undefined result which |
| 743 // will lead to an exception when trying to invoke the result as a | 725 // will lead to an exception when trying to invoke the result as a |
| 744 // function. | 726 // function. |
| 745 StackFrameIterator it; | 727 StackFrameIterator it; |
| 746 it.Advance(); // skip exit frame | 728 it.Advance(); // skip exit frame |
| 747 if (it.frame()->is_internal()) return *result; | 729 if (it.frame()->is_internal()) return result; |
| 748 | 730 |
| 749 // If the load is non-contextual, just return the undefined result. | 731 // If the load is non-contextual, just return the undefined result. |
| 750 // Note that both keyed and non-keyed loads may end up here, so we | 732 // Note that both keyed and non-keyed loads may end up here, so we |
| 751 // can't use either LoadIC or KeyedLoadIC constructors. | 733 // can't use either LoadIC or KeyedLoadIC constructors. |
| 752 IC ic(IC::NO_EXTRA_FRAME); | 734 IC ic(IC::NO_EXTRA_FRAME); |
| 753 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); | 735 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); |
| 754 if (!ic.is_contextual()) return *result; | 736 if (!ic.is_contextual()) return result; |
| 755 | 737 |
| 756 // Throw a reference error. | 738 // Throw a reference error. |
| 757 Handle<Object> error = | 739 { |
| 758 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 740 HandleScope scope; |
| 759 return Top::Throw(*error); | 741 // We cannot use the raw name pointer here since getting the |
| 742 // property might cause a GC. However, we can get the name from |
| 743 // the stack using the arguments object. |
| 744 Handle<String> name_handle = args.at<String>(2); |
| 745 Handle<Object> error = |
| 746 Factory::NewReferenceError("not_defined", |
| 747 HandleVector(&name_handle, 1)); |
| 748 return Top::Throw(*error); |
| 749 } |
| 760 } | 750 } |
| 761 | 751 |
| 762 | 752 |
| 763 Object* StoreInterceptorProperty(Arguments args) { | 753 Object* StoreInterceptorProperty(Arguments args) { |
| 764 HandleScope scope; | 754 JSObject* recv = JSObject::cast(args[0]); |
| 765 Handle<JSObject> recv = args.at<JSObject>(0); | 755 String* name = String::cast(args[1]); |
| 766 Handle<String> name = args.at<String>(1); | 756 Object* value = args[2]; |
| 767 Handle<Object> value = args.at<Object>(2); | |
| 768 ASSERT(recv->HasNamedInterceptor()); | 757 ASSERT(recv->HasNamedInterceptor()); |
| 769 PropertyAttributes attr = NONE; | 758 PropertyAttributes attr = NONE; |
| 770 Handle<Object> result = SetPropertyWithInterceptor(recv, name, value, attr); | 759 Object* result = recv->SetPropertyWithInterceptor(name, value, attr); |
| 771 | 760 return result; |
| 772 // SetPropertyWithInterceptor already converts a scheduled exception | |
| 773 // to a pending one if any. Don't use RETURN_IF_SCHEDULED_EXCEPTION() here. | |
| 774 | |
| 775 // Make sure to propagate exceptions. | |
| 776 if (result.is_null()) { | |
| 777 // Failure::Exception is converted to a null handle in the | |
| 778 // handle-based methods such as SetProperty. We therefore need | |
| 779 // to convert null handles back to exceptions. | |
| 780 ASSERT(Top::has_pending_exception()); | |
| 781 return Failure::Exception(); | |
| 782 } | |
| 783 return *result; | |
| 784 } | 761 } |
| 785 | 762 |
| 786 | 763 |
| 787 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { | 764 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { |
| 788 HandleScope scope; | 765 HandleScope scope; |
| 789 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 766 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 790 CallIC::GenerateInitialize(masm(), argc); | 767 CallIC::GenerateInitialize(masm(), argc); |
| 791 Object* result = GetCodeWithFlags(flags, "CompileCallInitialize"); | 768 Object* result = GetCodeWithFlags(flags, "CompileCallInitialize"); |
| 792 if (!result->IsFailure()) { | 769 if (!result->IsFailure()) { |
| 793 Counters::call_initialize_stubs.Increment(); | 770 Counters::call_initialize_stubs.Increment(); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 | 912 |
| 936 | 913 |
| 937 Object* CallStubCompiler::GetCode(PropertyType type, String* name) { | 914 Object* CallStubCompiler::GetCode(PropertyType type, String* name) { |
| 938 int argc = arguments_.immediate(); | 915 int argc = arguments_.immediate(); |
| 939 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, type, argc); | 916 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, type, argc); |
| 940 return GetCodeWithFlags(flags, name); | 917 return GetCodeWithFlags(flags, name); |
| 941 } | 918 } |
| 942 | 919 |
| 943 | 920 |
| 944 } } // namespace v8::internal | 921 } } // namespace v8::internal |
| OLD | NEW |