10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* Redistribution and use in source and binary forms, with or without
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* modification, are permitted provided that the following conditions are
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* met:
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*     * Redistributions of source code must retain the above copyright
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* notice, this list of conditions and the following disclaimer.
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*     * Redistributions in binary form must reproduce the above
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* copyright notice, this list of conditions and the following disclaimer
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* in the documentation and/or other materials provided with the
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* distribution.
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*     * Neither the name of Google Inc. nor the names of its
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* contributors may be used to endorse or promote products derived from
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* this software without specific prior written permission.
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch*/
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h"
320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8NPObject.h"
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "HTMLPlugInElement.h"
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "NPV8Object.h"
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8DOMMap.h"
380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8HTMLAppletElement.h"
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8HTMLEmbedElement.h"
400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8HTMLObjectElement.h"
410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8Helpers.h"
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8NPUtils.h"
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8Proxy.h"
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "npruntime_impl.h"
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "npruntime_priv.h"
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/OwnArrayPtr.h>
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
48e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blocknamespace WebCore {
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochenum InvokeFunctionType {
510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    InvokeMethod = 1,
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    InvokeConstruct = 2,
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    InvokeDefault = 3
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch};
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5621939df44de1705786c545cd1bf519d47250322dBen Murdochstruct IdentifierRep {
5721939df44de1705786c545cd1bf519d47250322dBen Murdoch    int number() const { return m_isString ? 0 : m_value.m_number; }
5821939df44de1705786c545cd1bf519d47250322dBen Murdoch    const char* string() const { return m_isString ? m_value.m_string : 0; }
5921939df44de1705786c545cd1bf519d47250322dBen Murdoch
6021939df44de1705786c545cd1bf519d47250322dBen Murdoch    union {
6121939df44de1705786c545cd1bf519d47250322dBen Murdoch        const char* m_string;
6221939df44de1705786c545cd1bf519d47250322dBen Murdoch        int m_number;
6321939df44de1705786c545cd1bf519d47250322dBen Murdoch    } m_value;
6421939df44de1705786c545cd1bf519d47250322dBen Murdoch    bool m_isString;
6521939df44de1705786c545cd1bf519d47250322dBen Murdoch};
6621939df44de1705786c545cd1bf519d47250322dBen Murdoch
670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// FIXME: need comments.
680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// Params: holder could be HTMLEmbedElement or NPObject
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, InvokeFunctionType functionId)
700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPObject* npObject;
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // These three types are subtypes of HTMLPlugInElement.
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (V8HTMLAppletElement::HasInstance(args.Holder()) || V8HTMLEmbedElement::HasInstance(args.Holder())
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        || V8HTMLObjectElement::HasInstance(args.Holder())) {
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // The holder object is a subtype of HTMLPlugInElement.
77d0825bca7fe65beaee391d30da42e937db621564Steve Block        HTMLPlugInElement* element;
78d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (V8HTMLAppletElement::HasInstance(args.Holder()))
79d0825bca7fe65beaee391d30da42e937db621564Steve Block            element = V8HTMLAppletElement::toNative(args.Holder());
80d0825bca7fe65beaee391d30da42e937db621564Steve Block        else if (V8HTMLEmbedElement::HasInstance(args.Holder()))
81d0825bca7fe65beaee391d30da42e937db621564Steve Block            element = V8HTMLEmbedElement::toNative(args.Holder());
82d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
83d0825bca7fe65beaee391d30da42e937db621564Steve Block            element = V8HTMLObjectElement::toNative(args.Holder());
840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ScriptInstance scriptInstance = element->getInstance();
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (scriptInstance)
86d0825bca7fe65beaee391d30da42e937db621564Steve Block            npObject = v8ObjectToNPObject(scriptInstance->instance());
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            npObject = 0;
890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // The holder object is not a subtype of HTMLPlugInElement, it must be an NPObject which has three
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // internal fields.
92d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (args.Holder()->InternalFieldCount() != npObjectInternalFieldCount)
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch          return throwError("NPMethod called on non-NPObject", V8Proxy::ReferenceError);
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
95d0825bca7fe65beaee391d30da42e937db621564Steve Block        npObject = v8ObjectToNPObject(args.Holder());
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Verify that our wrapper wasn't using a NPObject which has already been deleted.
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!npObject || !_NPN_IsAlive(npObject))
1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return throwError("NPObject deleted", V8Proxy::ReferenceError);
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Wrap up parameters.
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int numArgs = args.Length();
1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    OwnArrayPtr<NPVariant> npArgs = adoptArrayPtr(new NPVariant[numArgs]);
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    for (int i = 0; i < numArgs; i++)
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        convertV8ObjectToNPVariant(args[i], npObject, &npArgs[i]);
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPVariant result;
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    VOID_TO_NPVARIANT(result);
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
112cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    bool retval = true;
1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    switch (functionId) {
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case InvokeMethod:
1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (npObject->_class->invoke) {
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            v8::Handle<v8::String> functionName(v8::String::Cast(*args.Data()));
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            NPIdentifier identifier = getStringIdentifier(functionName);
118cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            retval = npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result);
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case InvokeConstruct:
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (npObject->_class->construct)
123cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            retval = npObject->_class->construct(npObject, npArgs.get(), numArgs, &result);
1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case InvokeDefault:
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (npObject->_class->invokeDefault)
127cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            retval = npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result);
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    default:
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
133cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!retval)
134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        throwError("Error calling method on NPObject.", V8Proxy::GeneralError);
135cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (int i = 0; i < numArgs; i++)
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        _NPN_ReleaseVariantValue(&npArgs[i]);
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Unwrap return values.
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::Value> returnValue = convertNPVariantToV8Object(&result, npObject);
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    _NPN_ReleaseVariantValue(&result);
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return returnValue;
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectMethodHandler(const v8::Arguments& args)
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectInvokeImpl(args, InvokeMethod);
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectInvokeDefaultHandler(const v8::Arguments& args)
1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (args.IsConstructCall())
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return npObjectInvokeImpl(args, InvokeConstruct);
157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return npObjectInvokeImpl(args, InvokeDefault);
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void weakTemplateCallback(v8::Persistent<v8::Value>, void* parameter);
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// NPIdentifier is PrivateIdentifier*.
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic WeakReferenceMap<PrivateIdentifier, v8::FunctionTemplate> staticTemplateMap(&weakTemplateCallback);
1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void weakTemplateCallback(v8::Persistent<v8::Value> object, void* parameter)
1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(parameter);
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(identifier);
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(staticTemplateMap.contains(identifier));
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    staticTemplateMap.forget(identifier);
1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> key)
1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
179d0825bca7fe65beaee391d30da42e937db621564Steve Block    NPObject* npObject = v8ObjectToNPObject(self);
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Verify that our wrapper wasn't using a NPObject which
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // has already been deleted.
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!npObject || !_NPN_IsAlive(npObject))
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return throwError("NPObject deleted", V8Proxy::ReferenceError);
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (npObject->_class->hasProperty && npObject->_class->hasProperty(npObject, identifier)
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        && npObject->_class->getProperty) {
1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        NPVariant result;
1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        VOID_TO_NPVARIANT(result);
1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (!npObject->_class->getProperty(npObject, identifier, &result))
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return v8::Handle<v8::Value>();
1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::Handle<v8::Value> returnValue = convertNPVariantToV8Object(&result, npObject);
1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        _NPN_ReleaseVariantValue(&result);
1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return returnValue;
1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
201643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasMethod(npObject, identifier)) {
2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        PrivateIdentifier* id = static_cast<PrivateIdentifier*>(identifier);
2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::Persistent<v8::FunctionTemplate> functionTemplate = staticTemplateMap.get(id);
2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Cache templates using identifier as the key.
2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (functionTemplate.IsEmpty()) {
2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // Create a new template.
2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            v8::Local<v8::FunctionTemplate> temp = v8::FunctionTemplate::New();
2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            temp->SetCallHandler(npObjectMethodHandler, key);
2090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            functionTemplate = v8::Persistent<v8::FunctionTemplate>::New(temp);
2100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            staticTemplateMap.set(id, functionTemplate);
2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // FunctionTemplate caches function for each context.
2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::Local<v8::Function> v8Function = functionTemplate->GetFunction();
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8Function->SetName(v8::Handle<v8::String>::Cast(key));
2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8Function;
2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return v8::Handle<v8::Value>();
2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = getStringIdentifier(name);
2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectGetProperty(info.Holder(), identifier, name);
2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = _NPN_GetIntIdentifier(index);
2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectGetProperty(info.Holder(), identifier, v8::Number::New(index));
2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectGetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name)
2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = getStringIdentifier(name);
2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectGetProperty(self, identifier, name);
2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectGetIndexedProperty(v8::Local<v8::Object> self, uint32_t index)
2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = _NPN_GetIntIdentifier(index);
2430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectGetProperty(self, identifier, v8::Number::New(index));
2440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
246545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochv8::Handle<v8::Integer> npObjectQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
247545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
248545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    NPIdentifier identifier = getStringIdentifier(name);
249545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return npObjectGetProperty(info.Holder(), identifier, name).IsEmpty() ? v8::Handle<v8::Integer>() : v8::Integer::New(v8::None);
250545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
251545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
2520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic v8::Handle<v8::Value> npObjectSetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> value)
2530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
254d0825bca7fe65beaee391d30da42e937db621564Steve Block    NPObject* npObject = v8ObjectToNPObject(self);
2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Verify that our wrapper wasn't using a NPObject which has already been deleted.
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!npObject || !_NPN_IsAlive(npObject)) {
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        throwError("NPObject deleted", V8Proxy::ReferenceError);
2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return value;  // Intercepted, but an exception was thrown.
2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (npObject->_class->hasProperty && npObject->_class->hasProperty(npObject, identifier)
2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        && npObject->_class->setProperty) {
2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        NPVariant npValue;
2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        VOID_TO_NPVARIANT(npValue);
2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        convertV8ObjectToNPVariant(value, npObject, &npValue);
2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        bool success = npObject->_class->setProperty(npObject, identifier, &npValue);
2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        _NPN_ReleaseVariantValue(&npValue);
2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (success)
2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return value; // Intercept the call.
2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return notHandledByInterceptor();
2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectNamedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
2780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = getStringIdentifier(name);
2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectSetProperty(info.Holder(), identifier, value);
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectIndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = _NPN_GetIntIdentifier(index);
2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectSetProperty(info.Holder(), identifier, value);
2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectSetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name, v8::Local<v8::Value> value)
2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = getStringIdentifier(name);
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectSetProperty(self, identifier, value);
2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> npObjectSetIndexedProperty(v8::Local<v8::Object> self, uint32_t index, v8::Local<v8::Value> value)
2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPIdentifier identifier = _NPN_GetIntIdentifier(index);
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return npObjectSetProperty(self, identifier, value);
3000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
302643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockv8::Handle<v8::Array> npObjectPropertyEnumerator(const v8::AccessorInfo& info, bool namedProperty)
303643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
304d0825bca7fe65beaee391d30da42e937db621564Steve Block    NPObject* npObject = v8ObjectToNPObject(info.Holder());
305643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
306643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Verify that our wrapper wasn't using a NPObject which
307643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // has already been deleted.
308643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!npObject || !_NPN_IsAlive(npObject))
309643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        throwError("NPObject deleted", V8Proxy::ReferenceError);
310643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
311643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate) {
312643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        uint32_t count;
313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        NPIdentifier* identifiers;
314643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (npObject->_class->enumerate(npObject, &identifiers, &count)) {
315643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            v8::Handle<v8::Array> properties = v8::Array::New(count);
316643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            for (uint32_t i = 0; i < count; ++i) {
317643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]);
318643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                if (namedProperty)
319643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    properties->Set(v8::Integer::New(i), v8::String::New(identifier->string()));
320643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                else
321643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    properties->Set(v8::Integer::New(i), v8::Integer::New(identifier->number()));
322643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
323643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return properties;
325643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
326643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
327643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
328643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return v8::Handle<v8::Array>();
329643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
330643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
331643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockv8::Handle<v8::Array> npObjectNamedPropertyEnumerator(const v8::AccessorInfo& info)
332643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
333643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return npObjectPropertyEnumerator(info, true);
334643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
335643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
336643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockv8::Handle<v8::Array> npObjectIndexedPropertyEnumerator(const v8::AccessorInfo& info)
337643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
338643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return npObjectPropertyEnumerator(info, false);
339643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void weakNPObjectCallback(v8::Persistent<v8::Value>, void* parameter);
3420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic DOMWrapperMap<NPObject> staticNPObjectMap(&weakNPObjectCallback);
3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void weakNPObjectCallback(v8::Persistent<v8::Value> object, void* parameter)
3460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPObject* npObject = static_cast<NPObject*>(parameter);
3480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(staticNPObjectMap.contains(npObject));
3490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(npObject);
3500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Must remove from our map before calling _NPN_ReleaseObject(). _NPN_ReleaseObject can call ForgetV8ObjectForNPObject, which
3520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // uses the table as well.
3530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    staticNPObjectMap.forget(npObject);
3540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (_NPN_IsAlive(npObject))
3560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        _NPN_ReleaseObject(npObject);
3570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root)
3610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    static v8::Persistent<v8::FunctionTemplate> npObjectDesc;
3630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(v8::Context::InContext());
3650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // If this is a v8 object, just return it.
3670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (object->_class == npScriptObjectClass) {
3680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        V8NPObject* v8NPObject = reinterpret_cast<V8NPObject*>(object);
3690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::Local<v8::Object>::New(v8NPObject->v8Object);
3700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // If we've already wrapped this object, just return it.
3730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (staticNPObjectMap.contains(object))
3740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::Local<v8::Object>::New(staticNPObjectMap.get(object));
3750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // FIXME: we should create a Wrapper type as a subclass of JSObject. It has two internal fields, field 0 is the wrapped
3770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // pointer, and field 1 is the type. There should be an api function that returns unused type id. The same Wrapper type
3780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // can be used by DOM bindings.
3790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (npObjectDesc.IsEmpty()) {
3800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        npObjectDesc = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
381d0825bca7fe65beaee391d30da42e937db621564Steve Block        npObjectDesc->InstanceTemplate()->SetInternalFieldCount(npObjectInternalFieldCount);
382545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        npObjectDesc->InstanceTemplate()->SetNamedPropertyHandler(npObjectNamedPropertyGetter, npObjectNamedPropertySetter, npObjectQueryProperty, 0, npObjectNamedPropertyEnumerator);
383643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        npObjectDesc->InstanceTemplate()->SetIndexedPropertyHandler(npObjectIndexedPropertyGetter, npObjectIndexedPropertySetter, 0, 0, npObjectIndexedPropertyEnumerator);
3840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        npObjectDesc->InstanceTemplate()->SetCallAsFunctionHandler(npObjectInvokeDefaultHandler);
3850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::Function> v8Function = npObjectDesc->GetFunction();
3880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Object> value = SafeAllocation::newInstance(v8Function);
3890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // If we were unable to allocate the instance, we avoid wrapping and registering the NP object.
3910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (value.IsEmpty())
3920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return value;
3930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
394dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    V8DOMWrapper::setDOMWrapper(value, npObjectTypeInfo(), object);
3950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // KJS retains the object as part of its wrapper (see Bindings::CInstance).
3970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    _NPN_RetainObject(object);
3980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    _NPN_RegisterObject(object, root);
4000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Maintain a weak pointer for v8 so we can cleanup the object.
4020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Persistent<v8::Object> weakRef = v8::Persistent<v8::Object>::New(value);
4030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    staticNPObjectMap.set(object, weakRef);
4040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return value;
4060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
4070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid forgetV8ObjectForNPObject(NPObject* object)
4090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
4100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (staticNPObjectMap.contains(object)) {
4110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::HandleScope scope;
4120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::Persistent<v8::Object> handle(staticNPObjectMap.get(object));
413dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        V8DOMWrapper::setDOMWrapper(handle, npObjectTypeInfo(), 0);
4140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        staticNPObjectMap.forget(object);
415d84a0d9c2b06d8d7290355f7cf0c4fa822100741Ben Murdoch        _NPN_ReleaseObject(object);
4160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
4170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
418e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
419e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} // namespace WebCore
420