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 |