Index: Source/bindings/core/v8/V8Binding.h |
diff --git a/Source/bindings/core/v8/V8Binding.h b/Source/bindings/core/v8/V8Binding.h |
index 3d00609a05944447731a0cfba80dc061c34bbf4b..490a73aa0bfc4804dd3817f5604ffdcd3bedcc37 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" |
@@ -570,25 +571,28 @@ PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, |
template<class T> struct NativeValueTraits; |
-v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*); |
+bool toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*, ExceptionState&); |
// 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> >(); |
} |
} |
@@ -596,66 +600,63 @@ 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); |
+ } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
+ if (!exceptionState.hadException()) |
+ 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); |
+ } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
+ if (!exceptionState.hadException()) |
+ 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); |
+ } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
+ if (!exceptionState.hadException()) |
+ 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> >(); |
} |
} |
@@ -663,32 +664,33 @@ 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); |
+ } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
+ if (!exceptionState.hadException()) |
+ 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> >(); |
} |
} |
@@ -696,32 +698,33 @@ 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); |
+ } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
+ if (!exceptionState.hadException()) |
+ 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> >(); |
} |
} |
@@ -731,14 +734,15 @@ 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); |
+ } else if (!toV8Sequence(value, length, isolate, exceptionState)) { |
+ if (!exceptionState.hadException()) |
+ exceptionState.throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex)); |
return Vector<T>(); |
} |
@@ -746,27 +750,39 @@ 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)); |
+ 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; |
} |
// Validates that the passed object is a sequence type per WebIDL spec |
// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence |
-inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate) |
+inline bool toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate, ExceptionState& exceptionState) |
{ |
// Attempt converting to a sequence if the value is not already an array but is |
// any kind of object except for a native Date object or a native RegExp object. |
@@ -775,7 +791,7 @@ inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& |
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806 |
if (!value->IsObject() || value->IsDate() || value->IsRegExp()) { |
// The caller is responsible for reporting a TypeError. |
- return v8Undefined(); |
+ return false; |
} |
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); |
@@ -785,62 +801,74 @@ inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& |
// FIXME: The specification states that the length property should be used as fallback, if value |
// is not a platform object that supports indexed properties. If it supports indexed properties, |
// length should actually be one greater than value’s maximum indexed property index. |
- TONATIVE_EXCEPTION(v8::Local<v8::Value>, lengthValue, object->Get(lengthSymbol)); |
+ v8::TryCatch block; |
+ v8::Local<v8::Value> lengthValue = object->Get(lengthSymbol); |
+ if (block.HasCaught()) { |
+ exceptionState.rethrowV8Exception(block.Exception()); |
+ return false; |
+ } |
if (lengthValue->IsUndefined() || lengthValue->IsNull()) { |
// The caller is responsible for reporting a TypeError. |
- return v8Undefined(); |
+ return false; |
+ } |
+ |
+ uint32_t sequenceLength = lengthValue->Int32Value(); |
+ if (block.HasCaught()) { |
+ exceptionState.rethrowV8Exception(block.Exception()); |
+ return false; |
} |
- TONATIVE_EXCEPTION(uint32_t, sequenceLength, lengthValue->Int32Value()); |
length = sequenceLength; |
- return v8Value; |
+ return true; |
} |
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<int> { |
- static inline int nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
+ static inline int nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState) |
{ |
- return toInt32(value); |
+ return toInt32(value, exceptionState); |
} |
}; |
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; |
} |
@@ -848,7 +876,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); |
} |
@@ -856,9 +884,9 @@ struct NativeValueTraits<ScriptValue> { |
template <typename T> |
struct NativeValueTraits<Vector<T> > { |
- static inline Vector<T> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) |
+ static inline Vector<T> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState) |
{ |
- return toImplArray<T>(value, 0, isolate); |
+ return toImplArray<T>(value, 0, isolate, exceptionState); |
} |
}; |