Chromium Code Reviews| Index: Source/bindings/core/v8/V8Binding.h |
| diff --git a/Source/bindings/core/v8/V8Binding.h b/Source/bindings/core/v8/V8Binding.h |
| index 000f5544abf557730e0a0a5f72140fbf3a50248d..6d096e8e91cfcdea087773aeabd614c3a647cb38 100644 |
| --- a/Source/bindings/core/v8/V8Binding.h |
| +++ b/Source/bindings/core/v8/V8Binding.h |
| @@ -34,6 +34,7 @@ |
| #include "bindings/core/v8/DOMWrapperWorld.h" |
| #include "bindings/core/v8/ExceptionMessages.h" |
| +#include "bindings/core/v8/ExceptionState.h" |
| #include "bindings/core/v8/ScriptValue.h" |
| #include "bindings/core/v8/ScriptWrappable.h" |
| #include "bindings/core/v8/V8BindingMacros.h" |
| @@ -572,40 +573,42 @@ template<class T> struct NativeValueTraits; |
| template<> |
| struct NativeValueTraits<String> { |
| - static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
| + static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - TOSTRING_DEFAULT(V8StringResource<>, stringValue, value, String()); |
| + V8StringResource<> stringValue(value); |
| + if (!stringValue.prepare(exceptionState)) |
| + return String(); |
| return stringValue; |
| } |
| }; |
| template<> |
| struct NativeValueTraits<unsigned> { |
| - static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
| + static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - return toUInt32(value); |
| + return toUInt32(value, exceptionState); |
| } |
| }; |
| template<> |
| struct NativeValueTraits<float> { |
| - static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
| + static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - return static_cast<float>(value->NumberValue()); |
| + return toFloat(value, exceptionState); |
| } |
| }; |
| template<> |
| struct NativeValueTraits<double> { |
| - static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
| + static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - return static_cast<double>(value->NumberValue()); |
| + return toDouble(value, exceptionState); |
| } |
| }; |
| template<> |
| struct NativeValueTraits<v8::Handle<v8::Value> > { |
| - static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
| + static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState&) |
| { |
| return value; |
| } |
| @@ -613,7 +616,7 @@ struct NativeValueTraits<v8::Handle<v8::Value> > { |
| template<> |
| struct NativeValueTraits<ScriptValue> { |
| - static inline ScriptValue nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
| + static inline ScriptValue nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState&) |
| { |
| return ScriptValue(ScriptState::current(isolate), value); |
| } |
| @@ -624,20 +627,23 @@ v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8:: |
| // Converts a JavaScript value to an array as per the Web IDL specification: |
| // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array |
| template <class T, class V8T> |
| -Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, uint32_t length, v8::Isolate* isolate, bool* success = 0) |
| +Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, uint32_t length, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| Vector<RefPtr<T> > result; |
| result.reserveInitialCapacity(length); |
| v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
| + v8::TryCatch block; |
| for (uint32_t i = 0; i < length; ++i) { |
| v8::Handle<v8::Value> element = object->Get(i); |
| + if (block.HasCaught()) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return Vector<RefPtr<T> >(); |
| + } |
| if (V8T::hasInstance(element, isolate)) { |
| v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element); |
| result.uncheckedAppend(V8T::toImpl(elementObject)); |
| } else { |
| - if (success) |
| - *success = false; |
| - V8ThrowException::throwTypeError("Invalid Array element type", isolate); |
| + exceptionState.throwTypeError("Invalid Array element type"); |
| return Vector<RefPtr<T> >(); |
| } |
| } |
| @@ -645,66 +651,60 @@ Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, ui |
| } |
| template <class T, class V8T> |
| -Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0) |
| +Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - if (success) |
| - *success = true; |
| - |
| v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
| uint32_t length = 0; |
| if (value->IsArray()) { |
| length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
| } else if (toV8Sequence(value, length, isolate).IsEmpty()) { |
| - V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate); |
| + exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex)); |
| return Vector<RefPtr<T> >(); |
| } |
| - return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success); |
| + return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, exceptionState); |
| } |
| template <class T, class V8T> |
| -Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* success = 0) |
| +Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - if (success) |
| - *success = true; |
| - |
| v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
| uint32_t length = 0; |
| if (value->IsArray()) { |
| length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
| } else if (toV8Sequence(value, length, isolate).IsEmpty()) { |
| - V8ThrowException::throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate); |
| + exceptionState.throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName)); |
| return Vector<RefPtr<T> >(); |
| } |
| - return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success); |
| + return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, exceptionState); |
| } |
| template <class T, class V8T> |
| -WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0) |
| +WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - if (success) |
| - *success = true; |
| - |
| v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
| uint32_t length = 0; |
| if (value->IsArray()) { |
| length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
| } else if (toV8Sequence(value, length, isolate).IsEmpty()) { |
| - V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate); |
| + exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex)); |
| return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
| } |
| WillBeHeapVector<RefPtrWillBeMember<T> > result; |
| result.reserveInitialCapacity(length); |
| v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
| + v8::TryCatch block; |
| for (uint32_t i = 0; i < length; ++i) { |
| v8::Handle<v8::Value> element = object->Get(i); |
| + if (block.HasCaught()) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
| + } |
| if (V8T::hasInstance(element, isolate)) { |
| v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element); |
| result.uncheckedAppend(V8T::toImpl(elementObject)); |
| } else { |
| - if (success) |
| - *success = false; |
| - V8ThrowException::throwTypeError("Invalid Array element type", isolate); |
| + exceptionState.throwTypeError("Invalid Array element type"); |
| return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
| } |
| } |
| @@ -712,32 +712,32 @@ WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Han |
| } |
| template <class T, class V8T> |
| -WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* success = 0) |
| +WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - if (success) |
| - *success = true; |
| - |
| v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
| uint32_t length = 0; |
| if (value->IsArray()) { |
| length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
| } else if (toV8Sequence(value, length, isolate).IsEmpty()) { |
| - V8ThrowException::throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate); |
| + exceptionState.throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName)); |
| return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
| } |
| WillBeHeapVector<RefPtrWillBeMember<T> > result; |
| result.reserveInitialCapacity(length); |
| v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
| + v8::TryCatch block; |
| for (uint32_t i = 0; i < length; ++i) { |
| v8::Handle<v8::Value> element = object->Get(i); |
| + if (block.HasCaught()) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return Vector<RefPtr<T> >(); |
| + } |
| if (V8T::hasInstance(element, isolate)) { |
| v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element); |
| result.uncheckedAppend(V8T::toImpl(elementObject)); |
| } else { |
| - if (success) |
| - *success = false; |
| - V8ThrowException::throwTypeError("Invalid Array element type", isolate); |
| + exceptionState.throwTypeError("Invalid Array element type"); |
| return WillBeHeapVector<RefPtrWillBeMember<T> >(); |
| } |
| } |
| @@ -745,32 +745,32 @@ WillBeHeapVector<RefPtrWillBeMember<T> > toRefPtrWillBeMemberNativeArray(v8::Han |
| } |
| template <class T, class V8T> |
| -HeapVector<Member<T> > toMemberNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0) |
| +HeapVector<Member<T> > toMemberNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| - if (success) |
| - *success = true; |
| - |
| v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
| uint32_t length = 0; |
| if (value->IsArray()) { |
| length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
| } else if (toV8Sequence(value, length, isolate).IsEmpty()) { |
| - V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate); |
| + exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex)); |
| return HeapVector<Member<T> >(); |
| } |
| HeapVector<Member<T> > result; |
| result.reserveInitialCapacity(length); |
| v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
| + v8::TryCatch block; |
| for (uint32_t i = 0; i < length; ++i) { |
| v8::Handle<v8::Value> element = object->Get(i); |
| + if (UNLIKELY(block.HasCaught())) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return HeapVector<Member<T> >(); |
| + } |
| if (V8T::hasInstance(element, isolate)) { |
| v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element); |
| result.uncheckedAppend(V8T::toImpl(elementObject)); |
| } else { |
| - if (success) |
| - *success = false; |
| - V8ThrowException::throwTypeError("Invalid Array element type", isolate); |
| + exceptionState.throwTypeError("Invalid Array element type"); |
| return HeapVector<Member<T> >(); |
| } |
| } |
| @@ -780,14 +780,14 @@ HeapVector<Member<T> > toMemberNativeArray(v8::Handle<v8::Value> value, int argu |
| // Converts a JavaScript value to an array as per the Web IDL specification: |
| // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array |
| template <class T> |
| -Vector<T> toImplArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate) |
| +Vector<T> toImplArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, ExceptionState& exceptionState) |
| { |
| v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
| uint32_t length = 0; |
| if (value->IsArray()) { |
| length = v8::Local<v8::Array>::Cast(v8Value)->Length(); |
| } else if (toV8Sequence(value, length, isolate).IsEmpty()) { |
| - V8ThrowException::throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate); |
| + exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex)); |
| return Vector<T>(); |
| } |
| @@ -795,21 +795,33 @@ Vector<T> toImplArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolat |
| result.reserveInitialCapacity(length); |
| typedef NativeValueTraits<T> TraitsType; |
| v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); |
| - for (uint32_t i = 0; i < length; ++i) |
| - result.uncheckedAppend(TraitsType::nativeValue(object->Get(i), isolate)); |
|
Jens Widell
2014/09/11 13:22:31
The change here (and in the other functions) to ad
|
| + v8::TryCatch block; |
| + for (uint32_t i = 0; i < length; ++i) { |
| + v8::Handle<v8::Value> element = object->Get(i); |
| + if (UNLIKELY(block.HasCaught())) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return Vector<T>(); |
| + } |
| + result.uncheckedAppend(TraitsType::nativeValue(element, isolate, exceptionState)); |
| + if (exceptionState.hadException()) |
| + return Vector<T>(); |
| + } |
| return result; |
| } |
| template <class T> |
| -Vector<T> toImplArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int startIndex) |
| +Vector<T> toImplArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int startIndex, ExceptionState& exceptionState) |
| { |
| ASSERT(startIndex <= info.Length()); |
| Vector<T> result; |
| typedef NativeValueTraits<T> TraitsType; |
| int length = info.Length(); |
| result.reserveInitialCapacity(length); |
| - for (int i = startIndex; i < length; ++i) |
| - result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate())); |
| + for (int i = startIndex; i < length; ++i) { |
| + result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate(), exceptionState)); |
| + if (exceptionState.hadException()) |
| + return Vector<T>(); |
| + } |
| return result; |
| } |