Index: Source/bindings/v8/V8Binding.cpp |
diff --git a/Source/bindings/v8/V8Binding.cpp b/Source/bindings/v8/V8Binding.cpp |
index b72bcf839bfab96924994051d6dd2cecb7a3f3c2..87083d3e3bda93874c5a77417f399b387a925de1 100644 |
--- a/Source/bindings/v8/V8Binding.cpp |
+++ b/Source/bindings/v8/V8Binding.cpp |
@@ -37,6 +37,7 @@ |
#include "V8WorkerGlobalScope.h" |
#include "V8XPathNSResolver.h" |
#include "bindings/v8/ScriptController.h" |
+#include "bindings/v8/V8BindingMacros.h" |
#include "bindings/v8/V8NodeFilterCondition.h" |
#include "bindings/v8/V8ObjectConstructor.h" |
#include "bindings/v8/V8WindowShell.h" |
@@ -154,15 +155,15 @@ const int32_t kMinInt32 = -kMaxInt32 - 1; |
const uint32_t kMaxUInt32 = 0xffffffff; |
const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, maximum integer exactly representable in ECMAScript. |
-static double enforceRange(double x, double minimum, double maximum, bool& ok) |
+static double enforceRange(double x, double minimum, double maximum, const char* typeName, ExceptionState& exceptionState) |
{ |
if (std::isnan(x) || std::isinf(x)) { |
- ok = false; |
+ exceptionState.throwTypeError("Value is" + String(std::isinf(x) ? " infinite and" : "") + " not of type '" + String(typeName) + "'."); |
return 0; |
} |
x = trunc(x); |
if (x < minimum || x > maximum) { |
- ok = false; |
+ exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range."); |
return 0; |
} |
return x; |
@@ -199,10 +200,9 @@ struct IntTypeLimits<uint16_t> { |
}; |
template <typename T> |
-static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState) |
{ |
typedef IntTypeLimits<T> LimitsTrait; |
- ok = true; |
// Fast case. The value is already a 32-bit integer in the right range. |
if (value->IsInt32()) { |
@@ -210,7 +210,7 @@ static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfi |
if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue) |
return static_cast<T>(result); |
if (configuration == EnforceRange) { |
- ok = false; |
+ exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range."); |
return 0; |
} |
result %= LimitsTrait::numberOfValues; |
@@ -218,14 +218,14 @@ static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfi |
} |
// Can the value be converted to a number? |
- v8::Local<v8::Number> numberObject = value->ToNumber(); |
+ V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0); |
if (numberObject.IsEmpty()) { |
- ok = false; |
+ exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'."); |
return 0; |
} |
if (configuration == EnforceRange) |
- return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, ok); |
+ return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, typeName, exceptionState); |
double numberValue = numberObject->Value(); |
if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) |
@@ -238,10 +238,9 @@ static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfi |
} |
template <typename T> |
-static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState) |
{ |
typedef IntTypeLimits<T> LimitsTrait; |
- ok = true; |
// Fast case. The value is a 32-bit signed integer - possibly positive? |
if (value->IsInt32()) { |
@@ -249,21 +248,21 @@ static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConf |
if (result >= 0 && result <= LimitsTrait::maxValue) |
return static_cast<T>(result); |
if (configuration == EnforceRange) { |
- ok = false; |
+ exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range."); |
return 0; |
} |
return static_cast<T>(result); |
} |
// Can the value be converted to a number? |
- v8::Local<v8::Number> numberObject = value->ToNumber(); |
+ V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0); |
if (numberObject.IsEmpty()) { |
- ok = false; |
+ exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'."); |
return 0; |
} |
if (configuration == EnforceRange) |
- return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, ok); |
+ return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typeName, exceptionState); |
// Does the value convert to nan or to an infinity? |
double numberValue = numberObject->Value(); |
@@ -277,44 +276,65 @@ static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConf |
return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues)); |
} |
-int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
{ |
- return toSmallerInt<int8_t>(value, configuration, ok); |
+ return toSmallerInt<int8_t>(value, configuration, "byte", exceptionState); |
} |
-uint8_t toUInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+int8_t toInt8(v8::Handle<v8::Value> value) |
{ |
- return toSmallerUInt<uint8_t>(value, configuration, ok); |
+ NonThrowableExceptionState exceptionState; |
+ return toInt8(value, NormalConversion, exceptionState); |
} |
-int16_t toInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+uint8_t toUInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
{ |
- return toSmallerInt<int16_t>(value, configuration, ok); |
+ return toSmallerUInt<uint8_t>(value, configuration, "octet", exceptionState); |
} |
-uint16_t toUInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+uint8_t toUInt8(v8::Handle<v8::Value> value) |
{ |
- return toSmallerUInt<uint16_t>(value, configuration, ok); |
+ NonThrowableExceptionState exceptionState; |
+ return toUInt8(value, NormalConversion, exceptionState); |
} |
-int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+int16_t toInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
{ |
- ok = true; |
+ return toSmallerInt<int16_t>(value, configuration, "short", exceptionState); |
+} |
+ |
+int16_t toInt16(v8::Handle<v8::Value> value) |
+{ |
+ NonThrowableExceptionState exceptionState; |
+ return toInt16(value, NormalConversion, exceptionState); |
+} |
+ |
+uint16_t toUInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
+{ |
+ return toSmallerUInt<uint16_t>(value, configuration, "unsigned short", exceptionState); |
+} |
+ |
+uint16_t toUInt16(v8::Handle<v8::Value> value) |
+{ |
+ NonThrowableExceptionState exceptionState; |
+ return toUInt16(value, NormalConversion, exceptionState); |
+} |
+int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
+{ |
// Fast case. The value is already a 32-bit integer. |
if (value->IsInt32()) |
return value->Int32Value(); |
// Can the value be converted to a number? |
- ok = false; |
- V8TRYCATCH_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), 0); |
+ V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0); |
if (numberObject.IsEmpty()) { |
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'long'.)"); |
return 0; |
} |
- ok = true; |
if (configuration == EnforceRange) |
- return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, ok); |
+ return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long", exceptionState); |
// Does the value convert to nan or to an infinity? |
double numberValue = numberObject->Value(); |
@@ -324,14 +344,18 @@ int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf |
if (configuration == Clamp) |
return clampTo<int32_t>(numberObject->Value()); |
- V8TRYCATCH_RETURN(int32_t, result, numberObject->Int32Value(), 0); |
+ V8TRYCATCH_EXCEPTION_RETURN(int32_t, result, numberObject->Int32Value(), exceptionState, 0); |
return result; |
} |
-uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+int32_t toInt32(v8::Handle<v8::Value> value) |
{ |
- ok = true; |
+ NonThrowableExceptionState exceptionState; |
+ return toInt32(value, NormalConversion, exceptionState); |
+} |
+uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
+{ |
// Fast case. The value is already a 32-bit unsigned integer. |
if (value->IsUint32()) |
return value->Uint32Value(); |
@@ -342,22 +366,21 @@ uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co |
if (result >= 0) |
return result; |
if (configuration == EnforceRange) { |
- ok = false; |
+ exceptionState.throwTypeError("Value is outside the 'unsigned long' value range."); |
return 0; |
} |
return result; |
} |
// Can the value be converted to a number? |
- ok = false; |
- V8TRYCATCH_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), 0); |
+ V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0); |
if (numberObject.IsEmpty()) { |
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'unsigned long'.)"); |
return 0; |
} |
- ok = true; |
if (configuration == EnforceRange) |
- return enforceRange(numberObject->Value(), 0, kMaxUInt32, ok); |
+ return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long", exceptionState); |
// Does the value convert to nan or to an infinity? |
double numberValue = numberObject->Value(); |
@@ -371,25 +394,29 @@ uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co |
return result; |
} |
-int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+uint32_t toUInt32(v8::Handle<v8::Value> value) |
{ |
- ok = true; |
+ NonThrowableExceptionState exceptionState; |
+ return toUInt32(value, NormalConversion, exceptionState); |
+} |
+int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
+{ |
// Fast case. The value is a 32-bit integer. |
if (value->IsInt32()) |
return value->Int32Value(); |
// Can the value be converted to a number? |
- v8::Local<v8::Number> numberObject = value->ToNumber(); |
+ V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0); |
if (numberObject.IsEmpty()) { |
- ok = false; |
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'long long'.)"); |
return 0; |
} |
double x = numberObject->Value(); |
if (configuration == EnforceRange) |
- return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, ok); |
+ return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, "long long", exceptionState); |
// Does the value convert to nan or to an infinity? |
if (std::isnan(x) || std::isinf(x)) |
@@ -401,10 +428,14 @@ int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf |
return integer; |
} |
-uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) |
+int64_t toInt64(v8::Handle<v8::Value> value) |
{ |
- ok = true; |
+ NonThrowableExceptionState exceptionState; |
+ return toInt64(value, NormalConversion, exceptionState); |
+} |
+uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState) |
+{ |
// Fast case. The value is a 32-bit unsigned integer. |
if (value->IsUint32()) |
return value->Uint32Value(); |
@@ -415,23 +446,23 @@ uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration co |
if (result >= 0) |
return result; |
if (configuration == EnforceRange) { |
- ok = false; |
+ exceptionState.throwTypeError("Value is outside the 'unsigned long long' value range."); |
return 0; |
} |
return result; |
} |
// Can the value be converted to a number? |
- v8::Local<v8::Number> numberObject = value->ToNumber(); |
+ V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0); |
if (numberObject.IsEmpty()) { |
- ok = false; |
+ exceptionState.throwTypeError("Not convertible to a number value (of type 'unsigned long long'.)"); |
return 0; |
} |
double x = numberObject->Value(); |
if (configuration == EnforceRange) |
- return enforceRange(x, 0, kJSMaxInteger, ok); |
+ return enforceRange(x, 0, kJSMaxInteger, "unsigned long long", exceptionState); |
// Does the value convert to nan or to an infinity? |
if (std::isnan(x) || std::isinf(x)) |
@@ -443,6 +474,18 @@ uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration co |
return integer; |
} |
+uint64_t toUInt64(v8::Handle<v8::Value> value) |
+{ |
+ NonThrowableExceptionState exceptionState; |
+ return toUInt64(value, NormalConversion, exceptionState); |
+} |
+ |
+float toFloat(v8::Handle<v8::Value> value, ExceptionState& exceptionState) |
+{ |
+ V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0); |
+ return numberObject->NumberValue(); |
+} |
+ |
PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value> value, v8::Isolate* isolate) |
{ |
RefPtr<XPathNSResolver> resolver; |