Home | History | Annotate | Download | only in v8
      1 /*
      2 * Copyright (C) 2009 Google Inc. All rights reserved.
      3 * Copyright (C) 2012 Ericsson AB. All rights reserved.
      4 *
      5 * Redistribution and use in source and binary forms, with or without
      6 * modification, are permitted provided that the following conditions are
      7 * met:
      8 *
      9 *     * Redistributions of source code must retain the above copyright
     10 * notice, this list of conditions and the following disclaimer.
     11 *     * Redistributions in binary form must reproduce the above
     12 * copyright notice, this list of conditions and the following disclaimer
     13 * in the documentation and/or other materials provided with the
     14 * distribution.
     15 *     * Neither the name of Google Inc. nor the names of its
     16 * contributors may be used to endorse or promote products derived from
     17 * this software without specific prior written permission.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     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.
     30 */
     31 
     32 #ifndef V8Binding_h
     33 #define V8Binding_h
     34 
     35 #include "bindings/v8/DOMWrapperWorld.h"
     36 #include "bindings/v8/V8BindingMacros.h"
     37 #include "bindings/v8/V8PerIsolateData.h"
     38 #include "bindings/v8/V8StringResource.h"
     39 #include "bindings/v8/V8ThrowException.h"
     40 #include "bindings/v8/V8ValueCache.h"
     41 #include "wtf/MathExtras.h"
     42 #include "wtf/text/AtomicString.h"
     43 #include <v8.h>
     44 
     45 namespace WebCore {
     46 
     47     class DOMStringList;
     48     class DOMWindow;
     49     class Document;
     50     class Frame;
     51     class NodeFilter;
     52     class ScriptExecutionContext;
     53     class ScriptWrappable;
     54     class XPathNSResolver;
     55 
     56     const int kMaxRecursionDepth = 22;
     57 
     58     // Schedule a DOM exception to be thrown, if the exception code is different
     59     // from zero.
     60     v8::Handle<v8::Value> setDOMException(int, v8::Isolate*);
     61     v8::Handle<v8::Value> setDOMException(int, const String&, v8::Isolate*);
     62 
     63     // Schedule a JavaScript error to be thrown.
     64     v8::Handle<v8::Value> throwError(V8ErrorType, const String&, v8::Isolate*);
     65 
     66     // Schedule a JavaScript error to be thrown.
     67     v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>);
     68 
     69     // A helper for throwing JavaScript TypeError.
     70     v8::Handle<v8::Value> throwTypeError(v8::Isolate*);
     71     v8::Handle<v8::Value> throwTypeError(const String&, v8::Isolate*);
     72 
     73     // A helper for throwing JavaScript TypeError for not enough arguments.
     74     v8::Handle<v8::Value> throwNotEnoughArgumentsError(v8::Isolate*);
     75 
     76     v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();
     77 
     78     v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*);
     79 
     80     inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& args, int index)
     81     {
     82         return index >= args.Length() ? v8::Local<v8::Value>() : args[index];
     83     }
     84 
     85     // Since v8::Null(isolate) crashes if we pass a null isolate,
     86     // we need to use v8NullWithCheck(isolate) if an isolate can be null.
     87     //
     88     // FIXME: Remove all null isolates from V8 bindings, and remove v8NullWithCheck(isolate).
     89     inline v8::Handle<v8::Value> v8NullWithCheck(v8::Isolate* isolate)
     90     {
     91         return isolate ? v8::Null(isolate) : v8::Null();
     92     }
     93 
     94     template<typename CallbackInfo, typename V>
     95     inline void v8SetReturnValue(const CallbackInfo& args, V v)
     96     {
     97         args.GetReturnValue().Set(v);
     98     }
     99 
    100     template<typename CallbackInfo>
    101     inline void v8SetReturnValueBool(const CallbackInfo& args, bool v)
    102     {
    103         args.GetReturnValue().Set(v);
    104     }
    105 
    106     template<typename CallbackInfo>
    107     inline void v8SetReturnValueInt(const CallbackInfo& args, int v)
    108     {
    109         args.GetReturnValue().Set(v);
    110     }
    111 
    112     template<typename CallbackInfo>
    113     inline void v8SetReturnValueUnsigned(const CallbackInfo& args, unsigned v)
    114     {
    115         args.GetReturnValue().Set(v);
    116     }
    117 
    118     template<typename CallbackInfo>
    119     inline void v8SetReturnValueNull(const CallbackInfo& args)
    120     {
    121         args.GetReturnValue().SetNull();
    122     }
    123 
    124     template<typename CallbackInfo>
    125     inline void v8SetReturnValueUndefined(const CallbackInfo& args)
    126     {
    127         args.GetReturnValue().SetUndefined();
    128     }
    129 
    130     template<typename CallbackInfo>
    131     inline void v8SetReturnValueEmptyString(const CallbackInfo& args)
    132     {
    133         args.GetReturnValue().SetEmptyString();
    134     }
    135 
    136     template <class CallbackInfo>
    137     inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
    138     {
    139         if (string.isNull()) {
    140             v8SetReturnValueEmptyString(info);
    141             return;
    142         }
    143         V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
    144     }
    145 
    146     template <class CallbackInfo>
    147     inline void v8SetReturnValueStringOrNull(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
    148     {
    149         if (string.isNull()) {
    150             v8SetReturnValueNull(info);
    151             return;
    152         }
    153         V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
    154     }
    155 
    156     template <class CallbackInfo>
    157     inline void v8SetReturnValueStringOrUndefined(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
    158     {
    159         if (string.isNull()) {
    160             v8SetReturnValueUndefined(info);
    161             return;
    162         }
    163         V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
    164     }
    165 
    166     // Convert v8 types to a WTF::String. If the V8 string is not already
    167     // an external string then it is transformed into an external string at this
    168     // point to avoid repeated conversions.
    169     //
    170     // FIXME: Replace all the call sites with V8TRYCATCH_FOR_V8STRINGRESOURCE().
    171     // Using this method will lead to a wrong behavior, because you cannot stop the
    172     // execution when an exception is thrown inside stringResource.prepare().
    173     inline String toWebCoreString(v8::Handle<v8::Value> value)
    174     {
    175         V8StringResource<> stringResource(value);
    176         if (!stringResource.prepare())
    177             return String();
    178         return stringResource;
    179     }
    180 
    181     // FIXME: See the above comment.
    182     inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
    183     {
    184         V8StringResource<WithNullCheck> stringResource(value);
    185         if (!stringResource.prepare())
    186             return String();
    187         return stringResource;
    188     }
    189 
    190     // FIXME: See the above comment.
    191     inline String toWebCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value)
    192     {
    193         V8StringResource<WithUndefinedOrNullCheck> stringResource(value);
    194         if (!stringResource.prepare())
    195             return String();
    196         return stringResource;
    197     }
    198 
    199     // FIXME: See the above comment.
    200     inline AtomicString toWebCoreAtomicString(v8::Handle<v8::Value> value)
    201     {
    202         V8StringResource<> stringResource(value);
    203         if (!stringResource.prepare())
    204             return AtomicString();
    205         return stringResource;
    206     }
    207 
    208     // FIXME: See the above comment.
    209     inline AtomicString toWebCoreAtomicStringWithNullCheck(v8::Handle<v8::Value> value)
    210     {
    211         V8StringResource<WithNullCheck> stringResource(value);
    212         if (!stringResource.prepare())
    213             return AtomicString();
    214         return stringResource;
    215     }
    216 
    217     // Convert a string to a V8 string.
    218     // Return a V8 external string that shares the underlying buffer with the given
    219     // WebCore string. The reference counting mechanism is used to keep the
    220     // underlying buffer alive while the string is still live in the V8 engine.
    221     inline v8::Handle<v8::String> v8String(const String& string, v8::Isolate* isolate)
    222     {
    223         if (string.isNull())
    224             return v8::String::Empty(isolate);
    225         return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
    226     }
    227 
    228     inline v8::Handle<v8::Value> v8Undefined()
    229     {
    230         return v8::Handle<v8::Value>();
    231     }
    232 
    233     template <class T>
    234     struct V8ValueTraits {
    235         static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate)
    236         {
    237             return toV8(WTF::getPtr(value), v8::Handle<v8::Object>(), isolate);
    238         }
    239     };
    240 
    241     template<>
    242     struct V8ValueTraits<String> {
    243         static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate)
    244         {
    245             return v8String(value, isolate);
    246         }
    247     };
    248 
    249     template<>
    250     struct V8ValueTraits<unsigned> {
    251         static inline v8::Handle<v8::Value> arrayV8Value(const unsigned& value, v8::Isolate* isolate)
    252         {
    253             return v8::Integer::NewFromUnsigned(value, isolate);
    254         }
    255     };
    256 
    257     template<>
    258     struct V8ValueTraits<unsigned long> {
    259         static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate)
    260         {
    261             return v8::Integer::NewFromUnsigned(value, isolate);
    262         }
    263     };
    264 
    265     template<>
    266     struct V8ValueTraits<float> {
    267         static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate*)
    268         {
    269             return v8::Number::New(value);
    270         }
    271     };
    272 
    273     template<>
    274     struct V8ValueTraits<double> {
    275         static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate*)
    276         {
    277             return v8::Number::New(value);
    278         }
    279     };
    280 
    281     template<typename T, size_t inlineCapacity>
    282     v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Isolate* isolate)
    283     {
    284         v8::Local<v8::Array> result = v8::Array::New(iterator.size());
    285         int index = 0;
    286         typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
    287         typedef V8ValueTraits<T> TraitsType;
    288         for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
    289             result->Set(v8::Integer::New(index++, isolate), TraitsType::arrayV8Value(*iter, isolate));
    290         return result;
    291     }
    292 
    293     v8::Handle<v8::Value> v8Array(PassRefPtr<DOMStringList>, v8::Isolate*);
    294 
    295     // Conversion flags, used in toIntXX/toUIntXX.
    296     enum IntegerConversionConfiguration {
    297         NormalConversion,
    298         EnforceRange,
    299         // FIXME: Implement Clamp
    300     };
    301 
    302     // Convert a value to a 8-bit signed integer. The conversion fails if the
    303     // value cannot be converted to a number or the range violated per WebIDL:
    304     // http://www.w3.org/TR/WebIDL/#es-byte
    305     int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    306     inline int8_t toInt8(v8::Handle<v8::Value> value, bool& ok) { return toInt8(value, NormalConversion, ok); }
    307 
    308     // Convert a value to a 8-bit integer assuming the conversion cannot fail.
    309     inline int8_t toInt8(v8::Handle<v8::Value> value)
    310     {
    311         bool ok;
    312         return toInt8(value, NormalConversion, ok);
    313     }
    314 
    315     // Convert a value to a 8-bit unsigned integer. The conversion fails if the
    316     // value cannot be converted to a number or the range violated per WebIDL:
    317     // http://www.w3.org/TR/WebIDL/#es-octet
    318     uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    319     inline uint8_t toUInt8(v8::Handle<v8::Value> value, bool& ok) { return toUInt8(value, NormalConversion, ok); }
    320 
    321     // Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail.
    322     inline uint8_t toUInt8(v8::Handle<v8::Value> value)
    323     {
    324         bool ok;
    325         return toUInt8(value, NormalConversion, ok);
    326     }
    327 
    328     // Convert a value to a 32-bit signed integer. The conversion fails if the
    329     // value cannot be converted to a number or the range violated per WebIDL:
    330     // http://www.w3.org/TR/WebIDL/#es-long
    331     int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    332     inline int32_t toInt32(v8::Handle<v8::Value> value, bool& ok) { return toInt32(value, NormalConversion, ok); }
    333 
    334     // Convert a value to a 32-bit integer assuming the conversion cannot fail.
    335     inline int32_t toInt32(v8::Handle<v8::Value> value)
    336     {
    337         bool ok;
    338         return toInt32(value, NormalConversion, ok);
    339     }
    340 
    341     // Convert a value to a 32-bit unsigned integer. The conversion fails if the
    342     // value cannot be converted to a number or the range violated per WebIDL:
    343     // http://www.w3.org/TR/WebIDL/#es-unsigned-long
    344     uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    345     inline uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok) { return toUInt32(value, NormalConversion, ok); }
    346 
    347     // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
    348     inline uint32_t toUInt32(v8::Handle<v8::Value> value)
    349     {
    350         bool ok;
    351         return toUInt32(value, NormalConversion, ok);
    352     }
    353 
    354     // Convert a value to a 64-bit signed integer. The conversion fails if the
    355     // value cannot be converted to a number or the range violated per WebIDL:
    356     // http://www.w3.org/TR/WebIDL/#es-long-long
    357     int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    358 
    359     // Convert a value to a 64-bit integer assuming the conversion cannot fail.
    360     inline int64_t toInt64(v8::Handle<v8::Value> value)
    361     {
    362         bool ok;
    363         return toInt64(value, NormalConversion, ok);
    364     }
    365 
    366     // Convert a value to a 64-bit unsigned integer. The conversion fails if the
    367     // value cannot be converted to a number or the range violated per WebIDL:
    368     // http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
    369     uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    370 
    371     // Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail.
    372     inline uint64_t toUInt64(v8::Handle<v8::Value> value)
    373     {
    374         bool ok;
    375         return toUInt64(value, NormalConversion, ok);
    376     }
    377 
    378     inline float toFloat(v8::Local<v8::Value> value)
    379     {
    380         return static_cast<float>(value->NumberValue());
    381     }
    382 
    383     WrapperWorldType worldType(v8::Isolate*);
    384     WrapperWorldType worldTypeInMainThread(v8::Isolate*);
    385 
    386     DOMWrapperWorld* isolatedWorldForIsolate(v8::Isolate*);
    387 
    388     template<class T> struct NativeValueTraits;
    389 
    390     template<>
    391     struct NativeValueTraits<String> {
    392         static inline String nativeValue(const v8::Handle<v8::Value>& value)
    393         {
    394             return toWebCoreString(value);
    395         }
    396     };
    397 
    398     template<>
    399     struct NativeValueTraits<unsigned> {
    400         static inline unsigned nativeValue(const v8::Handle<v8::Value>& value)
    401         {
    402             return toUInt32(value);
    403         }
    404     };
    405 
    406     template<>
    407     struct NativeValueTraits<float> {
    408         static inline float nativeValue(const v8::Handle<v8::Value>& value)
    409         {
    410             return static_cast<float>(value->NumberValue());
    411         }
    412     };
    413 
    414     template<>
    415     struct NativeValueTraits<double> {
    416         static inline double nativeValue(const v8::Handle<v8::Value>& value)
    417         {
    418             return static_cast<double>(value->NumberValue());
    419         }
    420     };
    421 
    422     // Converts a JavaScript value to an array as per the Web IDL specification:
    423     // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
    424     template <class T, class V8T>
    425     Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, v8::Isolate* isolate, bool* success = 0)
    426     {
    427         if (success)
    428             *success = true;
    429 
    430         v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
    431         uint32_t length = 0;
    432         if (value->IsArray())
    433             length = v8::Local<v8::Array>::Cast(v8Value)->Length();
    434         else if (toV8Sequence(value, length, isolate).IsEmpty())
    435             return Vector<RefPtr<T> >();
    436 
    437         Vector<RefPtr<T> > result;
    438         v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
    439         for (uint32_t i = 0; i < length; ++i) {
    440             v8::Handle<v8::Value> element = object->Get(i);
    441 
    442             if (V8T::HasInstance(element, isolate, worldType(isolate))) {
    443                 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element);
    444                 result.append(V8T::toNative(elementObject));
    445             } else {
    446                 if (success)
    447                     *success = false;
    448                 throwTypeError("Invalid Array element type", isolate);
    449                 return Vector<RefPtr<T> >();
    450             }
    451         }
    452         return result;
    453     }
    454 
    455     // Converts a JavaScript value to an array as per the Web IDL specification:
    456     // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
    457     template <class T>
    458     Vector<T> toNativeArray(v8::Handle<v8::Value> value, v8::Isolate* isolate)
    459     {
    460         v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
    461         uint32_t length = 0;
    462         if (value->IsArray())
    463             length = v8::Local<v8::Array>::Cast(v8Value)->Length();
    464         else if (toV8Sequence(value, length, isolate).IsEmpty())
    465             return Vector<T>();
    466 
    467         Vector<T> result;
    468         typedef NativeValueTraits<T> TraitsType;
    469         v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
    470         for (uint32_t i = 0; i < length; ++i)
    471             result.append(TraitsType::nativeValue(object->Get(i)));
    472         return result;
    473     }
    474 
    475     template <class T>
    476     Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& args, int startIndex)
    477     {
    478         ASSERT(startIndex <= args.Length());
    479         Vector<T> result;
    480         typedef NativeValueTraits<T> TraitsType;
    481         int length = args.Length();
    482         for (int i = startIndex; i < length; ++i)
    483             result.append(TraitsType::nativeValue(args[i]));
    484         return result;
    485     }
    486 
    487     Vector<v8::Handle<v8::Value> > toVectorOfArguments(const v8::FunctionCallbackInfo<v8::Value>& args);
    488 
    489     // Validates that the passed object is a sequence type per WebIDL spec
    490     // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence
    491     inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate)
    492     {
    493         // Attempt converting to a sequence if the value is not already an array but is
    494         // any kind of object except for a native Date object or a native RegExp object.
    495         ASSERT(!value->IsArray());
    496         // FIXME: Do we really need to special case Date and RegExp object?
    497         // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806
    498         if (!value->IsObject() || value->IsDate() || value->IsRegExp()) {
    499             throwTypeError(isolate);
    500             return v8Undefined();
    501         }
    502 
    503         v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
    504         v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
    505 
    506         // FIXME: The specification states that the length property should be used as fallback, if value
    507         // is not a platform object that supports indexed properties. If it supports indexed properties,
    508         // length should actually be one greater than values maximum indexed property index.
    509         V8TRYCATCH(v8::Local<v8::Value>, lengthValue, object->Get(v8::String::NewSymbol("length")));
    510 
    511         if (lengthValue->IsUndefined() || lengthValue->IsNull()) {
    512             throwTypeError(isolate);
    513             return v8Undefined();
    514         }
    515 
    516         V8TRYCATCH(uint32_t, sequenceLength, lengthValue->Int32Value());
    517         length = sequenceLength;
    518 
    519         return v8Value;
    520     }
    521 
    522     PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Isolate*);
    523 
    524     inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
    525     {
    526         return value->IsNull() || value->IsUndefined();
    527     }
    528 
    529     // Returns true if the provided object is to be considered a 'host object', as used in the
    530     // HTML5 structured clone algorithm.
    531     inline bool isHostObject(v8::Handle<v8::Object> object)
    532     {
    533         // If the object has any internal fields, then we won't be able to serialize or deserialize
    534         // them; conveniently, this is also a quick way to detect DOM wrapper objects, because
    535         // the mechanism for these relies on data stored in these fields. We should
    536         // catch external array data as a special case.
    537         return object->InternalFieldCount() || object->HasIndexedPropertiesInExternalArrayData();
    538     }
    539 
    540     inline v8::Handle<v8::Boolean> v8Boolean(bool value)
    541     {
    542         return value ? v8::True() : v8::False();
    543     }
    544 
    545     inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate)
    546     {
    547         return value ? v8::True(isolate) : v8::False(isolate);
    548     }
    549 
    550     // Since v8Boolean(value, isolate) crashes if we pass a null isolate,
    551     // we need to use v8BooleanWithCheck(value, isolate) if an isolate can be null.
    552     //
    553     // FIXME: Remove all null isolates from V8 bindings, and remove v8BooleanWithCheck(value, isolate).
    554     inline v8::Handle<v8::Boolean> v8BooleanWithCheck(bool value, v8::Isolate* isolate)
    555     {
    556         return isolate ? v8Boolean(value, isolate) : v8Boolean(value);
    557     }
    558 
    559     inline double toWebCoreDate(v8::Handle<v8::Value> object)
    560     {
    561         return (object->IsDate() || object->IsNumber()) ? object->NumberValue() : std::numeric_limits<double>::quiet_NaN();
    562     }
    563 
    564     inline v8::Handle<v8::Value> v8DateOrNull(double value, v8::Isolate* isolate)
    565     {
    566         ASSERT(isolate);
    567         return std::isfinite(value) ? v8::Date::New(value) : v8NullWithCheck(isolate);
    568     }
    569 
    570     v8::Handle<v8::FunctionTemplate> createRawTemplate(v8::Isolate*);
    571 
    572     PassRefPtr<DOMStringList> toDOMStringList(v8::Handle<v8::Value>, v8::Isolate*);
    573     PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*);
    574 
    575     v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context>);
    576     DOMWindow* toDOMWindow(v8::Handle<v8::Context>);
    577     ScriptExecutionContext* toScriptExecutionContext(v8::Handle<v8::Context>);
    578 
    579     DOMWindow* activeDOMWindow();
    580     DOMWindow* firstDOMWindow();
    581     Document* currentDocument();
    582 
    583     // Returns the context associated with a ScriptExecutionContext.
    584     v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, DOMWrapperWorld*);
    585 
    586     // Returns the frame object of the window object associated with
    587     // a context, if the window is currently being displayed in the Frame.
    588     Frame* toFrameIfNotDetached(v8::Handle<v8::Context>);
    589 
    590     inline DOMWrapperWorld* isolatedWorldForEnteredContext()
    591     {
    592         v8::Handle<v8::Context> context = v8::Context::GetEntered();
    593         if (context.IsEmpty())
    594             return 0;
    595         return DOMWrapperWorld::isolatedWorld(context);
    596     }
    597 
    598     // FIXME: This will be soon embedded in the generated code.
    599     template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
    600     {
    601         Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
    602         int length = collection->length();
    603         v8::Handle<v8::Array> properties = v8::Array::New(length);
    604         for (int i = 0; i < length; ++i) {
    605             // FIXME: Do we need to check that the item function returns a non-null value for this index?
    606             v8::Handle<v8::Integer> integer = v8::Integer::New(i, info.GetIsolate());
    607             properties->Set(integer, integer);
    608         }
    609         v8SetReturnValue(info, properties);
    610     }
    611 
    612     // If the current context causes out of memory, JavaScript setting
    613     // is disabled and it returns true.
    614     bool handleOutOfMemory();
    615     // FIXME: This should receive an Isolate.
    616     v8::Local<v8::Value> handleMaxRecursionDepthExceeded();
    617 
    618     void crashIfV8IsDead();
    619 
    620     template <class T>
    621     v8::Handle<T> unsafeHandleFromRawValue(const T* value)
    622     {
    623         const v8::Handle<T>* handle = reinterpret_cast<const v8::Handle<T>*>(&value);
    624         return *handle;
    625     }
    626 
    627     // Attaches |environment| to |function| and returns it.
    628     inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment)
    629     {
    630         return v8::FunctionTemplate::New(function, environment)->GetFunction();
    631     }
    632 
    633     v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, v8::Handle<v8::String> key);
    634 
    635 } // namespace WebCore
    636 
    637 #endif // V8Binding_h
    638