Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/V8Binding.h

Issue 2834053003: Split V8Binding (Closed)
Patch Set: Revert commit that moved functions back into core Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698