OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * Copyright (C) 2012 Ericsson AB. All rights reserved. | 3 * Copyright (C) 2012 Ericsson AB. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 16 matching lines...) Expand all Loading... | |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #ifndef V8Binding_h | 32 #ifndef V8Binding_h |
33 #define V8Binding_h | 33 #define V8Binding_h |
34 | 34 |
35 #include "bindings/core/v8/DOMWrapperWorld.h" | 35 #include "bindings/core/v8/DOMWrapperWorld.h" |
36 #include "bindings/core/v8/ExceptionMessages.h" | 36 #include "bindings/core/v8/ExceptionMessages.h" |
37 #include "bindings/core/v8/ExceptionState.h" | |
37 #include "bindings/core/v8/ScriptValue.h" | 38 #include "bindings/core/v8/ScriptValue.h" |
38 #include "bindings/core/v8/ScriptWrappable.h" | 39 #include "bindings/core/v8/ScriptWrappable.h" |
39 #include "bindings/core/v8/V8BindingMacros.h" | 40 #include "bindings/core/v8/V8BindingMacros.h" |
40 #include "bindings/core/v8/V8PerIsolateData.h" | 41 #include "bindings/core/v8/V8PerIsolateData.h" |
41 #include "bindings/core/v8/V8StringResource.h" | 42 #include "bindings/core/v8/V8StringResource.h" |
42 #include "bindings/core/v8/V8ThrowException.h" | 43 #include "bindings/core/v8/V8ThrowException.h" |
43 #include "bindings/core/v8/V8ValueCache.h" | 44 #include "bindings/core/v8/V8ValueCache.h" |
44 #include "platform/heap/Heap.h" | 45 #include "platform/heap/Heap.h" |
45 #include "wtf/GetPtr.h" | 46 #include "wtf/GetPtr.h" |
46 #include "wtf/MathExtras.h" | 47 #include "wtf/MathExtras.h" |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 } | 566 } |
566 | 567 |
567 // FIXME: Remove the special casing for NodeFilter and XPathNSResolver. | 568 // FIXME: Remove the special casing for NodeFilter and XPathNSResolver. |
568 PassRefPtrWillBeRawPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Handl e<v8::Object>, ScriptState*); | 569 PassRefPtrWillBeRawPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Handl e<v8::Object>, ScriptState*); |
569 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*); | 570 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*); |
570 | 571 |
571 template<class T> struct NativeValueTraits; | 572 template<class T> struct NativeValueTraits; |
572 | 573 |
573 template<> | 574 template<> |
574 struct NativeValueTraits<String> { | 575 struct NativeValueTraits<String> { |
575 static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Iso late* isolate) | 576 static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Iso late* isolate, ExceptionState& exceptionState) |
576 { | 577 { |
577 TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, String()); | 578 V8StringResource<> stringValue(value); |
579 if (!stringValue.prepare(exceptionState)) | |
580 return String(); | |
578 return stringValue; | 581 return stringValue; |
579 } | 582 } |
580 }; | 583 }; |
581 | 584 |
582 template<> | 585 template<> |
583 struct NativeValueTraits<unsigned> { | 586 struct NativeValueTraits<unsigned> { |
584 static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::I solate* isolate) | 587 static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::I solate* isolate, ExceptionState& exceptionState) |
585 { | 588 { |
586 return toUInt32(value); | 589 return toUInt32(value, exceptionState); |
587 } | 590 } |
588 }; | 591 }; |
589 | 592 |
590 template<> | 593 template<> |
591 struct NativeValueTraits<float> { | 594 struct NativeValueTraits<float> { |
592 static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isol ate* isolate) | 595 static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isol ate* isolate, ExceptionState& exceptionState) |
593 { | 596 { |
594 return static_cast<float>(value->NumberValue()); | 597 return toFloat(value, exceptionState); |
595 } | 598 } |
596 }; | 599 }; |
597 | 600 |
598 template<> | 601 template<> |
599 struct NativeValueTraits<double> { | 602 struct NativeValueTraits<double> { |
600 static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Iso late* isolate) | 603 static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Iso late* isolate, ExceptionState& exceptionState) |
601 { | 604 { |
602 return static_cast<double>(value->NumberValue()); | 605 return toDouble(value, exceptionState); |
603 } | 606 } |
604 }; | 607 }; |
605 | 608 |
606 template<> | 609 template<> |
607 struct NativeValueTraits<v8::Handle<v8::Value> > { | 610 struct NativeValueTraits<v8::Handle<v8::Value> > { |
608 static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) | 611 static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState&) |
609 { | 612 { |
610 return value; | 613 return value; |
611 } | 614 } |
612 }; | 615 }; |
613 | 616 |
614 template<> | 617 template<> |
615 struct NativeValueTraits<ScriptValue> { | 618 struct NativeValueTraits<ScriptValue> { |
616 static inline ScriptValue nativeValue(const v8::Handle<v8::Value>& value, v8 ::Isolate* isolate) | 619 static inline ScriptValue nativeValue(const v8::Handle<v8::Value>& value, v8 ::Isolate* isolate, ExceptionState&) |
617 { | 620 { |
618 return ScriptValue(ScriptState::current(isolate), value); | 621 return ScriptValue(ScriptState::current(isolate), value); |
619 } | 622 } |
620 }; | 623 }; |
621 | 624 |
622 v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8:: Isolate*); | 625 bool toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*, Excepti onState&); |
Jens Widell
2014/09/12 11:34:36
Extended patch to cover toV8Sequence() too.
Its e
| |
623 | 626 |
624 // Converts a JavaScript value to an array as per the Web IDL specification: | 627 // Converts a JavaScript value to an array as per the Web IDL specification: |
625 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array | 628 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array |
626 template <class T, class V8T> | 629 template <class T, class V8T> |
627 Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, ui nt32_t length, v8::Isolate* isolate, bool* success = 0) | 630 Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, ui nt32_t length, v8::Isolate* isolate, ExceptionState& exceptionState) |
628 { | 631 { |
629 Vector<RefPtr<T> > result; | 632 Vector<RefPtr<T> > result; |
630 result.reserveInitialCapacity(length); | 633 result.reserveInitialCapacity(length); |
631 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); | 634 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
635 v8::TryCatch block; | |
632 for (uint32_t i = 0; i < length; ++i) { | 636 for (uint32_t i = 0; i < length; ++i) { |
633 v8::Handle<v8::Value> element = object->Get(i); | 637 v8::Handle<v8::Value> element = object->Get(i); |
638 if (block.HasCaught()) { | |
639 exceptionState.rethrowV8Exception(block.Exception()); | |
640 return Vector<RefPtr<T> >(); | |
641 } | |
634 if (V8T::hasInstance(element, isolate)) { | 642 if (V8T::hasInstance(element, isolate)) { |
635 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); | 643 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); |
636 result.uncheckedAppend(V8T::toImpl(elementObject)); | 644 result.uncheckedAppend(V8T::toImpl(elementObject)); |
637 } else { | 645 } else { |
638 if (success) | 646 exceptionState.throwTypeError("Invalid Array element type"); |
639 *success = false; | |
640 V8ThrowException::throwTypeError("Invalid Array element type", isola te); | |
641 return Vector<RefPtr<T> >(); | 647 return Vector<RefPtr<T> >(); |
642 } | 648 } |
643 } | 649 } |
644 return result; | 650 return result; |
645 } | 651 } |
646 | 652 |
647 template <class T, class V8T> | 653 template <class T, class V8T> |
648 Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argument Index, v8::Isolate* isolate, bool* success = 0) | 654 Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argument Index, v8::Isolate* isolate, ExceptionState& exceptionState) |
649 { | 655 { |
650 if (success) | |
651 *success = true; | |
652 | |
653 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); | 656 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
654 uint32_t length = 0; | 657 uint32_t length = 0; |
655 if (value->IsArray()) { | 658 if (value->IsArray()) { |
656 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); | 659 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
657 } else if (toV8Sequence(value, length, isolate).IsEmpty()) { | 660 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
658 V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgume ntOrValue(argumentIndex), isolate); | 661 if (!exceptionState.hadException()) |
662 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum entOrValue(argumentIndex)); | |
659 return Vector<RefPtr<T> >(); | 663 return Vector<RefPtr<T> >(); |
660 } | 664 } |
661 return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, succes s); | 665 return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, except ionState); |
662 } | 666 } |
663 | 667 |
664 template <class T, class V8T> | 668 template <class T, class V8T> |
665 Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String & propertyName, v8::Isolate* isolate, bool* success = 0) | 669 Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String & propertyName, v8::Isolate* isolate, ExceptionState& exceptionState) |
666 { | 670 { |
667 if (success) | |
668 *success = true; | |
669 | |
670 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); | 671 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
671 uint32_t length = 0; | 672 uint32_t length = 0; |
672 if (value->IsArray()) { | 673 if (value->IsArray()) { |
673 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); | 674 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
674 } else if (toV8Sequence(value, length, isolate).IsEmpty()) { | 675 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
675 V8ThrowException::throwTypeError(ExceptionMessages::notASequenceTypeProp erty(propertyName), isolate); | 676 if (!exceptionState.hadException()) |
677 exceptionState.throwTypeError(ExceptionMessages::notASequenceTypePro perty(propertyName)); | |
676 return Vector<RefPtr<T> >(); | 678 return Vector<RefPtr<T> >(); |
677 } | 679 } |
678 return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, succes s); | 680 return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, except ionState); |
679 } | 681 } |
680 | 682 |
681 template <class T, class V8T> | 683 template <class T, class V8T> |
682 WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Han dle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0 ) | 684 WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Han dle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, ExceptionState& e xceptionState) |
683 { | 685 { |
684 if (success) | |
685 *success = true; | |
686 | |
687 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); | 686 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
688 uint32_t length = 0; | 687 uint32_t length = 0; |
689 if (value->IsArray()) { | 688 if (value->IsArray()) { |
690 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); | 689 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
691 } else if (toV8Sequence(value, length, isolate).IsEmpty()) { | 690 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
692 V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgume ntOrValue(argumentIndex), isolate); | 691 if (!exceptionState.hadException()) |
692 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum entOrValue(argumentIndex)); | |
693 return WillBeHeapVector<RefPtrWillBeMember<T> >(); | 693 return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
694 } | 694 } |
695 | 695 |
696 WillBeHeapVector<RefPtrWillBeMember<T> > result; | 696 WillBeHeapVector<RefPtrWillBeMember<T> > result; |
697 result.reserveInitialCapacity(length); | 697 result.reserveInitialCapacity(length); |
698 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); | 698 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
699 v8::TryCatch block; | |
699 for (uint32_t i = 0; i < length; ++i) { | 700 for (uint32_t i = 0; i < length; ++i) { |
700 v8::Handle<v8::Value> element = object->Get(i); | 701 v8::Handle<v8::Value> element = object->Get(i); |
702 if (block.HasCaught()) { | |
703 exceptionState.rethrowV8Exception(block.Exception()); | |
704 return WillBeHeapVector<RefPtrWillBeMember<T> >(); | |
705 } | |
701 if (V8T::hasInstance(element, isolate)) { | 706 if (V8T::hasInstance(element, isolate)) { |
702 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); | 707 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); |
703 result.uncheckedAppend(V8T::toImpl(elementObject)); | 708 result.uncheckedAppend(V8T::toImpl(elementObject)); |
704 } else { | 709 } else { |
705 if (success) | 710 exceptionState.throwTypeError("Invalid Array element type"); |
706 *success = false; | |
707 V8ThrowException::throwTypeError("Invalid Array element type", isola te); | |
708 return WillBeHeapVector<RefPtrWillBeMember<T> >(); | 711 return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
709 } | 712 } |
710 } | 713 } |
711 return result; | 714 return result; |
712 } | 715 } |
713 | 716 |
714 template <class T, class V8T> | 717 template <class T, class V8T> |
715 WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Han dle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* su ccess = 0) | 718 WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Han dle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, Exceptio nState& exceptionState) |
716 { | 719 { |
717 if (success) | |
718 *success = true; | |
719 | |
720 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); | 720 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
721 uint32_t length = 0; | 721 uint32_t length = 0; |
722 if (value->IsArray()) { | 722 if (value->IsArray()) { |
723 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); | 723 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
724 } else if (toV8Sequence(value, length, isolate).IsEmpty()) { | 724 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
725 V8ThrowException::throwTypeError(ExceptionMessages::notASequenceTypeProp erty(propertyName), isolate); | 725 if (!exceptionState.hadException()) |
726 exceptionState.throwTypeError(ExceptionMessages::notASequenceTypePro perty(propertyName)); | |
726 return WillBeHeapVector<RefPtrWillBeMember<T> >(); | 727 return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
727 } | 728 } |
728 | 729 |
729 WillBeHeapVector<RefPtrWillBeMember<T> > result; | 730 WillBeHeapVector<RefPtrWillBeMember<T> > result; |
730 result.reserveInitialCapacity(length); | 731 result.reserveInitialCapacity(length); |
731 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); | 732 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
733 v8::TryCatch block; | |
732 for (uint32_t i = 0; i < length; ++i) { | 734 for (uint32_t i = 0; i < length; ++i) { |
733 v8::Handle<v8::Value> element = object->Get(i); | 735 v8::Handle<v8::Value> element = object->Get(i); |
736 if (block.HasCaught()) { | |
737 exceptionState.rethrowV8Exception(block.Exception()); | |
738 return Vector<RefPtr<T> >(); | |
739 } | |
734 if (V8T::hasInstance(element, isolate)) { | 740 if (V8T::hasInstance(element, isolate)) { |
735 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); | 741 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); |
736 result.uncheckedAppend(V8T::toImpl(elementObject)); | 742 result.uncheckedAppend(V8T::toImpl(elementObject)); |
737 } else { | 743 } else { |
738 if (success) | 744 exceptionState.throwTypeError("Invalid Array element type"); |
739 *success = false; | |
740 V8ThrowException::throwTypeError("Invalid Array element type", isola te); | |
741 return WillBeHeapVector<RefPtrWillBeMember<T> >(); | 745 return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
742 } | 746 } |
743 } | 747 } |
744 return result; | 748 return result; |
745 } | 749 } |
746 | 750 |
747 template <class T, class V8T> | 751 template <class T, class V8T> |
748 HeapVector<Member<T> > toMemberNativeArray(v8::Handle<v8::Value> value, int argu mentIndex, v8::Isolate* isolate, bool* success = 0) | 752 HeapVector<Member<T> > toMemberNativeArray(v8::Handle<v8::Value> value, int argu mentIndex, v8::Isolate* isolate, ExceptionState& exceptionState) |
749 { | 753 { |
750 if (success) | |
751 *success = true; | |
752 | |
753 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); | 754 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
754 uint32_t length = 0; | 755 uint32_t length = 0; |
755 if (value->IsArray()) { | 756 if (value->IsArray()) { |
756 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); | 757 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
757 } else if (toV8Sequence(value, length, isolate).IsEmpty()) { | 758 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
758 V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgume ntOrValue(argumentIndex), isolate); | 759 if (!exceptionState.hadException()) |
760 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum entOrValue(argumentIndex)); | |
759 return HeapVector<Member<T> >(); | 761 return HeapVector<Member<T> >(); |
760 } | 762 } |
761 | 763 |
762 HeapVector<Member<T> > result; | 764 HeapVector<Member<T> > result; |
763 result.reserveInitialCapacity(length); | 765 result.reserveInitialCapacity(length); |
764 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); | 766 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
767 v8::TryCatch block; | |
765 for (uint32_t i = 0; i < length; ++i) { | 768 for (uint32_t i = 0; i < length; ++i) { |
766 v8::Handle<v8::Value> element = object->Get(i); | 769 v8::Handle<v8::Value> element = object->Get(i); |
770 if (UNLIKELY(block.HasCaught())) { | |
771 exceptionState.rethrowV8Exception(block.Exception()); | |
772 return HeapVector<Member<T> >(); | |
773 } | |
767 if (V8T::hasInstance(element, isolate)) { | 774 if (V8T::hasInstance(element, isolate)) { |
768 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); | 775 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast( element); |
769 result.uncheckedAppend(V8T::toImpl(elementObject)); | 776 result.uncheckedAppend(V8T::toImpl(elementObject)); |
770 } else { | 777 } else { |
771 if (success) | 778 exceptionState.throwTypeError("Invalid Array element type"); |
772 *success = false; | |
773 V8ThrowException::throwTypeError("Invalid Array element type", isola te); | |
774 return HeapVector<Member<T> >(); | 779 return HeapVector<Member<T> >(); |
775 } | 780 } |
776 } | 781 } |
777 return result; | 782 return result; |
778 } | 783 } |
779 | 784 |
780 // Converts a JavaScript value to an array as per the Web IDL specification: | 785 // Converts a JavaScript value to an array as per the Web IDL specification: |
781 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array | 786 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array |
782 template <class T> | 787 template <class T> |
783 Vector<T> toImplArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolat e* isolate) | 788 Vector<T> toImplArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolat e* isolate, ExceptionState& exceptionState) |
784 { | 789 { |
785 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); | 790 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
786 uint32_t length = 0; | 791 uint32_t length = 0; |
787 if (value->IsArray()) { | 792 if (value->IsArray()) { |
788 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); | 793 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
789 } else if (toV8Sequence(value, length, isolate).IsEmpty()) { | 794 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
790 V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgume ntOrValue(argumentIndex), isolate); | 795 if (!exceptionState.hadException()) |
796 exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgum entOrValue(argumentIndex)); | |
791 return Vector<T>(); | 797 return Vector<T>(); |
792 } | 798 } |
793 | 799 |
794 Vector<T> result; | 800 Vector<T> result; |
795 result.reserveInitialCapacity(length); | 801 result.reserveInitialCapacity(length); |
796 typedef NativeValueTraits<T> TraitsType; | 802 typedef NativeValueTraits<T> TraitsType; |
797 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); | 803 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
798 for (uint32_t i = 0; i < length; ++i) | 804 v8::TryCatch block; |
799 result.uncheckedAppend(TraitsType::nativeValue(object->Get(i), isolate)) ; | 805 for (uint32_t i = 0; i < length; ++i) { |
806 v8::Handle<v8::Value> element = object->Get(i); | |
807 if (UNLIKELY(block.HasCaught())) { | |
808 exceptionState.rethrowV8Exception(block.Exception()); | |
809 return Vector<T>(); | |
810 } | |
811 result.uncheckedAppend(TraitsType::nativeValue(element, isolate, excepti onState)); | |
812 if (exceptionState.hadException()) | |
813 return Vector<T>(); | |
814 } | |
800 return result; | 815 return result; |
801 } | 816 } |
802 | 817 |
803 template <class T> | 818 template <class T> |
804 Vector<T> toImplArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int s tartIndex) | 819 Vector<T> toImplArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int s tartIndex, ExceptionState& exceptionState) |
805 { | 820 { |
806 ASSERT(startIndex <= info.Length()); | 821 ASSERT(startIndex <= info.Length()); |
807 Vector<T> result; | 822 Vector<T> result; |
808 typedef NativeValueTraits<T> TraitsType; | 823 typedef NativeValueTraits<T> TraitsType; |
809 int length = info.Length(); | 824 int length = info.Length(); |
810 result.reserveInitialCapacity(length); | 825 result.reserveInitialCapacity(length); |
811 for (int i = startIndex; i < length; ++i) | 826 for (int i = startIndex; i < length; ++i) { |
812 result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate( ))); | 827 result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate( ), exceptionState)); |
828 if (exceptionState.hadException()) | |
829 return Vector<T>(); | |
830 } | |
813 return result; | 831 return result; |
814 } | 832 } |
815 | 833 |
816 // Validates that the passed object is a sequence type per WebIDL spec | 834 // Validates that the passed object is a sequence type per WebIDL spec |
817 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence | 835 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence |
818 inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate) | 836 bool toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* is olate, ExceptionState& exceptionState) |
819 { | 837 { |
820 // Attempt converting to a sequence if the value is not already an array but is | 838 // Attempt converting to a sequence if the value is not already an array but is |
821 // any kind of object except for a native Date object or a native RegExp obj ect. | 839 // any kind of object except for a native Date object or a native RegExp obj ect. |
822 ASSERT(!value->IsArray()); | 840 ASSERT(!value->IsArray()); |
823 // FIXME: Do we really need to special case Date and RegExp object? | 841 // FIXME: Do we really need to special case Date and RegExp object? |
824 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806 | 842 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806 |
825 if (!value->IsObject() || value->IsDate() || value->IsRegExp()) { | 843 if (!value->IsObject() || value->IsDate() || value->IsRegExp()) { |
826 // The caller is responsible for reporting a TypeError. | 844 // The caller is responsible for reporting a TypeError. |
827 return v8Undefined(); | 845 return false; |
828 } | 846 } |
829 | 847 |
830 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); | 848 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
831 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); | 849 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
832 v8::Local<v8::String> lengthSymbol = v8AtomicString(isolate, "length"); | 850 v8::Local<v8::String> lengthSymbol = v8AtomicString(isolate, "length"); |
833 | 851 |
834 // FIXME: The specification states that the length property should be used a s fallback, if value | 852 // FIXME: The specification states that the length property should be used a s fallback, if value |
835 // is not a platform object that supports indexed properties. If it supports indexed properties, | 853 // is not a platform object that supports indexed properties. If it supports indexed properties, |
836 // length should actually be one greater than value’s maximum indexed proper ty index. | 854 // length should actually be one greater than value’s maximum indexed proper ty index. |
837 TONATIVE_EXCEPTION(v8::Local<v8::Value>, lengthValue, object->Get(lengthSymb ol)); | 855 v8::TryCatch block; |
856 v8::Local<v8::Value> lengthValue = object->Get(lengthSymbol); | |
857 if (block.HasCaught()) { | |
858 exceptionState.rethrowV8Exception(block.Exception()); | |
859 return false; | |
860 } | |
838 | 861 |
839 if (lengthValue->IsUndefined() || lengthValue->IsNull()) { | 862 if (lengthValue->IsUndefined() || lengthValue->IsNull()) { |
840 // The caller is responsible for reporting a TypeError. | 863 // The caller is responsible for reporting a TypeError. |
841 return v8Undefined(); | 864 return false; |
842 } | 865 } |
843 | 866 |
844 TONATIVE_EXCEPTION(uint32_t, sequenceLength, lengthValue->Int32Value()); | 867 uint32_t sequenceLength = lengthValue->Int32Value(); |
868 if (block.HasCaught()) { | |
869 exceptionState.rethrowV8Exception(block.Exception()); | |
870 return false; | |
871 } | |
872 | |
845 length = sequenceLength; | 873 length = sequenceLength; |
846 return v8Value; | 874 return true; |
847 } | 875 } |
848 | 876 |
849 v8::Isolate* toIsolate(ExecutionContext*); | 877 v8::Isolate* toIsolate(ExecutionContext*); |
850 v8::Isolate* toIsolate(LocalFrame*); | 878 v8::Isolate* toIsolate(LocalFrame*); |
851 | 879 |
852 LocalDOMWindow* toDOMWindow(v8::Handle<v8::Value>, v8::Isolate*); | 880 LocalDOMWindow* toDOMWindow(v8::Handle<v8::Value>, v8::Isolate*); |
853 LocalDOMWindow* toDOMWindow(v8::Handle<v8::Context>); | 881 LocalDOMWindow* toDOMWindow(v8::Handle<v8::Context>); |
854 LocalDOMWindow* enteredDOMWindow(v8::Isolate*); | 882 LocalDOMWindow* enteredDOMWindow(v8::Isolate*); |
855 LocalDOMWindow* currentDOMWindow(v8::Isolate*); | 883 LocalDOMWindow* currentDOMWindow(v8::Isolate*); |
856 LocalDOMWindow* callingDOMWindow(v8::Isolate*); | 884 LocalDOMWindow* callingDOMWindow(v8::Isolate*); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
974 v8::Local<v8::Value> v8IteratorResult(v8::Isolate*, v8::Handle<v8::Value>); | 1002 v8::Local<v8::Value> v8IteratorResult(v8::Isolate*, v8::Handle<v8::Value>); |
975 template <typename T> | 1003 template <typename T> |
976 v8::Local<v8::Value> v8IteratorResult(ScriptState* scriptState, const T& value) | 1004 v8::Local<v8::Value> v8IteratorResult(ScriptState* scriptState, const T& value) |
977 { | 1005 { |
978 return v8IteratorResult(scriptState->isolate(), V8ValueTraits<T>::toV8Value( value, scriptState->context()->Global(), scriptState->isolate())); | 1006 return v8IteratorResult(scriptState->isolate(), V8ValueTraits<T>::toV8Value( value, scriptState->context()->Global(), scriptState->isolate())); |
979 } | 1007 } |
980 | 1008 |
981 } // namespace blink | 1009 } // namespace blink |
982 | 1010 |
983 #endif // V8Binding_h | 1011 #endif // V8Binding_h |
OLD | NEW |