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 |