18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/*
28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* Copyright (C) 2009 Google Inc. All rights reserved.
3dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch*
48f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* Redistribution and use in source and binary forms, with or without
58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* modification, are permitted provided that the following conditions are
68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* met:
7dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch*
88f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian*     * Redistributions of source code must retain the above copyright
98f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* notice, this list of conditions and the following disclaimer.
108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian*     * Redistributions in binary form must reproduce the above
118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* copyright notice, this list of conditions and the following disclaimer
128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* in the documentation and/or other materials provided with the
138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* distribution.
148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian*     * Neither the name of Google Inc. nor the names of its
158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* contributors may be used to endorse or promote products derived from
168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* this software without specific prior written permission.
17dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch*
188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian*/
308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#ifndef V8Binding_h
328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define V8Binding_h
338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
34d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "BindingSecurity.h"
350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "MathExtras.h"
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "PlatformString.h"
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "V8DOMWrapper.h"
38f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/AtomicString.h>
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <v8.h>
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace WebCore {
43dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    class DOMStringList;
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    class EventListener;
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    class EventTarget;
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
48cad810f21b803229eb11403f9209855525a25d57Steve Block    // FIXME: Remove V8Binding.
49d0825bca7fe65beaee391d30da42e937db621564Steve Block    class V8Binding {
50d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
51d0825bca7fe65beaee391d30da42e937db621564Steve Block    typedef BindingSecurity<V8Binding> V8BindingSecurity;
525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    enum ExternalMode {
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        Externalize,
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoNotExternalize
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    };
575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    template <typename StringType>
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external);
608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
61dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // Convert v8 types to a WTF::String. If the V8 string is not already
620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // an external string then it is transformed into an external string at this
630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // point to avoid repeated conversions.
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    inline String v8StringToWebCoreString(v8::Handle<v8::String> v8String)
65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8StringToWebCoreString<String>(v8String, Externalize);
67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String v8NonStringValueToWebCoreString(v8::Handle<v8::Value>);
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String v8ValueToWebCoreString(v8::Handle<v8::Value> value);
700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
71dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // Convert v8 types to a WTF::AtomicString.
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    inline AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8String)
73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return v8StringToWebCoreString<AtomicString>(v8String, Externalize);
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    AtomicString v8NonStringValueToAtomicWebCoreString(v8::Handle<v8::Value>);
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> value);
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // Note: RefPtr is a must as we cache by StringImpl* equality, not identity
8006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // hence lastStringImpl might be not a key of the cache (in sense of identity)
8106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // and hence it's not refed on addition.
8206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    extern RefPtr<StringImpl> lastStringImpl;
8306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    extern v8::Persistent<v8::String> lastV8String;
8406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    v8::Local<v8::String> v8ExternalStringSlow(StringImpl* stringImpl);
8506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Return a V8 external string that shares the underlying buffer with the given
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // WebCore string. The reference counting mechanism is used to keep the
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // underlying buffer alive while the string is still live in the V8 engine.
8906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    inline v8::Local<v8::String> v8ExternalString(const String& string)
9006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    {
9106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        StringImpl* stringImpl = string.impl();
9206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        if (!stringImpl)
9306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            return v8::String::Empty();
9406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
9506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        if (lastStringImpl.get() == stringImpl) {
9606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            ASSERT(!lastV8String.IsNearDeath());
9706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            ASSERT(!lastV8String.IsEmpty());
9806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            return v8::Local<v8::String>::New(lastV8String);
9906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        }
10006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
10106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        return v8ExternalStringSlow(stringImpl);
10206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Convert a string to a V8 string.
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    inline v8::Handle<v8::String> v8String(const String& string)
106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return v8ExternalString(string);
108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
110dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // Enables caching v8 wrappers created for WTF::StringImpl.  Currently this cache requires
111dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // all the calls (both to convert WTF::String to v8::String and to GC the handle)
1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // to be performed on the main thread.
1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    void enableStringImplCache();
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Convert a value to a 32-bit integer.  The conversion fails if the
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // value cannot be converted to an integer or converts to nan or to an infinity.
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int toInt32(v8::Handle<v8::Value> value, bool& ok);
1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Convert a value to a 32-bit integer assuming the conversion cannot fail.
1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    inline int toInt32(v8::Handle<v8::Value> value)
1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        bool ok;
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return toInt32(value, ok);
1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Convert a value to a 32-bit unsigned integer.  The conversion fails if the
127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // value cannot be converted to an unsigned integer or converts to nan or to an infinity.
128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok);
129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inline uint32_t toUInt32(v8::Handle<v8::Value> value)
132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        bool ok;
134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return toUInt32(value, ok);
135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    inline float toFloat(v8::Local<v8::Value> value)
1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return static_cast<float>(value->NumberValue());
1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
142d0825bca7fe65beaee391d30da42e937db621564Steve Block    inline long long toInt64(v8::Local<v8::Value> value)
143d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
144d0825bca7fe65beaee391d30da42e937db621564Steve Block        return static_cast<long long>(value->IntegerValue());
145d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
146d0825bca7fe65beaee391d30da42e937db621564Steve Block
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // FIXME: Drop this in favor of the type specific v8ValueToWebCoreString when we rework the code generation.
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    inline String toWebCoreString(v8::Handle<v8::Value> object)
1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8ValueToWebCoreString(object);
1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
152dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String toWebCoreString(const v8::Arguments&, int index);
1548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // The string returned by this function is still owned by the argument
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // and will be deallocated when the argument is deallocated.
1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    inline const uint16_t* fromWebCoreString(const String& str)
1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return reinterpret_cast<const uint16_t*>(str.characters());
1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
162643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool isUndefinedOrNull(v8::Handle<v8::Value> value);
1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Handle<v8::Boolean> v8Boolean(bool value);
165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
166643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
170643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value);
171dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Handle<v8::String> v8UndetectableString(const String& str);
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Handle<v8::Value> v8StringOrNull(const String& str);
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
176643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Handle<v8::Value> v8StringOrUndefined(const String& str);
177643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
178643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Handle<v8::Value> v8StringOrFalse(const String& str);
179d0825bca7fe65beaee391d30da42e937db621564Steve Block
180d0825bca7fe65beaee391d30da42e937db621564Steve Block    double toWebCoreDate(v8::Handle<v8::Value> object);
181d0825bca7fe65beaee391d30da42e937db621564Steve Block
182d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Handle<v8::Value> v8DateOrNull(double value);
183dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Persistent<v8::FunctionTemplate> createRawTemplate();
185643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    struct BatchedAttribute;
187643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    struct BatchedCallback;
188dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
189643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Local<v8::Signature> configureTemplate(v8::Persistent<v8::FunctionTemplate>,
1908a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                                               const char* interfaceName,
1918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                                               v8::Persistent<v8::FunctionTemplate> parentClass,
192643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                               int fieldCount,
193dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch                                               const BatchedAttribute*,
194643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                               size_t attributeCount,
195643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                               const BatchedCallback*,
196643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                               size_t callbackCount);
197dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
198643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Handle<v8::Value> getElementStringAttr(const v8::AccessorInfo&,
199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                               const QualifiedName&);
200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    void setElementStringAttr(const v8::AccessorInfo&,
201643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                              const QualifiedName&,
202643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                              v8::Local<v8::Value>);
203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
204dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
205d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Persistent<v8::String> getToStringName();
206d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Persistent<v8::FunctionTemplate> getToStringTemplate();
207dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
2085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    String int32ToWebCoreString(int value);
2095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    PassRefPtr<DOMStringList> v8ValueToWebCoreDOMStringList(v8::Handle<v8::Value>);
2112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    class V8ParameterBase {
2135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    public:
2145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        operator String() { return toString<String>(); }
2155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        operator AtomicString() { return toString<AtomicString>(); }
2165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    protected:
2185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        V8ParameterBase(v8::Local<v8::Value> object) : m_v8Object(object), m_mode(Externalize), m_string() { }
2195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        bool prepareBase()
2215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        {
2225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            if (LIKELY(m_v8Object->IsString()))
2235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                return true;
2245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            if (LIKELY(m_v8Object->IsInt32())) {
2265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                setString(int32ToWebCoreString(m_v8Object->Int32Value()));
2275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                return true;
2285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            }
2295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            m_mode = DoNotExternalize;
2315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            v8::TryCatch block;
2325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            m_v8Object = m_v8Object->ToString();
2335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            // Handle the case where an exception is thrown as part of invoking toString on the object.
2345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            if (block.HasCaught()) {
2355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                block.ReThrow();
2365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                return false;
2375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            }
2385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // This path is unexpected.  However there is hypothesis that it
2402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // might be combination of v8 and v8 bindings bugs.  For now
2412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // just bailout as we'll crash if attempt to convert empty handle into a string.
2422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (m_v8Object.IsEmpty()) {
2432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                ASSERT_NOT_REACHED();
2442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return false;
2452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
2462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            return true;
2485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
2495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        v8::Local<v8::Value> object() { return m_v8Object; }
2515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        void setString(String string)
2535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        {
2545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            m_string = string;
2555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            m_v8Object.Clear(); // To signal that String is ready.
2565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
2575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen     private:
2595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        v8::Local<v8::Value> m_v8Object;
2605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        ExternalMode m_mode;
2615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        String m_string;
2625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        template <class StringType>
2645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        StringType toString()
2655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        {
2665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            if (LIKELY(!m_v8Object.IsEmpty()))
2675ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                return v8StringToWebCoreString<StringType>(m_v8Object.As<v8::String>(), m_mode);
2685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            return StringType(m_string);
2705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
2715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    };
2725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
273643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // V8Parameter is an adapter class that converts V8 values to Strings
274643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // or AtomicStrings as appropriate, using multiple typecast operators.
275643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    enum V8ParameterMode {
276643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DefaultMode,
277643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        WithNullCheck,
278643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        WithUndefinedOrNullCheck
279643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    };
280643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    template <V8ParameterMode MODE = DefaultMode>
2815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    class V8Parameter: public V8ParameterBase {
282643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    public:
2835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        V8Parameter(v8::Local<v8::Value> object) : V8ParameterBase(object) { }
2845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        V8Parameter(v8::Local<v8::Value> object, bool) : V8ParameterBase(object) { prepare(); }
2855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        bool prepare();
287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    };
288dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
2895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    template<> inline bool V8Parameter<DefaultMode>::prepare()
2905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    {
2915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return V8ParameterBase::prepareBase();
2925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
2935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    template<> inline bool V8Parameter<WithNullCheck>::prepare()
2955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    {
2965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (object()->IsNull()) {
2975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            setString(String());
2985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            return true;
2995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
300643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
3015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return V8ParameterBase::prepareBase();
3025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
3035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
3045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    template<> inline bool V8Parameter<WithUndefinedOrNullCheck>::prepare()
3055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    {
3065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (object()->IsNull() || object()->IsUndefined()) {
3075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            setString(String());
3085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            return true;
3095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        }
3105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
3115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return V8ParameterBase::prepareBase();
3125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} // namespace WebCore
3158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // V8Binding_h
317