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