OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2006, 2007, 2008, 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 #include "config.h" | |
32 | |
33 #include "bindings/v8/V8NPObject.h" | |
34 | |
35 #include "bindings/core/v8/V8HTMLAppletElement.h" | |
36 #include "bindings/core/v8/V8HTMLEmbedElement.h" | |
37 #include "bindings/core/v8/V8HTMLObjectElement.h" | |
38 #include "bindings/v8/NPV8Object.h" | |
39 #include "bindings/v8/V8Binding.h" | |
40 #include "bindings/v8/V8NPUtils.h" | |
41 #include "bindings/v8/V8ObjectConstructor.h" | |
42 #include "bindings/v8/V8PersistentValueMap.h" | |
43 #include "bindings/v8/npruntime_impl.h" | |
44 #include "bindings/v8/npruntime_priv.h" | |
45 #include "core/html/HTMLPlugInElement.h" | |
46 #include "v8-util.h" | |
47 #include "wtf/OwnPtr.h" | |
48 | |
49 namespace WebCore { | |
50 | |
51 enum InvokeFunctionType { | |
52 InvokeMethod = 1, | |
53 InvokeConstruct = 2, | |
54 InvokeDefault = 3 | |
55 }; | |
56 | |
57 struct IdentifierRep { | |
58 int number() const { return m_isString ? 0 : m_value.m_number; } | |
59 const char* string() const { return m_isString ? m_value.m_string : 0; } | |
60 | |
61 union { | |
62 const char* m_string; | |
63 int m_number; | |
64 } m_value; | |
65 bool m_isString; | |
66 }; | |
67 | |
68 // FIXME: need comments. | |
69 // Params: holder could be HTMLEmbedElement or NPObject | |
70 static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
InvokeFunctionType functionId) | |
71 { | |
72 NPObject* npObject; | |
73 v8::Isolate* isolate = info.GetIsolate(); | |
74 | |
75 // These three types are subtypes of HTMLPlugInElement. | |
76 HTMLPlugInElement* element = V8HTMLAppletElement::toNativeWithTypeCheck(isol
ate, info.Holder()); | |
77 if (!element) { | |
78 element = V8HTMLEmbedElement::toNativeWithTypeCheck(isolate, info.Holder
()); | |
79 if (!element) { | |
80 element = V8HTMLObjectElement::toNativeWithTypeCheck(isolate, info.H
older()); | |
81 } | |
82 } | |
83 if (element) { | |
84 if (RefPtr<SharedPersistent<v8::Object> > wrapper = element->pluginWrapp
er()) { | |
85 v8::HandleScope handleScope(isolate); | |
86 npObject = v8ObjectToNPObject(wrapper->newLocal(isolate)); | |
87 } else | |
88 npObject = 0; | |
89 } else { | |
90 // The holder object is not a subtype of HTMLPlugInElement, it must be a
n NPObject which has three | |
91 // internal fields. | |
92 if (info.Holder()->InternalFieldCount() != npObjectInternalFieldCount) { | |
93 throwError(v8ReferenceError, "NPMethod called on non-NPObject", info
.GetIsolate()); | |
94 return; | |
95 } | |
96 | |
97 npObject = v8ObjectToNPObject(info.Holder()); | |
98 } | |
99 | |
100 // Verify that our wrapper wasn't using a NPObject which has already been de
leted. | |
101 if (!npObject || !_NPN_IsAlive(npObject)) { | |
102 throwError(v8ReferenceError, "NPObject deleted", isolate); | |
103 return; | |
104 } | |
105 | |
106 // Wrap up parameters. | |
107 int numArgs = info.Length(); | |
108 OwnPtr<NPVariant[]> npArgs = adoptArrayPtr(new NPVariant[numArgs]); | |
109 | |
110 for (int i = 0; i < numArgs; i++) | |
111 convertV8ObjectToNPVariant(info[i], npObject, &npArgs[i], isolate); | |
112 | |
113 NPVariant result; | |
114 VOID_TO_NPVARIANT(result); | |
115 | |
116 bool retval = true; | |
117 switch (functionId) { | |
118 case InvokeMethod: | |
119 if (npObject->_class->invoke) { | |
120 v8::Handle<v8::String> functionName = v8::Handle<v8::String>::Cast(i
nfo.Data()); | |
121 NPIdentifier identifier = getStringIdentifier(functionName); | |
122 retval = npObject->_class->invoke(npObject, identifier, npArgs.get()
, numArgs, &result); | |
123 } | |
124 break; | |
125 case InvokeConstruct: | |
126 if (npObject->_class->construct) | |
127 retval = npObject->_class->construct(npObject, npArgs.get(), numArgs
, &result); | |
128 break; | |
129 case InvokeDefault: | |
130 if (npObject->_class->invokeDefault) | |
131 retval = npObject->_class->invokeDefault(npObject, npArgs.get(), num
Args, &result); | |
132 break; | |
133 default: | |
134 break; | |
135 } | |
136 | |
137 if (!retval) | |
138 throwError(v8GeneralError, "Error calling method on NPObject.", isolate)
; | |
139 | |
140 for (int i = 0; i < numArgs; i++) | |
141 _NPN_ReleaseVariantValue(&npArgs[i]); | |
142 | |
143 // Unwrap return values. | |
144 v8::Handle<v8::Value> returnValue; | |
145 if (_NPN_IsAlive(npObject)) | |
146 returnValue = convertNPVariantToV8Object(&result, npObject, isolate); | |
147 _NPN_ReleaseVariantValue(&result); | |
148 | |
149 v8SetReturnValue(info, returnValue); | |
150 } | |
151 | |
152 | |
153 void npObjectMethodHandler(const v8::FunctionCallbackInfo<v8::Value>& info) | |
154 { | |
155 return npObjectInvokeImpl(info, InvokeMethod); | |
156 } | |
157 | |
158 | |
159 void npObjectInvokeDefaultHandler(const v8::FunctionCallbackInfo<v8::Value>& inf
o) | |
160 { | |
161 if (info.IsConstructCall()) { | |
162 npObjectInvokeImpl(info, InvokeConstruct); | |
163 return; | |
164 } | |
165 | |
166 npObjectInvokeImpl(info, InvokeDefault); | |
167 } | |
168 | |
169 class V8TemplateMapTraits : public V8PersistentValueMapTraits<PrivateIdentifier*
, v8::FunctionTemplate, true> { | |
170 public: | |
171 typedef v8::PersistentValueMap<PrivateIdentifier*, v8::FunctionTemplate, V8T
emplateMapTraits> MapType; | |
172 typedef PrivateIdentifier WeakCallbackDataType; | |
173 | |
174 static WeakCallbackDataType* WeakCallbackParameter(MapType* map, PrivateIden
tifier* key, const v8::Local<v8::FunctionTemplate>& value) | |
175 { | |
176 return key; | |
177 } | |
178 | |
179 static void DisposeCallbackData(WeakCallbackDataType* callbackData) { } | |
180 | |
181 static MapType* MapFromWeakCallbackData( | |
182 const v8::WeakCallbackData<v8::FunctionTemplate, WeakCallbackDataType>&)
; | |
183 | |
184 static PrivateIdentifier* KeyFromWeakCallbackData( | |
185 const v8::WeakCallbackData<v8::FunctionTemplate, WeakCallbackDataType>&
data) | |
186 { | |
187 return data.GetParameter(); | |
188 } | |
189 | |
190 // Dispose traits: | |
191 static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<v8::FunctionT
emplate> value, PrivateIdentifier* key) { } | |
192 }; | |
193 | |
194 | |
195 class V8NPTemplateMap { | |
196 public: | |
197 // NPIdentifier is PrivateIdentifier*. | |
198 typedef v8::PersistentValueMap<PrivateIdentifier*, v8::FunctionTemplate, V8T
emplateMapTraits> MapType; | |
199 | |
200 v8::Local<v8::FunctionTemplate> get(PrivateIdentifier* key) | |
201 { | |
202 return m_map.Get(key); | |
203 } | |
204 | |
205 void set(PrivateIdentifier* key, v8::Handle<v8::FunctionTemplate> handle) | |
206 { | |
207 ASSERT(!m_map.Contains(key)); | |
208 m_map.Set(key, handle); | |
209 } | |
210 | |
211 static V8NPTemplateMap& sharedInstance(v8::Isolate* isolate) | |
212 { | |
213 DEFINE_STATIC_LOCAL(V8NPTemplateMap, map, (isolate)); | |
214 ASSERT(isolate == map.m_map.GetIsolate()); | |
215 return map; | |
216 } | |
217 | |
218 friend class V8TemplateMapTraits; | |
219 | |
220 private: | |
221 explicit V8NPTemplateMap(v8::Isolate* isolate) | |
222 : m_map(isolate) | |
223 { | |
224 } | |
225 | |
226 MapType m_map; | |
227 }; | |
228 | |
229 V8TemplateMapTraits::MapType* V8TemplateMapTraits::MapFromWeakCallbackData(const
v8::WeakCallbackData<v8::FunctionTemplate, WeakCallbackDataType>& data) | |
230 { | |
231 return &V8NPTemplateMap::sharedInstance(data.GetIsolate()).m_map; | |
232 } | |
233 | |
234 | |
235 static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPI
dentifier identifier, v8::Local<v8::Value> key, v8::Isolate* isolate) | |
236 { | |
237 NPObject* npObject = v8ObjectToNPObject(self); | |
238 | |
239 // Verify that our wrapper wasn't using a NPObject which | |
240 // has already been deleted. | |
241 if (!npObject || !_NPN_IsAlive(npObject)) | |
242 return throwError(v8ReferenceError, "NPObject deleted", isolate); | |
243 | |
244 | |
245 if (npObject->_class->hasProperty && npObject->_class->getProperty && npObje
ct->_class->hasProperty(npObject, identifier)) { | |
246 if (!_NPN_IsAlive(npObject)) | |
247 return throwError(v8ReferenceError, "NPObject deleted", isolate); | |
248 | |
249 NPVariant result; | |
250 VOID_TO_NPVARIANT(result); | |
251 if (!npObject->_class->getProperty(npObject, identifier, &result)) | |
252 return v8Undefined(); | |
253 | |
254 v8::Handle<v8::Value> returnValue; | |
255 if (_NPN_IsAlive(npObject)) | |
256 returnValue = convertNPVariantToV8Object(&result, npObject, isolate)
; | |
257 _NPN_ReleaseVariantValue(&result); | |
258 return returnValue; | |
259 | |
260 } | |
261 | |
262 if (!_NPN_IsAlive(npObject)) | |
263 return throwError(v8ReferenceError, "NPObject deleted", isolate); | |
264 | |
265 if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasM
ethod(npObject, identifier)) { | |
266 if (!_NPN_IsAlive(npObject)) | |
267 return throwError(v8ReferenceError, "NPObject deleted", isolate); | |
268 | |
269 PrivateIdentifier* id = static_cast<PrivateIdentifier*>(identifier); | |
270 v8::Local<v8::FunctionTemplate> functionTemplate = V8NPTemplateMap::shar
edInstance(isolate).get(id); | |
271 // Cache templates using identifier as the key. | |
272 if (functionTemplate.IsEmpty()) { | |
273 // Create a new template. | |
274 functionTemplate = v8::FunctionTemplate::New(isolate); | |
275 functionTemplate->SetCallHandler(npObjectMethodHandler, key); | |
276 V8NPTemplateMap::sharedInstance(isolate).set(id, functionTemplate); | |
277 } | |
278 v8::Local<v8::Function> v8Function = functionTemplate->GetFunction(); | |
279 v8Function->SetName(v8::Handle<v8::String>::Cast(key)); | |
280 return v8Function; | |
281 } | |
282 | |
283 return v8Undefined(); | |
284 } | |
285 | |
286 void npObjectNamedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyC
allbackInfo<v8::Value>& info) | |
287 { | |
288 NPIdentifier identifier = getStringIdentifier(name); | |
289 v8SetReturnValue(info, npObjectGetProperty(info.Holder(), identifier, name,
info.GetIsolate())); | |
290 } | |
291 | |
292 void npObjectIndexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInf
o<v8::Value>& info) | |
293 { | |
294 NPIdentifier identifier = _NPN_GetIntIdentifier(index); | |
295 v8SetReturnValue(info, npObjectGetProperty(info.Holder(), identifier, v8::Nu
mber::New(info.GetIsolate(), index), info.GetIsolate())); | |
296 } | |
297 | |
298 void npObjectGetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String>
name, const v8::PropertyCallbackInfo<v8::Value>& info) | |
299 { | |
300 NPIdentifier identifier = getStringIdentifier(name); | |
301 v8SetReturnValue(info, npObjectGetProperty(self, identifier, name, info.GetI
solate())); | |
302 } | |
303 | |
304 void npObjectGetIndexedProperty(v8::Local<v8::Object> self, uint32_t index, cons
t v8::PropertyCallbackInfo<v8::Value>& info) | |
305 { | |
306 NPIdentifier identifier = _NPN_GetIntIdentifier(index); | |
307 v8SetReturnValue(info, npObjectGetProperty(self, identifier, v8::Number::New
(info.GetIsolate(), index), info.GetIsolate())); | |
308 } | |
309 | |
310 void npObjectQueryProperty(v8::Local<v8::String> name, const v8::PropertyCallbac
kInfo<v8::Integer>& info) | |
311 { | |
312 NPIdentifier identifier = getStringIdentifier(name); | |
313 if (npObjectGetProperty(info.Holder(), identifier, name, info.GetIsolate()).
IsEmpty()) | |
314 return; | |
315 v8SetReturnValueInt(info, 0); | |
316 } | |
317 | |
318 static v8::Handle<v8::Value> npObjectSetProperty(v8::Local<v8::Object> self, NPI
dentifier identifier, v8::Local<v8::Value> value, v8::Isolate* isolate) | |
319 { | |
320 NPObject* npObject = v8ObjectToNPObject(self); | |
321 | |
322 // Verify that our wrapper wasn't using a NPObject which has already been de
leted. | |
323 if (!npObject || !_NPN_IsAlive(npObject)) { | |
324 throwError(v8ReferenceError, "NPObject deleted", isolate); | |
325 return value; // Intercepted, but an exception was thrown. | |
326 } | |
327 | |
328 if (npObject->_class->hasProperty && npObject->_class->setProperty && npObje
ct->_class->hasProperty(npObject, identifier)) { | |
329 if (!_NPN_IsAlive(npObject)) | |
330 return throwError(v8ReferenceError, "NPObject deleted", isolate); | |
331 | |
332 NPVariant npValue; | |
333 VOID_TO_NPVARIANT(npValue); | |
334 convertV8ObjectToNPVariant(value, npObject, &npValue, isolate); | |
335 bool success = npObject->_class->setProperty(npObject, identifier, &npVa
lue); | |
336 _NPN_ReleaseVariantValue(&npValue); | |
337 if (success) | |
338 return value; // Intercept the call. | |
339 } | |
340 return v8Undefined(); | |
341 } | |
342 | |
343 | |
344 void npObjectNamedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value
> value, const v8::PropertyCallbackInfo<v8::Value>& info) | |
345 { | |
346 NPIdentifier identifier = getStringIdentifier(name); | |
347 v8SetReturnValue(info, npObjectSetProperty(info.Holder(), identifier, value,
info.GetIsolate())); | |
348 } | |
349 | |
350 | |
351 void npObjectIndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, c
onst v8::PropertyCallbackInfo<v8::Value>& info) | |
352 { | |
353 NPIdentifier identifier = _NPN_GetIntIdentifier(index); | |
354 v8SetReturnValue(info, npObjectSetProperty(info.Holder(), identifier, value,
info.GetIsolate())); | |
355 } | |
356 | |
357 void npObjectSetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String>
name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& inf
o) | |
358 { | |
359 NPIdentifier identifier = getStringIdentifier(name); | |
360 v8SetReturnValue(info, npObjectSetProperty(self, identifier, value, info.Get
Isolate())); | |
361 } | |
362 | |
363 void npObjectSetIndexedProperty(v8::Local<v8::Object> self, uint32_t index, v8::
Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) | |
364 { | |
365 NPIdentifier identifier = _NPN_GetIntIdentifier(index); | |
366 v8SetReturnValue(info, npObjectSetProperty(self, identifier, value, info.Get
Isolate())); | |
367 } | |
368 | |
369 void npObjectPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info,
bool namedProperty) | |
370 { | |
371 NPObject* npObject = v8ObjectToNPObject(info.Holder()); | |
372 | |
373 // Verify that our wrapper wasn't using a NPObject which | |
374 // has already been deleted. | |
375 if (!npObject || !_NPN_IsAlive(npObject)) | |
376 throwError(v8ReferenceError, "NPObject deleted", info.GetIsolate()); | |
377 | |
378 if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->
enumerate) { | |
379 uint32_t count; | |
380 NPIdentifier* identifiers; | |
381 if (npObject->_class->enumerate(npObject, &identifiers, &count)) { | |
382 uint32_t propertiesCount = 0; | |
383 for (uint32_t i = 0; i < count; ++i) { | |
384 IdentifierRep* identifier = static_cast<IdentifierRep*>(identifi
ers[i]); | |
385 if (namedProperty == identifier->m_isString) | |
386 ++propertiesCount; | |
387 } | |
388 v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(),
propertiesCount); | |
389 for (uint32_t i = 0, propertyIndex = 0; i < count; ++i) { | |
390 IdentifierRep* identifier = static_cast<IdentifierRep*>(identifi
ers[i]); | |
391 if (namedProperty == identifier->m_isString) { | |
392 ASSERT(propertyIndex < propertiesCount); | |
393 if (namedProperty) | |
394 properties->Set(v8::Integer::New(info.GetIsolate(), prop
ertyIndex++), v8AtomicString(info.GetIsolate(), identifier->string())); | |
395 else | |
396 properties->Set(v8::Integer::New(info.GetIsolate(), prop
ertyIndex++), v8::Integer::New(info.GetIsolate(), identifier->number())); | |
397 } | |
398 } | |
399 | |
400 v8SetReturnValue(info, properties); | |
401 return; | |
402 } | |
403 } | |
404 } | |
405 | |
406 void npObjectNamedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>&
info) | |
407 { | |
408 npObjectPropertyEnumerator(info, true); | |
409 } | |
410 | |
411 void npObjectIndexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>
& info) | |
412 { | |
413 npObjectPropertyEnumerator(info, false); | |
414 } | |
415 | |
416 static DOMWrapperMap<NPObject>& staticNPObjectMap() | |
417 { | |
418 DEFINE_STATIC_LOCAL(DOMWrapperMap<NPObject>, npObjectMap, (v8::Isolate::GetC
urrent())); | |
419 return npObjectMap; | |
420 } | |
421 | |
422 template <> | |
423 inline void DOMWrapperMap<NPObject>::PersistentValueMapTraits::Dispose( | |
424 v8::Isolate* isolate, | |
425 v8::UniquePersistent<v8::Object> value, | |
426 NPObject* npObject) | |
427 { | |
428 ASSERT(npObject); | |
429 if (_NPN_IsAlive(npObject)) | |
430 _NPN_ReleaseObject(npObject); | |
431 } | |
432 | |
433 v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root
, v8::Isolate* isolate) | |
434 { | |
435 static v8::Eternal<v8::FunctionTemplate> npObjectDesc; | |
436 | |
437 ASSERT(isolate->InContext()); | |
438 | |
439 // If this is a v8 object, just return it. | |
440 V8NPObject* v8NPObject = npObjectToV8NPObject(object); | |
441 if (v8NPObject) | |
442 return v8::Local<v8::Object>::New(isolate, v8NPObject->v8Object); | |
443 | |
444 // If we've already wrapped this object, just return it. | |
445 v8::Handle<v8::Object> wrapper = staticNPObjectMap().newLocal(object, isolat
e); | |
446 if (!wrapper.IsEmpty()) | |
447 return wrapper; | |
448 | |
449 // FIXME: we should create a Wrapper type as a subclass of JSObject. It has
two internal fields, field 0 is the wrapped | |
450 // pointer, and field 1 is the type. There should be an api function that re
turns unused type id. The same Wrapper type | |
451 // can be used by DOM bindings. | |
452 if (npObjectDesc.IsEmpty()) { | |
453 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolat
e); | |
454 templ->InstanceTemplate()->SetInternalFieldCount(npObjectInternalFieldCo
unt); | |
455 templ->InstanceTemplate()->SetNamedPropertyHandler(npObjectNamedProperty
Getter, npObjectNamedPropertySetter, npObjectQueryProperty, 0, npObjectNamedProp
ertyEnumerator); | |
456 templ->InstanceTemplate()->SetIndexedPropertyHandler(npObjectIndexedProp
ertyGetter, npObjectIndexedPropertySetter, 0, 0, npObjectIndexedPropertyEnumerat
or); | |
457 templ->InstanceTemplate()->SetCallAsFunctionHandler(npObjectInvokeDefaul
tHandler); | |
458 npObjectDesc.Set(isolate, templ); | |
459 } | |
460 | |
461 // FIXME: Move staticNPObjectMap() to DOMDataStore. | |
462 // Use V8DOMWrapper::createWrapper() and | |
463 // V8DOMWrapper::associateObjectWithWrapper() | |
464 // to create a wrapper object. | |
465 v8::Handle<v8::Function> v8Function = npObjectDesc.Get(isolate)->GetFunction
(); | |
466 v8::Local<v8::Object> value = V8ObjectConstructor::newInstance(isolate, v8Fu
nction); | |
467 if (value.IsEmpty()) | |
468 return value; | |
469 | |
470 V8DOMWrapper::setNativeInfo(value, npObjectTypeInfo(), object); | |
471 | |
472 // KJS retains the object as part of its wrapper (see Bindings::CInstance). | |
473 _NPN_RetainObject(object); | |
474 _NPN_RegisterObject(object, root); | |
475 | |
476 WrapperConfiguration configuration = buildWrapperConfiguration(object, Wrapp
erConfiguration::Dependent); | |
477 staticNPObjectMap().set(object, value, configuration); | |
478 ASSERT(V8DOMWrapper::isDOMWrapper(value)); | |
479 return value; | |
480 } | |
481 | |
482 void forgetV8ObjectForNPObject(NPObject* object) | |
483 { | |
484 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | |
485 v8::HandleScope scope(isolate); | |
486 v8::Handle<v8::Object> wrapper = staticNPObjectMap().newLocal(object, isolat
e); | |
487 if (!wrapper.IsEmpty()) { | |
488 V8DOMWrapper::clearNativeInfo(wrapper, npObjectTypeInfo()); | |
489 staticNPObjectMap().removeAndDispose(object); | |
490 _NPN_ReleaseObject(object); | |
491 } | |
492 } | |
493 | |
494 } // namespace WebCore | |
OLD | NEW |