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(); // Fast case. The value is a 32-bit signed integer - possibly positive? if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= 0) return result; if (configuration == EnforceRange) { exceptionState.throwTypeError("Value is outside the 'unsigned long' value range."); return 0; } return result; } // Can the value be converted to a number? 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; } if (configuration == EnforceRange) return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long", exceptionState); // Does the value convert to nan or to an infinity? double numberValue = numberObject->Value(); if (std::isnan(numberValue) || std::isinf(numberValue)) return 0; if (configuration == Clamp) return clampTo<uint32_t>(numberObject->Value()); V8TRYCATCH_RETURN(uint32_t, result, numberObject->Uint32Value(), 0); return result; }
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(); // Fast case. The value is a 32-bit integer. if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= 0) return result; if (configuration == EnforceRange) { exceptionState.throwTypeError("Value is outside the 'unsigned long long' value range."); return 0; } return result; } // Can the value be converted to a number? 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 long'.)"); return 0; } double x = numberObject->Value(); if (configuration == EnforceRange) 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)) return 0; // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. unsigned long long integer; doubleToInteger(x, integer); return integer; }
uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) { ok = true; // Fast case. The value is a 32-bit unsigned integer. if (value->IsUint32()) return value->Uint32Value(); // Fast case. The value is a 32-bit integer. if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= 0) return result; if (configuration == EnforceRange) { ok = false; return 0; } return result; } // Can the value be converted to a number? v8::Local<v8::Number> numberObject = value->ToNumber(); if (numberObject.IsEmpty()) { ok = false; return 0; } double x = numberObject->Value(); if (configuration == EnforceRange) return enforceRange(x, 0, kJSMaxInteger, ok); // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. unsigned long long integer; doubleToInteger(x, integer); return integer; }
static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState) { typedef IntTypeLimits<T> LimitsTrait; // Fast case. The value is a 32-bit signed integer - possibly positive? if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= 0 && result <= LimitsTrait::maxValue) return static_cast<T>(result); if (configuration == EnforceRange) { 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? 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 '" + String(typeName) + "'."); return 0; } if (configuration == EnforceRange) return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typeName, exceptionState); // Does the value convert to nan or to an infinity? double numberValue = numberObject->Value(); if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) return 0; if (configuration == Clamp) return clampTo<T>(numberObject->Value()); numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue)); return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues)); }
static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) { typedef IntTypeLimits<T> LimitsTrait; ok = true; // Fast case. The value is already a 32-bit integer in the right range. if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue) return static_cast<T>(result); if (configuration == EnforceRange) { ok = false; return 0; } result %= LimitsTrait::numberOfValues; return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTrait::numberOfValues : result); } // Can the value be converted to a number? v8::Local<v8::Number> numberObject = value->ToNumber(); if (numberObject.IsEmpty()) { ok = false; return 0; } if (configuration == EnforceRange) return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, ok); double numberValue = numberObject->Value(); if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) return 0; numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue)); numberValue = fmod(numberValue, LimitsTrait::numberOfValues); return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - LimitsTrait::numberOfValues : numberValue); }
static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState) { typedef IntTypeLimits<T> LimitsTrait; // Fast case. The value is already a 32-bit integer in the right range. if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue) return static_cast<T>(result); if (configuration == EnforceRange) { exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range."); return 0; } result %= LimitsTrait::numberOfValues; return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTrait::numberOfValues : result); } // Can the value be converted to a number? 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 '" + String(typeName) + "'."); return 0; } if (configuration == EnforceRange) return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, typeName, exceptionState); double numberValue = numberObject->Value(); if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) return 0; numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue)); numberValue = fmod(numberValue, LimitsTrait::numberOfValues); return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - LimitsTrait::numberOfValues : numberValue); }
uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) { ok = true; // Fast case. The value is already a 32-bit unsigned integer. if (value->IsUint32()) return value->Uint32Value(); // Fast case. The value is a 32-bit signed integer - possibly positive? if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= 0) return result; if (configuration == EnforceRange) { ok = false; return 0; } return result; } // Can the value be converted to a number? v8::Local<v8::Number> numberObject = value->ToNumber(); if (numberObject.IsEmpty()) { ok = false; return 0; } if (configuration == EnforceRange) return enforceRange(numberObject->Value(), 0, kMaxUInt32, ok); // Does the value convert to nan or to an infinity? double numberValue = numberObject->Value(); if (std::isnan(numberValue) || std::isinf(numberValue)) return 0; return numberObject->Uint32Value(); }
int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) { ok = true; // Fast case. The value is already 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(); if (numberObject.IsEmpty()) { ok = false; return 0; } if (configuration == EnforceRange) return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, ok); // Does the value convert to nan or to an infinity? double numberValue = numberObject->Value(); if (std::isnan(numberValue) || std::isinf(numberValue)) return 0; return numberObject->Int32Value(); }
int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok) { ok = true; // Fast case. The value is already a 32-bit integer in the right range. if (value->IsInt32()) { int32_t result = value->Int32Value(); if (result >= kMinInt8 && result <= kMaxInt8) return static_cast<int8_t>(result); if (configuration == EnforceRange) { ok = false; return 0; } result %= 256; // 2^8. return static_cast<int8_t>(result > kMaxInt8 ? result - 256 : result); } // Can the value be converted to a number? v8::Local<v8::Number> numberObject = value->ToNumber(); if (numberObject.IsEmpty()) { ok = false; return 0; } if (configuration == EnforceRange) return enforceRange(numberObject->Value(), kMinInt8, kMaxInt8, ok); double numberValue = numberObject->Value(); if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) return 0; numberValue = numberValue < 0 ? -floor(abs(numberValue)) : floor(abs(numberValue)); numberValue = fmod(numberValue, 256); // 2^8. return static_cast<int8_t>(numberValue > kMaxInt8 ? numberValue - 256 : numberValue); }