Move WebCore into Source
[WebKit-https.git] / Source / WebCore / bindings / v8 / V8Binding.h
1 /*
2 * Copyright (C) 2009 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 are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef V8Binding_h
32 #define V8Binding_h
33
34 #include "BindingSecurity.h"
35 #include "MathExtras.h"
36 #include "PlatformString.h"
37 #include "V8DOMWrapper.h"
38 #include <wtf/text/AtomicString.h>
39
40 #include <v8.h>
41
42 namespace WebCore {
43
44     class EventListener;
45     class EventTarget;
46
47     // FIXME: Remove V8Binding.
48     class V8Binding {
49     };
50     typedef BindingSecurity<V8Binding> V8BindingSecurity;
51
52     enum ExternalMode {
53         Externalize,
54         DoNotExternalize
55     };
56
57     template <typename StringType>
58     StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external);
59
60     // Convert v8 types to a WTF::String. If the V8 string is not already
61     // an external string then it is transformed into an external string at this
62     // point to avoid repeated conversions.
63     inline String v8StringToWebCoreString(v8::Handle<v8::String> v8String)
64     {
65         return v8StringToWebCoreString<String>(v8String, Externalize);
66     }
67     String v8NonStringValueToWebCoreString(v8::Handle<v8::Value>);
68     String v8ValueToWebCoreString(v8::Handle<v8::Value> value);
69
70     // Convert v8 types to a WTF::AtomicString.
71     inline AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8String)
72     {
73         return v8StringToWebCoreString<AtomicString>(v8String, Externalize);
74     }
75     AtomicString v8NonStringValueToAtomicWebCoreString(v8::Handle<v8::Value>);
76     AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> value);
77
78     // Note: RefPtr is a must as we cache by StringImpl* equality, not identity
79     // hence lastStringImpl might be not a key of the cache (in sense of identity)
80     // and hence it's not refed on addition.
81     extern RefPtr<StringImpl> lastStringImpl;
82     extern v8::Persistent<v8::String> lastV8String;
83     v8::Local<v8::String> v8ExternalStringSlow(StringImpl* stringImpl);
84
85     // Return a V8 external string that shares the underlying buffer with the given
86     // WebCore string. The reference counting mechanism is used to keep the
87     // underlying buffer alive while the string is still live in the V8 engine.
88     inline v8::Local<v8::String> v8ExternalString(const String& string)
89     {
90         StringImpl* stringImpl = string.impl();
91         if (!stringImpl)
92             return v8::String::Empty();
93
94         if (lastStringImpl.get() == stringImpl) {
95             ASSERT(!lastV8String.IsNearDeath());
96             ASSERT(!lastV8String.IsEmpty());
97             return v8::Local<v8::String>::New(lastV8String);
98         }
99
100         return v8ExternalStringSlow(stringImpl);
101     }
102
103     // Convert a string to a V8 string.
104     inline v8::Handle<v8::String> v8String(const String& string)
105     {
106         return v8ExternalString(string);
107     }
108
109     // Enables caching v8 wrappers created for WTF::StringImpl.  Currently this cache requires
110     // all the calls (both to convert WTF::String to v8::String and to GC the handle)
111     // to be performed on the main thread.
112     void enableStringImplCache();
113
114     // Convert a value to a 32-bit integer.  The conversion fails if the
115     // value cannot be converted to an integer or converts to nan or to an infinity.
116     int toInt32(v8::Handle<v8::Value> value, bool& ok);
117
118     // Convert a value to a 32-bit integer assuming the conversion cannot fail.
119     inline int toInt32(v8::Handle<v8::Value> value)
120     {
121         bool ok;
122         return toInt32(value, ok);
123     }
124
125     // Convert a value to a 32-bit unsigned integer.  The conversion fails if the
126     // value cannot be converted to an unsigned integer or converts to nan or to an infinity.
127     uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok);
128
129     // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
130     inline uint32_t toUInt32(v8::Handle<v8::Value> value)
131     {
132         bool ok;
133         return toUInt32(value, ok);
134     }
135
136     inline float toFloat(v8::Local<v8::Value> value)
137     {
138         return static_cast<float>(value->NumberValue());
139     }
140
141     inline long long toInt64(v8::Local<v8::Value> value)
142     {
143         return static_cast<long long>(value->IntegerValue());
144     }
145
146     // FIXME: Drop this in favor of the type specific v8ValueToWebCoreString when we rework the code generation.
147     inline String toWebCoreString(v8::Handle<v8::Value> object)
148     {
149         return v8ValueToWebCoreString(object);
150     }
151
152     String toWebCoreString(const v8::Arguments&, int index);
153
154     // The string returned by this function is still owned by the argument
155     // and will be deallocated when the argument is deallocated.
156     inline const uint16_t* fromWebCoreString(const String& str)
157     {
158         return reinterpret_cast<const uint16_t*>(str.characters());
159     }
160
161     bool isUndefinedOrNull(v8::Handle<v8::Value> value);
162
163     v8::Handle<v8::Boolean> v8Boolean(bool value);
164
165     String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
166
167     AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
168
169     String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value);
170
171     v8::Handle<v8::String> v8UndetectableString(const String& str);
172
173     v8::Handle<v8::Value> v8StringOrNull(const String& str);
174
175     v8::Handle<v8::Value> v8StringOrUndefined(const String& str);
176
177     v8::Handle<v8::Value> v8StringOrFalse(const String& str);
178
179     double toWebCoreDate(v8::Handle<v8::Value> object);
180
181     v8::Handle<v8::Value> v8DateOrNull(double value);
182
183     v8::Persistent<v8::FunctionTemplate> createRawTemplate();
184
185     struct BatchedAttribute;
186     struct BatchedCallback;
187
188     v8::Local<v8::Signature> configureTemplate(v8::Persistent<v8::FunctionTemplate>,
189                                                const char* interfaceName,
190                                                v8::Persistent<v8::FunctionTemplate> parentClass,
191                                                int fieldCount,
192                                                const BatchedAttribute*,
193                                                size_t attributeCount,
194                                                const BatchedCallback*,
195                                                size_t callbackCount);
196
197     v8::Handle<v8::Value> getElementStringAttr(const v8::AccessorInfo&,
198                                                const QualifiedName&);
199     void setElementStringAttr(const v8::AccessorInfo&,
200                               const QualifiedName&,
201                               v8::Local<v8::Value>);
202
203
204     v8::Persistent<v8::String> getToStringName();
205     v8::Persistent<v8::FunctionTemplate> getToStringTemplate();
206
207     String int32ToWebCoreString(int value);
208
209     class V8ParameterBase {
210     public:
211         operator String() { return toString<String>(); }
212         operator AtomicString() { return toString<AtomicString>(); }
213
214     protected:
215         V8ParameterBase(v8::Local<v8::Value> object) : m_v8Object(object), m_mode(Externalize), m_string() { }
216
217         bool prepareBase()
218         {
219             if (LIKELY(m_v8Object->IsString()))
220                 return true;
221
222             if (LIKELY(m_v8Object->IsInt32())) {
223                 setString(int32ToWebCoreString(m_v8Object->Int32Value()));
224                 return true;
225             }
226
227             m_mode = DoNotExternalize;
228             v8::TryCatch block;
229             m_v8Object = m_v8Object->ToString();
230             // Handle the case where an exception is thrown as part of invoking toString on the object.
231             if (block.HasCaught()) {
232                 block.ReThrow();
233                 return false;
234             }
235
236             return true;
237         }
238
239         v8::Local<v8::Value> object() { return m_v8Object; }
240
241         void setString(String string)
242         {
243             m_string = string;
244             m_v8Object.Clear(); // To signal that String is ready.
245         }
246
247      private:
248         v8::Local<v8::Value> m_v8Object;
249         ExternalMode m_mode;
250         String m_string;
251
252         template <class StringType>
253         StringType toString()
254         {
255             if (LIKELY(!m_v8Object.IsEmpty()))
256                 return v8StringToWebCoreString<StringType>(m_v8Object.As<v8::String>(), m_mode);
257
258             return StringType(m_string);
259         }
260     };
261
262     // V8Parameter is an adapter class that converts V8 values to Strings
263     // or AtomicStrings as appropriate, using multiple typecast operators.
264     enum V8ParameterMode {
265         DefaultMode,
266         WithNullCheck,
267         WithUndefinedOrNullCheck
268     };
269     template <V8ParameterMode MODE = DefaultMode>
270     class V8Parameter: public V8ParameterBase {
271     public:
272         V8Parameter(v8::Local<v8::Value> object) : V8ParameterBase(object) { }
273         V8Parameter(v8::Local<v8::Value> object, bool) : V8ParameterBase(object) { prepare(); }
274
275         bool prepare();
276     };
277
278     template<> inline bool V8Parameter<DefaultMode>::prepare()
279     {
280         return V8ParameterBase::prepareBase();
281     }
282
283     template<> inline bool V8Parameter<WithNullCheck>::prepare()
284     {
285         if (object()->IsNull()) {
286             setString(String());
287             return true;
288         }
289
290         return V8ParameterBase::prepareBase();
291     }
292
293     template<> inline bool V8Parameter<WithUndefinedOrNullCheck>::prepare()
294     {
295         if (object()->IsNull() || object()->IsUndefined()) {
296             setString(String());
297             return true;
298         }
299
300         return V8ParameterBase::prepareBase();
301     }
302
303 } // namespace WebCore
304
305 #endif // V8Binding_h