Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2012 Ericsson AB. All rights reserved. | 3 * Copyright (C) 2012 Ericsson AB. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| 11 * * Redistributions in binary form must reproduce the above | 11 * * Redistributions in binary form must reproduce the above |
| 12 * copyright notice, this list of conditions and the following disclaimer | 12 * copyright notice, this list of conditions and the following disclaimer |
| 13 * in the documentation and/or other materials provided with the | 13 * in the documentation and/or other materials provided with the |
| 14 * distribution. | 14 * distribution. |
| 15 * * Neither the name of Google Inc. nor the names of its | 15 * * Neither the name of Google Inc. nor the names of its |
| 16 * contributors may be used to endorse or promote products derived from | 16 * contributors may be used to endorse or promote products derived from |
| 17 * this software without specific prior written permission. | 17 * this software without specific prior written permission. |
| 18 * | 18 * |
| 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ | 30 */ |
| 31 | 31 |
| 32 #ifndef V8Binding_h | 32 #ifndef V8Binding_h |
| 33 #define V8Binding_h | 33 #define V8Binding_h |
| 34 | 34 |
| 35 #include "bindings/core/v8/DOMDataStore.h" | 35 #include "bindings/core/v8/DOMDataStore.h" |
| 36 #include "bindings/core/v8/DOMWrapperWorld.h" | 36 #include "bindings/core/v8/DOMWrapperWorld.h" |
| 37 #include "bindings/core/v8/ExceptionMessages.h" | |
| 38 #include "bindings/core/v8/ExceptionState.h" | |
| 39 #include "bindings/core/v8/NativeValueTraits.h" | |
| 40 #include "bindings/core/v8/ScriptState.h" | |
| 41 #include "bindings/core/v8/ScriptValue.h" | |
| 42 #include "bindings/core/v8/ScriptWrappable.h" | 37 #include "bindings/core/v8/ScriptWrappable.h" |
| 38 #include "bindings/core/v8/StringResource.h" | |
| 43 #include "bindings/core/v8/V8BindingMacros.h" | 39 #include "bindings/core/v8/V8BindingMacros.h" |
| 44 #include "bindings/core/v8/V8PerIsolateData.h" | 40 #include "bindings/core/v8/V8PerIsolateData.h" |
| 45 #include "bindings/core/v8/V8ScriptRunner.h" | 41 #include "bindings/core/v8/V8ScriptRunner.h" |
| 46 #include "bindings/core/v8/V8StringResource.h" | |
| 47 #include "bindings/core/v8/V8ThrowException.h" | |
| 48 #include "bindings/core/v8/V8ValueCache.h" | 42 #include "bindings/core/v8/V8ValueCache.h" |
| 49 #include "core/CoreExport.h" | 43 #include "core/CoreExport.h" |
| 50 #include "core/dom/ArrayBufferViewHelpers.h" | |
| 51 #include "platform/heap/Handle.h" | 44 #include "platform/heap/Handle.h" |
| 52 #include "platform/wtf/text/AtomicString.h" | 45 #include "platform/wtf/text/AtomicString.h" |
| 53 #include "platform/wtf/text/StringView.h" | 46 #include "platform/wtf/text/StringView.h" |
| 54 #include "v8/include/v8.h" | 47 #include "v8/include/v8.h" |
| 55 | 48 |
| 56 namespace blink { | 49 namespace blink { |
| 57 | 50 |
|
haraken
2017/04/21 20:09:41
Would you add a comment and mention what should be
adithyas
2017/04/24 14:38:27
Done.
| |
| 58 class DOMWindow; | |
| 59 class EventListener; | |
| 60 class ExceptionState; | |
| 61 class ExecutionContext; | |
| 62 class FlexibleArrayBufferView; | |
| 63 class Frame; | |
| 64 class LocalDOMWindow; | |
| 65 class LocalFrame; | |
| 66 class NodeFilter; | |
| 67 class XPathNSResolver; | |
| 68 | |
| 69 template <typename T> | 51 template <typename T> |
| 70 struct V8TypeOf { | 52 struct V8TypeOf { |
| 71 STATIC_ONLY(V8TypeOf); | 53 STATIC_ONLY(V8TypeOf); |
| 72 // |Type| provides C++ -> V8 type conversion for DOM wrappers. | 54 // |Type| provides C++ -> V8 type conversion for DOM wrappers. |
| 73 // The Blink binding code generator will generate specialized version of | 55 // The Blink binding code generator will generate specialized version of |
| 74 // V8TypeOf for each wrapper class. | 56 // V8TypeOf for each wrapper class. |
| 75 typedef void Type; | 57 typedef void Type; |
| 76 }; | 58 }; |
| 77 | 59 |
| 78 template <typename CallbackInfo, typename S> | 60 template <typename CallbackInfo, typename S> |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 impl->Wrap(callback_info.GetIsolate(), creation_context); | 164 impl->Wrap(callback_info.GetIsolate(), creation_context); |
| 183 V8SetReturnValue(callback_info, wrapper); | 165 V8SetReturnValue(callback_info, wrapper); |
| 184 } | 166 } |
| 185 | 167 |
| 186 template <typename CallbackInfo> | 168 template <typename CallbackInfo> |
| 187 inline void V8SetReturnValue(const CallbackInfo& callback_info, | 169 inline void V8SetReturnValue(const CallbackInfo& callback_info, |
| 188 ScriptWrappable* impl) { | 170 ScriptWrappable* impl) { |
| 189 V8SetReturnValue(callback_info, impl, callback_info.Holder()); | 171 V8SetReturnValue(callback_info, impl, callback_info.Holder()); |
| 190 } | 172 } |
| 191 | 173 |
| 192 template <typename CallbackInfo> | |
| 193 inline void V8SetReturnValue(const CallbackInfo& callback_info, Node* impl) { | |
| 194 V8SetReturnValue(callback_info, ScriptWrappable::FromNode(impl)); | |
| 195 } | |
| 196 | |
| 197 template <typename CallbackInfo, typename T> | 174 template <typename CallbackInfo, typename T> |
| 198 inline void V8SetReturnValue(const CallbackInfo& callback_info, | 175 inline void V8SetReturnValue(const CallbackInfo& callback_info, |
| 199 PassRefPtr<T> impl) { | 176 PassRefPtr<T> impl) { |
| 200 V8SetReturnValue(callback_info, impl.Get()); | 177 V8SetReturnValue(callback_info, impl.Get()); |
| 201 } | 178 } |
| 202 | 179 |
| 203 template <typename CallbackInfo, typename T> | |
| 204 inline void V8SetReturnValue(const CallbackInfo& callbackInfo, | |
| 205 NotShared<T> notShared) { | |
| 206 V8SetReturnValue(callbackInfo, notShared.View()); | |
| 207 } | |
| 208 | |
| 209 template <typename CallbackInfo> | 180 template <typename CallbackInfo> |
| 210 inline void V8SetReturnValueForMainWorld(const CallbackInfo& callback_info, | 181 inline void V8SetReturnValueForMainWorld(const CallbackInfo& callback_info, |
| 211 ScriptWrappable* impl) { | 182 ScriptWrappable* impl) { |
| 212 DCHECK(DOMWrapperWorld::Current(callback_info.GetIsolate()).IsMainWorld()); | 183 DCHECK(DOMWrapperWorld::Current(callback_info.GetIsolate()).IsMainWorld()); |
| 213 if (UNLIKELY(!impl)) { | 184 if (UNLIKELY(!impl)) { |
| 214 V8SetReturnValueNull(callback_info); | 185 V8SetReturnValueNull(callback_info); |
| 215 return; | 186 return; |
| 216 } | 187 } |
| 217 if (DOMDataStore::SetReturnValueForMainWorld(callback_info.GetReturnValue(), | 188 if (DOMDataStore::SetReturnValueForMainWorld(callback_info.GetReturnValue(), |
| 218 impl)) | 189 impl)) |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 237 return; | 208 return; |
| 238 } | 209 } |
| 239 if (DOMDataStore::SetReturnValueFast(callback_info.GetReturnValue(), impl, | 210 if (DOMDataStore::SetReturnValueFast(callback_info.GetReturnValue(), impl, |
| 240 callback_info.Holder(), wrappable)) | 211 callback_info.Holder(), wrappable)) |
| 241 return; | 212 return; |
| 242 v8::Local<v8::Object> wrapper = | 213 v8::Local<v8::Object> wrapper = |
| 243 impl->Wrap(callback_info.GetIsolate(), callback_info.Holder()); | 214 impl->Wrap(callback_info.GetIsolate(), callback_info.Holder()); |
| 244 V8SetReturnValue(callback_info, wrapper); | 215 V8SetReturnValue(callback_info, wrapper); |
| 245 } | 216 } |
| 246 | 217 |
| 247 template <typename CallbackInfo> | |
| 248 inline void V8SetReturnValueFast(const CallbackInfo& callback_info, | |
| 249 Node* impl, | |
| 250 const ScriptWrappable* wrappable) { | |
| 251 V8SetReturnValueFast(callback_info, ScriptWrappable::FromNode(impl), | |
| 252 wrappable); | |
| 253 } | |
| 254 | |
| 255 template <typename CallbackInfo, typename T, typename Wrappable> | 218 template <typename CallbackInfo, typename T, typename Wrappable> |
| 256 inline void V8SetReturnValueFast(const CallbackInfo& callback_info, | 219 inline void V8SetReturnValueFast(const CallbackInfo& callback_info, |
| 257 PassRefPtr<T> impl, | 220 PassRefPtr<T> impl, |
| 258 const Wrappable* wrappable) { | 221 const Wrappable* wrappable) { |
| 259 V8SetReturnValueFast(callback_info, impl.Get(), wrappable); | 222 V8SetReturnValueFast(callback_info, impl.Get(), wrappable); |
| 260 } | 223 } |
| 261 | 224 |
| 262 template <typename CallbackInfo, typename T> | 225 template <typename CallbackInfo, typename T> |
| 263 inline void V8SetReturnValueFast(const CallbackInfo& callback_info, | 226 inline void V8SetReturnValueFast(const CallbackInfo& callback_info, |
| 264 const v8::Local<T> handle, | 227 const v8::Local<T> handle, |
| 265 const ScriptWrappable*) { | 228 const ScriptWrappable*) { |
| 266 V8SetReturnValue(callback_info, handle); | 229 V8SetReturnValue(callback_info, handle); |
| 267 } | 230 } |
| 268 | 231 |
| 269 template <typename CallbackInfo, typename T> | |
| 270 inline void V8SetReturnValueFast(const CallbackInfo& callbackInfo, | |
| 271 NotShared<T> notShared, | |
| 272 const ScriptWrappable* wrappable) { | |
| 273 V8SetReturnValueFast(callbackInfo, notShared.View(), wrappable); | |
| 274 } | |
| 275 | |
| 276 // Convert v8::String to a WTF::String. If the V8 string is not already | 232 // Convert v8::String to a WTF::String. If the V8 string is not already |
| 277 // an external string then it is transformed into an external string at this | 233 // an external string then it is transformed into an external string at this |
| 278 // point to avoid repeated conversions. | 234 // point to avoid repeated conversions. |
| 279 inline String ToCoreString(v8::Local<v8::String> value) { | 235 inline String ToCoreString(v8::Local<v8::String> value) { |
| 280 return V8StringToWebCoreString<String>(value, kExternalize); | 236 return V8StringToWebCoreString<String>(value, kExternalize); |
| 281 } | 237 } |
| 282 | 238 |
| 283 inline String ToCoreStringWithNullCheck(v8::Local<v8::String> value) { | 239 inline String ToCoreStringWithNullCheck(v8::Local<v8::String> value) { |
| 284 if (value.IsEmpty() || value->IsNull()) | 240 if (value.IsEmpty() || value->IsNull()) |
| 285 return String(); | 241 return String(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 DCHECK(isolate); | 340 DCHECK(isolate); |
| 385 return v8::String::NewFromUtf8(isolate, bytes, v8::NewStringType::kNormal, | 341 return v8::String::NewFromUtf8(isolate, bytes, v8::NewStringType::kNormal, |
| 386 length) | 342 length) |
| 387 .ToLocalChecked(); | 343 .ToLocalChecked(); |
| 388 } | 344 } |
| 389 | 345 |
| 390 inline v8::Local<v8::Value> V8Undefined() { | 346 inline v8::Local<v8::Value> V8Undefined() { |
| 391 return v8::Local<v8::Value>(); | 347 return v8::Local<v8::Value>(); |
| 392 } | 348 } |
| 393 | 349 |
| 394 // Conversion flags, used in toIntXX/toUIntXX. | |
| 395 enum IntegerConversionConfiguration { | |
| 396 kNormalConversion, | |
| 397 kEnforceRange, | |
| 398 kClamp | |
| 399 }; | |
| 400 | |
| 401 // Convert a value to a boolean. | |
| 402 CORE_EXPORT bool ToBooleanSlow(v8::Isolate*, | |
| 403 v8::Local<v8::Value>, | |
| 404 ExceptionState&); | |
| 405 inline bool ToBoolean(v8::Isolate* isolate, | |
| 406 v8::Local<v8::Value> value, | |
| 407 ExceptionState& exception_state) { | |
| 408 if (LIKELY(value->IsBoolean())) | |
| 409 return value.As<v8::Boolean>()->Value(); | |
| 410 return ToBooleanSlow(isolate, value, exception_state); | |
| 411 } | |
| 412 | |
| 413 // Convert a value to a 8-bit signed integer. The conversion fails if the | |
| 414 // value cannot be converted to a number or the range violated per WebIDL: | |
| 415 // http://www.w3.org/TR/WebIDL/#es-byte | |
| 416 CORE_EXPORT int8_t ToInt8(v8::Isolate*, | |
| 417 v8::Local<v8::Value>, | |
| 418 IntegerConversionConfiguration, | |
| 419 ExceptionState&); | |
| 420 | |
| 421 // Convert a value to a 8-bit unsigned integer. The conversion fails if the | |
| 422 // value cannot be converted to a number or the range violated per WebIDL: | |
| 423 // http://www.w3.org/TR/WebIDL/#es-octet | |
| 424 CORE_EXPORT uint8_t ToUInt8(v8::Isolate*, | |
| 425 v8::Local<v8::Value>, | |
| 426 IntegerConversionConfiguration, | |
| 427 ExceptionState&); | |
| 428 | |
| 429 // Convert a value to a 16-bit signed integer. The conversion fails if the | |
| 430 // value cannot be converted to a number or the range violated per WebIDL: | |
| 431 // http://www.w3.org/TR/WebIDL/#es-short | |
| 432 CORE_EXPORT int16_t ToInt16(v8::Isolate*, | |
| 433 v8::Local<v8::Value>, | |
| 434 IntegerConversionConfiguration, | |
| 435 ExceptionState&); | |
| 436 | |
| 437 // Convert a value to a 16-bit unsigned integer. The conversion fails if the | |
| 438 // value cannot be converted to a number or the range violated per WebIDL: | |
| 439 // http://www.w3.org/TR/WebIDL/#es-unsigned-short | |
| 440 CORE_EXPORT uint16_t ToUInt16(v8::Isolate*, | |
| 441 v8::Local<v8::Value>, | |
| 442 IntegerConversionConfiguration, | |
| 443 ExceptionState&); | |
| 444 | |
| 445 // Convert a value to a 32-bit signed integer. The conversion fails if the | |
| 446 // value cannot be converted to a number or the range violated per WebIDL: | |
| 447 // http://www.w3.org/TR/WebIDL/#es-long | |
| 448 CORE_EXPORT int32_t ToInt32Slow(v8::Isolate*, | |
| 449 v8::Local<v8::Value>, | |
| 450 IntegerConversionConfiguration, | |
| 451 ExceptionState&); | |
| 452 inline int32_t ToInt32(v8::Isolate* isolate, | |
| 453 v8::Local<v8::Value> value, | |
| 454 IntegerConversionConfiguration configuration, | |
| 455 ExceptionState& exception_state) { | |
| 456 // Fast case. The value is already a 32-bit integer. | |
| 457 if (LIKELY(value->IsInt32())) | |
| 458 return value.As<v8::Int32>()->Value(); | |
| 459 return ToInt32Slow(isolate, value, configuration, exception_state); | |
| 460 } | |
| 461 | |
| 462 // Convert a value to a 32-bit unsigned integer. The conversion fails if the | |
| 463 // value cannot be converted to a number or the range violated per WebIDL: | |
| 464 // http://www.w3.org/TR/WebIDL/#es-unsigned-long | |
| 465 CORE_EXPORT uint32_t ToUInt32Slow(v8::Isolate*, | |
| 466 v8::Local<v8::Value>, | |
| 467 IntegerConversionConfiguration, | |
| 468 ExceptionState&); | |
| 469 inline uint32_t ToUInt32(v8::Isolate* isolate, | |
| 470 v8::Local<v8::Value> value, | |
| 471 IntegerConversionConfiguration configuration, | |
| 472 ExceptionState& exception_state) { | |
| 473 // Fast case. The value is already a 32-bit unsigned integer. | |
| 474 if (LIKELY(value->IsUint32())) | |
| 475 return value.As<v8::Uint32>()->Value(); | |
| 476 | |
| 477 // Fast case. The value is a 32-bit signed integer with NormalConversion | |
| 478 // configuration. | |
| 479 if (LIKELY(value->IsInt32() && configuration == kNormalConversion)) | |
| 480 return value.As<v8::Int32>()->Value(); | |
| 481 | |
| 482 return ToUInt32Slow(isolate, value, configuration, exception_state); | |
| 483 } | |
| 484 | |
| 485 // Convert a value to a 64-bit signed integer. The conversion fails if the | |
| 486 // value cannot be converted to a number or the range violated per WebIDL: | |
| 487 // http://www.w3.org/TR/WebIDL/#es-long-long | |
| 488 CORE_EXPORT int64_t ToInt64Slow(v8::Isolate*, | |
| 489 v8::Local<v8::Value>, | |
| 490 IntegerConversionConfiguration, | |
| 491 ExceptionState&); | |
| 492 inline int64_t ToInt64(v8::Isolate* isolate, | |
| 493 v8::Local<v8::Value> value, | |
| 494 IntegerConversionConfiguration configuration, | |
| 495 ExceptionState& exception_state) { | |
| 496 // Clamping not supported for int64_t/long long int. See | |
| 497 // Source/wtf/MathExtras.h. | |
| 498 DCHECK_NE(configuration, kClamp); | |
| 499 | |
| 500 // Fast case. The value is a 32-bit integer. | |
| 501 if (LIKELY(value->IsInt32())) | |
| 502 return value.As<v8::Int32>()->Value(); | |
| 503 | |
| 504 return ToInt64Slow(isolate, value, configuration, exception_state); | |
| 505 } | |
| 506 | |
| 507 // Convert a value to a 64-bit unsigned integer. The conversion fails if the | |
| 508 // value cannot be converted to a number or the range violated per WebIDL: | |
| 509 // http://www.w3.org/TR/WebIDL/#es-unsigned-long-long | |
| 510 CORE_EXPORT uint64_t ToUInt64Slow(v8::Isolate*, | |
| 511 v8::Local<v8::Value>, | |
| 512 IntegerConversionConfiguration, | |
| 513 ExceptionState&); | |
| 514 inline uint64_t ToUInt64(v8::Isolate* isolate, | |
| 515 v8::Local<v8::Value> value, | |
| 516 IntegerConversionConfiguration configuration, | |
| 517 ExceptionState& exception_state) { | |
| 518 // Fast case. The value is a 32-bit unsigned integer. | |
| 519 if (LIKELY(value->IsUint32())) | |
| 520 return value.As<v8::Uint32>()->Value(); | |
| 521 | |
| 522 if (LIKELY(value->IsInt32() && configuration == kNormalConversion)) | |
| 523 return value.As<v8::Int32>()->Value(); | |
| 524 | |
| 525 return ToUInt64Slow(isolate, value, configuration, exception_state); | |
| 526 } | |
| 527 | |
| 528 // Convert a value to a double precision float, which might fail. | |
| 529 CORE_EXPORT double ToDoubleSlow(v8::Isolate*, | |
| 530 v8::Local<v8::Value>, | |
| 531 ExceptionState&); | |
| 532 inline double ToDouble(v8::Isolate* isolate, | |
| 533 v8::Local<v8::Value> value, | |
| 534 ExceptionState& exception_state) { | |
| 535 if (LIKELY(value->IsNumber())) | |
| 536 return value.As<v8::Number>()->Value(); | |
| 537 return ToDoubleSlow(isolate, value, exception_state); | |
| 538 } | |
| 539 | |
| 540 // Convert a value to a double precision float, throwing on non-finite values. | |
| 541 CORE_EXPORT double ToRestrictedDouble(v8::Isolate*, | |
| 542 v8::Local<v8::Value>, | |
| 543 ExceptionState&); | |
| 544 | |
| 545 // Convert a value to a single precision float, which might fail. | |
| 546 inline float ToFloat(v8::Isolate* isolate, | |
| 547 v8::Local<v8::Value> value, | |
| 548 ExceptionState& exception_state) { | |
| 549 return static_cast<float>(ToDouble(isolate, value, exception_state)); | |
| 550 } | |
| 551 | |
| 552 // Convert a value to a single precision float, throwing on non-finite values. | |
| 553 CORE_EXPORT float ToRestrictedFloat(v8::Isolate*, | |
| 554 v8::Local<v8::Value>, | |
| 555 ExceptionState&); | |
| 556 | |
| 557 // Converts a value to a String, throwing if any code unit is outside 0-255. | |
| 558 CORE_EXPORT String ToByteString(v8::Isolate*, | |
| 559 v8::Local<v8::Value>, | |
| 560 ExceptionState&); | |
| 561 | |
| 562 // Converts a value to a String, replacing unmatched UTF-16 surrogates with | |
| 563 // replacement characters. | |
| 564 CORE_EXPORT String ToUSVString(v8::Isolate*, | |
| 565 v8::Local<v8::Value>, | |
| 566 ExceptionState&); | |
| 567 | |
| 568 inline v8::Local<v8::Boolean> V8Boolean(bool value, v8::Isolate* isolate) { | 350 inline v8::Local<v8::Boolean> V8Boolean(bool value, v8::Isolate* isolate) { |
| 569 return value ? v8::True(isolate) : v8::False(isolate); | 351 return value ? v8::True(isolate) : v8::False(isolate); |
| 570 } | 352 } |
| 571 | 353 |
| 572 inline double ToCoreDate(v8::Isolate* isolate, | |
| 573 v8::Local<v8::Value> object, | |
| 574 ExceptionState& exception_state) { | |
| 575 if (object->IsNull()) | |
| 576 return std::numeric_limits<double>::quiet_NaN(); | |
| 577 if (!object->IsDate()) { | |
| 578 exception_state.ThrowTypeError("The provided value is not a Date."); | |
| 579 return 0; | |
| 580 } | |
| 581 return object.As<v8::Date>()->ValueOf(); | |
| 582 } | |
| 583 | |
| 584 inline v8::MaybeLocal<v8::Value> V8DateOrNaN(v8::Isolate* isolate, | 354 inline v8::MaybeLocal<v8::Value> V8DateOrNaN(v8::Isolate* isolate, |
| 585 double value) { | 355 double value) { |
| 586 DCHECK(isolate); | 356 DCHECK(isolate); |
| 587 return v8::Date::New(isolate->GetCurrentContext(), value); | 357 return v8::Date::New(isolate->GetCurrentContext(), value); |
| 588 } | 358 } |
| 589 | 359 |
| 590 // FIXME: Remove the special casing for NodeFilter and XPathNSResolver. | |
| 591 NodeFilter* ToNodeFilter(v8::Local<v8::Value>, | |
| 592 v8::Local<v8::Object>, | |
| 593 ScriptState*); | |
| 594 XPathNSResolver* ToXPathNSResolver(ScriptState*, v8::Local<v8::Value>); | |
| 595 | |
| 596 bool ToV8Sequence(v8::Local<v8::Value>, | |
| 597 uint32_t& length, | |
| 598 v8::Isolate*, | |
| 599 ExceptionState&); | |
| 600 | |
| 601 template <typename T> | |
| 602 HeapVector<Member<T>> ToMemberNativeArray(v8::Local<v8::Value> value, | |
| 603 int argument_index, | |
| 604 v8::Isolate* isolate, | |
| 605 ExceptionState& exception_state) { | |
| 606 v8::Local<v8::Value> v8_value(v8::Local<v8::Value>::New(isolate, value)); | |
| 607 uint32_t length = 0; | |
| 608 if (value->IsArray()) { | |
| 609 length = v8::Local<v8::Array>::Cast(v8_value)->Length(); | |
| 610 } else if (!ToV8Sequence(value, length, isolate, exception_state)) { | |
| 611 if (!exception_state.HadException()) | |
| 612 exception_state.ThrowTypeError( | |
| 613 ExceptionMessages::NotAnArrayTypeArgumentOrValue(argument_index)); | |
| 614 return HeapVector<Member<T>>(); | |
| 615 } | |
| 616 | |
| 617 using VectorType = HeapVector<Member<T>>; | |
| 618 if (length > VectorType::MaxCapacity()) { | |
| 619 exception_state.ThrowRangeError("Array length exceeds supported limit."); | |
| 620 return VectorType(); | |
| 621 } | |
| 622 | |
| 623 VectorType result; | |
| 624 result.ReserveInitialCapacity(length); | |
| 625 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8_value); | |
| 626 v8::TryCatch block(isolate); | |
| 627 for (uint32_t i = 0; i < length; ++i) { | |
| 628 v8::Local<v8::Value> element; | |
| 629 if (!V8Call(object->Get(isolate->GetCurrentContext(), i), element, block)) { | |
| 630 exception_state.RethrowV8Exception(block.Exception()); | |
| 631 return VectorType(); | |
| 632 } | |
| 633 if (V8TypeOf<T>::Type::hasInstance(element, isolate)) { | |
| 634 v8::Local<v8::Object> element_object = | |
| 635 v8::Local<v8::Object>::Cast(element); | |
| 636 result.UncheckedAppend(V8TypeOf<T>::Type::toImpl(element_object)); | |
| 637 } else { | |
| 638 exception_state.ThrowTypeError("Invalid Array element type"); | |
| 639 return VectorType(); | |
| 640 } | |
| 641 } | |
| 642 return result; | |
| 643 } | |
| 644 | |
| 645 template <typename T> | |
| 646 HeapVector<Member<T>> ToMemberNativeArray(v8::Local<v8::Value> value, | |
| 647 const String& property_name, | |
| 648 v8::Isolate* isolate, | |
| 649 ExceptionState& exception_state) { | |
| 650 v8::Local<v8::Value> v8_value(v8::Local<v8::Value>::New(isolate, value)); | |
| 651 uint32_t length = 0; | |
| 652 if (value->IsArray()) { | |
| 653 length = v8::Local<v8::Array>::Cast(v8_value)->Length(); | |
| 654 } else if (!ToV8Sequence(value, length, isolate, exception_state)) { | |
| 655 if (!exception_state.HadException()) | |
| 656 exception_state.ThrowTypeError( | |
| 657 ExceptionMessages::NotASequenceTypeProperty(property_name)); | |
| 658 return HeapVector<Member<T>>(); | |
| 659 } | |
| 660 | |
| 661 using VectorType = HeapVector<Member<T>>; | |
| 662 if (length > VectorType::MaxCapacity()) { | |
| 663 exception_state.ThrowRangeError("Array length exceeds supported limit."); | |
| 664 return VectorType(); | |
| 665 } | |
| 666 | |
| 667 VectorType result; | |
| 668 result.ReserveInitialCapacity(length); | |
| 669 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8_value); | |
| 670 v8::TryCatch block(isolate); | |
| 671 for (uint32_t i = 0; i < length; ++i) { | |
| 672 v8::Local<v8::Value> element; | |
| 673 if (!V8Call(object->Get(isolate->GetCurrentContext(), i), element, block)) { | |
| 674 exception_state.RethrowV8Exception(block.Exception()); | |
| 675 return VectorType(); | |
| 676 } | |
| 677 if (V8TypeOf<T>::Type::hasInstance(element, isolate)) { | |
| 678 v8::Local<v8::Object> element_object = | |
| 679 v8::Local<v8::Object>::Cast(element); | |
| 680 result.UncheckedAppend(V8TypeOf<T>::Type::toImpl(element_object)); | |
| 681 } else { | |
| 682 exception_state.ThrowTypeError("Invalid Array element type"); | |
| 683 return VectorType(); | |
| 684 } | |
| 685 } | |
| 686 return result; | |
| 687 } | |
| 688 | |
| 689 // Converts a JavaScript value to an array as per the Web IDL specification: | |
| 690 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array | |
| 691 template <typename VectorType, | |
| 692 typename ValueType = typename VectorType::ValueType> | |
| 693 VectorType ToImplArray(v8::Local<v8::Value> value, | |
| 694 int argument_index, | |
| 695 v8::Isolate* isolate, | |
| 696 ExceptionState& exception_state) { | |
| 697 typedef NativeValueTraits<ValueType> TraitsType; | |
| 698 | |
| 699 uint32_t length = 0; | |
| 700 if (value->IsArray()) { | |
| 701 length = v8::Local<v8::Array>::Cast(value)->Length(); | |
| 702 } else if (!ToV8Sequence(value, length, isolate, exception_state)) { | |
| 703 if (!exception_state.HadException()) | |
| 704 exception_state.ThrowTypeError( | |
| 705 ExceptionMessages::NotAnArrayTypeArgumentOrValue(argument_index)); | |
| 706 return VectorType(); | |
| 707 } | |
| 708 | |
| 709 if (length > VectorType::MaxCapacity()) { | |
| 710 exception_state.ThrowRangeError("Array length exceeds supported limit."); | |
| 711 return VectorType(); | |
| 712 } | |
| 713 | |
| 714 VectorType result; | |
| 715 result.ReserveInitialCapacity(length); | |
| 716 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); | |
| 717 v8::TryCatch block(isolate); | |
| 718 for (uint32_t i = 0; i < length; ++i) { | |
| 719 v8::Local<v8::Value> element; | |
| 720 if (!V8Call(object->Get(isolate->GetCurrentContext(), i), element, block)) { | |
| 721 exception_state.RethrowV8Exception(block.Exception()); | |
| 722 return VectorType(); | |
| 723 } | |
| 724 result.UncheckedAppend( | |
| 725 TraitsType::NativeValue(isolate, element, exception_state)); | |
| 726 if (exception_state.HadException()) | |
| 727 return VectorType(); | |
| 728 } | |
| 729 return result; | |
| 730 } | |
| 731 | |
| 732 template <typename VectorType> | |
| 733 VectorType ToImplArray(const Vector<ScriptValue>& value, | |
| 734 v8::Isolate* isolate, | |
| 735 ExceptionState& exception_state) { | |
| 736 using ValueType = typename VectorType::ValueType; | |
| 737 using TraitsType = NativeValueTraits<ValueType>; | |
| 738 | |
| 739 if (value.size() > VectorType::MaxCapacity()) { | |
| 740 exception_state.ThrowRangeError("Array length exceeds supported limit."); | |
| 741 return VectorType(); | |
| 742 } | |
| 743 | |
| 744 VectorType result; | |
| 745 result.ReserveInitialCapacity(value.size()); | |
| 746 for (unsigned i = 0; i < value.size(); ++i) { | |
| 747 result.UncheckedAppend( | |
| 748 TraitsType::NativeValue(isolate, value[i].V8Value(), exception_state)); | |
| 749 if (exception_state.HadException()) | |
| 750 return VectorType(); | |
| 751 } | |
| 752 return result; | |
| 753 } | |
| 754 | |
| 755 template <typename VectorType> | |
| 756 VectorType ToImplArguments(const v8::FunctionCallbackInfo<v8::Value>& info, | |
| 757 int start_index, | |
| 758 ExceptionState& exception_state) { | |
| 759 using ValueType = typename VectorType::ValueType; | |
| 760 using TraitsType = NativeValueTraits<ValueType>; | |
| 761 | |
| 762 int length = info.Length(); | |
| 763 VectorType result; | |
| 764 if (start_index < length) { | |
| 765 if (static_cast<size_t>(length - start_index) > VectorType::MaxCapacity()) { | |
| 766 exception_state.ThrowRangeError("Array length exceeds supported limit."); | |
| 767 return VectorType(); | |
| 768 } | |
| 769 result.ReserveInitialCapacity(length - start_index); | |
| 770 for (int i = start_index; i < length; ++i) { | |
| 771 result.UncheckedAppend( | |
| 772 TraitsType::NativeValue(info.GetIsolate(), info[i], exception_state)); | |
| 773 if (exception_state.HadException()) | |
| 774 return VectorType(); | |
| 775 } | |
| 776 } | |
| 777 return result; | |
| 778 } | |
| 779 | |
| 780 // Gets an iterator from an Object. | |
| 781 CORE_EXPORT v8::Local<v8::Object> GetEsIterator(v8::Isolate*, | |
| 782 v8::Local<v8::Object>, | |
| 783 ExceptionState&); | |
| 784 | |
| 785 // Validates that the passed object is a sequence type per WebIDL spec | |
| 786 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence | |
| 787 inline bool ToV8Sequence(v8::Local<v8::Value> value, | |
| 788 uint32_t& length, | |
| 789 v8::Isolate* isolate, | |
| 790 ExceptionState& exception_state) { | |
| 791 // Attempt converting to a sequence if the value is not already an array but | |
| 792 // is any kind of object except for a native Date object or a native RegExp | |
| 793 // object. | |
| 794 DCHECK(!value->IsArray()); | |
| 795 // FIXME: Do we really need to special case Date and RegExp object? | |
| 796 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806 | |
| 797 if (!value->IsObject() || value->IsDate() || value->IsRegExp()) { | |
| 798 // The caller is responsible for reporting a TypeError. | |
| 799 return false; | |
| 800 } | |
| 801 | |
| 802 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); | |
| 803 v8::Local<v8::String> length_symbol = V8AtomicString(isolate, "length"); | |
| 804 | |
| 805 // FIXME: The specification states that the length property should be used as | |
| 806 // fallback, if value is not a platform object that supports indexed | |
| 807 // properties. If it supports indexed properties, length should actually be | |
| 808 // one greater than value's maximum indexed property index. | |
| 809 v8::TryCatch block(isolate); | |
| 810 v8::Local<v8::Value> length_value; | |
| 811 if (!V8Call(object->Get(isolate->GetCurrentContext(), length_symbol), | |
| 812 length_value, block)) { | |
| 813 exception_state.RethrowV8Exception(block.Exception()); | |
| 814 return false; | |
| 815 } | |
| 816 | |
| 817 if (length_value->IsUndefined() || length_value->IsNull()) { | |
| 818 // The caller is responsible for reporting a TypeError. | |
| 819 return false; | |
| 820 } | |
| 821 | |
| 822 uint32_t sequence_length; | |
| 823 if (!V8Call(length_value->Uint32Value(isolate->GetCurrentContext()), | |
| 824 sequence_length, block)) { | |
| 825 exception_state.RethrowV8Exception(block.Exception()); | |
| 826 return false; | |
| 827 } | |
| 828 | |
| 829 length = sequence_length; | |
| 830 return true; | |
| 831 } | |
| 832 // Validates that the passed object is a sequence type per the WebIDL spec: it | |
| 833 // has a callable @iterator. | |
| 834 // https://heycam.github.io/webidl/#es-sequence | |
| 835 CORE_EXPORT bool HasCallableIteratorSymbol(v8::Isolate*, | |
| 836 v8::Local<v8::Value>, | |
| 837 ExceptionState&); | |
| 838 | |
| 839 // TODO(rakuco): remove the specializations below (and consequently the | |
| 840 // non-IDLBase version of NativeValueTraitsBase) once we manage to convert all | |
| 841 // uses of NativeValueTraits to types that derive from IDLBase or for generated | |
| 842 // IDL interfaces/dictionaries/unions. | |
| 843 template <> | |
| 844 struct NativeValueTraits<String> { | |
| 845 static inline String NativeValue(v8::Isolate* isolate, | |
| 846 v8::Local<v8::Value> value, | |
| 847 ExceptionState& exception_state) { | |
| 848 V8StringResource<> string_value(value); | |
| 849 if (!string_value.Prepare(exception_state)) | |
| 850 return String(); | |
| 851 return string_value; | |
| 852 } | |
| 853 }; | |
| 854 | |
| 855 template <> | |
| 856 struct NativeValueTraits<AtomicString> { | |
| 857 static inline AtomicString NativeValue(v8::Isolate* isolate, | |
| 858 v8::Local<v8::Value> value, | |
| 859 ExceptionState& exception_state) { | |
| 860 V8StringResource<> string_value(value); | |
| 861 if (!string_value.Prepare(exception_state)) | |
| 862 return AtomicString(); | |
| 863 return string_value; | |
| 864 } | |
| 865 }; | |
| 866 | |
| 867 template <> | |
| 868 struct NativeValueTraits<int> { | |
| 869 static inline int NativeValue(v8::Isolate* isolate, | |
| 870 v8::Local<v8::Value> value, | |
| 871 ExceptionState& exception_state) { | |
| 872 return ToInt32(isolate, value, kNormalConversion, exception_state); | |
| 873 } | |
| 874 }; | |
| 875 | |
| 876 template <> | |
| 877 struct NativeValueTraits<unsigned> { | |
| 878 static inline unsigned NativeValue(v8::Isolate* isolate, | |
| 879 v8::Local<v8::Value> value, | |
| 880 ExceptionState& exception_state) { | |
| 881 return ToUInt32(isolate, value, kNormalConversion, exception_state); | |
| 882 } | |
| 883 }; | |
| 884 | |
| 885 template <> | |
| 886 struct NativeValueTraits<float> { | |
| 887 static inline float NativeValue(v8::Isolate* isolate, | |
| 888 v8::Local<v8::Value> value, | |
| 889 ExceptionState& exception_state) { | |
| 890 return ToFloat(isolate, value, exception_state); | |
| 891 } | |
| 892 }; | |
| 893 | |
| 894 template <> | |
| 895 struct NativeValueTraits<double> { | |
| 896 static inline double NativeValue(v8::Isolate* isolate, | |
| 897 v8::Local<v8::Value> value, | |
| 898 ExceptionState& exception_state) { | |
| 899 return ToDouble(isolate, value, exception_state); | |
| 900 } | |
| 901 }; | |
| 902 | |
| 903 template <> | |
| 904 struct NativeValueTraits<v8::Local<v8::Value>> | |
| 905 : public NativeValueTraitsBase<v8::Local<v8::Value>> { | |
| 906 static inline v8::Local<v8::Value> NativeValue( | |
| 907 v8::Isolate* isolate, | |
| 908 v8::Local<v8::Value> value, | |
| 909 ExceptionState& exception_state) { | |
| 910 return value; | |
| 911 } | |
| 912 }; | |
| 913 | |
| 914 template <typename T> | |
| 915 struct NativeValueTraits<Vector<T>> { | |
| 916 static inline Vector<T> NativeValue(v8::Isolate* isolate, | |
| 917 v8::Local<v8::Value> value, | |
| 918 ExceptionState& exception_state) { | |
| 919 return ToImplArray<Vector<T>>(value, 0, isolate, exception_state); | |
| 920 } | |
| 921 }; | |
| 922 | |
| 923 CORE_EXPORT v8::Isolate* ToIsolate(ExecutionContext*); | |
| 924 CORE_EXPORT v8::Isolate* ToIsolate(LocalFrame*); | |
| 925 | |
| 926 CORE_EXPORT DOMWindow* ToDOMWindow(v8::Isolate*, v8::Local<v8::Value>); | |
| 927 LocalDOMWindow* ToLocalDOMWindow(v8::Local<v8::Context>); | |
| 928 LocalDOMWindow* EnteredDOMWindow(v8::Isolate*); | |
| 929 CORE_EXPORT LocalDOMWindow* CurrentDOMWindow(v8::Isolate*); | |
| 930 CORE_EXPORT ExecutionContext* ToExecutionContext(v8::Local<v8::Context>); | |
| 931 CORE_EXPORT void RegisterToExecutionContextForModules(ExecutionContext* ( | |
| 932 *to_execution_context_for_modules)(v8::Local<v8::Context>)); | |
| 933 CORE_EXPORT ExecutionContext* CurrentExecutionContext(v8::Isolate*); | |
| 934 | |
| 935 // Returns a V8 context associated with a ExecutionContext and a | |
| 936 // DOMWrapperWorld. This method returns an empty context if there is no frame | |
| 937 // or the frame is already detached. | |
| 938 CORE_EXPORT v8::Local<v8::Context> ToV8Context(ExecutionContext*, | |
| 939 DOMWrapperWorld&); | |
| 940 // Returns a V8 context associated with a Frame and a DOMWrapperWorld. | |
| 941 // This method returns an empty context if the frame is already detached. | |
| 942 CORE_EXPORT v8::Local<v8::Context> ToV8Context(LocalFrame*, DOMWrapperWorld&); | |
| 943 // Like toV8Context but also returns the context if the frame is already | |
| 944 // detached. | |
| 945 CORE_EXPORT v8::Local<v8::Context> ToV8ContextEvenIfDetached(LocalFrame*, | |
| 946 DOMWrapperWorld&); | |
| 947 | |
| 948 // These methods can return nullptr if the context associated with the | |
| 949 // ScriptState has already been detached. | |
| 950 CORE_EXPORT ScriptState* ToScriptState(LocalFrame*, DOMWrapperWorld&); | |
| 951 // Do not use this method unless you are sure you should use the main world's | |
| 952 // ScriptState | |
| 953 CORE_EXPORT ScriptState* ToScriptStateForMainWorld(LocalFrame*); | |
| 954 | |
| 955 // Returns the frame object of the window object associated with | |
| 956 // a context, if the window is currently being displayed in a Frame. | |
| 957 CORE_EXPORT LocalFrame* ToLocalFrameIfNotDetached(v8::Local<v8::Context>); | |
| 958 | |
| 959 // If 'storage' is non-null, it must be large enough to copy all bytes in the | |
| 960 // array buffer view into it. Use allocateFlexibleArrayBufferStorage(v8Value) | |
| 961 // to allocate it using alloca() in the callers stack frame. | |
| 962 CORE_EXPORT void ToFlexibleArrayBufferView(v8::Isolate*, | |
| 963 v8::Local<v8::Value>, | |
| 964 FlexibleArrayBufferView&, | |
| 965 void* storage = nullptr); | |
| 966 | |
| 967 // Converts a V8 value to an array (an IDL sequence) as per the WebIDL | |
| 968 // specification: http://heycam.github.io/webidl/#es-sequence | |
| 969 template <typename VectorType> | |
| 970 VectorType ToImplSequence(v8::Isolate* isolate, | |
| 971 v8::Local<v8::Value> value, | |
| 972 ExceptionState& exception_state) { | |
| 973 using ValueType = typename VectorType::ValueType; | |
| 974 | |
| 975 if (!value->IsObject() || value->IsRegExp()) { | |
| 976 exception_state.ThrowTypeError( | |
| 977 "The provided value cannot be converted to a sequence."); | |
| 978 return VectorType(); | |
| 979 } | |
| 980 | |
| 981 v8::TryCatch block(isolate); | |
| 982 v8::Local<v8::Object> iterator = | |
| 983 GetEsIterator(isolate, value.As<v8::Object>(), exception_state); | |
| 984 if (exception_state.HadException()) | |
| 985 return VectorType(); | |
| 986 | |
| 987 v8::Local<v8::String> next_key = V8String(isolate, "next"); | |
| 988 v8::Local<v8::String> value_key = V8String(isolate, "value"); | |
| 989 v8::Local<v8::String> done_key = V8String(isolate, "done"); | |
| 990 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | |
| 991 VectorType result; | |
| 992 while (true) { | |
| 993 v8::Local<v8::Value> next; | |
| 994 if (!iterator->Get(context, next_key).ToLocal(&next)) { | |
| 995 exception_state.RethrowV8Exception(block.Exception()); | |
| 996 return VectorType(); | |
| 997 } | |
| 998 // TODO(bashi): Support callable objects. | |
| 999 if (!next->IsObject() || !next.As<v8::Object>()->IsFunction()) { | |
| 1000 exception_state.ThrowTypeError("Iterator.next should be callable."); | |
| 1001 return VectorType(); | |
| 1002 } | |
| 1003 v8::Local<v8::Value> next_result; | |
| 1004 if (!V8ScriptRunner::CallFunction(next.As<v8::Function>(), | |
| 1005 ToExecutionContext(context), iterator, 0, | |
| 1006 nullptr, isolate) | |
| 1007 .ToLocal(&next_result)) { | |
| 1008 exception_state.RethrowV8Exception(block.Exception()); | |
| 1009 return VectorType(); | |
| 1010 } | |
| 1011 if (!next_result->IsObject()) { | |
| 1012 exception_state.ThrowTypeError( | |
| 1013 "Iterator.next() did not return an object."); | |
| 1014 return VectorType(); | |
| 1015 } | |
| 1016 v8::Local<v8::Object> result_object = next_result.As<v8::Object>(); | |
| 1017 v8::Local<v8::Value> element; | |
| 1018 v8::Local<v8::Value> done; | |
| 1019 if (!result_object->Get(context, value_key).ToLocal(&element) || | |
| 1020 !result_object->Get(context, done_key).ToLocal(&done)) { | |
| 1021 exception_state.RethrowV8Exception(block.Exception()); | |
| 1022 return VectorType(); | |
| 1023 } | |
| 1024 v8::Local<v8::Boolean> done_boolean; | |
| 1025 if (!done->ToBoolean(context).ToLocal(&done_boolean)) { | |
| 1026 exception_state.RethrowV8Exception(block.Exception()); | |
| 1027 return VectorType(); | |
| 1028 } | |
| 1029 if (done_boolean->Value()) | |
| 1030 break; | |
| 1031 result.push_back(NativeValueTraits<ValueType>::NativeValue( | |
| 1032 isolate, element, exception_state)); | |
| 1033 } | |
| 1034 return result; | |
| 1035 } | |
| 1036 | |
| 1037 // If the current context causes out of memory, JavaScript setting | |
| 1038 // is disabled and it returns true. | |
| 1039 bool HandleOutOfMemory(); | |
| 1040 | |
| 1041 inline bool IsUndefinedOrNull(v8::Local<v8::Value> value) { | 360 inline bool IsUndefinedOrNull(v8::Local<v8::Value> value) { |
| 1042 return value.IsEmpty() || value->IsNull() || value->IsUndefined(); | 361 return value.IsEmpty() || value->IsNull() || value->IsUndefined(); |
| 1043 } | 362 } |
| 1044 v8::Local<v8::Function> GetBoundFunction(v8::Local<v8::Function>); | 363 v8::Local<v8::Function> GetBoundFunction(v8::Local<v8::Function>); |
| 1045 | 364 |
| 1046 // FIXME: This will be soon embedded in the generated code. | 365 // FIXME: This will be soon embedded in the generated code. |
| 1047 template <typename Collection> | 366 template <typename Collection> |
| 1048 static void IndexedPropertyEnumerator( | 367 static void IndexedPropertyEnumerator( |
| 1049 const v8::PropertyCallbackInfo<v8::Array>& info) { | 368 const v8::PropertyCallbackInfo<v8::Array>& info) { |
| 1050 Collection* collection = | 369 Collection* collection = |
| 1051 ToScriptWrappable(info.Holder())->ToImpl<Collection>(); | 370 ToScriptWrappable(info.Holder())->ToImpl<Collection>(); |
| 1052 int length = collection->length(); | 371 int length = collection->length(); |
| 1053 v8::Local<v8::Array> properties = v8::Array::New(info.GetIsolate(), length); | 372 v8::Local<v8::Array> properties = v8::Array::New(info.GetIsolate(), length); |
| 1054 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); | 373 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); |
| 1055 for (int i = 0; i < length; ++i) { | 374 for (int i = 0; i < length; ++i) { |
| 1056 v8::Local<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i); | 375 v8::Local<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i); |
| 1057 if (!V8CallBoolean(properties->CreateDataProperty(context, i, integer))) | 376 if (!V8CallBoolean(properties->CreateDataProperty(context, i, integer))) |
| 1058 return; | 377 return; |
| 1059 } | 378 } |
| 1060 V8SetReturnValue(info, properties); | 379 V8SetReturnValue(info, properties); |
| 1061 } | 380 } |
| 1062 | 381 |
| 1063 CORE_EXPORT bool IsValidEnum(const String& value, | |
| 1064 const char** valid_values, | |
| 1065 size_t length, | |
| 1066 const String& enum_name, | |
| 1067 ExceptionState&); | |
| 1068 CORE_EXPORT bool IsValidEnum(const Vector<String>& values, | |
| 1069 const char** valid_values, | |
| 1070 size_t length, | |
| 1071 const String& enum_name, | |
| 1072 ExceptionState&); | |
| 1073 | |
| 1074 // These methods store hidden values into an array that is stored in the | 382 // These methods store hidden values into an array that is stored in the |
| 1075 // internal field of a DOM wrapper. | 383 // internal field of a DOM wrapper. |
| 1076 bool AddHiddenValueToArray(v8::Isolate*, | 384 bool AddHiddenValueToArray(v8::Isolate*, |
| 1077 v8::Local<v8::Object>, | 385 v8::Local<v8::Object>, |
| 1078 v8::Local<v8::Value>, | 386 v8::Local<v8::Value>, |
| 1079 int cache_index); | 387 int cache_index); |
| 1080 void RemoveHiddenValueFromArray(v8::Isolate*, | 388 void RemoveHiddenValueFromArray(v8::Isolate*, |
| 1081 v8::Local<v8::Object>, | 389 v8::Local<v8::Object>, |
| 1082 v8::Local<v8::Value>, | 390 v8::Local<v8::Value>, |
| 1083 int cache_index); | 391 int cache_index); |
| 1084 CORE_EXPORT void MoveEventListenerToNewWrapper(v8::Isolate*, | |
| 1085 v8::Local<v8::Object>, | |
| 1086 EventListener* old_value, | |
| 1087 v8::Local<v8::Value> new_value, | |
| 1088 int cache_index); | |
| 1089 | |
| 1090 // Result values for platform object 'deleter' methods, | |
| 1091 // http://www.w3.org/TR/WebIDL/#delete | |
| 1092 enum DeleteResult { kDeleteSuccess, kDeleteReject, kDeleteUnknownProperty }; | |
| 1093 | 392 |
| 1094 // Freeze a V8 object. The type of the first parameter and the return value is | 393 // Freeze a V8 object. The type of the first parameter and the return value is |
| 1095 // intentionally v8::Value so that this function can wrap ToV8(). | 394 // intentionally v8::Value so that this function can wrap ToV8(). |
| 1096 // If the argument isn't an object, this will crash. | 395 // If the argument isn't an object, this will crash. |
| 1097 CORE_EXPORT v8::Local<v8::Value> FreezeV8Object(v8::Local<v8::Value>, | 396 CORE_EXPORT v8::Local<v8::Value> FreezeV8Object(v8::Local<v8::Value>, |
| 1098 v8::Isolate*); | 397 v8::Isolate*); |
| 1099 | 398 |
| 1100 CORE_EXPORT v8::Local<v8::Value> FromJSONString(v8::Isolate*, | |
| 1101 const String& stringified_json, | |
| 1102 ExceptionState&); | |
| 1103 | |
| 1104 // Ensure that a typed array value is not backed by a SharedArrayBuffer. If it | |
| 1105 // is, an exception will be thrown. The return value will use the NotShared | |
| 1106 // wrapper type. | |
| 1107 template <typename NotSharedType> | |
| 1108 NotSharedType ToNotShared(v8::Isolate* isolate, | |
| 1109 v8::Local<v8::Value> value, | |
| 1110 ExceptionState& exception_state) { | |
| 1111 using DOMTypedArray = typename NotSharedType::TypedArrayType; | |
| 1112 DOMTypedArray* dom_typed_array = | |
| 1113 V8TypeOf<DOMTypedArray>::Type::toImplWithTypeCheck(isolate, value); | |
| 1114 if (dom_typed_array && dom_typed_array->IsShared()) { | |
| 1115 exception_state.ThrowTypeError( | |
| 1116 "The provided ArrayBufferView value must not be shared."); | |
| 1117 return NotSharedType(); | |
| 1118 } | |
| 1119 return NotSharedType(dom_typed_array); | |
| 1120 } | |
| 1121 | |
| 1122 // Wrap a typed array value in MaybeShared<>, to signify that it may be backed | |
| 1123 // by a SharedArrayBuffer. | |
| 1124 template <typename MaybeSharedType> | |
| 1125 MaybeSharedType ToMaybeShared(v8::Isolate* isolate, | |
| 1126 v8::Local<v8::Value> value, | |
| 1127 ExceptionState& exception_state) { | |
| 1128 using DOMTypedArray = typename MaybeSharedType::TypedArrayType; | |
| 1129 DOMTypedArray* dom_typed_array = | |
| 1130 V8TypeOf<DOMTypedArray>::Type::toImplWithTypeCheck(isolate, value); | |
| 1131 return MaybeSharedType(dom_typed_array); | |
| 1132 } | |
| 1133 | |
| 1134 } // namespace blink | 399 } // namespace blink |
| 1135 | 400 |
| 1136 #endif // V8Binding_h | 401 #endif // V8Binding_h |
| OLD | NEW |