| Index: Source/bindings/v8/V8Binding.cpp
|
| diff --git a/Source/bindings/v8/V8Binding.cpp b/Source/bindings/v8/V8Binding.cpp
|
| index 2d8da03d149da659eb13c671735f449d1a70ce70..7635506356f29664e05daba6a8e6f1465e0fb82d 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"
|
| @@ -142,15 +143,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;
|
| @@ -187,10 +188,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()) {
|
| @@ -198,7 +198,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;
|
| @@ -206,14 +206,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)
|
| @@ -226,10 +226,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()) {
|
| @@ -237,21 +236,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();
|
| @@ -265,44 +264,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();
|
| @@ -312,14 +332,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();
|
| @@ -330,22 +354,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();
|
| @@ -359,25 +382,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))
|
| @@ -389,10 +416,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();
|
| @@ -403,23 +434,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))
|
| @@ -431,6 +462,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();
|
| +}
|
| +
|
| v8::Handle<v8::FunctionTemplate> createRawTemplate(v8::Isolate* isolate)
|
| {
|
| v8::EscapableHandleScope scope(isolate);
|
|
|