| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 | 190 |
| 191 // Fast case. The value is already a 32-bit integer in the right range. | 191 // Fast case. The value is already a 32-bit integer in the right range. |
| 192 if (value->IsInt32()) { | 192 if (value->IsInt32()) { |
| 193 int32_t result = value->Int32Value(); | 193 int32_t result = value->Int32Value(); |
| 194 if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue) | 194 if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue) |
| 195 return static_cast<T>(result); | 195 return static_cast<T>(result); |
| 196 if (configuration == EnforceRange) { | 196 if (configuration == EnforceRange) { |
| 197 exceptionState.throwTypeError("Value is outside the '" + String(type
Name) + "' value range."); | 197 exceptionState.throwTypeError("Value is outside the '" + String(type
Name) + "' value range."); |
| 198 return 0; | 198 return 0; |
| 199 } | 199 } |
| 200 if (configuration == Clamp) |
| 201 return clampTo<T>(result); |
| 200 result %= LimitsTrait::numberOfValues; | 202 result %= LimitsTrait::numberOfValues; |
| 201 return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTr
ait::numberOfValues : result); | 203 return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTr
ait::numberOfValues : result); |
| 202 } | 204 } |
| 203 | 205 |
| 204 // Can the value be converted to a number? | 206 // Can the value be converted to a number? |
| 205 v8::TryCatch block; | 207 v8::TryCatch block; |
| 206 v8::Local<v8::Number> numberObject(value->ToNumber()); | 208 v8::Local<v8::Number> numberObject(value->ToNumber()); |
| 207 if (block.HasCaught()) { | 209 if (block.HasCaught()) { |
| 208 exceptionState.rethrowV8Exception(block.Exception()); | 210 exceptionState.rethrowV8Exception(block.Exception()); |
| 209 return 0; | 211 return 0; |
| 210 } | 212 } |
| 211 | 213 |
| 212 ASSERT(!numberObject.IsEmpty()); | 214 ASSERT(!numberObject.IsEmpty()); |
| 213 | 215 |
| 214 if (configuration == EnforceRange) | 216 if (configuration == EnforceRange) |
| 215 return enforceRange(numberObject->Value(), LimitsTrait::minValue, Limits
Trait::maxValue, typeName, exceptionState); | 217 return enforceRange(numberObject->Value(), LimitsTrait::minValue, Limits
Trait::maxValue, typeName, exceptionState); |
| 216 | 218 |
| 217 double numberValue = numberObject->Value(); | 219 double numberValue = numberObject->Value(); |
| 218 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) | 220 if (std::isnan(numberValue) || !numberValue) |
| 221 return 0; |
| 222 |
| 223 if (configuration == Clamp) |
| 224 return clampTo<T>(numberValue); |
| 225 |
| 226 if (std::isinf(numberValue)) |
| 219 return 0; | 227 return 0; |
| 220 | 228 |
| 221 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numbe
rValue)); | 229 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numbe
rValue)); |
| 222 numberValue = fmod(numberValue, LimitsTrait::numberOfValues); | 230 numberValue = fmod(numberValue, LimitsTrait::numberOfValues); |
| 223 | 231 |
| 224 return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - Li
mitsTrait::numberOfValues : numberValue); | 232 return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - Li
mitsTrait::numberOfValues : numberValue); |
| 225 } | 233 } |
| 226 | 234 |
| 227 template <typename T> | 235 template <typename T> |
| 228 static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConf
iguration configuration, const char* typeName, ExceptionState& exceptionState) | 236 static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConf
iguration configuration, const char* typeName, ExceptionState& exceptionState) |
| 229 { | 237 { |
| 230 typedef IntTypeLimits<T> LimitsTrait; | 238 typedef IntTypeLimits<T> LimitsTrait; |
| 231 | 239 |
| 232 // Fast case. The value is a 32-bit signed integer - possibly positive? | 240 // Fast case. The value is a 32-bit signed integer - possibly positive? |
| 233 if (value->IsInt32()) { | 241 if (value->IsInt32()) { |
| 234 int32_t result = value->Int32Value(); | 242 int32_t result = value->Int32Value(); |
| 235 if (result >= 0 && result <= LimitsTrait::maxValue) | 243 if (result >= 0 && result <= LimitsTrait::maxValue) |
| 236 return static_cast<T>(result); | 244 return static_cast<T>(result); |
| 237 if (configuration == EnforceRange) { | 245 if (configuration == EnforceRange) { |
| 238 exceptionState.throwTypeError("Value is outside the '" + String(type
Name) + "' value range."); | 246 exceptionState.throwTypeError("Value is outside the '" + String(type
Name) + "' value range."); |
| 239 return 0; | 247 return 0; |
| 240 } | 248 } |
| 249 if (configuration == Clamp) |
| 250 return clampTo<T>(result); |
| 241 return static_cast<T>(result); | 251 return static_cast<T>(result); |
| 242 } | 252 } |
| 243 | 253 |
| 244 // Can the value be converted to a number? | 254 // Can the value be converted to a number? |
| 245 v8::TryCatch block; | 255 v8::TryCatch block; |
| 246 v8::Local<v8::Number> numberObject(value->ToNumber()); | 256 v8::Local<v8::Number> numberObject(value->ToNumber()); |
| 247 if (block.HasCaught()) { | 257 if (block.HasCaught()) { |
| 248 exceptionState.rethrowV8Exception(block.Exception()); | 258 exceptionState.rethrowV8Exception(block.Exception()); |
| 249 return 0; | 259 return 0; |
| 250 } | 260 } |
| 251 | 261 |
| 252 ASSERT(!numberObject.IsEmpty()); | 262 ASSERT(!numberObject.IsEmpty()); |
| 253 | 263 |
| 254 if (configuration == EnforceRange) | 264 if (configuration == EnforceRange) |
| 255 return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typ
eName, exceptionState); | 265 return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typ
eName, exceptionState); |
| 256 | 266 |
| 257 // Does the value convert to nan or to an infinity? | |
| 258 double numberValue = numberObject->Value(); | 267 double numberValue = numberObject->Value(); |
| 259 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) | 268 |
| 269 if (std::isnan(numberValue) || !numberValue) |
| 260 return 0; | 270 return 0; |
| 261 | 271 |
| 262 if (configuration == Clamp) | 272 if (configuration == Clamp) |
| 263 return clampTo<T>(numberObject->Value()); | 273 return clampTo<T>(numberValue); |
| 274 |
| 275 if (std::isinf(numberValue)) |
| 276 return 0; |
| 264 | 277 |
| 265 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numbe
rValue)); | 278 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numbe
rValue)); |
| 266 return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues)); | 279 return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues)); |
| 267 } | 280 } |
| 268 | 281 |
| 269 int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration config
uration, ExceptionState& exceptionState) | 282 int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration config
uration, ExceptionState& exceptionState) |
| 270 { | 283 { |
| 271 return toSmallerInt<int8_t>(value, configuration, "byte", exceptionState); | 284 return toSmallerInt<int8_t>(value, configuration, "byte", exceptionState); |
| 272 } | 285 } |
| 273 | 286 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 if (block.HasCaught()) { | 335 if (block.HasCaught()) { |
| 323 exceptionState.rethrowV8Exception(block.Exception()); | 336 exceptionState.rethrowV8Exception(block.Exception()); |
| 324 return 0; | 337 return 0; |
| 325 } | 338 } |
| 326 | 339 |
| 327 ASSERT(!numberObject.IsEmpty()); | 340 ASSERT(!numberObject.IsEmpty()); |
| 328 | 341 |
| 329 if (configuration == EnforceRange) | 342 if (configuration == EnforceRange) |
| 330 return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long",
exceptionState); | 343 return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long",
exceptionState); |
| 331 | 344 |
| 332 // Does the value convert to nan or to an infinity? | |
| 333 double numberValue = numberObject->Value(); | 345 double numberValue = numberObject->Value(); |
| 334 if (std::isnan(numberValue) || std::isinf(numberValue)) | 346 |
| 347 if (std::isnan(numberValue)) |
| 335 return 0; | 348 return 0; |
| 336 | 349 |
| 337 if (configuration == Clamp) | 350 if (configuration == Clamp) |
| 338 return clampTo<int32_t>(numberObject->Value()); | 351 return clampTo<int32_t>(numberValue); |
| 352 |
| 353 if (std::isinf(numberValue)) |
| 354 return 0; |
| 339 | 355 |
| 340 return numberObject->Int32Value(); | 356 return numberObject->Int32Value(); |
| 341 } | 357 } |
| 342 | 358 |
| 343 int32_t toInt32(v8::Handle<v8::Value> value) | 359 int32_t toInt32(v8::Handle<v8::Value> value) |
| 344 { | 360 { |
| 345 NonThrowableExceptionState exceptionState; | 361 NonThrowableExceptionState exceptionState; |
| 346 return toInt32(value, NormalConversion, exceptionState); | 362 return toInt32(value, NormalConversion, exceptionState); |
| 347 } | 363 } |
| 348 | 364 |
| 349 uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
nfiguration, ExceptionState& exceptionState) | 365 uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
nfiguration, ExceptionState& exceptionState) |
| 350 { | 366 { |
| 351 // Fast case. The value is already a 32-bit unsigned integer. | 367 // Fast case. The value is already a 32-bit unsigned integer. |
| 352 if (value->IsUint32()) | 368 if (value->IsUint32()) |
| 353 return value->Uint32Value(); | 369 return value->Uint32Value(); |
| 354 | 370 |
| 355 // Fast case. The value is a 32-bit signed integer - possibly positive? | 371 // Fast case. The value is a 32-bit signed integer - possibly positive? |
| 356 if (value->IsInt32()) { | 372 if (value->IsInt32()) { |
| 357 int32_t result = value->Int32Value(); | 373 int32_t result = value->Int32Value(); |
| 358 if (result >= 0) | 374 if (result >= 0) |
| 359 return result; | 375 return result; |
| 360 if (configuration == EnforceRange) { | 376 if (configuration == EnforceRange) { |
| 361 exceptionState.throwTypeError("Value is outside the 'unsigned long'
value range."); | 377 exceptionState.throwTypeError("Value is outside the 'unsigned long'
value range."); |
| 362 return 0; | 378 return 0; |
| 363 } | 379 } |
| 380 if (configuration == Clamp) |
| 381 return clampTo<uint32_t>(result); |
| 364 return result; | 382 return result; |
| 365 } | 383 } |
| 366 | 384 |
| 367 // Can the value be converted to a number? | 385 // Can the value be converted to a number? |
| 368 v8::TryCatch block; | 386 v8::TryCatch block; |
| 369 v8::Local<v8::Number> numberObject(value->ToNumber()); | 387 v8::Local<v8::Number> numberObject(value->ToNumber()); |
| 370 if (block.HasCaught()) { | 388 if (block.HasCaught()) { |
| 371 exceptionState.rethrowV8Exception(block.Exception()); | 389 exceptionState.rethrowV8Exception(block.Exception()); |
| 372 return 0; | 390 return 0; |
| 373 } | 391 } |
| 374 | 392 |
| 375 ASSERT(!numberObject.IsEmpty()); | 393 ASSERT(!numberObject.IsEmpty()); |
| 376 | 394 |
| 377 if (configuration == EnforceRange) | 395 if (configuration == EnforceRange) |
| 378 return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long
", exceptionState); | 396 return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long
", exceptionState); |
| 379 | 397 |
| 380 // Does the value convert to nan or to an infinity? | |
| 381 double numberValue = numberObject->Value(); | 398 double numberValue = numberObject->Value(); |
| 382 if (std::isnan(numberValue) || std::isinf(numberValue)) | 399 |
| 400 if (std::isnan(numberValue)) |
| 383 return 0; | 401 return 0; |
| 384 | 402 |
| 385 if (configuration == Clamp) | 403 if (configuration == Clamp) |
| 386 return clampTo<uint32_t>(numberObject->Value()); | 404 return clampTo<uint32_t>(numberValue); |
| 405 |
| 406 if (std::isinf(numberValue)) |
| 407 return 0; |
| 387 | 408 |
| 388 return numberObject->Uint32Value(); | 409 return numberObject->Uint32Value(); |
| 389 } | 410 } |
| 390 | 411 |
| 391 uint32_t toUInt32(v8::Handle<v8::Value> value) | 412 uint32_t toUInt32(v8::Handle<v8::Value> value) |
| 392 { | 413 { |
| 393 NonThrowableExceptionState exceptionState; | 414 NonThrowableExceptionState exceptionState; |
| 394 return toUInt32(value, NormalConversion, exceptionState); | 415 return toUInt32(value, NormalConversion, exceptionState); |
| 395 } | 416 } |
| 396 | 417 |
| 397 int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
iguration, ExceptionState& exceptionState) | 418 int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
iguration, ExceptionState& exceptionState) |
| 398 { | 419 { |
| 420 // Clamping not supported for int64_t/long long int. See Source/wtf/MathExtr
as.h. |
| 421 ASSERT(configuration != Clamp); |
| 422 |
| 399 // Fast case. The value is a 32-bit integer. | 423 // Fast case. The value is a 32-bit integer. |
| 400 if (value->IsInt32()) | 424 if (value->IsInt32()) |
| 401 return value->Int32Value(); | 425 return value->Int32Value(); |
| 402 | 426 |
| 403 // Can the value be converted to a number? | 427 // Can the value be converted to a number? |
| 404 v8::TryCatch block; | 428 v8::TryCatch block; |
| 405 v8::Local<v8::Number> numberObject(value->ToNumber()); | 429 v8::Local<v8::Number> numberObject(value->ToNumber()); |
| 406 if (block.HasCaught()) { | 430 if (block.HasCaught()) { |
| 407 exceptionState.rethrowV8Exception(block.Exception()); | 431 exceptionState.rethrowV8Exception(block.Exception()); |
| 408 return 0; | 432 return 0; |
| 409 } | 433 } |
| 410 | 434 |
| 411 ASSERT(!numberObject.IsEmpty()); | 435 ASSERT(!numberObject.IsEmpty()); |
| 412 | 436 |
| 413 double x = numberObject->Value(); | 437 double numberValue = numberObject->Value(); |
| 414 | 438 |
| 415 if (configuration == EnforceRange) | 439 if (configuration == EnforceRange) |
| 416 return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, "long long", excep
tionState); | 440 return enforceRange(numberValue, -kJSMaxInteger, kJSMaxInteger, "long lo
ng", exceptionState); |
| 417 | 441 |
| 418 // Does the value convert to nan or to an infinity? | 442 if (std::isnan(numberValue) || std::isinf(numberValue)) |
| 419 if (std::isnan(x) || std::isinf(x)) | |
| 420 return 0; | 443 return 0; |
| 421 | 444 |
| 422 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. | 445 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. |
| 423 unsigned long long integer; | 446 unsigned long long integer; |
| 424 doubleToInteger(x, integer); | 447 doubleToInteger(numberValue, integer); |
| 425 return integer; | 448 return integer; |
| 426 } | 449 } |
| 427 | 450 |
| 428 int64_t toInt64(v8::Handle<v8::Value> value) | 451 int64_t toInt64(v8::Handle<v8::Value> value) |
| 429 { | 452 { |
| 430 NonThrowableExceptionState exceptionState; | 453 NonThrowableExceptionState exceptionState; |
| 431 return toInt64(value, NormalConversion, exceptionState); | 454 return toInt64(value, NormalConversion, exceptionState); |
| 432 } | 455 } |
| 433 | 456 |
| 434 uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
nfiguration, ExceptionState& exceptionState) | 457 uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
nfiguration, ExceptionState& exceptionState) |
| 435 { | 458 { |
| 436 // Fast case. The value is a 32-bit unsigned integer. | 459 // Fast case. The value is a 32-bit unsigned integer. |
| 437 if (value->IsUint32()) | 460 if (value->IsUint32()) |
| 438 return value->Uint32Value(); | 461 return value->Uint32Value(); |
| 439 | 462 |
| 440 // Fast case. The value is a 32-bit integer. | 463 // Fast case. The value is a 32-bit integer. |
| 441 if (value->IsInt32()) { | 464 if (value->IsInt32()) { |
| 442 int32_t result = value->Int32Value(); | 465 int32_t result = value->Int32Value(); |
| 443 if (result >= 0) | 466 if (result >= 0) |
| 444 return result; | 467 return result; |
| 445 if (configuration == EnforceRange) { | 468 if (configuration == EnforceRange) { |
| 446 exceptionState.throwTypeError("Value is outside the 'unsigned long l
ong' value range."); | 469 exceptionState.throwTypeError("Value is outside the 'unsigned long l
ong' value range."); |
| 447 return 0; | 470 return 0; |
| 448 } | 471 } |
| 472 if (configuration == Clamp) |
| 473 return clampTo<uint64_t>(result); |
| 449 return result; | 474 return result; |
| 450 } | 475 } |
| 451 | 476 |
| 452 // Can the value be converted to a number? | 477 // Can the value be converted to a number? |
| 453 v8::TryCatch block; | 478 v8::TryCatch block; |
| 454 v8::Local<v8::Number> numberObject(value->ToNumber()); | 479 v8::Local<v8::Number> numberObject(value->ToNumber()); |
| 455 if (block.HasCaught()) { | 480 if (block.HasCaught()) { |
| 456 exceptionState.rethrowV8Exception(block.Exception()); | 481 exceptionState.rethrowV8Exception(block.Exception()); |
| 457 return 0; | 482 return 0; |
| 458 } | 483 } |
| 459 | 484 |
| 460 ASSERT(!numberObject.IsEmpty()); | 485 ASSERT(!numberObject.IsEmpty()); |
| 461 | 486 |
| 462 double x = numberObject->Value(); | 487 double numberValue = numberObject->Value(); |
| 463 | 488 |
| 464 if (configuration == EnforceRange) | 489 if (configuration == EnforceRange) |
| 465 return enforceRange(x, 0, kJSMaxInteger, "unsigned long long", exception
State); | 490 return enforceRange(numberValue, 0, kJSMaxInteger, "unsigned long long",
exceptionState); |
| 466 | 491 |
| 467 // Does the value convert to nan or to an infinity? | 492 if (std::isnan(numberValue)) |
| 468 if (std::isnan(x) || std::isinf(x)) | 493 return 0; |
| 494 |
| 495 if (configuration == Clamp) |
| 496 return clampTo<uint64_t>(numberValue); |
| 497 |
| 498 if (std::isinf(numberValue)) |
| 469 return 0; | 499 return 0; |
| 470 | 500 |
| 471 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. | 501 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. |
| 472 unsigned long long integer; | 502 unsigned long long integer; |
| 473 doubleToInteger(x, integer); | 503 doubleToInteger(numberValue, integer); |
| 474 return integer; | 504 return integer; |
| 475 } | 505 } |
| 476 | 506 |
| 477 uint64_t toUInt64(v8::Handle<v8::Value> value) | 507 uint64_t toUInt64(v8::Handle<v8::Value> value) |
| 478 { | 508 { |
| 479 NonThrowableExceptionState exceptionState; | 509 NonThrowableExceptionState exceptionState; |
| 480 return toUInt64(value, NormalConversion, exceptionState); | 510 return toUInt64(value, NormalConversion, exceptionState); |
| 481 } | 511 } |
| 482 | 512 |
| 483 float toFloat(v8::Handle<v8::Value> value, ExceptionState& exceptionState) | 513 float toFloat(v8::Handle<v8::Value> value, ExceptionState& exceptionState) |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 | 992 |
| 963 v8::Local<v8::Value> v8IteratorResult(v8::Isolate* isolate, v8::Handle<v8::Value
> value) | 993 v8::Local<v8::Value> v8IteratorResult(v8::Isolate* isolate, v8::Handle<v8::Value
> value) |
| 964 { | 994 { |
| 965 v8::Local<v8::Object> result = v8::Object::New(isolate); | 995 v8::Local<v8::Object> result = v8::Object::New(isolate); |
| 966 result->Set(v8String(isolate, "value"), value); | 996 result->Set(v8String(isolate, "value"), value); |
| 967 result->Set(v8String(isolate, "done"), v8Boolean(false, isolate)); | 997 result->Set(v8String(isolate, "done"), v8Boolean(false, isolate)); |
| 968 return result; | 998 return result; |
| 969 } | 999 } |
| 970 | 1000 |
| 971 } // namespace blink | 1001 } // namespace blink |
| OLD | NEW |