Home | History | Annotate | Download | only in v8
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #include "bindings/core/v8/ArrayValue.h"
     29 #include "bindings/core/v8/DictionaryHelperForBindings.h"
     30 #include "bindings/core/v8/ExceptionMessages.h"
     31 #include "bindings/core/v8/ExceptionState.h"
     32 #include "bindings/core/v8/V8Binding.h"
     33 #include "bindings/core/v8/V8DOMError.h"
     34 #include "bindings/core/v8/V8Element.h"
     35 #include "bindings/core/v8/V8EventTarget.h"
     36 #include "bindings/core/v8/V8MediaKeyError.h"
     37 #include "bindings/core/v8/V8MessagePort.h"
     38 #include "bindings/core/v8/V8Path2D.h"
     39 #include "bindings/core/v8/V8Storage.h"
     40 #include "bindings/core/v8/V8TextTrack.h"
     41 #include "bindings/core/v8/V8VoidCallback.h"
     42 #include "bindings/core/v8/V8Window.h"
     43 #include "bindings/core/v8/custom/V8ArrayBufferViewCustom.h"
     44 #include "bindings/core/v8/custom/V8Uint8ArrayCustom.h"
     45 #include "core/html/track/TrackBase.h"
     46 #include "wtf/MathExtras.h"
     47 
     48 namespace blink {
     49 
     50 template <>
     51 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, v8::Local<v8::Value>& value)
     52 {
     53     return dictionary.get(key, value);
     54 }
     55 
     56 template <>
     57 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, Dictionary& value)
     58 {
     59     return dictionary.get(key, value);
     60 }
     61 
     62 template <>
     63 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, bool& value)
     64 {
     65     v8::Local<v8::Value> v8Value;
     66     if (!dictionary.get(key, v8Value))
     67         return false;
     68 
     69     v8::Local<v8::Boolean> v8Bool = v8Value->ToBoolean();
     70     if (v8Bool.IsEmpty())
     71         return false;
     72     value = v8Bool->Value();
     73     return true;
     74 }
     75 
     76 template <>
     77 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, bool& value)
     78 {
     79     Dictionary::ConversionContextScope scope(context);
     80     DictionaryHelper::get(dictionary, key, value);
     81     return true;
     82 }
     83 
     84 template <>
     85 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, int32_t& value)
     86 {
     87     v8::Local<v8::Value> v8Value;
     88     if (!dictionary.get(key, v8Value))
     89         return false;
     90 
     91     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
     92     if (v8Int32.IsEmpty())
     93         return false;
     94     value = v8Int32->Value();
     95     return true;
     96 }
     97 
     98 template <>
     99 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, double& value, bool& hasValue)
    100 {
    101     v8::Local<v8::Value> v8Value;
    102     if (!dictionary.get(key, v8Value)) {
    103         hasValue = false;
    104         return false;
    105     }
    106 
    107     hasValue = true;
    108     TONATIVE_DEFAULT(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
    109     if (v8Number.IsEmpty())
    110         return false;
    111     value = v8Number->Value();
    112     return true;
    113 }
    114 
    115 template <>
    116 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, double& value)
    117 {
    118     bool unused;
    119     return DictionaryHelper::get(dictionary, key, value, unused);
    120 }
    121 
    122 template <>
    123 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, double& value)
    124 {
    125     Dictionary::ConversionContextScope scope(context);
    126 
    127     bool hasValue = false;
    128     if (!DictionaryHelper::get(dictionary, key, value, hasValue) && hasValue) {
    129         context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "is not of type 'double'."));
    130         return false;
    131     }
    132     return true;
    133 }
    134 
    135 template<typename StringType>
    136 bool getStringType(const Dictionary& dictionary, const String& key, StringType& value)
    137 {
    138     v8::Local<v8::Value> v8Value;
    139     if (!dictionary.get(key, v8Value))
    140         return false;
    141 
    142     TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false);
    143     value = stringValue;
    144     return true;
    145 }
    146 
    147 template <>
    148 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, String& value)
    149 {
    150     return getStringType(dictionary, key, value);
    151 }
    152 
    153 template <>
    154 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, AtomicString& value)
    155 {
    156     return getStringType(dictionary, key, value);
    157 }
    158 
    159 template <>
    160 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, String& value)
    161 {
    162     Dictionary::ConversionContextScope scope(context);
    163 
    164     v8::Local<v8::Value> v8Value;
    165     if (!dictionary.get(key, v8Value))
    166         return true;
    167 
    168     TOSTRING_DEFAULT(V8StringResource<>, stringValue, v8Value, false);
    169     value = stringValue;
    170     return true;
    171 }
    172 
    173 template <>
    174 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, ScriptValue& value)
    175 {
    176     v8::Local<v8::Value> v8Value;
    177     if (!dictionary.get(key, v8Value))
    178         return false;
    179 
    180     value = ScriptValue(ScriptState::current(dictionary.isolate()), v8Value);
    181     return true;
    182 }
    183 
    184 template <>
    185 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, ScriptValue& value)
    186 {
    187     Dictionary::ConversionContextScope scope(context);
    188 
    189     DictionaryHelper::get(dictionary, key, value);
    190     return true;
    191 }
    192 
    193 template<typename NumericType>
    194 bool getNumericType(const Dictionary& dictionary, const String& key, NumericType& value)
    195 {
    196     v8::Local<v8::Value> v8Value;
    197     if (!dictionary.get(key, v8Value))
    198         return false;
    199 
    200     v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
    201     if (v8Int32.IsEmpty())
    202         return false;
    203     value = static_cast<NumericType>(v8Int32->Value());
    204     return true;
    205 }
    206 
    207 template <>
    208 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, short& value)
    209 {
    210     return getNumericType<short>(dictionary, key, value);
    211 }
    212 
    213 template <>
    214 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned short& value)
    215 {
    216     return getNumericType<unsigned short>(dictionary, key, value);
    217 }
    218 
    219 template <>
    220 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned& value)
    221 {
    222     return getNumericType<unsigned>(dictionary, key, value);
    223 }
    224 
    225 template <>
    226 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned long& value)
    227 {
    228     v8::Local<v8::Value> v8Value;
    229     if (!dictionary.get(key, v8Value))
    230         return false;
    231 
    232     v8::Local<v8::Integer> v8Integer = v8Value->ToInteger();
    233     if (v8Integer.IsEmpty())
    234         return false;
    235     value = static_cast<unsigned long>(v8Integer->Value());
    236     return true;
    237 }
    238 
    239 template <>
    240 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, unsigned long long& value)
    241 {
    242     v8::Local<v8::Value> v8Value;
    243     if (!dictionary.get(key, v8Value))
    244         return false;
    245 
    246     TONATIVE_DEFAULT(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
    247     if (v8Number.IsEmpty())
    248         return false;
    249     double d = v8Number->Value();
    250     doubleToInteger(d, value);
    251     return true;
    252 }
    253 
    254 template <>
    255 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, RefPtrWillBeMember<LocalDOMWindow>& value)
    256 {
    257     v8::Local<v8::Value> v8Value;
    258     if (!dictionary.get(key, v8Value))
    259         return false;
    260 
    261     // We need to handle a DOMWindow specially, because a DOMWindow wrapper
    262     // exists on a prototype chain of v8Value.
    263     value = toDOMWindow(v8Value, dictionary.isolate());
    264     return true;
    265 }
    266 
    267 template <>
    268 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, HashSet<AtomicString>& value)
    269 {
    270     v8::Local<v8::Value> v8Value;
    271     if (!dictionary.get(key, v8Value))
    272         return false;
    273 
    274     // FIXME: Support array-like objects
    275     if (!v8Value->IsArray())
    276         return false;
    277 
    278     ASSERT(dictionary.isolate());
    279     ASSERT(dictionary.isolate() == v8::Isolate::GetCurrent());
    280     v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
    281     for (size_t i = 0; i < v8Array->Length(); ++i) {
    282         v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(dictionary.isolate(), i));
    283         TOSTRING_DEFAULT(V8StringResource<>, stringValue, indexedValue, false);
    284         value.add(stringValue);
    285     }
    286 
    287     return true;
    288 }
    289 
    290 template <>
    291 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, HashSet<AtomicString>& value)
    292 {
    293     Dictionary::ConversionContextScope scope(context);
    294 
    295     v8::Local<v8::Value> v8Value;
    296     if (!dictionary.get(key, v8Value))
    297         return true;
    298 
    299     if (context.isNullable() && blink::isUndefinedOrNull(v8Value))
    300         return true;
    301 
    302     if (!v8Value->IsArray()) {
    303         context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
    304         return false;
    305     }
    306 
    307     return DictionaryHelper::get(dictionary, key, value);
    308 }
    309 
    310 template <>
    311 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, RefPtrWillBeMember<TrackBase>& value)
    312 {
    313     v8::Local<v8::Value> v8Value;
    314     if (!dictionary.get(key, v8Value))
    315         return false;
    316 
    317     TrackBase* source = 0;
    318     if (v8Value->IsObject()) {
    319         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
    320 
    321         // FIXME: this will need to be changed so it can also return an AudioTrack or a VideoTrack once
    322         // we add them.
    323         v8::Handle<v8::Object> track = V8TextTrack::findInstanceInPrototypeChain(wrapper, dictionary.isolate());
    324         if (!track.IsEmpty())
    325             source = V8TextTrack::toImpl(track);
    326     }
    327     value = source;
    328     return true;
    329 }
    330 
    331 template <>
    332 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, RefPtrWillBeMember<EventTarget>& value)
    333 {
    334     v8::Local<v8::Value> v8Value;
    335     if (!dictionary.get(key, v8Value))
    336         return false;
    337 
    338     value = nullptr;
    339     // We need to handle a LocalDOMWindow specially, because a LocalDOMWindow wrapper
    340     // exists on a prototype chain of v8Value.
    341     if (v8Value->IsObject()) {
    342         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
    343         v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(wrapper, dictionary.isolate());
    344         if (!window.IsEmpty()) {
    345             value = toWrapperTypeInfo(window)->toEventTarget(window);
    346             return true;
    347         }
    348     }
    349 
    350     if (V8DOMWrapper::isDOMWrapper(v8Value)) {
    351         v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
    352         value = toWrapperTypeInfo(wrapper)->toEventTarget(wrapper);
    353     }
    354     return true;
    355 }
    356 
    357 template <>
    358 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, Vector<String>& value)
    359 {
    360     v8::Local<v8::Value> v8Value;
    361     if (!dictionary.get(key, v8Value))
    362         return false;
    363 
    364     if (!v8Value->IsArray())
    365         return false;
    366 
    367     v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
    368     for (size_t i = 0; i < v8Array->Length(); ++i) {
    369         v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(dictionary.isolate(), i));
    370         TOSTRING_DEFAULT(V8StringResource<>, stringValue, indexedValue, false);
    371         value.append(stringValue);
    372     }
    373 
    374     return true;
    375 }
    376 
    377 template <>
    378 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, Vector<String>& value)
    379 {
    380     Dictionary::ConversionContextScope scope(context);
    381 
    382     v8::Local<v8::Value> v8Value;
    383     if (!dictionary.get(key, v8Value))
    384         return true;
    385 
    386     if (context.isNullable() && blink::isUndefinedOrNull(v8Value))
    387         return true;
    388 
    389     if (!v8Value->IsArray()) {
    390         context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
    391         return false;
    392     }
    393 
    394     return DictionaryHelper::get(dictionary, key, value);
    395 }
    396 
    397 template <>
    398 bool DictionaryHelper::get(const Dictionary& dictionary, const String& key, ArrayValue& value)
    399 {
    400     v8::Local<v8::Value> v8Value;
    401     if (!dictionary.get(key, v8Value))
    402         return false;
    403 
    404     if (!v8Value->IsArray())
    405         return false;
    406 
    407     ASSERT(dictionary.isolate());
    408     ASSERT(dictionary.isolate() == v8::Isolate::GetCurrent());
    409     value = ArrayValue(v8::Local<v8::Array>::Cast(v8Value), dictionary.isolate());
    410     return true;
    411 }
    412 
    413 template <>
    414 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, ArrayValue& value)
    415 {
    416     Dictionary::ConversionContextScope scope(context);
    417 
    418     v8::Local<v8::Value> v8Value;
    419     if (!dictionary.get(key, v8Value))
    420         return true;
    421 
    422     if (context.isNullable() && blink::isUndefinedOrNull(v8Value))
    423         return true;
    424 
    425     if (!v8Value->IsArray()) {
    426         context.throwTypeError(ExceptionMessages::notASequenceTypeProperty(key));
    427         return false;
    428     }
    429 
    430     return DictionaryHelper::get(dictionary, key, value);
    431 }
    432 
    433 template <>
    434 struct DictionaryHelperTraits<Uint8Array> {
    435     typedef V8Uint8Array type;
    436 };
    437 
    438 template <>
    439 struct DictionaryHelperTraits<ArrayBufferView> {
    440     typedef V8ArrayBufferView type;
    441 };
    442 
    443 template <>
    444 struct DictionaryHelperTraits<MediaKeyError> {
    445     typedef V8MediaKeyError type;
    446 };
    447 
    448 template <>
    449 struct DictionaryHelperTraits<DOMError> {
    450     typedef V8DOMError type;
    451 };
    452 
    453 template <>
    454 struct DictionaryHelperTraits<Storage> {
    455     typedef V8Storage type;
    456 };
    457 
    458 template <>
    459 struct DictionaryHelperTraits<Element> {
    460     typedef V8Element type;
    461 };
    462 
    463 template <>
    464 struct DictionaryHelperTraits<Path2D> {
    465     typedef V8Path2D type;
    466 };
    467 
    468 template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtr<Uint8Array>& value);
    469 template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtr<ArrayBufferView>& value);
    470 template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<MediaKeyError>& value);
    471 template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<DOMError>& value);
    472 template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<Storage>& value);
    473 template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<Element>& value);
    474 template bool DictionaryHelper::get(const Dictionary&, const String& key, RawPtr<Element>& value);
    475 template bool DictionaryHelper::get(const Dictionary&, const String& key, RefPtrWillBeMember<Path2D>& value);
    476 template bool DictionaryHelper::get(const Dictionary&, const String& key, RawPtr<Path2D>& value);
    477 
    478 template <typename T>
    479 struct IntegralTypeTraits {
    480 };
    481 
    482 template <>
    483 struct IntegralTypeTraits<uint8_t> {
    484     static inline uint8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    485     {
    486         return toUInt8(value, configuration, exceptionState);
    487     }
    488     static const String typeName() { return "UInt8"; }
    489 };
    490 
    491 template <>
    492 struct IntegralTypeTraits<int8_t> {
    493     static inline int8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    494     {
    495         return toInt8(value, configuration, exceptionState);
    496     }
    497     static const String typeName() { return "Int8"; }
    498 };
    499 
    500 template <>
    501 struct IntegralTypeTraits<unsigned short> {
    502     static inline uint16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    503     {
    504         return toUInt16(value, configuration, exceptionState);
    505     }
    506     static const String typeName() { return "UInt16"; }
    507 };
    508 
    509 template <>
    510 struct IntegralTypeTraits<short> {
    511     static inline int16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    512     {
    513         return toInt16(value, configuration, exceptionState);
    514     }
    515     static const String typeName() { return "Int16"; }
    516 };
    517 
    518 template <>
    519 struct IntegralTypeTraits<unsigned> {
    520     static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    521     {
    522         return toUInt32(value, configuration, exceptionState);
    523     }
    524     static const String typeName() { return "UInt32"; }
    525 };
    526 
    527 template <>
    528 struct IntegralTypeTraits<unsigned long> {
    529     static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    530     {
    531         return toUInt32(value, configuration, exceptionState);
    532     }
    533     static const String typeName() { return "UInt32"; }
    534 };
    535 
    536 template <>
    537 struct IntegralTypeTraits<int> {
    538     static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    539     {
    540         return toInt32(value, configuration, exceptionState);
    541     }
    542     static const String typeName() { return "Int32"; }
    543 };
    544 
    545 template <>
    546 struct IntegralTypeTraits<long> {
    547     static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    548     {
    549         return toInt32(value, configuration, exceptionState);
    550     }
    551     static const String typeName() { return "Int32"; }
    552 };
    553 
    554 template <>
    555 struct IntegralTypeTraits<unsigned long long> {
    556     static inline unsigned long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    557     {
    558         return toUInt64(value, configuration, exceptionState);
    559     }
    560     static const String typeName() { return "UInt64"; }
    561 };
    562 
    563 template <>
    564 struct IntegralTypeTraits<long long> {
    565     static inline long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
    566     {
    567         return toInt64(value, configuration, exceptionState);
    568     }
    569     static const String typeName() { return "Int64"; }
    570 };
    571 
    572 template<typename T>
    573 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, T& value)
    574 {
    575     Dictionary::ConversionContextScope scope(context);
    576 
    577     v8::Local<v8::Value> v8Value;
    578     if (!dictionary.get(key, v8Value))
    579         return true;
    580 
    581     value = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState());
    582     if (context.exceptionState().throwIfNeeded())
    583         return false;
    584 
    585     return true;
    586 }
    587 
    588 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, uint8_t& value);
    589 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, int8_t& value);
    590 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned short& value);
    591 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, short& value);
    592 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned& value);
    593 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned long& value);
    594 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, int& value);
    595 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, long& value);
    596 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, long long& value);
    597 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, unsigned long long& value);
    598 
    599 template<typename T>
    600 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, Nullable<T>& value)
    601 {
    602     Dictionary::ConversionContextScope scope(context);
    603 
    604     v8::Local<v8::Value> v8Value;
    605     if (!dictionary.get(key, v8Value))
    606         return true;
    607 
    608     if (context.isNullable() && blink::isUndefinedOrNull(v8Value)) {
    609         value = Nullable<T>();
    610         return true;
    611     }
    612 
    613     T converted = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState());
    614 
    615     if (context.exceptionState().throwIfNeeded())
    616         return false;
    617 
    618     value = Nullable<T>(converted);
    619     return true;
    620 }
    621 
    622 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<uint8_t>& value);
    623 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<int8_t>& value);
    624 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned short>& value);
    625 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<short>& value);
    626 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned>& value);
    627 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned long>& value);
    628 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<int>& value);
    629 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<long>& value);
    630 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<long long>& value);
    631 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, Nullable<unsigned long long>& value);
    632 
    633 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<LocalDOMWindow>& value);
    634 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<Storage>& value);
    635 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtr<Uint8Array>& value);
    636 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtr<ArrayBufferView>& value);
    637 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<MediaKeyError>& value);
    638 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<TrackBase>& value);
    639 template bool DictionaryHelper::convert(const Dictionary&, Dictionary::ConversionContext&, const String& key, RefPtrWillBeMember<EventTarget>& value);
    640 
    641 template <>
    642 bool DictionaryHelper::convert(const Dictionary& dictionary, Dictionary::ConversionContext& context, const String& key, MessagePortArray& value)
    643 {
    644     Dictionary::ConversionContextScope scope(context);
    645 
    646     v8::Local<v8::Value> v8Value;
    647     if (!dictionary.get(key, v8Value))
    648         return true;
    649 
    650     ASSERT(dictionary.isolate());
    651     ASSERT(dictionary.isolate() == v8::Isolate::GetCurrent());
    652 
    653     if (isUndefinedOrNull(v8Value))
    654         return true;
    655 
    656     value = toRefPtrWillBeMemberNativeArray<MessagePort, V8MessagePort>(v8Value, key, dictionary.isolate(), context.exceptionState());
    657 
    658     if (context.exceptionState().throwIfNeeded())
    659         return false;
    660 
    661     return true;
    662 }
    663 
    664 } // namespace blink
    665