OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * Copyright (C) 2012 Ericsson AB. All rights reserved. | 3 * Copyright (C) 2012 Ericsson AB. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 11 matching lines...) Expand all Loading... |
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #ifndef V8Binding_h | 32 // This file has been moved to platform/bindings/V8Binding.h. |
33 #define V8Binding_h | 33 // TODO(adithyas): Remove this file. |
34 | 34 #include "platform/bindings/V8Binding.h" |
35 #include "bindings/core/v8/DOMDataStore.h" | |
36 #include "bindings/core/v8/DOMWrapperWorld.h" | |
37 #include "bindings/core/v8/ScriptWrappable.h" | |
38 #include "bindings/core/v8/StringResource.h" | |
39 #include "bindings/core/v8/V8BindingMacros.h" | |
40 #include "bindings/core/v8/V8PerIsolateData.h" | |
41 #include "bindings/core/v8/V8ScriptRunner.h" | |
42 #include "bindings/core/v8/V8ValueCache.h" | |
43 #include "core/CoreExport.h" | |
44 #include "platform/heap/Handle.h" | |
45 #include "platform/wtf/text/AtomicString.h" | |
46 #include "platform/wtf/text/StringView.h" | |
47 #include "v8/include/v8.h" | |
48 | |
49 namespace blink { | |
50 | |
51 // This file contains bindings helper functions that do not have dependencies | |
52 // to core/ or bindings/core. For core-specific helper functions, see | |
53 // bindings/core/v8/V8BindingForCore.h. | |
54 | |
55 template <typename T> | |
56 struct V8TypeOf { | |
57 STATIC_ONLY(V8TypeOf); | |
58 // |Type| provides C++ -> V8 type conversion for DOM wrappers. | |
59 // The Blink binding code generator will generate specialized version of | |
60 // V8TypeOf for each wrapper class. | |
61 typedef void Type; | |
62 }; | |
63 | |
64 template <typename CallbackInfo, typename S> | |
65 inline void V8SetReturnValue(const CallbackInfo& info, | |
66 const v8::Persistent<S>& handle) { | |
67 info.GetReturnValue().Set(handle); | |
68 } | |
69 | |
70 template <typename CallbackInfo, typename S> | |
71 inline void V8SetReturnValue(const CallbackInfo& info, | |
72 const v8::Local<S> handle) { | |
73 info.GetReturnValue().Set(handle); | |
74 } | |
75 | |
76 template <typename CallbackInfo, typename S> | |
77 inline void V8SetReturnValue(const CallbackInfo& info, | |
78 v8::MaybeLocal<S> maybe) { | |
79 if (LIKELY(!maybe.IsEmpty())) | |
80 info.GetReturnValue().Set(maybe.ToLocalChecked()); | |
81 } | |
82 | |
83 template <typename CallbackInfo> | |
84 inline void V8SetReturnValue(const CallbackInfo& info, bool value) { | |
85 info.GetReturnValue().Set(value); | |
86 } | |
87 | |
88 template <typename CallbackInfo> | |
89 inline void V8SetReturnValue(const CallbackInfo& info, double value) { | |
90 info.GetReturnValue().Set(value); | |
91 } | |
92 | |
93 template <typename CallbackInfo> | |
94 inline void V8SetReturnValue(const CallbackInfo& info, int32_t value) { | |
95 info.GetReturnValue().Set(value); | |
96 } | |
97 | |
98 template <typename CallbackInfo> | |
99 inline void V8SetReturnValue(const CallbackInfo& info, uint32_t value) { | |
100 info.GetReturnValue().Set(value); | |
101 } | |
102 | |
103 template <typename CallbackInfo> | |
104 inline void V8SetReturnValueBool(const CallbackInfo& info, bool v) { | |
105 info.GetReturnValue().Set(v); | |
106 } | |
107 | |
108 template <typename CallbackInfo> | |
109 inline void V8SetReturnValueInt(const CallbackInfo& info, int v) { | |
110 info.GetReturnValue().Set(v); | |
111 } | |
112 | |
113 template <typename CallbackInfo> | |
114 inline void V8SetReturnValueUnsigned(const CallbackInfo& info, unsigned v) { | |
115 info.GetReturnValue().Set(v); | |
116 } | |
117 | |
118 template <typename CallbackInfo> | |
119 inline void V8SetReturnValueNull(const CallbackInfo& info) { | |
120 info.GetReturnValue().SetNull(); | |
121 } | |
122 | |
123 template <typename CallbackInfo> | |
124 inline void V8SetReturnValueUndefined(const CallbackInfo& info) { | |
125 info.GetReturnValue().SetUndefined(); | |
126 } | |
127 | |
128 template <typename CallbackInfo> | |
129 inline void V8SetReturnValueEmptyString(const CallbackInfo& info) { | |
130 info.GetReturnValue().SetEmptyString(); | |
131 } | |
132 | |
133 template <typename CallbackInfo> | |
134 inline void V8SetReturnValueString(const CallbackInfo& info, | |
135 const String& string, | |
136 v8::Isolate* isolate) { | |
137 if (string.IsNull()) { | |
138 V8SetReturnValueEmptyString(info); | |
139 return; | |
140 } | |
141 V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString( | |
142 info.GetReturnValue(), string.Impl()); | |
143 } | |
144 | |
145 template <typename CallbackInfo> | |
146 inline void V8SetReturnValueStringOrNull(const CallbackInfo& info, | |
147 const String& string, | |
148 v8::Isolate* isolate) { | |
149 if (string.IsNull()) { | |
150 V8SetReturnValueNull(info); | |
151 return; | |
152 } | |
153 V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString( | |
154 info.GetReturnValue(), string.Impl()); | |
155 } | |
156 | |
157 template <typename CallbackInfo> | |
158 inline void V8SetReturnValue(const CallbackInfo& callback_info, | |
159 ScriptWrappable* impl, | |
160 v8::Local<v8::Object> creation_context) { | |
161 if (UNLIKELY(!impl)) { | |
162 V8SetReturnValueNull(callback_info); | |
163 return; | |
164 } | |
165 if (DOMDataStore::SetReturnValue(callback_info.GetReturnValue(), impl)) | |
166 return; | |
167 v8::Local<v8::Object> wrapper = | |
168 impl->Wrap(callback_info.GetIsolate(), creation_context); | |
169 V8SetReturnValue(callback_info, wrapper); | |
170 } | |
171 | |
172 template <typename CallbackInfo> | |
173 inline void V8SetReturnValue(const CallbackInfo& callback_info, | |
174 ScriptWrappable* impl) { | |
175 V8SetReturnValue(callback_info, impl, callback_info.Holder()); | |
176 } | |
177 | |
178 template <typename CallbackInfo> | |
179 inline void V8SetReturnValueForMainWorld(const CallbackInfo& callback_info, | |
180 ScriptWrappable* impl) { | |
181 DCHECK(DOMWrapperWorld::Current(callback_info.GetIsolate()).IsMainWorld()); | |
182 if (UNLIKELY(!impl)) { | |
183 V8SetReturnValueNull(callback_info); | |
184 return; | |
185 } | |
186 if (DOMDataStore::SetReturnValueForMainWorld(callback_info.GetReturnValue(), | |
187 impl)) | |
188 return; | |
189 v8::Local<v8::Object> wrapper = | |
190 impl->Wrap(callback_info.GetIsolate(), callback_info.Holder()); | |
191 V8SetReturnValue(callback_info, wrapper); | |
192 } | |
193 | |
194 template <typename CallbackInfo> | |
195 inline void V8SetReturnValueFast(const CallbackInfo& callback_info, | |
196 ScriptWrappable* impl, | |
197 const ScriptWrappable* wrappable) { | |
198 if (UNLIKELY(!impl)) { | |
199 V8SetReturnValueNull(callback_info); | |
200 return; | |
201 } | |
202 if (DOMDataStore::SetReturnValueFast(callback_info.GetReturnValue(), impl, | |
203 callback_info.Holder(), wrappable)) | |
204 return; | |
205 v8::Local<v8::Object> wrapper = | |
206 impl->Wrap(callback_info.GetIsolate(), callback_info.Holder()); | |
207 V8SetReturnValue(callback_info, wrapper); | |
208 } | |
209 | |
210 template <typename CallbackInfo, typename T> | |
211 inline void V8SetReturnValueFast(const CallbackInfo& callback_info, | |
212 const v8::Local<T> handle, | |
213 const ScriptWrappable*) { | |
214 V8SetReturnValue(callback_info, handle); | |
215 } | |
216 | |
217 // Convert v8::String to a WTF::String. If the V8 string is not already | |
218 // an external string then it is transformed into an external string at this | |
219 // point to avoid repeated conversions. | |
220 inline String ToCoreString(v8::Local<v8::String> value) { | |
221 return V8StringToWebCoreString<String>(value, kExternalize); | |
222 } | |
223 | |
224 inline String ToCoreStringWithNullCheck(v8::Local<v8::String> value) { | |
225 if (value.IsEmpty() || value->IsNull()) | |
226 return String(); | |
227 return ToCoreString(value); | |
228 } | |
229 | |
230 inline String ToCoreStringWithUndefinedOrNullCheck( | |
231 v8::Local<v8::String> value) { | |
232 if (value.IsEmpty()) | |
233 return String(); | |
234 return ToCoreString(value); | |
235 } | |
236 | |
237 inline AtomicString ToCoreAtomicString(v8::Local<v8::String> value) { | |
238 return V8StringToWebCoreString<AtomicString>(value, kExternalize); | |
239 } | |
240 | |
241 // This method will return a null String if the v8::Value does not contain a | |
242 // v8::String. It will not call ToString() on the v8::Value. If you want | |
243 // ToString() to be called, please use the TONATIVE_FOR_V8STRINGRESOURCE_*() | |
244 // macros instead. | |
245 inline String ToCoreStringWithUndefinedOrNullCheck(v8::Local<v8::Value> value) { | |
246 if (value.IsEmpty() || !value->IsString()) | |
247 return String(); | |
248 return ToCoreString(value.As<v8::String>()); | |
249 } | |
250 | |
251 // Convert a string to a V8 string. | |
252 | |
253 inline v8::Local<v8::String> V8String(v8::Isolate* isolate, | |
254 const StringView& string) { | |
255 DCHECK(isolate); | |
256 if (string.IsNull()) | |
257 return v8::String::Empty(isolate); | |
258 if (StringImpl* impl = string.SharedImpl()) | |
259 return V8PerIsolateData::From(isolate)->GetStringCache()->V8ExternalString( | |
260 isolate, impl); | |
261 if (string.Is8Bit()) | |
262 return v8::String::NewFromOneByte( | |
263 isolate, reinterpret_cast<const uint8_t*>(string.Characters8()), | |
264 v8::NewStringType::kNormal, static_cast<int>(string.length())) | |
265 .ToLocalChecked(); | |
266 return v8::String::NewFromTwoByte( | |
267 isolate, reinterpret_cast<const uint16_t*>(string.Characters16()), | |
268 v8::NewStringType::kNormal, static_cast<int>(string.length())) | |
269 .ToLocalChecked(); | |
270 } | |
271 | |
272 // As above, for string literals. The compiler doesn't optimize away the is8Bit | |
273 // and sharedImpl checks for string literals in the StringView version. | |
274 inline v8::Local<v8::String> V8String(v8::Isolate* isolate, | |
275 const char* string) { | |
276 DCHECK(isolate); | |
277 if (!string || string[0] == '\0') | |
278 return v8::String::Empty(isolate); | |
279 return v8::String::NewFromOneByte(isolate, | |
280 reinterpret_cast<const uint8_t*>(string), | |
281 v8::NewStringType::kNormal, strlen(string)) | |
282 .ToLocalChecked(); | |
283 } | |
284 | |
285 inline v8::Local<v8::Value> V8StringOrNull(v8::Isolate* isolate, | |
286 const AtomicString& string) { | |
287 if (string.IsNull()) | |
288 return v8::Null(isolate); | |
289 return V8PerIsolateData::From(isolate)->GetStringCache()->V8ExternalString( | |
290 isolate, string.Impl()); | |
291 } | |
292 | |
293 inline v8::Local<v8::String> V8AtomicString(v8::Isolate* isolate, | |
294 const StringView& string) { | |
295 DCHECK(isolate); | |
296 if (string.Is8Bit()) | |
297 return v8::String::NewFromOneByte( | |
298 isolate, reinterpret_cast<const uint8_t*>(string.Characters8()), | |
299 v8::NewStringType::kInternalized, | |
300 static_cast<int>(string.length())) | |
301 .ToLocalChecked(); | |
302 return v8::String::NewFromTwoByte( | |
303 isolate, reinterpret_cast<const uint16_t*>(string.Characters16()), | |
304 v8::NewStringType::kInternalized, | |
305 static_cast<int>(string.length())) | |
306 .ToLocalChecked(); | |
307 } | |
308 | |
309 // As above, for string literals. The compiler doesn't optimize away the is8Bit | |
310 // check for string literals in the StringView version. | |
311 inline v8::Local<v8::String> V8AtomicString(v8::Isolate* isolate, | |
312 const char* string) { | |
313 DCHECK(isolate); | |
314 if (!string || string[0] == '\0') | |
315 return v8::String::Empty(isolate); | |
316 return v8::String::NewFromOneByte( | |
317 isolate, reinterpret_cast<const uint8_t*>(string), | |
318 v8::NewStringType::kInternalized, strlen(string)) | |
319 .ToLocalChecked(); | |
320 } | |
321 | |
322 inline v8::Local<v8::String> V8StringFromUtf8(v8::Isolate* isolate, | |
323 const char* bytes, | |
324 int length) { | |
325 DCHECK(isolate); | |
326 return v8::String::NewFromUtf8(isolate, bytes, v8::NewStringType::kNormal, | |
327 length) | |
328 .ToLocalChecked(); | |
329 } | |
330 | |
331 inline v8::Local<v8::Value> V8Undefined() { | |
332 return v8::Local<v8::Value>(); | |
333 } | |
334 | |
335 inline v8::MaybeLocal<v8::Value> V8DateOrNaN(v8::Isolate* isolate, | |
336 double value) { | |
337 DCHECK(isolate); | |
338 return v8::Date::New(isolate->GetCurrentContext(), value); | |
339 } | |
340 | |
341 inline bool IsUndefinedOrNull(v8::Local<v8::Value> value) { | |
342 return value.IsEmpty() || value->IsNullOrUndefined(); | |
343 } | |
344 v8::Local<v8::Function> GetBoundFunction(v8::Local<v8::Function>); | |
345 | |
346 // FIXME: This will be soon embedded in the generated code. | |
347 template <typename Collection> | |
348 static void IndexedPropertyEnumerator( | |
349 const v8::PropertyCallbackInfo<v8::Array>& info) { | |
350 Collection* collection = | |
351 ToScriptWrappable(info.Holder())->ToImpl<Collection>(); | |
352 int length = collection->length(); | |
353 v8::Local<v8::Array> properties = v8::Array::New(info.GetIsolate(), length); | |
354 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); | |
355 for (int i = 0; i < length; ++i) { | |
356 v8::Local<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i); | |
357 if (!V8CallBoolean(properties->CreateDataProperty(context, i, integer))) | |
358 return; | |
359 } | |
360 V8SetReturnValue(info, properties); | |
361 } | |
362 | |
363 // These methods store hidden values into an array that is stored in the | |
364 // internal field of a DOM wrapper. | |
365 bool AddHiddenValueToArray(v8::Isolate*, | |
366 v8::Local<v8::Object>, | |
367 v8::Local<v8::Value>, | |
368 int cache_index); | |
369 void RemoveHiddenValueFromArray(v8::Isolate*, | |
370 v8::Local<v8::Object>, | |
371 v8::Local<v8::Value>, | |
372 int cache_index); | |
373 | |
374 // Freeze a V8 object. The type of the first parameter and the return value is | |
375 // intentionally v8::Value so that this function can wrap ToV8(). | |
376 // If the argument isn't an object, this will crash. | |
377 CORE_EXPORT v8::Local<v8::Value> FreezeV8Object(v8::Local<v8::Value>, | |
378 v8::Isolate*); | |
379 | |
380 } // namespace blink | |
381 | |
382 #endif // V8Binding_h | |
OLD | NEW |