Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / v8 / V8Binding.h
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/ExceptionMessages.h"
37 #include "bindings/v8/V8BindingMacros.h"
38 #include "bindings/v8/V8PerIsolateData.h"
39 #include "bindings/v8/V8StringResource.h"
40 #include "bindings/v8/V8ThrowException.h"
41 #include "bindings/v8/V8ValueCache.h"
42 #include "heap/Heap.h"
43 #include "wtf/MathExtras.h"
44 #include "wtf/text/AtomicString.h"
45 #include <v8.h>
46
47 namespace WebCore {
48
49     class DOMWindow;
50     class Document;
51     class EventListener;
52     class ExceptionState;
53     class Frame;
54     class NodeFilter;
55     class ExecutionContext;
56     class ScriptWrappable;
57     class XPathNSResolver;
58
59     const int kMaxRecursionDepth = 22;
60
61     // Schedule a DOM exception to be thrown, if the exception code is different
62     // from zero.
63     v8::Handle<v8::Value> setDOMException(int, v8::Isolate*);
64     v8::Handle<v8::Value> setDOMException(int, const String&, v8::Isolate*);
65
66     // Schedule a JavaScript error to be thrown.
67     v8::Handle<v8::Value> throwError(V8ErrorType, const String&, v8::Isolate*);
68
69     // Schedule a JavaScript error to be thrown.
70     v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>, v8::Isolate*);
71
72     // A helper for throwing JavaScript TypeError.
73     v8::Handle<v8::Value> throwTypeError(const String&, v8::Isolate*);
74
75     v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();
76
77     inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& info, int index)
78     {
79         return index >= info.Length() ? v8::Local<v8::Value>() : info[index];
80     }
81
82     template<typename CallbackInfo, typename V>
83     inline void v8SetReturnValue(const CallbackInfo& info, V v)
84     {
85         info.GetReturnValue().Set(v);
86     }
87
88     template<typename CallbackInfo>
89     inline void v8SetReturnValueBool(const CallbackInfo& info, bool v)
90     {
91         info.GetReturnValue().Set(v);
92     }
93
94     template<typename CallbackInfo>
95     inline void v8SetReturnValueInt(const CallbackInfo& info, int v)
96     {
97         info.GetReturnValue().Set(v);
98     }
99
100     template<typename CallbackInfo>
101     inline void v8SetReturnValueUnsigned(const CallbackInfo& info, unsigned v)
102     {
103         info.GetReturnValue().Set(v);
104     }
105
106     template<typename CallbackInfo>
107     inline void v8SetReturnValueNull(const CallbackInfo& info)
108     {
109         info.GetReturnValue().SetNull();
110     }
111
112     template<typename CallbackInfo>
113     inline void v8SetReturnValueUndefined(const CallbackInfo& info)
114     {
115         info.GetReturnValue().SetUndefined();
116     }
117
118     template<typename CallbackInfo>
119     inline void v8SetReturnValueEmptyString(const CallbackInfo& info)
120     {
121         info.GetReturnValue().SetEmptyString();
122     }
123
124     template <class CallbackInfo>
125     inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
126     {
127         if (string.isNull()) {
128             v8SetReturnValueEmptyString(info);
129             return;
130         }
131         V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
132     }
133
134     template <class CallbackInfo>
135     inline void v8SetReturnValueStringOrNull(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
136     {
137         if (string.isNull()) {
138             v8SetReturnValueNull(info);
139             return;
140         }
141         V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
142     }
143
144     template <class CallbackInfo>
145     inline void v8SetReturnValueStringOrUndefined(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
146     {
147         if (string.isNull()) {
148             v8SetReturnValueUndefined(info);
149             return;
150         }
151         V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
152     }
153
154     // Convert v8::String to a WTF::String. If the V8 string is not already
155     // an external string then it is transformed into an external string at this
156     // point to avoid repeated conversions.
157     inline String toCoreString(v8::Handle<v8::String> value)
158     {
159         return v8StringToWebCoreString<String>(value, Externalize);
160     }
161
162     inline String toCoreStringWithNullCheck(v8::Handle<v8::String> value)
163     {
164         if (value.IsEmpty() || value->IsNull())
165             return String();
166         return toCoreString(value);
167     }
168
169     inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::String> value)
170     {
171         if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
172             return String();
173         return toCoreString(value);
174     }
175
176     inline AtomicString toCoreAtomicString(v8::Handle<v8::String> value)
177     {
178         return v8StringToWebCoreString<AtomicString>(value, Externalize);
179     }
180
181     // This method will return a null String if the v8::Value does not contain a v8::String.
182     // It will not call ToString() on the v8::Value. If you want ToString() to be called,
183     // please use the V8TRYCATCH_FOR_V8STRINGRESOURCE_*() macros instead.
184     inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value)
185     {
186         if (value.IsEmpty() || !value->IsString())
187             return String();
188
189         return toCoreString(value.As<v8::String>());
190     }
191
192     // Convert a string to a V8 string.
193     // Return a V8 external string that shares the underlying buffer with the given
194     // WebCore string. The reference counting mechanism is used to keep the
195     // underlying buffer alive while the string is still live in the V8 engine.
196     inline v8::Handle<v8::String> v8String(v8::Isolate* isolate, const String& string)
197     {
198         if (string.isNull())
199             return v8::String::Empty(isolate);
200         return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
201     }
202
203     inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str)
204     {
205         ASSERT(isolate);
206         return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, strlen(str));
207     }
208
209     inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str, size_t length)
210     {
211         ASSERT(isolate);
212         return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, length);
213     }
214
215     inline v8::Handle<v8::Value> v8Undefined()
216     {
217         return v8::Handle<v8::Value>();
218     }
219
220     template <class T>
221     struct V8ValueTraits {
222         static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate)
223         {
224             return toV8(WTF::getPtr(value), v8::Handle<v8::Object>(), isolate);
225         }
226     };
227
228     template<>
229     struct V8ValueTraits<String> {
230         static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate)
231         {
232             return v8String(isolate, value);
233         }
234     };
235
236     template<>
237     struct V8ValueTraits<AtomicString> {
238         static inline v8::Handle<v8::Value> arrayV8Value(const AtomicString& value, v8::Isolate* isolate)
239         {
240             return v8String(isolate, value);
241         }
242     };
243
244     template<>
245     struct V8ValueTraits<unsigned> {
246         static inline v8::Handle<v8::Value> arrayV8Value(const unsigned& value, v8::Isolate* isolate)
247         {
248             return v8::Integer::NewFromUnsigned(isolate, value);
249         }
250     };
251
252     template<>
253     struct V8ValueTraits<unsigned long> {
254         static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate)
255         {
256             return v8::Integer::NewFromUnsigned(isolate, value);
257         }
258     };
259
260     template<>
261     struct V8ValueTraits<float> {
262         static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate* isolate)
263         {
264             return v8::Number::New(isolate, value);
265         }
266     };
267
268     template<>
269     struct V8ValueTraits<double> {
270         static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate* isolate)
271         {
272             return v8::Number::New(isolate, value);
273         }
274     };
275
276     template<typename T, size_t inlineCapacity>
277     v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Isolate* isolate)
278     {
279         v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
280         int index = 0;
281         typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
282         typedef V8ValueTraits<T> TraitsType;
283         for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
284             result->Set(v8::Integer::New(isolate, index++), TraitsType::arrayV8Value(*iter, isolate));
285         return result;
286     }
287
288     template<typename T, size_t inlineCapacity>
289     v8::Handle<v8::Value> v8Array(const HeapVector<T, inlineCapacity>& iterator, v8::Isolate* isolate)
290     {
291         v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
292         int index = 0;
293         typename HeapVector<T, inlineCapacity>::const_iterator end = iterator.end();
294         typedef V8ValueTraits<T> TraitsType;
295         for (typename HeapVector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
296             result->Set(v8::Integer::New(isolate, index++), TraitsType::arrayV8Value(*iter, isolate));
297         return result;
298     }
299
300     // Conversion flags, used in toIntXX/toUIntXX.
301     enum IntegerConversionConfiguration {
302         NormalConversion,
303         EnforceRange,
304         Clamp
305     };
306
307     // Convert a value to a 8-bit signed integer. The conversion fails if the
308     // value cannot be converted to a number or the range violated per WebIDL:
309     // http://www.w3.org/TR/WebIDL/#es-byte
310     int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
311     inline int8_t toInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
312     {
313         return toInt8(value, NormalConversion, exceptionState);
314     }
315
316     // Convert a value to a 8-bit integer assuming the conversion cannot fail.
317     int8_t toInt8(v8::Handle<v8::Value>);
318
319     // Convert a value to a 8-bit unsigned integer. The conversion fails if the
320     // value cannot be converted to a number or the range violated per WebIDL:
321     // http://www.w3.org/TR/WebIDL/#es-octet
322     uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
323     inline uint8_t toUInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
324     {
325         return toUInt8(value, NormalConversion, exceptionState);
326     }
327
328     // Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail.
329     uint8_t toUInt8(v8::Handle<v8::Value>);
330
331     // Convert a value to a 16-bit signed integer. The conversion fails if the
332     // value cannot be converted to a number or the range violated per WebIDL:
333     // http://www.w3.org/TR/WebIDL/#es-short
334     int16_t toInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
335     inline int16_t toInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
336     {
337         return toInt16(value, NormalConversion, exceptionState);
338     }
339
340     // Convert a value to a 16-bit integer assuming the conversion cannot fail.
341     int16_t toInt16(v8::Handle<v8::Value>);
342
343     // Convert a value to a 16-bit unsigned integer. The conversion fails if the
344     // value cannot be converted to a number or the range violated per WebIDL:
345     // http://www.w3.org/TR/WebIDL/#es-unsigned-short
346     uint16_t toUInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
347     inline uint16_t toUInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
348     {
349         return toUInt16(value, NormalConversion, exceptionState);
350     }
351
352     // Convert a value to a 16-bit unsigned integer assuming the conversion cannot fail.
353     uint16_t toUInt16(v8::Handle<v8::Value>);
354
355     // Convert a value to a 32-bit signed integer. The conversion fails if the
356     // value cannot be converted to a number or the range violated per WebIDL:
357     // http://www.w3.org/TR/WebIDL/#es-long
358     int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
359     inline int32_t toInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
360     {
361         return toInt32(value, NormalConversion, exceptionState);
362     }
363
364     // Convert a value to a 32-bit integer assuming the conversion cannot fail.
365     int32_t toInt32(v8::Handle<v8::Value>);
366
367     // Convert a value to a 32-bit unsigned integer. The conversion fails if the
368     // value cannot be converted to a number or the range violated per WebIDL:
369     // http://www.w3.org/TR/WebIDL/#es-unsigned-long
370     uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
371     inline uint32_t toUInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
372     {
373         return toUInt32(value, NormalConversion, exceptionState);
374     }
375
376     // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
377     uint32_t toUInt32(v8::Handle<v8::Value>);
378
379     // Convert a value to a 64-bit signed integer. The conversion fails if the
380     // value cannot be converted to a number or the range violated per WebIDL:
381     // http://www.w3.org/TR/WebIDL/#es-long-long
382     int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
383     inline int64_t toInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
384     {
385         return toInt64(value, NormalConversion, exceptionState);
386     }
387
388     // Convert a value to a 64-bit integer assuming the conversion cannot fail.
389     int64_t toInt64(v8::Handle<v8::Value>);
390
391     // Convert a value to a 64-bit unsigned integer. The conversion fails if the
392     // value cannot be converted to a number or the range violated per WebIDL:
393     // http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
394     uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
395     inline uint64_t toUInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
396     {
397         return toUInt64(value, NormalConversion, exceptionState);
398     }
399
400     // Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail.
401     uint64_t toUInt64(v8::Handle<v8::Value>);
402
403     // Convert a value to a single precision float, which might fail.
404     float toFloat(v8::Handle<v8::Value>, ExceptionState&);
405
406     // Convert a value to a single precision float assuming the conversion cannot fail.
407     inline float toFloat(v8::Local<v8::Value> value)
408     {
409         return static_cast<float>(value->NumberValue());
410     }
411
412     inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate)
413     {
414         return value ? v8::True(isolate) : v8::False(isolate);
415     }
416
417     inline double toCoreDate(v8::Handle<v8::Value> object)
418     {
419         if (object->IsDate())
420             return v8::Handle<v8::Date>::Cast(object)->ValueOf();
421         if (object->IsNumber())
422             return object->NumberValue();
423         return std::numeric_limits<double>::quiet_NaN();
424     }
425
426     inline v8::Handle<v8::Value> v8DateOrNull(double value, v8::Isolate* isolate)
427     {
428         ASSERT(isolate);
429         return std::isfinite(value) ? v8::Date::New(isolate, value) : v8::Handle<v8::Value>::Cast(v8::Null(isolate));
430     }
431
432     // FIXME: Remove the special casing for NodeFilter and XPathNSResolver.
433     PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Isolate*);
434     PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*);
435
436     template<class T> struct NativeValueTraits;
437
438     template<>
439     struct NativeValueTraits<String> {
440         static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
441         {
442             V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, value, String());
443             return stringValue;
444         }
445     };
446
447     template<>
448     struct NativeValueTraits<unsigned> {
449         static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
450         {
451             return toUInt32(value);
452         }
453     };
454
455     template<>
456     struct NativeValueTraits<float> {
457         static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
458         {
459             return static_cast<float>(value->NumberValue());
460         }
461     };
462
463     template<>
464     struct NativeValueTraits<double> {
465         static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
466         {
467             return static_cast<double>(value->NumberValue());
468         }
469     };
470
471     template<>
472     struct NativeValueTraits<v8::Handle<v8::Value> > {
473         static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
474         {
475             return value;
476         }
477     };
478
479     // Converts a JavaScript value to an array as per the Web IDL specification:
480     // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
481     template <class T, class V8T>
482     Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, uint32_t length, v8::Isolate* isolate, bool* success = 0)
483     {
484         Vector<RefPtr<T> > result;
485         result.reserveInitialCapacity(length);
486         v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
487         for (uint32_t i = 0; i < length; ++i) {
488             v8::Handle<v8::Value> element = object->Get(i);
489
490             if (V8T::hasInstance(element, isolate)) {
491                 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element);
492                 result.uncheckedAppend(V8T::toNative(elementObject));
493             } else {
494                 if (success)
495                     *success = false;
496                 throwTypeError("Invalid Array element type", isolate);
497                 return Vector<RefPtr<T> >();
498             }
499         }
500         return result;
501     }
502
503     v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*);
504
505     template <class T, class V8T>
506     Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0)
507     {
508         if (success)
509             *success = true;
510
511         v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
512         uint32_t length = 0;
513         if (value->IsArray()) {
514             length = v8::Local<v8::Array>::Cast(v8Value)->Length();
515         } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
516             throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
517             return Vector<RefPtr<T> >();
518         }
519
520         return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
521     }
522
523     template <class T, class V8T>
524     Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* success = 0)
525     {
526         if (success)
527             *success = true;
528
529         v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
530         uint32_t length = 0;
531         if (value->IsArray()) {
532             length = v8::Local<v8::Array>::Cast(v8Value)->Length();
533         } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
534             throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate);
535             return Vector<RefPtr<T> >();
536         }
537
538         return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
539     }
540
541     // Converts a JavaScript value to an array as per the Web IDL specification:
542     // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
543     template <class T>
544     Vector<T> toNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate)
545     {
546         v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
547         uint32_t length = 0;
548         if (value->IsArray()) {
549             length = v8::Local<v8::Array>::Cast(v8Value)->Length();
550         } else if (toV8Sequence(value, length, isolate).IsEmpty()) {
551             throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
552             return Vector<T>();
553         }
554
555         Vector<T> result;
556         result.reserveInitialCapacity(length);
557         typedef NativeValueTraits<T> TraitsType;
558         v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
559         for (uint32_t i = 0; i < length; ++i)
560             result.uncheckedAppend(TraitsType::nativeValue(object->Get(i), isolate));
561         return result;
562     }
563
564     template <class T>
565     Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int startIndex)
566     {
567         ASSERT(startIndex <= info.Length());
568         Vector<T> result;
569         typedef NativeValueTraits<T> TraitsType;
570         int length = info.Length();
571         result.reserveInitialCapacity(length);
572         for (int i = startIndex; i < length; ++i)
573             result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate()));
574         return result;
575     }
576
577     // Validates that the passed object is a sequence type per WebIDL spec
578     // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence
579     inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate)
580     {
581         // Attempt converting to a sequence if the value is not already an array but is
582         // any kind of object except for a native Date object or a native RegExp object.
583         ASSERT(!value->IsArray());
584         // FIXME: Do we really need to special case Date and RegExp object?
585         // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806
586         if (!value->IsObject() || value->IsDate() || value->IsRegExp()) {
587             // The caller is responsible for reporting a TypeError.
588             return v8Undefined();
589         }
590
591         v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
592         v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
593         v8::Local<v8::String> lengthSymbol = v8AtomicString(isolate, "length");
594
595         // FIXME: The specification states that the length property should be used as fallback, if value
596         // is not a platform object that supports indexed properties. If it supports indexed properties,
597         // length should actually be one greater than value’s maximum indexed property index.
598         V8TRYCATCH(v8::Local<v8::Value>, lengthValue, object->Get(lengthSymbol));
599
600         if (lengthValue->IsUndefined() || lengthValue->IsNull()) {
601             // The caller is responsible for reporting a TypeError.
602             return v8Undefined();
603         }
604
605         V8TRYCATCH(uint32_t, sequenceLength, lengthValue->Int32Value());
606         length = sequenceLength;
607
608         return v8Value;
609     }
610
611     v8::Isolate* toIsolate(ExecutionContext*);
612     v8::Isolate* toIsolate(Frame*);
613
614     WrapperWorldType worldType(v8::Isolate*);
615     WrapperWorldType worldTypeInMainThread(v8::Isolate*);
616
617     DOMWindow* toDOMWindow(v8::Handle<v8::Value>, v8::Isolate*);
618     DOMWindow* toDOMWindow(v8::Handle<v8::Context>);
619     ExecutionContext* toExecutionContext(v8::Handle<v8::Context>);
620
621     DOMWindow* activeDOMWindow(v8::Isolate*);
622     ExecutionContext* activeExecutionContext(v8::Isolate*);
623     DOMWindow* firstDOMWindow(v8::Isolate*);
624     Document* currentDocument(v8::Isolate*);
625     ExecutionContext* currentExecutionContext(v8::Isolate*);
626
627     // Returns a V8 context associated with a ExecutionContext and a DOMWrapperWorld.
628     // This method returns an empty context if there is no frame or the frame is already detached.
629     v8::Local<v8::Context> toV8Context(ExecutionContext*, DOMWrapperWorld*);
630     // Returns a V8 context associated with a Frame and a DOMWrapperWorld.
631     // This method returns an empty context if the frame is already detached.
632     v8::Local<v8::Context> toV8Context(v8::Isolate*, Frame*, DOMWrapperWorld*);
633
634     // Returns the frame object of the window object associated with
635     // a context, if the window is currently being displayed in the Frame.
636     Frame* toFrameIfNotDetached(v8::Handle<v8::Context>);
637
638     // If the current context causes out of memory, JavaScript setting
639     // is disabled and it returns true.
640     bool handleOutOfMemory();
641     v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate*);
642     void crashIfV8IsDead();
643
644     inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
645     {
646         return value->IsNull() || value->IsUndefined();
647     }
648     v8::Handle<v8::Function> getBoundFunction(v8::Handle<v8::Function>);
649
650     // Attaches |environment| to |function| and returns it.
651     inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment, v8::Isolate* isolate)
652     {
653         return v8::Function::New(isolate, function, environment);
654     }
655
656     // FIXME: This will be soon embedded in the generated code.
657     template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
658     {
659         Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
660         int length = collection->length();
661         v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(), length);
662         for (int i = 0; i < length; ++i) {
663             // FIXME: Do we need to check that the item function returns a non-null value for this index?
664             v8::Handle<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i);
665             properties->Set(integer, integer);
666         }
667         v8SetReturnValue(info, properties);
668     }
669
670     v8::Local<v8::Value> getHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*);
671     v8::Local<v8::Value> getHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
672     bool setHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*, v8::Handle<v8::Value>);
673     bool setHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>, v8::Handle<v8::Value>);
674     bool deleteHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*);
675     bool deleteHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
676     v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, const char*);
677     v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, v8::Handle<v8::String>);
678
679     // These methods store hidden values into an array that is stored in the internal field of a DOM wrapper.
680     void addHiddenValueToArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
681     void removeHiddenValueFromArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
682     void moveEventListenerToNewWrapper(v8::Handle<v8::Object>, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex, v8::Isolate*);
683
684     // Converts a DOM object to a v8 value.
685     // This is a no-inline version of toV8(). If you want to call toV8()
686     // without creating #include cycles, you can use this function instead.
687     // Each specialized implementation will be generated.
688     template<typename T>
689     v8::Handle<v8::Value> toV8NoInline(T* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
690
691     // Result values for platform object 'deleter' methods,
692     // http://www.w3.org/TR/WebIDL/#delete
693     enum DeleteResult {
694         DeleteSuccess,
695         DeleteReject,
696         DeleteUnknownProperty
697     };
698
699     class V8IsolateInterruptor : public ThreadState::Interruptor {
700     public:
701         explicit V8IsolateInterruptor(v8::Isolate* isolate) : m_isolate(isolate) { }
702
703         static void onInterruptCallback(v8::Isolate* isolate, void* data)
704         {
705             reinterpret_cast<V8IsolateInterruptor*>(data)->onInterrupted();
706         }
707
708         virtual void requestInterrupt() OVERRIDE
709         {
710             m_isolate->RequestInterrupt(&onInterruptCallback, this);
711         }
712
713         virtual void clearInterrupt() OVERRIDE
714         {
715             m_isolate->ClearInterrupt();
716         }
717
718     private:
719         v8::Isolate* m_isolate;
720     };
721
722 } // namespace WebCore
723
724 #endif // V8Binding_h