15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)*/ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 32e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8NPObject.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "V8HTMLAppletElement.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "V8HTMLEmbedElement.h" 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "V8HTMLObjectElement.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/NPV8Object.h" 395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "bindings/v8/UnsafePersistent.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8Binding.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8NPUtils.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8ObjectConstructor.h" 4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/npruntime_impl.h" 4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/npruntime_priv.h" 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLPlugInElement.h" 4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/OwnArrayPtr.h" 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum InvokeFunctionType { 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InvokeMethod = 1, 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InvokeConstruct = 2, 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InvokeDefault = 3 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct IdentifierRep { 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int number() const { return m_isString ? 0 : m_value.m_number; } 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char* string() const { return m_isString ? m_value.m_string : 0; } 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) union { 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char* m_string; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_number; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } m_value; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_isString; 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: need comments. 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Params: holder could be HTMLEmbedElement or NPObject 695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& args, InvokeFunctionType functionId) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPObject* npObject; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) WrapperWorldType currentWorldType = worldType(args.GetIsolate()); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // These three types are subtypes of HTMLPlugInElement. 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (V8HTMLAppletElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType) || V8HTMLEmbedElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType) 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) || V8HTMLObjectElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType)) { 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The holder object is a subtype of HTMLPlugInElement. 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HTMLPlugInElement* element; 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (V8HTMLAppletElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType)) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element = V8HTMLAppletElement::toNative(args.Holder()); 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else if (V8HTMLEmbedElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType)) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element = V8HTMLEmbedElement::toNative(args.Holder()); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element = V8HTMLObjectElement::toNative(args.Holder()); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScriptInstance scriptInstance = element->getInstance(); 8693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (scriptInstance) { 8793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 8893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::HandleScope handleScope(isolate); 8993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) npObject = v8ObjectToNPObject(scriptInstance->newLocal(isolate)); 9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } else 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) npObject = 0; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The holder object is not a subtype of HTMLPlugInElement, it must be an NPObject which has three 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // internal fields. 955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (args.Holder()->InternalFieldCount() != npObjectInternalFieldCount) { 965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) throwError(v8ReferenceError, "NPMethod called on non-NPObject", args.GetIsolate()); 975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return; 985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) npObject = v8ObjectToNPObject(args.Holder()); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that our wrapper wasn't using a NPObject which has already been deleted. 1045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (!npObject || !_NPN_IsAlive(npObject)) { 1055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) throwError(v8ReferenceError, "NPObject deleted", args.GetIsolate()); 1065267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return; 1075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Wrap up parameters. 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int numArgs = args.Length(); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnArrayPtr<NPVariant> npArgs = adoptArrayPtr(new NPVariant[numArgs]); 112e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < numArgs; i++) 114e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch convertV8ObjectToNPVariant(args[i], npObject, &npArgs[i]); 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPVariant result; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VOID_TO_NPVARIANT(result); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool retval = true; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (functionId) { 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case InvokeMethod: 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (npObject->_class->invoke) { 1235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::String> functionName = v8::Handle<v8::String>::Cast(args.Data()); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = getStringIdentifier(functionName); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) retval = npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case InvokeConstruct: 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (npObject->_class->construct) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) retval = npObject->_class->construct(npObject, npArgs.get(), numArgs, &result); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case InvokeDefault: 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (npObject->_class->invokeDefault) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) retval = npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!retval) 141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) throwError(v8GeneralError, "Error calling method on NPObject.", args.GetIsolate()); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < numArgs; i++) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _NPN_ReleaseVariantValue(&npArgs[i]); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Unwrap return values. 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> returnValue; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (_NPN_IsAlive(npObject)) 149e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch returnValue = convertNPVariantToV8Object(&result, npObject, args.GetIsolate()); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _NPN_ReleaseVariantValue(&result); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8SetReturnValue(args, returnValue); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void npObjectMethodHandler(const v8::FunctionCallbackInfo<v8::Value>& args) 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return npObjectInvokeImpl(args, InvokeMethod); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void npObjectInvokeDefaultHandler(const v8::FunctionCallbackInfo<v8::Value>& args) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (args.IsConstructCall()) { 1655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) npObjectInvokeImpl(args, InvokeConstruct); 1665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return; 1675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) npObjectInvokeImpl(args, InvokeDefault); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class V8NPTemplateMap { 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // NPIdentifier is PrivateIdentifier*. 1755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) typedef HashMap<PrivateIdentifier*, UnsafePersistent<v8::FunctionTemplate> > MapType; 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) UnsafePersistent<v8::FunctionTemplate> get(PrivateIdentifier* key) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_map.get(key); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) void set(PrivateIdentifier* key, v8::Handle<v8::FunctionTemplate> handle) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_map.contains(key)); 1855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Persistent<v8::FunctionTemplate> wrapper(m_isolate, handle); 186521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) wrapper.MakeWeak(key, &makeWeakCallback); 1875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_map.set(key, UnsafePersistent<v8::FunctionTemplate>(wrapper)); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) static V8NPTemplateMap& sharedInstance(v8::Isolate* isolate) 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 192926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DEFINE_STATIC_LOCAL(V8NPTemplateMap, map, (isolate)); 193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(isolate == map.m_isolate); 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return map; 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) explicit V8NPTemplateMap(v8::Isolate* isolate) 199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_isolate(isolate) 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void dispose(PrivateIdentifier* key) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MapType::iterator it = m_map.find(key); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(it != m_map.end()); 2075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) it->value.dispose(); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_map.remove(it); 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) static void makeWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::FunctionTemplate>*, PrivateIdentifier* key) 21293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 21393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) V8NPTemplateMap::sharedInstance(isolate).dispose(key); 21493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 21593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MapType m_map; 217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Isolate* m_isolate; 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> key, v8::Isolate* isolate) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPObject* npObject = v8ObjectToNPObject(self); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that our wrapper wasn't using a NPObject which 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // has already been deleted. 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!npObject || !_NPN_IsAlive(npObject)) 227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return throwError(v8ReferenceError, "NPObject deleted", isolate); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 229e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (npObject->_class->hasProperty && npObject->_class->getProperty && npObject->_class->hasProperty(npObject, identifier)) { 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!_NPN_IsAlive(npObject)) 232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return throwError(v8ReferenceError, "NPObject deleted", isolate); 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPVariant result; 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VOID_TO_NPVARIANT(result); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!npObject->_class->getProperty(npObject, identifier, &result)) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return v8Undefined(); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Value> returnValue; 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (_NPN_IsAlive(npObject)) 241e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch returnValue = convertNPVariantToV8Object(&result, npObject, isolate); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _NPN_ReleaseVariantValue(&result); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return returnValue; 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!_NPN_IsAlive(npObject)) 248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return throwError(v8ReferenceError, "NPObject deleted", isolate); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasMethod(npObject, identifier)) { 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!_NPN_IsAlive(npObject)) 252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return throwError(v8ReferenceError, "NPObject deleted", isolate); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PrivateIdentifier* id = static_cast<PrivateIdentifier*>(identifier); 2555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) UnsafePersistent<v8::FunctionTemplate> functionTemplate = V8NPTemplateMap::sharedInstance(isolate).get(id); 2565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // FunctionTemplate caches function for each context. 2575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Local<v8::Function> v8Function; 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cache templates using identifier as the key. 2595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (functionTemplate.isEmpty()) { 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Create a new template. 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::FunctionTemplate> temp = v8::FunctionTemplate::New(); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) temp->SetCallHandler(npObjectMethodHandler, key); 2635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) V8NPTemplateMap::sharedInstance(isolate).set(id, temp); 2645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8Function = temp->GetFunction(); 2655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } else { 2665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8Function = functionTemplate.newLocal(isolate)->GetFunction(); 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8Function->SetName(v8::Handle<v8::String>::Cast(key)); 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return v8Function; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return v8Undefined(); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 275521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectNamedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = getStringIdentifier(name); 278521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectGetProperty(info.Holder(), identifier, name, info.GetIsolate())); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 281521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectIndexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = _NPN_GetIntIdentifier(index); 284521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectGetProperty(info.Holder(), identifier, v8::Number::New(index), info.GetIsolate())); 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 287521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectGetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = getStringIdentifier(name); 290521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectGetProperty(self, identifier, name, info.GetIsolate())); 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 293521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectGetIndexedProperty(v8::Local<v8::Object> self, uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = _NPN_GetIntIdentifier(index); 296521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectGetProperty(self, identifier, v8::Number::New(index), info.GetIsolate())); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 299521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectQueryProperty(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info) 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = getStringIdentifier(name); 302521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (npObjectGetProperty(info.Holder(), identifier, name, info.GetIsolate()).IsEmpty()) 303521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 304521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValueInt(info, 0); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static v8::Handle<v8::Value> npObjectSetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> value, v8::Isolate* isolate) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPObject* npObject = v8ObjectToNPObject(self); 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that our wrapper wasn't using a NPObject which has already been deleted. 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!npObject || !_NPN_IsAlive(npObject)) { 313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) throwError(v8ReferenceError, "NPObject deleted", isolate); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value; // Intercepted, but an exception was thrown. 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (npObject->_class->hasProperty && npObject->_class->setProperty && npObject->_class->hasProperty(npObject, identifier)) { 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!_NPN_IsAlive(npObject)) 319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return throwError(v8ReferenceError, "NPObject deleted", isolate); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPVariant npValue; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VOID_TO_NPVARIANT(npValue); 323e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch convertV8ObjectToNPVariant(value, npObject, &npValue); 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool success = npObject->_class->setProperty(npObject, identifier, &npValue); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _NPN_ReleaseVariantValue(&npValue); 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (success) 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value; // Intercept the call. 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return v8Undefined(); 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 333521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectNamedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = getStringIdentifier(name); 336521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectSetProperty(info.Holder(), identifier, value, info.GetIsolate())); 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 340521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectIndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = _NPN_GetIntIdentifier(index); 343521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectSetProperty(info.Holder(), identifier, value, info.GetIsolate())); 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 346521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectSetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = getStringIdentifier(name); 349521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectSetProperty(self, identifier, value, info.GetIsolate())); 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 352521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectSetIndexedProperty(v8::Local<v8::Object> self, uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier identifier = _NPN_GetIntIdentifier(index); 355521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, npObjectSetProperty(self, identifier, value, info.GetIsolate())); 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 358521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info, bool namedProperty) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPObject* npObject = v8ObjectToNPObject(info.Holder()); 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that our wrapper wasn't using a NPObject which 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // has already been deleted. 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!npObject || !_NPN_IsAlive(npObject)) 365926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) throwError(v8ReferenceError, "NPObject deleted", info.GetIsolate()); 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate) { 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t count; 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NPIdentifier* identifiers; 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (npObject->_class->enumerate(npObject, &identifiers, &count)) { 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Array> properties = v8::Array::New(count); 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (uint32_t i = 0; i < count; ++i) { 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]); 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (namedProperty) 375591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch properties->Set(v8::Integer::New(i, info.GetIsolate()), v8::String::NewSymbol(identifier->string())); 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 377591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch properties->Set(v8::Integer::New(i, info.GetIsolate()), v8::Integer::New(identifier->number(), info.GetIsolate())); 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 380521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) v8SetReturnValue(info, properties); 381521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 386521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectNamedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 388521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) npObjectPropertyEnumerator(info, true); 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 391521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void npObjectIndexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 393521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) npObjectPropertyEnumerator(info, false); 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static DOMWrapperMap<NPObject>& staticNPObjectMap() 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 39853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) DEFINE_STATIC_LOCAL(DOMWrapperMap<NPObject>, npObjectMap, (v8::Isolate::GetCurrent())); 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return npObjectMap; 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)template<> 40393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)inline void DOMWrapperMap<NPObject>::makeWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* wrapper, DOMWrapperMap<NPObject>*) 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 40593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) NPObject* npObject = static_cast<NPObject*>(toNative(*wrapper)); 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(npObject); 40893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(staticNPObjectMap().get(npObject) == *wrapper); 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Must remove from our map before calling _NPN_ReleaseObject(). _NPN_ReleaseObject can 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // call forgetV8ObjectForNPObject, which uses the table as well. 41293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) staticNPObjectMap().removeAndDispose(npObject); 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (_NPN_IsAlive(npObject)) 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _NPN_ReleaseObject(npObject); 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 418e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochv8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root) 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static v8::Persistent<v8::FunctionTemplate> npObjectDesc; 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(v8::Context::InContext()); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 4255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this is a v8 object, just return it. 427591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch V8NPObject* v8NPObject = npObjectToV8NPObject(object); 428591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (v8NPObject) 4295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return v8::Local<v8::Object>::New(isolate, v8NPObject->v8Object); 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we've already wrapped this object, just return it. 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Handle<v8::Object> wrapper = staticNPObjectMap().get(object); 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!wrapper.IsEmpty()) 4345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return v8::Local<v8::Object>::New(isolate, wrapper); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: we should create a Wrapper type as a subclass of JSObject. It has two internal fields, field 0 is the wrapped 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // pointer, and field 1 is the type. There should be an api function that returns unused type id. The same Wrapper type 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // can be used by DOM bindings. 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (npObjectDesc.IsEmpty()) { 4405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); 4415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) templ->InstanceTemplate()->SetInternalFieldCount(npObjectInternalFieldCount); 4425267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) templ->InstanceTemplate()->SetNamedPropertyHandler(npObjectNamedPropertyGetter, npObjectNamedPropertySetter, npObjectQueryProperty, 0, npObjectNamedPropertyEnumerator); 4435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) templ->InstanceTemplate()->SetIndexedPropertyHandler(npObjectIndexedPropertyGetter, npObjectIndexedPropertySetter, 0, 0, npObjectIndexedPropertyEnumerator); 4445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) templ->InstanceTemplate()->SetCallAsFunctionHandler(npObjectInvokeDefaultHandler); 4455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) npObjectDesc.Reset(isolate, templ); 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 448926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME: Move staticNPObjectMap() to DOMDataStore. 449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Use V8DOMWrapper::createWrapper() and 450926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // V8DOMWrapper::associateObjectWithWrapper() 451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // to create a wrapper object. 4525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) v8::Handle<v8::Function> v8Function = v8::Local<v8::FunctionTemplate>::New(isolate, npObjectDesc)->GetFunction(); 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Local<v8::Object> value = V8ObjectConstructor::newInstance(v8Function); 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (value.IsEmpty()) 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value; 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 457926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) V8DOMWrapper::setNativeInfo(value, npObjectTypeInfo(), object); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // KJS retains the object as part of its wrapper (see Bindings::CInstance). 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _NPN_RetainObject(object); 461e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch _NPN_RegisterObject(object, root); 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 463926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) WrapperConfiguration configuration = buildWrapperConfiguration(object, WrapperConfiguration::Dependent); 464926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) staticNPObjectMap().set(object, value, configuration); 465926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(V8DOMWrapper::maybeDOMWrapper(value)); 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value; 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void forgetV8ObjectForNPObject(NPObject* object) 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 47193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Isolate* isolate = v8::Isolate::GetCurrent(); 47293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::HandleScope scope(isolate); 47393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) v8::Handle<v8::Object> wrapper = staticNPObjectMap().getNewLocal(isolate, object); 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!wrapper.IsEmpty()) { 475926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) V8DOMWrapper::clearNativeInfo(wrapper, npObjectTypeInfo()); 47693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) staticNPObjectMap().removeAndDispose(object); 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _NPN_ReleaseObject(object); 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 482