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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 result %= LimitsTrait::numberOfValues; | 200 result %= LimitsTrait::numberOfValues; |
201 return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTr
ait::numberOfValues : result); | 201 return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTr
ait::numberOfValues : result); |
202 } | 202 } |
203 | 203 |
204 // Can the value be converted to a number? | 204 // Can the value be converted to a number? |
205 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->
ToNumber(), exceptionState, 0); | 205 v8::TryCatch block; |
206 if (numberObject.IsEmpty()) { | 206 v8::Local<v8::Number> numberObject(value->ToNumber()); |
207 exceptionState.throwTypeError("Not convertible to a number value (of typ
e '" + String(typeName) + "'."); | 207 if (block.HasCaught()) { |
| 208 exceptionState.rethrowV8Exception(block.Exception()); |
208 return 0; | 209 return 0; |
209 } | 210 } |
210 | 211 |
| 212 ASSERT(!numberObject.IsEmpty()); |
| 213 |
211 if (configuration == EnforceRange) | 214 if (configuration == EnforceRange) |
212 return enforceRange(numberObject->Value(), LimitsTrait::minValue, Limits
Trait::maxValue, typeName, exceptionState); | 215 return enforceRange(numberObject->Value(), LimitsTrait::minValue, Limits
Trait::maxValue, typeName, exceptionState); |
213 | 216 |
214 double numberValue = numberObject->Value(); | 217 double numberValue = numberObject->Value(); |
215 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) | 218 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) |
216 return 0; | 219 return 0; |
217 | 220 |
218 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numbe
rValue)); | 221 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numbe
rValue)); |
219 numberValue = fmod(numberValue, LimitsTrait::numberOfValues); | 222 numberValue = fmod(numberValue, LimitsTrait::numberOfValues); |
220 | 223 |
(...skipping 11 matching lines...) Expand all Loading... |
232 if (result >= 0 && result <= LimitsTrait::maxValue) | 235 if (result >= 0 && result <= LimitsTrait::maxValue) |
233 return static_cast<T>(result); | 236 return static_cast<T>(result); |
234 if (configuration == EnforceRange) { | 237 if (configuration == EnforceRange) { |
235 exceptionState.throwTypeError("Value is outside the '" + String(type
Name) + "' value range."); | 238 exceptionState.throwTypeError("Value is outside the '" + String(type
Name) + "' value range."); |
236 return 0; | 239 return 0; |
237 } | 240 } |
238 return static_cast<T>(result); | 241 return static_cast<T>(result); |
239 } | 242 } |
240 | 243 |
241 // Can the value be converted to a number? | 244 // Can the value be converted to a number? |
242 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->
ToNumber(), exceptionState, 0); | 245 v8::TryCatch block; |
243 if (numberObject.IsEmpty()) { | 246 v8::Local<v8::Number> numberObject(value->ToNumber()); |
244 exceptionState.throwTypeError("Not convertible to a number value (of typ
e '" + String(typeName) + "'."); | 247 if (block.HasCaught()) { |
| 248 exceptionState.rethrowV8Exception(block.Exception()); |
245 return 0; | 249 return 0; |
246 } | 250 } |
247 | 251 |
| 252 ASSERT(!numberObject.IsEmpty()); |
| 253 |
248 if (configuration == EnforceRange) | 254 if (configuration == EnforceRange) |
249 return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typ
eName, exceptionState); | 255 return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typ
eName, exceptionState); |
250 | 256 |
251 // Does the value convert to nan or to an infinity? | 257 // Does the value convert to nan or to an infinity? |
252 double numberValue = numberObject->Value(); | 258 double numberValue = numberObject->Value(); |
253 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) | 259 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue) |
254 return 0; | 260 return 0; |
255 | 261 |
256 if (configuration == Clamp) | 262 if (configuration == Clamp) |
257 return clampTo<T>(numberObject->Value()); | 263 return clampTo<T>(numberObject->Value()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 return toUInt16(value, NormalConversion, exceptionState); | 310 return toUInt16(value, NormalConversion, exceptionState); |
305 } | 311 } |
306 | 312 |
307 int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
iguration, ExceptionState& exceptionState) | 313 int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
iguration, ExceptionState& exceptionState) |
308 { | 314 { |
309 // Fast case. The value is already a 32-bit integer. | 315 // Fast case. The value is already a 32-bit integer. |
310 if (value->IsInt32()) | 316 if (value->IsInt32()) |
311 return value->Int32Value(); | 317 return value->Int32Value(); |
312 | 318 |
313 // Can the value be converted to a number? | 319 // Can the value be converted to a number? |
314 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->
ToNumber(), exceptionState, 0); | 320 v8::TryCatch block; |
315 if (numberObject.IsEmpty()) { | 321 v8::Local<v8::Number> numberObject(value->ToNumber()); |
316 exceptionState.throwTypeError("Not convertible to a number value (of typ
e 'long'.)"); | 322 if (block.HasCaught()) { |
| 323 exceptionState.rethrowV8Exception(block.Exception()); |
317 return 0; | 324 return 0; |
318 } | 325 } |
319 | 326 |
| 327 ASSERT(!numberObject.IsEmpty()); |
| 328 |
320 if (configuration == EnforceRange) | 329 if (configuration == EnforceRange) |
321 return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long",
exceptionState); | 330 return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long",
exceptionState); |
322 | 331 |
323 // Does the value convert to nan or to an infinity? | 332 // Does the value convert to nan or to an infinity? |
324 double numberValue = numberObject->Value(); | 333 double numberValue = numberObject->Value(); |
325 if (std::isnan(numberValue) || std::isinf(numberValue)) | 334 if (std::isnan(numberValue) || std::isinf(numberValue)) |
326 return 0; | 335 return 0; |
327 | 336 |
328 if (configuration == Clamp) | 337 if (configuration == Clamp) |
329 return clampTo<int32_t>(numberObject->Value()); | 338 return clampTo<int32_t>(numberObject->Value()); |
330 | 339 |
331 TONATIVE_DEFAULT_EXCEPTIONSTATE(int32_t, result, numberObject->Int32Value(),
exceptionState, 0); | 340 return numberObject->Int32Value(); |
332 return result; | |
333 } | 341 } |
334 | 342 |
335 int32_t toInt32(v8::Handle<v8::Value> value) | 343 int32_t toInt32(v8::Handle<v8::Value> value) |
336 { | 344 { |
337 NonThrowableExceptionState exceptionState; | 345 NonThrowableExceptionState exceptionState; |
338 return toInt32(value, NormalConversion, exceptionState); | 346 return toInt32(value, NormalConversion, exceptionState); |
339 } | 347 } |
340 | 348 |
341 uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
nfiguration, ExceptionState& exceptionState) | 349 uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration co
nfiguration, ExceptionState& exceptionState) |
342 { | 350 { |
343 // Fast case. The value is already a 32-bit unsigned integer. | 351 // Fast case. The value is already a 32-bit unsigned integer. |
344 if (value->IsUint32()) | 352 if (value->IsUint32()) |
345 return value->Uint32Value(); | 353 return value->Uint32Value(); |
346 | 354 |
347 // Fast case. The value is a 32-bit signed integer - possibly positive? | 355 // Fast case. The value is a 32-bit signed integer - possibly positive? |
348 if (value->IsInt32()) { | 356 if (value->IsInt32()) { |
349 int32_t result = value->Int32Value(); | 357 int32_t result = value->Int32Value(); |
350 if (result >= 0) | 358 if (result >= 0) |
351 return result; | 359 return result; |
352 if (configuration == EnforceRange) { | 360 if (configuration == EnforceRange) { |
353 exceptionState.throwTypeError("Value is outside the 'unsigned long'
value range."); | 361 exceptionState.throwTypeError("Value is outside the 'unsigned long'
value range."); |
354 return 0; | 362 return 0; |
355 } | 363 } |
356 return result; | 364 return result; |
357 } | 365 } |
358 | 366 |
359 // Can the value be converted to a number? | 367 // Can the value be converted to a number? |
360 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->
ToNumber(), exceptionState, 0); | 368 v8::TryCatch block; |
361 if (numberObject.IsEmpty()) { | 369 v8::Local<v8::Number> numberObject(value->ToNumber()); |
362 exceptionState.throwTypeError("Not convertible to a number value (of typ
e 'unsigned long'.)"); | 370 if (block.HasCaught()) { |
| 371 exceptionState.rethrowV8Exception(block.Exception()); |
363 return 0; | 372 return 0; |
364 } | 373 } |
365 | 374 |
| 375 ASSERT(!numberObject.IsEmpty()); |
| 376 |
366 if (configuration == EnforceRange) | 377 if (configuration == EnforceRange) |
367 return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long
", exceptionState); | 378 return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long
", exceptionState); |
368 | 379 |
369 // Does the value convert to nan or to an infinity? | 380 // Does the value convert to nan or to an infinity? |
370 double numberValue = numberObject->Value(); | 381 double numberValue = numberObject->Value(); |
371 if (std::isnan(numberValue) || std::isinf(numberValue)) | 382 if (std::isnan(numberValue) || std::isinf(numberValue)) |
372 return 0; | 383 return 0; |
373 | 384 |
374 if (configuration == Clamp) | 385 if (configuration == Clamp) |
375 return clampTo<uint32_t>(numberObject->Value()); | 386 return clampTo<uint32_t>(numberObject->Value()); |
376 | 387 |
377 TONATIVE_DEFAULT(uint32_t, result, numberObject->Uint32Value(), 0); | 388 return numberObject->Uint32Value(); |
378 return result; | |
379 } | 389 } |
380 | 390 |
381 uint32_t toUInt32(v8::Handle<v8::Value> value) | 391 uint32_t toUInt32(v8::Handle<v8::Value> value) |
382 { | 392 { |
383 NonThrowableExceptionState exceptionState; | 393 NonThrowableExceptionState exceptionState; |
384 return toUInt32(value, NormalConversion, exceptionState); | 394 return toUInt32(value, NormalConversion, exceptionState); |
385 } | 395 } |
386 | 396 |
387 int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
iguration, ExceptionState& exceptionState) | 397 int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration conf
iguration, ExceptionState& exceptionState) |
388 { | 398 { |
389 // Fast case. The value is a 32-bit integer. | 399 // Fast case. The value is a 32-bit integer. |
390 if (value->IsInt32()) | 400 if (value->IsInt32()) |
391 return value->Int32Value(); | 401 return value->Int32Value(); |
392 | 402 |
393 // Can the value be converted to a number? | 403 // Can the value be converted to a number? |
394 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->
ToNumber(), exceptionState, 0); | 404 v8::TryCatch block; |
395 if (numberObject.IsEmpty()) { | 405 v8::Local<v8::Number> numberObject(value->ToNumber()); |
396 exceptionState.throwTypeError("Not convertible to a number value (of typ
e 'long long'.)"); | 406 if (block.HasCaught()) { |
| 407 exceptionState.rethrowV8Exception(block.Exception()); |
397 return 0; | 408 return 0; |
398 } | 409 } |
399 | 410 |
| 411 ASSERT(!numberObject.IsEmpty()); |
| 412 |
400 double x = numberObject->Value(); | 413 double x = numberObject->Value(); |
401 | 414 |
402 if (configuration == EnforceRange) | 415 if (configuration == EnforceRange) |
403 return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, "long long", excep
tionState); | 416 return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, "long long", excep
tionState); |
404 | 417 |
405 // Does the value convert to nan or to an infinity? | 418 // Does the value convert to nan or to an infinity? |
406 if (std::isnan(x) || std::isinf(x)) | 419 if (std::isnan(x) || std::isinf(x)) |
407 return 0; | 420 return 0; |
408 | 421 |
409 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. | 422 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. |
(...skipping 20 matching lines...) Expand all Loading... |
430 if (result >= 0) | 443 if (result >= 0) |
431 return result; | 444 return result; |
432 if (configuration == EnforceRange) { | 445 if (configuration == EnforceRange) { |
433 exceptionState.throwTypeError("Value is outside the 'unsigned long l
ong' value range."); | 446 exceptionState.throwTypeError("Value is outside the 'unsigned long l
ong' value range."); |
434 return 0; | 447 return 0; |
435 } | 448 } |
436 return result; | 449 return result; |
437 } | 450 } |
438 | 451 |
439 // Can the value be converted to a number? | 452 // Can the value be converted to a number? |
440 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->
ToNumber(), exceptionState, 0); | 453 v8::TryCatch block; |
441 if (numberObject.IsEmpty()) { | 454 v8::Local<v8::Number> numberObject(value->ToNumber()); |
442 exceptionState.throwTypeError("Not convertible to a number value (of typ
e 'unsigned long long'.)"); | 455 if (block.HasCaught()) { |
| 456 exceptionState.rethrowV8Exception(block.Exception()); |
443 return 0; | 457 return 0; |
444 } | 458 } |
445 | 459 |
| 460 ASSERT(!numberObject.IsEmpty()); |
| 461 |
446 double x = numberObject->Value(); | 462 double x = numberObject->Value(); |
447 | 463 |
448 if (configuration == EnforceRange) | 464 if (configuration == EnforceRange) |
449 return enforceRange(x, 0, kJSMaxInteger, "unsigned long long", exception
State); | 465 return enforceRange(x, 0, kJSMaxInteger, "unsigned long long", exception
State); |
450 | 466 |
451 // Does the value convert to nan or to an infinity? | 467 // Does the value convert to nan or to an infinity? |
452 if (std::isnan(x) || std::isinf(x)) | 468 if (std::isnan(x) || std::isinf(x)) |
453 return 0; | 469 return 0; |
454 | 470 |
455 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. | 471 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64. |
456 unsigned long long integer; | 472 unsigned long long integer; |
457 doubleToInteger(x, integer); | 473 doubleToInteger(x, integer); |
458 return integer; | 474 return integer; |
459 } | 475 } |
460 | 476 |
461 uint64_t toUInt64(v8::Handle<v8::Value> value) | 477 uint64_t toUInt64(v8::Handle<v8::Value> value) |
462 { | 478 { |
463 NonThrowableExceptionState exceptionState; | 479 NonThrowableExceptionState exceptionState; |
464 return toUInt64(value, NormalConversion, exceptionState); | 480 return toUInt64(value, NormalConversion, exceptionState); |
465 } | 481 } |
466 | 482 |
467 float toFloat(v8::Handle<v8::Value> value, ExceptionState& exceptionState) | 483 float toFloat(v8::Handle<v8::Value> value, ExceptionState& exceptionState) |
468 { | 484 { |
469 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::Number>, numberObject, value->
ToNumber(), exceptionState, 0); | 485 v8::TryCatch block; |
| 486 v8::Local<v8::Number> numberObject(value->ToNumber()); |
| 487 if (block.HasCaught()) { |
| 488 exceptionState.rethrowV8Exception(block.Exception()); |
| 489 return 0; |
| 490 } |
470 return numberObject->NumberValue(); | 491 return numberObject->NumberValue(); |
471 } | 492 } |
472 | 493 |
473 String toByteString(v8::Handle<v8::Value> value, ExceptionState& exceptionState) | 494 String toByteString(v8::Handle<v8::Value> value, ExceptionState& exceptionState) |
474 { | 495 { |
475 // Handle null default value. | 496 // Handle null default value. |
476 if (value.IsEmpty()) | 497 if (value.IsEmpty()) |
477 return String(); | 498 return String(); |
478 | 499 |
479 // From the Web IDL spec: http://heycam.github.io/webidl/#es-ByteString | 500 // From the Web IDL spec: http://heycam.github.io/webidl/#es-ByteString |
480 if (value.IsEmpty()) | 501 if (value.IsEmpty()) |
481 return String(); | 502 return String(); |
482 | 503 |
483 // 1. Let x be ToString(v) | 504 // 1. Let x be ToString(v) |
484 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value->
ToString(), exceptionState, String()); | 505 v8::TryCatch block; |
| 506 v8::Local<v8::String> stringObject(value->ToString()); |
| 507 if (block.HasCaught()) { |
| 508 exceptionState.rethrowV8Exception(block.Exception()); |
| 509 return String(); |
| 510 } |
| 511 |
485 String x = toCoreString(stringObject); | 512 String x = toCoreString(stringObject); |
486 | 513 |
487 // 2. If the value of any element of x is greater than 255, then throw a Typ
eError. | 514 // 2. If the value of any element of x is greater than 255, then throw a Typ
eError. |
488 if (!x.containsOnlyLatin1()) { | 515 if (!x.containsOnlyLatin1()) { |
489 exceptionState.throwTypeError("Value is not a valid ByteString."); | 516 exceptionState.throwTypeError("Value is not a valid ByteString."); |
490 return String(); | 517 return String(); |
491 } | 518 } |
492 | 519 |
493 // 3. Return an IDL ByteString value whose length is the length of x, and wh
ere the | 520 // 3. Return an IDL ByteString value whose length is the length of x, and wh
ere the |
494 // value of each element is the value of the corresponding element of x. | 521 // value of each element is the value of the corresponding element of x. |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 ASSERT(u.length() == string.length()); | 625 ASSERT(u.length() == string.length()); |
599 return u.toString(); | 626 return u.toString(); |
600 } | 627 } |
601 | 628 |
602 String toScalarValueString(v8::Handle<v8::Value> value, ExceptionState& exceptio
nState) | 629 String toScalarValueString(v8::Handle<v8::Value> value, ExceptionState& exceptio
nState) |
603 { | 630 { |
604 // From the Encoding standard (with a TODO to move to Web IDL): | 631 // From the Encoding standard (with a TODO to move to Web IDL): |
605 // http://encoding.spec.whatwg.org/#type-scalarvaluestring | 632 // http://encoding.spec.whatwg.org/#type-scalarvaluestring |
606 if (value.IsEmpty()) | 633 if (value.IsEmpty()) |
607 return String(); | 634 return String(); |
608 TONATIVE_DEFAULT_EXCEPTIONSTATE(v8::Local<v8::String>, stringObject, value->
ToString(), exceptionState, String()); | 635 |
| 636 v8::TryCatch block; |
| 637 v8::Local<v8::String> stringObject(value->ToString()); |
| 638 if (block.HasCaught()) { |
| 639 exceptionState.rethrowV8Exception(block.Exception()); |
| 640 return String(); |
| 641 } |
609 | 642 |
610 // ScalarValueString is identical to DOMString except that "convert a | 643 // ScalarValueString is identical to DOMString except that "convert a |
611 // DOMString to a sequence of Unicode characters" is used subsequently | 644 // DOMString to a sequence of Unicode characters" is used subsequently |
612 // when converting to an IDL value | 645 // when converting to an IDL value |
613 String x = toCoreString(stringObject); | 646 String x = toCoreString(stringObject); |
614 return replaceUnmatchedSurrogates(x); | 647 return replaceUnmatchedSurrogates(x); |
615 } | 648 } |
616 | 649 |
617 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>
value, v8::Isolate* isolate) | 650 PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>
value, v8::Isolate* isolate) |
618 { | 651 { |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 | 953 |
921 v8::Local<v8::Value> v8IteratorResult(v8::Isolate* isolate, v8::Handle<v8::Value
> value) | 954 v8::Local<v8::Value> v8IteratorResult(v8::Isolate* isolate, v8::Handle<v8::Value
> value) |
922 { | 955 { |
923 v8::Local<v8::Object> result = v8::Object::New(isolate); | 956 v8::Local<v8::Object> result = v8::Object::New(isolate); |
924 result->Set(v8String(isolate, "value"), value); | 957 result->Set(v8String(isolate, "value"), value); |
925 result->Set(v8String(isolate, "done"), v8Boolean(false, isolate)); | 958 result->Set(v8String(isolate, "done"), v8Boolean(false, isolate)); |
926 return result; | 959 return result; |
927 } | 960 } |
928 | 961 |
929 } // namespace blink | 962 } // namespace blink |
OLD | NEW |