Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Unified Diff: Source/bindings/core/v8/V8Binding.h

Issue 555133003: Use ExceptionState to throw exceptions when converting arrays (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebased Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/core/v8/SerializedScriptValue.cpp ('k') | Source/bindings/core/v8/V8Binding.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
};
« no previous file with comments | « Source/bindings/core/v8/SerializedScriptValue.cpp ('k') | Source/bindings/core/v8/V8Binding.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698