diff --git a/mozilla/dom/src/base/nsDOMClassInfo.cpp b/mozilla/dom/src/base/nsDOMClassInfo.cpp index 6a75637c3d6..33c4a596860 100644 --- a/mozilla/dom/src/base/nsDOMClassInfo.cpp +++ b/mozilla/dom/src/base/nsDOMClassInfo.cpp @@ -124,6 +124,7 @@ // HTMLEmbed/ObjectElement helper includes #include "nsIPluginInstance.h" #include "nsIObjectFrame.h" +#include "nsINPRuntimePlugin.h" #include "nsIScriptablePlugin.h" #include "nsIPluginHost.h" #include "nsPIPluginHost.h" @@ -6174,6 +6175,19 @@ nsHTMLPluginObjElementSH::GetPluginJSObject(JSContext *cx, JSObject *obj, *plugin_obj = nsnull; *plugin_proto = nsnull; + nsCOMPtr npruntime_plugin = + do_QueryInterface(plugin_inst); + + if (npruntime_plugin) { + *plugin_obj = npruntime_plugin->GetJSObject(cx); + + if (*plugin_obj) { + *plugin_proto = ::JS_GetPrototype(cx, *plugin_obj); + + return NS_OK; + } + } + // Check if the plugin object has the nsIScriptablePlugin interface, // describing how to expose it to JavaScript. Given this interface, // use it to get the scriptable peer object (possibly the plugin diff --git a/mozilla/modules/plugin/base/public/Makefile.in b/mozilla/modules/plugin/base/public/Makefile.in index d7d7954dcf9..ba9145b7c93 100644 --- a/mozilla/modules/plugin/base/public/Makefile.in +++ b/mozilla/modules/plugin/base/public/Makefile.in @@ -55,11 +55,16 @@ EXPORTS = \ nsPluginsCID.h \ npapi.h \ npupp.h \ + npruntime.h \ + nptypes.h \ + nsINPRuntimePlugin.h \ $(NULL) SDK_HEADERS = \ npapi.h \ npupp.h \ + nptypes.h \ + npruntime.h \ $(NULL) XPIDLSRCS = \ diff --git a/mozilla/modules/plugin/base/public/npapi.h b/mozilla/modules/plugin/base/public/npapi.h index 250612f4336..2ab207734d7 100644 --- a/mozilla/modules/plugin/base/public/npapi.h +++ b/mozilla/modules/plugin/base/public/npapi.h @@ -37,7 +37,7 @@ /* - * npapi.h $Revision: 3.34 $ + * npapi.h $Revision: 3.35 $ * Netscape client plug-in API spec */ @@ -125,7 +125,7 @@ /*----------------------------------------------------------------------*/ #define NP_VERSION_MAJOR 0 -#define NP_VERSION_MINOR 13 +#define NP_VERSION_MINOR 14 /* The OS/2 version of Netscape uses RC_DATA to define the @@ -186,7 +186,7 @@ typedef unsigned short uint16; #endif #ifndef _UINT32 -# if defined(__alpha) +# if defined(__alpha) || defined(__amd64__) defined(__x86_64__) typedef unsigned int uint32; # else /* __alpha */ typedef unsigned long uint32; @@ -202,7 +202,7 @@ typedef short int16; #endif #ifndef _INT32 -# if defined(__alpha) +# if defined(__alpha) || defined(__amd64__) defined(__x86_64__) typedef int int32; # else /* __alpha */ typedef long int32; @@ -387,7 +387,10 @@ typedef enum { /* 12 and over are available on Mozilla builds starting with 0.9.9 */ NPPVjavascriptPushCallerBool = 12, NPPVpluginKeepLibraryInMemory = 13, /* available in Mozilla 1.0 */ - NPPVpluginNeedsXEmbed = 14 + NPPVpluginNeedsXEmbed = 14, + + /* Get the NPObject for scripting the plugin. */ + NPPVpluginScriptableNPObject = 15 } NPPVariable; /* @@ -406,7 +409,13 @@ typedef enum { NPNVDOMElement = (11 | NP_ABI_MASK), /* available in Mozilla 1.2 */ NPNVDOMWindow = (12 | NP_ABI_MASK), NPNVToolkit = (13 | NP_ABI_MASK), - NPNVSupportsXEmbedBool = 14 + NPNVSupportsXEmbedBool = 14, + + /* Get the NPObject wrapper for the browser window. */ + NPNVWindowNPObject = 15, + + /* Get the NPObject wrapper for the plugins DOM element. */ + NPNVPluginElementNPObject = 16 } NPNVariable; /* @@ -653,6 +662,9 @@ void NP_LOADDS NPP_URLNotify(NPP instance, const char* url, jref NP_LOADDS NPP_GetJavaClass(void); #endif NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value); +/* + * Uh, shouldn't NPP_SetValue() take an NPPVariable and not an NPNVariable? + */ NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value); /* diff --git a/mozilla/modules/plugin/base/public/npruntime.h b/mozilla/modules/plugin/base/public/npruntime.h new file mode 100644 index 00000000000..f74c7c80e9c --- /dev/null +++ b/mozilla/modules/plugin/base/public/npruntime.h @@ -0,0 +1,389 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright © 2004, Apple Computer, Inc. and The Mozilla Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla + * Foundation ("Mozilla") nor the names of their contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR + * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Revision 1 (March 4, 2004): + * Initial proposal. + * + * Revision 2 (March 10, 2004): + * All calls into script were made asynchronous. Results are + * provided via the NPScriptResultFunctionPtr callback. + * + * Revision 3 (March 10, 2004): + * Corrected comments to not refer to class retain/release FunctionPtrs. + * + * Revision 4 (March 11, 2004): + * Added additional convenience NPN_SetExceptionWithUTF8(). + * Changed NPHasPropertyFunctionPtr and NPHasMethodFunctionPtr to take NPClass + * pointers instead of NPObject pointers. + * Added NPIsValidIdentifier(). + * + * Revision 5 (March 17, 2004): + * Added context parameter to result callbacks from ScriptObject functions. + * + * Revision 6 (March 29, 2004): + * Renamed functions implemented by user agent to NPN_*. Removed _ from + * type names. + * Renamed "JavaScript" types to "Script". + * + * Revision 7 (April 21, 2004): + * NPIdentifier becomes a void*, was int32_t + * Remove NP_IsValidIdentifier, renamed NP_IdentifierFromUTF8 to NP_GetIdentifier + * Added NPVariant and modified functions to use this new type. + * + * Revision 8 (July 9, 2004): + * Updated to joint Apple-Mozilla license. + * + */ +#ifndef _NP_RUNTIME_H_ +#define _NP_RUNTIME_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nptypes.h" + +/* + This API is used to facilitate binding code written in C to script + objects. The API in this header does not assume the presence of a + user agent. That is, it can be used to bind C code to scripting + environments outside of the context of a user agent. + + However, the normal use of the this API is in the context of a + scripting environment running in a browser or other user agent. + In particular it is used to support the extended Netscape + script-ability API for plugins (NP-SAP). NP-SAP is an extension + of the Netscape plugin API. As such we have adopted the use of + the "NP" prefix for this API. + + The following NP{N|P}Variables were added to the Netscape plugin + API (in npapi.h): + + NPNVWindowNPObject + NPNVPluginElementNPObject + NPPVpluginScriptableNPObject + + These variables are exposed through NPN_GetValue() and + NPP_GetValue() (respectively) and are used to establish the + initial binding between the user agent and native code. The DOM + objects in the user agent can be examined and manipulated using + the NPN_ functions that operate on NPObjects described in this + header. + + To the extent possible the assumptions about the scripting + language used by the scripting environment have been minimized. +*/ + +#define NP_BEGIN_MACRO do { +#define NP_END_MACRO } while (0) + +/* + Objects (non-primitive data) passed between 'C' and script is + always wrapped in an NPObject. The 'interface' of an NPObject is + described by an NPClass. +*/ +typedef struct NPObject NPObject; +typedef struct NPClass NPClass; + +typedef char NPUTF8; +typedef struct _NPString { + const NPUTF8 *utf8characters; + uint32_t utf8length; +} NPString; + +typedef enum { + NPVariantType_Void, + NPVariantType_Null, + NPVariantType_Bool, + NPVariantType_Int32, + NPVariantType_Double, + NPVariantType_String, + NPVariantType_Object +} NPVariantType; + +typedef struct _NPVariant { + NPVariantType type; + union { + bool boolValue; + uint32_t intValue; + double doubleValue; + NPString stringValue; + NPObject *objectValue; + } value; +} NPVariant; + +/* + NPN_ReleaseVariantValue is called on all 'out' parameters + references. Specifically it is to be called on variants that own + their value, as is the case with all non-const NPVariant* + arguments after a successful call to any methods (except this one) + in this API. + + After calling NPN_ReleaseVariantValue, the type of the variant + will be NPVariantType_Void. +*/ +void NPN_ReleaseVariantValue(NPVariant *variant); + +#define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void) +#define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null) +#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool) +#define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32) +#define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double) +#define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String) +#define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object) + +#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue) +#define NPVARIANT_TO_INT32(_v) ((_v).value.intValue) +#define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue) +#define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue) +#define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue) + +#define VOID_TO_NPVARIANT(_v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Void; \ + (_v).value.objectValue = NULL; \ +NP_END_MACRO + +#define NULL_TO_NPVARIANT(_v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Null; \ + (_v).value.objectValue = NULL; \ +NP_END_MACRO + +#define BOOLEAN_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Bool; \ + (_v).value.boolValue = !!(_val); \ +NP_END_MACRO + +#define INT32_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Int32; \ + (_v).value.intValue = _val; \ +NP_END_MACRO + +#define DOUBLE_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Double; \ + (_v).value.doubleValue = _val; \ +NP_END_MACRO + +#define STRINGZ_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_String; \ + NPString str = { _val, strlen(_val) }; \ + (_v).value.stringValue = str; \ +NP_END_MACRO + +#define STRINGN_TO_NPVARIANT(_val, _len, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_String; \ + NPString str = { _val, _len }; \ + (_v).value.stringValue = str; \ +NP_END_MACRO + +#define OBJECT_TO_NPVARIANT(_val, _v) \ +NP_BEGIN_MACRO \ + (_v).type = NPVariantType_Object; \ + (_v).value.objectValue = _val; \ +NP_END_MACRO + + +/* + Type mappings (JavaScript types have been used for illustration + purposes): + + JavaScript to C (NPVariant with type:) + undefined NPVariantType_Void + null NPVariantType_Null + Boolean NPVariantType_Bool + Number NPVariantType_Double or NPVariantType_Int32 + String NPVariantType_String + Object NPVariantType_Object + + C (NPVariant with type:) to JavaScript + NPVariantType_Void undefined + NPVariantType_Null null + NPVariantType_Bool Boolean + NPVariantType_Int32 Number + NPVariantType_Double Number + NPVariantType_String String + NPVariantType_Object Object +*/ + +typedef void *NPIdentifier; + +/* + NPObjects have methods and properties. Methods and properties are + identified with NPIdentifiers. These identifiers may be reflected + in script. NPIdentifiers can be either strings or integers, IOW, + methods and properties can be identified by either strings or + integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be + compared using ==. In case of any errors, the requested + NPIdentifier(s) will be NULL. +*/ +NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name); +void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, + NPIdentifier *identifiers); +NPIdentifier NPN_GetIntIdentifier(int32_t intid); +bool NPN_IdentifierIsString(NPIdentifier *identifier); + +/* + The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed. +*/ +NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier); + +/* + Get the integer represented by identifier. If identifier is not an + integer identifier, the behaviour is undefined. +*/ +int32_t NPN_IntFromIdentifier(NPIdentifier identifier); + +/* + NPObject behavior is implemented using the following set of + callback functions. + + The NPVariant *result argument of these functions (where + applicable) should be released using NPN_ReleaseVariantValue(). +*/ +typedef NPObject *(*NPAllocateFunctionPtr)(); +typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj); +typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj); +typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name); +typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name, + const NPVariant *args, uint32_t argCount, + NPVariant *result); +typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name); +typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, + NPVariant *result); +typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, + const NPVariant *value); +typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj, NPIdentifier name); + +/* + NPObjects returned by create, retain, invoke, and getProperty pass + a reference count to the caller. That is, the callee adds a + reference count which passes to the caller. It is the caller's + responsibility to release the returned object. + + NPInvokeFunctionPtr function may return 0 to indicate a void + result. + + NPInvalidateFunctionPtr is called by the scripting environment + when the native code is shutdown. Any attempt to message a + NPObject instance after the invalidate callback has been + called will result in undefined behavior, even if the native code + is still retaining those NPObject instances. (The runtime + will typically return immediately, with 0 or NULL, from an attempt + to dispatch to a NPObject, but this behavior should not be + depended upon.) +*/ +struct NPClass +{ + uint32_t structVersion; + NPAllocateFunctionPtr allocate; + NPDeallocateFunctionPtr deallocate; + NPInvalidateFunctionPtr invalidate; + NPHasMethodFunctionPtr hasMethod; + NPInvokeFunctionPtr invoke; + NPHasPropertyFunctionPtr hasProperty; + NPGetPropertyFunctionPtr getProperty; + NPSetPropertyFunctionPtr setProperty; + NPRemovePropertyFunctionPtr removeProperty; +}; + +#define NP_CLASS_STRUCT_VERSION 1 + +struct NPObject { + NPClass *_class; + uint32_t referenceCount; + /* + * Additional space may be allocated here by types of NPObjects + */ +}; + +/* + If the class has an allocate function, NPN_CreateObject invokes + that function, otherwise a NPObject is allocated and + returned. This method will initialize the referenceCount member of + the NPObject to 1. +*/ +NPObject *NPN_CreateObject(NPClass *aClass); + +/* + Increment the NPObject's reference count. +*/ +NPObject *NPN_RetainObject(NPObject *npobj); + +/* + Decremented the NPObject's reference count. If the reference + count goes to zero, the class's destroy function is invoke if + specified, otherwise the object is freed directly. +*/ +void NPN_ReleaseObject(NPObject *npobj); + +/* + Functions to access script objects represented by NPObject. + + Calls to script objects are synchronous. If a function returns a + value, it will be supplied via the result NPVariant + argument. Successful calls will return true, false will be + returned in case of an error. + + Calls made from plugin code to script must be made from the thread + on which the plugin was initialized. +*/ + +bool NPN_Call(NPObject *npobj, NPIdentifier methodName, + const NPVariant *args, uint32_t argCount, NPVariant *result); +bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, + NPVariant *result); +bool NPN_GetProperty(NPObject *npobj, NPIdentifier propertyName, + NPVariant *result); +bool NPN_SetProperty(NPObject *npobj, NPIdentifier propertyName, + const NPVariant *value); +bool NPN_RemoveProperty(NPObject *npobj, NPIdentifier propertyName); +bool NPN_HasProperty(NPObject *npobj, NPIdentifier propertyName); +bool NPN_HasMethod(NPObject *npobj, NPIdentifier methodName); + +/* + NPN_SetException may be called to trigger a script exception upon + return from entry points into NPObjects. Typical usage: + + NPN_SetException (npobj, message); +*/ +void NPN_SetException(NPObject *npobj, const NPUTF8 *message); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mozilla/modules/plugin/base/public/nptypes.h b/mozilla/modules/plugin/base/public/nptypes.h new file mode 100644 index 00000000000..b2cbf34f3f0 --- /dev/null +++ b/mozilla/modules/plugin/base/public/nptypes.h @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * mozilla.org. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnny Stenback (Original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Header file for ensuring that C99 types ([u]int32_t and boolean) + * are available. + */ + +#if defined(WIN32) || defined(OS2) +typedef int int32_t; +typedef unsigned int uint32_t; +#else +#include +#include +#include +#endif diff --git a/mozilla/modules/plugin/base/public/npupp.h b/mozilla/modules/plugin/base/public/npupp.h index c57198f6b7b..dc00fc4f1ff 100644 --- a/mozilla/modules/plugin/base/public/npupp.h +++ b/mozilla/modules/plugin/base/public/npupp.h @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -37,7 +37,7 @@ /* - * npupp.h $Revision: 3.16 $ + * npupp.h $Revision: 3.17 $ * function call mecahnics needed by platform specific glue code. */ @@ -57,6 +57,8 @@ #include "npapi.h" #endif +#include "npruntime.h" + #include "jri.h" /****************************************************************************************** @@ -486,8 +488,6 @@ typedef NPError (* NP_LOADDS NPP_SetValueUPP)(NPP instance, NPNVariable variable #endif - - /* * Netscape entry points */ @@ -1061,6 +1061,441 @@ typedef void (* NP_LOADDS NPN_ForceRedrawUPP)(NPP instance); #endif +/* NPN_GetStringIdentifier */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_GetStringIdentifierUPP; +enum { + uppNPN_GetStringIdentifierProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(const NPUTF8*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPIdentifier))) +}; + +#define NewNPN_GetStringIdentifierProc(FUNC) \ + (NPN_GetStringIdentifierUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetStringIdentifierProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetStringIdentifierProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetStringIdentifierProcInfo, (ARG1)) + +#else + +typedef NPIdentifier (* NP_LOADDS NPN_GetStringIdentifierUPP)(const NPUTF8* name); +#define NewNPN_GetStringIdentifierProc(FUNC) \ + ((NPN_GetStringIdentifierUPP) (FUNC)) +#define CallNPN_GetStringIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_GetStringIdentifiers */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_GetStringIdentifiersUPP; +enum { + uppNPN_GetStringIdentifiersProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(const NPUTF8**))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(int32_t))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPIdentifier*))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_GetStringIdentifiersProc(FUNC) \ + (NPN_GetStringIdentifiersUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetStringIdentifiersProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetStringIdentifiersProc(FUNC, ARG1, ARG2, ARG3) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetStringIdentifiersProcInfo, (ARG1), (ARG2), (ARG3)) + +#else + +typedef void (* NP_LOADDS NPN_GetStringIdentifiersUPP)(const NPUTF8** names, + int32_t nameCount, + NPIdentifier* identifiers); +#define NewNPN_GetStringIdentifiersProc(FUNC) \ + ((NPN_GetStringIdentifiersUPP) (FUNC)) +#define CallNPN_GetStringIdentifiersProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +#endif + +/* NPN_GetIntIdentifier */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_GetIntIdentifierUPP; +enum { + uppNPN_GetIntIdentifierProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(int32_t))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPIdentifier))) +}; + +#define NewNPN_GetIntIdentifierProc(FUNC) \ + (NPN_GetIntIdentifierUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetIntIdentifierProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetIntIdentifierProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetIntIdentifierProcInfo, (ARG1)) + +#else + +typedef NPIdentifier (* NP_LOADDS NPN_GetIntIdentifierUPP)(int32_t intid); +#define NewNPN_GetIntIdentifierProc(FUNC) \ + ((NPN_GetIntIdentifierUPP) (FUNC)) +#define CallNPN_GetIntIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_IdentifierIsString */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_IdentifierIsStringUPP; +enum { + uppNPN_IdentifierIsStringProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPIdentifier identifier))) + | RESULT_SIZE(SIZE_CODE(sizeof(bool))) +}; + +#define NewNPN_IdentifierIsStringProc(FUNC) \ + (NPN_IdentifierIsStringUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_IdentifierIsStringProcInfo, GetCurrentArchitecture()) +#define CallNPN_IdentifierIsStringProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_IdentifierIsStringProcInfo, (ARG1)) + +#else + +typedef bool (* NP_LOADDS NPN_IdentifierIsStringUPP)(NPIdentifier identifier); +#define NewNPN_IdentifierIsStringProc(FUNC) \ + ((NPN_IdentifierIsStringUPP) (FUNC)) +#define CallNPN_IdentifierIsStringProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_UTF8FromIdentifier */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_UTF8FromIdentifierUPP; +enum { + uppNPN_UTF8FromIdentifierProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPIdentifier))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPUTF8*))) +}; + +#define NewNPN_UTF8FromIdentifierProc(FUNC) \ + (NPN_UTF8FromIdentifierUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_UTF8FromIdentifierProcInfo, GetCurrentArchitecture()) +#define CallNPN_UTF8FromIdentifierProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_UTF8FromIdentifierProcInfo, (ARG1)) + +#else + +typedef NPUTF8* (* NP_LOADDS NPN_UTF8FromIdentifierUPP)(NPIdentifier identifier); +#define NewNPN_UTF8FromIdentifierProc(FUNC) \ + ((NPN_UTF8FromIdentifierUPP) (FUNC)) +#define CallNPN_UTF8FromIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_IntFromIdentifier */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_IntFromIdentifierUPP; +enum { + uppNPN_IntFromIdentifierProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPIdentifier))) + | RESULT_SIZE(SIZE_CODE(sizeof(int32_t))) +}; + +#define NewNPN_IntFromIdentifierProc(FUNC) \ + (NPN_IntFromIdentifierUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_IntFromIdentifierProcInfo, GetCurrentArchitecture()) +#define CallNPN_IntFromIdentifierProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_IntFromIdentifierProcInfo, (ARG1)) + +#else + +typedef int32_t (* NP_LOADDS NPN_IntFromIdentifierUPP)(NPIdentifier identifier); +#define NewNPN_IntFromIdentifierProc(FUNC) \ + ((NPN_IntFromIdentifierUPP) (FUNC)) +#define CallNPN_IntFromIdentifierProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_CreateObject */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_CreateObjectUPP; +enum { + uppNPN_CreateObjectProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPClass*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPObject*))) +}; + +#define NewNPN_CreateObjectProc(FUNC) \ + (NPN_CreateObjectUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_CreateObjectProcInfo, GetCurrentArchitecture()) +#define CallNPN_CreateObjectProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_CreateObjectProcInfo, (ARG1)) + +#else + +typedef NPObject* (* NP_LOADDS NPN_CreateObjectUPP)(NPClass *aClass); +#define NewNPN_CreateObjectProc(FUNC) \ + ((NPN_CreateObjectUPP) (FUNC)) +#define CallNPN_CreateObjectProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_RetainObject */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_RetainObjectUPP; +enum { + uppNPN_RetainObjectProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*))) + | RESULT_SIZE(SIZE_CODE(sizeof(NPObject*))) +}; + +#define NewNPN_RetainObjectProc(FUNC) \ + (NPN_RetainObjectUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_RetainObjectProcInfo, GetCurrentArchitecture()) +#define CallNPN_RetainObjectProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_RetainObjectProcInfo, (ARG1)) + +#else + +typedef NPObject* (* NP_LOADDS NPN_RetainObjectUPP)(NPObject *obj); +#define NewNPN_RetainObjectProc(FUNC) \ + ((NPN_RetainObjectUPP) (FUNC)) +#define CallNPN_RetainObjectProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_ReleaseObject */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_ReleaseObjectUPP; +enum { + uppNPN_ReleaseObjectProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_ReleaseObjectProc(FUNC) \ + (NPN_ReleaseObjectUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_ReleaseObjectProcInfo, GetCurrentArchitecture()) +#define CallNPN_ReleaseObjectProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_ReleaseObjectProcInfo, (ARG1)) + +#else + +typedef void (* NP_LOADDS NPN_ReleaseObjectUPP)(NPObject *obj); +#define NewNPN_ReleaseObjectProc(FUNC) \ + ((NPN_ReleaseObjectUPP) (FUNC)) +#define CallNPN_ReleaseObjectProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_Call */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_CallUPP; +enum { + uppNPN_CallProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPIdentifier))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const NPVariant*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32_t))) + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(NPVariant*))) + | RESULT_SIZE(SIZE_CODE(sizeof(bool))) +}; + +#define NewNPN_CallProc(FUNC) \ + (NPN_CallUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_CallProcInfo, GetCurrentArchitecture()) +#define CallNPN_CallProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_CallProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) + +#else + +typedef bool (* NP_LOADDS NPN_CallUPP)(NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result); +#define NewNPN_CallProc(FUNC) \ + ((NPN_CallUPP) (FUNC)) +#define CallNPN_CallProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) + +#endif + +/* NPN_Evaluate */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_EvaluateUPP; +enum { + uppNPN_EvaluateProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPString*))) + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPVariant*))) + | RESULT_SIZE(SIZE_CODE(sizeof(bool))) +}; + +#define NewNPN_EvaluateProc(FUNC) \ + (NPN_EvaluateUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_EvaluateProcInfo, GetCurrentArchitecture()) +#define CallNPN_EvaluateProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_EvaluateProcInfo, (ARG1), (ARG2), (ARG3), (ARG4)) + +#else + +typedef bool (* NP_LOADDS NPN_EvaluateUPP)(NPP npp, NPObject *obj, NPString *script, NPVariant *result); +#define NewNPN_EvaluateProc(FUNC) \ + ((NPN_EvaluateUPP) (FUNC)) +#define CallNPN_EvaluateProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ + (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) + +#endif + +/* NPN_GetProperty */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_GetPropertyUPP; +enum { + uppNPN_GetPropertyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPIdentifier))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPVariant*))) + | RESULT_SIZE(SIZE_CODE(sizeof(bool))) +}; + +#define NewNPN_GetPropertyProc(FUNC) \ + (NPN_GetPropertyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetPropertyProcInfo, GetCurrentArchitecture()) +#define CallNPN_GetPropertyProc(FUNC, ARG1, ARG2, ARG3) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetPropertyProcInfo, (ARG1), (ARG2), (ARG3)) + +#else + +typedef bool (* NP_LOADDS NPN_GetPropertyUPP)(NPObject *obj, NPIdentifier propertyName, NPVariant *result); +#define NewNPN_GetPropertyProc(FUNC) \ + ((NPN_GetPropertyUPP) (FUNC)) +#define CallNPN_GetPropertyProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +#endif + +/* NPN_SetProperty */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_SetPropertyUPP; +enum { + uppNPN_SetPropertyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPIdentifier))) + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const NPVariant*))) + | RESULT_SIZE(SIZE_CODE(sizeof(bool))) +}; + +#define NewNPN_SetPropertyProc(FUNC) \ + (NPN_SetPropertyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_SetPropertyProcInfo, GetCurrentArchitecture()) +#define CallNPN_SetPropertyProc(FUNC, ARG1, ARG2, ARG3) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_SetPropertyProcInfo, (ARG1), (ARG2), (ARG3)) + +#else + +typedef bool (* NP_LOADDS NPN_SetPropertyUPP)(NPObject *obj, NPIdentifier propertyName, const NPVariant *value); +#define NewNPN_SetPropertyProc(FUNC) \ + ((NPN_SetPropertyUPP) (FUNC)) +#define CallNPN_SetPropertyProc(FUNC, ARG1, ARG2, ARG3) \ + (*(FUNC))((ARG1), (ARG2), (ARG3)) + +#endif + +/* NPN_RemoveProperty */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_RemovePropertyUPP; +enum { + uppNPN_RemovePropertyProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPIdentifier))) + | RESULT_SIZE(SIZE_CODE(sizeof(bool))) +}; + +#define NewNPN_RemovePropertyProc(FUNC) \ + (NPN_RemovePropertyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_RemovePropertyProcInfo, GetCurrentArchitecture()) +#define CallNPN_RemovePropertyProc(FUNC, ARG1, ARG2) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_RemovePropertyProcInfo, (ARG1), (ARG2)) + +#else + +typedef bool (* NP_LOADDS NPN_RemovePropertyUPP)(NPObject *obj, NPIdentifier propertyName); +#define NewNPN_RemovePropertyProc(FUNC) \ + ((NPN_RemovePropertyUPP) (FUNC)) +#define CallNPN_RemovePropertyProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + +/* NPN_ReleaseVariantValue */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_ReleaseVariantValue; +enum { + uppNPN_ReleaseVariantValueProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPVariant*))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_ReleaseVariantValueProc(FUNC) \ + (NPN_ReleaseVariantValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_ReleaseVariantValueProcInfo, GetCurrentArchitecture()) +#define CallNPN_ReleaseVariantValueProc(FUNC, ARG1) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_ReleaseVariantValueProcInfo, (ARG1)) + +#else + +typedef void (* NP_LOADDS NPN_ReleaseVariantValueUPP)(NPVariant *variant); +#define NewNPN_ReleaseVariantValueProc(FUNC) \ + ((NPN_ReleaseVariantValueUPP) (FUNC)) +#define CallNPN_ReleaseVariantValueProc(FUNC, ARG1) \ + (*(FUNC))((ARG1)) + +#endif + +/* NPN_SetException */ + +#if _NPUPP_USE_UPP_ + +typedef UniversalProcPtr NPN_SetExceptionUPP; +enum { + uppNPN_SetExceptionProcInfo = kThinkCStackBased + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*))) + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const NPUTF8*))) + | RESULT_SIZE(SIZE_CODE(0)) +}; + +#define NewNPN_SetExceptionProc(FUNC) \ + (NPN_SetExceptionUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_SetExceptionProcInfo, GetCurrentArchitecture()) +#define CallNPN_SetExceptionProc(FUNC, ARG1, ARG2) \ + (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_SetExceptionProcInfo, (ARG1), (ARG2)) + +#else + +typedef void (* NP_LOADDS NPN_SetExceptionUPP)(NPObject *obj, const NPUTF8 *message); +#define NewNPN_SetExceptionProc(FUNC) \ + ((NPN_SetExceptionUPP) (FUNC)) +#define CallNPN_SetExceptionProc(FUNC, ARG1, ARG2) \ + (*(FUNC))((ARG1), (ARG2)) + +#endif + + + /****************************************************************************************** * The actual plugin function table definitions @@ -1115,6 +1550,22 @@ typedef struct _NPNetscapeFuncs { NPN_InvalidateRectUPP invalidaterect; NPN_InvalidateRegionUPP invalidateregion; NPN_ForceRedrawUPP forceredraw; + NPN_GetStringIdentifierUPP getstringidentifier; + NPN_GetStringIdentifiersUPP getstringidentifiers; + NPN_GetIntIdentifierUPP getintidentifier; + NPN_IdentifierIsStringUPP identifierisstring; + NPN_UTF8FromIdentifierUPP utf8fromidentifier; + NPN_IntFromIdentifierUPP intfromidentifier; + NPN_CreateObjectUPP createobject; + NPN_RetainObjectUPP retainobject; + NPN_ReleaseObjectUPP releaseobject; + NPN_CallUPP call; + NPN_EvaluateUPP evaluate; + NPN_GetPropertyUPP getproperty; + NPN_SetPropertyUPP setproperty; + NPN_RemovePropertyUPP removeproperty; + NPN_ReleaseVariantValueUPP releasevariantvalue; + NPN_SetExceptionUPP setexception; } NPNetscapeFuncs; #ifdef XP_MAC diff --git a/mozilla/modules/plugin/base/public/nsINPRuntimePlugin.h b/mozilla/modules/plugin/base/public/nsINPRuntimePlugin.h new file mode 100644 index 00000000000..2ef80bd1ce2 --- /dev/null +++ b/mozilla/modules/plugin/base/public/nsINPRuntimePlugin.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef nsINPRuntimePlugin_h___ +#define nsINPRuntimePlugin_h___ + +#include "nsISupports.h" + +struct JSObject; +struct JSContext; + +#define NS_INPRUNTIMEPLUGIN_IID \ + {0xbd962bb4, 0x54c3, 0x4d23, \ + { 0xa8, 0xca, 0x54, 0x16, 0x08, 0x02, 0xc2, 0x59 }} + +class NS_NO_VTABLE nsINPRuntimePlugin : public nsISupports +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_INPRUNTIMEPLUGIN_IID) + + virtual JSObject *GetJSObject(JSContext *cx) = 0; +}; + +#endif /* nsINPRuntimePlugin_h___ */ diff --git a/mozilla/modules/plugin/base/public/nsIPluginInstance.idl b/mozilla/modules/plugin/base/public/nsIPluginInstance.idl index 49ad2bf2fbc..892e7c96780 100644 --- a/mozilla/modules/plugin/base/public/nsIPluginInstance.idl +++ b/mozilla/modules/plugin/base/public/nsIPluginInstance.idl @@ -75,13 +75,14 @@ interface nsIPluginInstancePeer; interface nsIPluginInstance : nsISupports { /** - * Initializes a newly created plugin instance, passing to it the plugin - * instance peer which it should use for all communication back to the browser. + * Initializes a newly created plugin instance, passing to it the + * plugin instance peer which it should use for all communication + * back to the browser. * - * @param aPeer - the corresponding plugin instance peer - * @result - NS_OK if this operation was successful + * @param aPeer - the corresponding plugin instance peer + * @result - NS_OK if this operation was successful */ - void initialize(in nsIPluginInstancePeer aPeer); + void initialize(in nsIPluginInstancePeer aPeer); /** * Returns a reference back to the plugin instance peer. This method is @@ -89,38 +90,40 @@ interface nsIPluginInstance : nsISupports * instance. The implementation of this method should be sure to increment * the reference count on the peer by calling AddRef. * - * @param aPeer - the resulting plugin instance peer - * @result - NS_OK if this operation was successful + * @param aPeer - the resulting plugin instance peer + * @result - NS_OK if this operation was successful */ readonly attribute nsIPluginInstancePeer peer; /** - * Called to instruct the plugin instance to start. This will be called after - * the plugin is first created and initialized, and may be called after the - * plugin is stopped (via the Stop method) if the plugin instance is returned - * to in the browser window's history. - * - * @result - NS_OK if this operation was successful + * Called to instruct the plugin instance to start. This will be + * called after the plugin is first created and initialized, and + * may be called after the plugin is stopped (via the Stop method) + * if the plugin instance is returned to in the browser window's + * history. + * + * @result - NS_OK if this operation was successful */ void start(); /** - * Called to instruct the plugin instance to stop, thereby suspending its state. - * This method will be called whenever the browser window goes on to display - * another page and the page containing the plugin goes into the window's history - * list. - * - * @result - NS_OK if this operation was successful + * Called to instruct the plugin instance to stop, thereby + * suspending its state. This method will be called whenever the + * browser window goes on to display another page and the page + * containing the plugin goes into the window's history list. + * + * @result - NS_OK if this operation was successful */ void stop(); /** - * Called to instruct the plugin instance to destroy itself. This is called when - * it become no longer possible to return to the plugin instance, either because - * the browser window's history list of pages is being trimmed, or because the - * window containing this page in the history is being closed. - * - * @result - NS_OK if this operation was successful + * Called to instruct the plugin instance to destroy itself. This + * is called when it become no longer possible to return to the + * plugin instance, either because the browser window's history + * list of pages is being trimmed, or because the window + * containing this page in the history is being closed. + * + * @result - NS_OK if this operation was successful */ void destroy(); @@ -129,10 +132,10 @@ interface nsIPluginInstance : nsISupports * * (Corresponds to NPP_SetWindow.) * - * @param aWindow - the plugin window structure - * @result - NS_OK if this operation was successful + * @param aWindow - the plugin window structure + * @result - NS_OK if this operation was successful */ - void setWindow(in nsPluginWindowPtr aWindow); + void setWindow(in nsPluginWindowPtr aWindow); /** * Called to tell the plugin that the initial src/data stream is @@ -140,46 +143,46 @@ interface nsIPluginInstance : nsISupports * * (Corresponds to NPP_NewStream.) * - * @param aListener - listener the browser will use to give the plugin the data - * @result - NS_OK if this operation was successful + * @param aListener - listener the browser will use to give the plugin the data + * @result - NS_OK if this operation was successful */ - void newStream(out nsIPluginStreamListener aListener); + void newStream(out nsIPluginStreamListener aListener); /** * Called to instruct the plugin instance to print itself to a printer. * * (Corresponds to NPP_Print.) * - * @param aPlatformPrint - platform-specific printing information - * @result - NS_OK if this operation was successful - */ - void print(in nsPluginPrintPtr aPlatformPrint); + * @param aPlatformPrint - platform-specific printing information + * @result - NS_OK if this operation was successful + */ + void print(in nsPluginPrintPtr aPlatformPrint); - /** - * Returns the value of a variable associated with the plugin instance. - * - * @param aVariable - the plugin instance variable to get - * @param aValue - the address of where to store the resulting value - * @result - NS_OK if this operation was successful - */ - void getValue(in nsPluginInstanceVariable aVariable, in voidPtr aValue); + /** + * Returns the value of a variable associated with the plugin instance. + * + * @param aVariable - the plugin instance variable to get + * @param aValue - the address of where to store the resulting value + * @result - NS_OK if this operation was successful + */ + void getValue(in nsPluginInstanceVariable aVariable, in voidPtr aValue); - /** - * Handles an event. An nsIEventHandler can also get registered with with - * nsIPluginManager2::RegisterWindow and will be called whenever an event - * comes in for that window. - * - * Note that for Unix and Mac the nsPluginEvent structure is different - * from the old NPEvent structure -- it's no longer the native event - * record, but is instead a struct. This was done for future extensibility, - * and so that the Mac could receive the window argument too. For Windows - * and OS2, it's always been a struct, so there's no change for them. - * - * (Corresponds to NPP_HandleEvent.) - * - * @param aEvent - the event to be handled - * @param aHandled - set to PR_TRUE if event was handled + /** + * Handles an event. An nsIEventHandler can also get registered with with + * nsIPluginManager2::RegisterWindow and will be called whenever an event + * comes in for that window. + * + * Note that for Unix and Mac the nsPluginEvent structure is different + * from the old NPEvent structure -- it's no longer the native event + * record, but is instead a struct. This was done for future extensibility, + * and so that the Mac could receive the window argument too. For Windows + * and OS2, it's always been a struct, so there's no change for them. + * + * (Corresponds to NPP_HandleEvent.) + * + * @param aEvent - the event to be handled + * @param aHandled - set to PR_TRUE if event was handled * @result - NS_OK if this operation was successful */ - void handleEvent(in nsPluginEventPtr aEvent, out boolean aHandled); + void handleEvent(in nsPluginEventPtr aEvent, out boolean aHandled); }; diff --git a/mozilla/modules/plugin/base/public/nsIScriptablePlugin.idl b/mozilla/modules/plugin/base/public/nsIScriptablePlugin.idl index d67d889e951..c675fe068c8 100644 --- a/mozilla/modules/plugin/base/public/nsIScriptablePlugin.idl +++ b/mozilla/modules/plugin/base/public/nsIScriptablePlugin.idl @@ -46,7 +46,7 @@ interface nsIScriptablePlugin : nsISupports { /** * The object to be wrapped and exposed to JavaScript. It should - * be an XPCOM object, and it can be the same object as the plugin. + * be an XPCOM object, and it can be the same object as the plugin. */ readonly attribute nsQIResult scriptablePeer; diff --git a/mozilla/modules/plugin/base/src/Makefile.in b/mozilla/modules/plugin/base/src/Makefile.in index e5342ddf026..591d9509075 100644 --- a/mozilla/modules/plugin/base/src/Makefile.in +++ b/mozilla/modules/plugin/base/src/Makefile.in @@ -91,6 +91,7 @@ CPPSRCS = \ nsPluginModule.cpp \ nsPluginInstancePeer.cpp \ nsPluginDirServiceProvider.cpp \ + nsJSNPRuntime.cpp \ $(NULL) ifeq ($(OS_ARCH), BeOS) @@ -131,6 +132,7 @@ EXTRA_DSO_LDOPTS = \ $(MOZ_NECKO_UTIL_LIBS) \ $(MOZ_UNICHARUTIL_LIBS) \ $(MOZ_COMPONENT_LIBS) \ + $(MOZ_JS_LIBS) \ $(NULL) ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) diff --git a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp index a9e0a36be9d..be7c56f4a95 100644 --- a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp @@ -38,6 +38,7 @@ // TODO: Implement Java callbacks #include "prtypes.h" +#include "prmem.h" #include "ns4xPlugin.h" #include "ns4xPluginInstance.h" #include "ns4xPluginStreamListener.h" @@ -59,6 +60,9 @@ #include "nsIDOMWindow.h" #include "nsIDocument.h" #include "nsIScriptGlobalObject.h" +#include "nsIScriptContext.h" + +#include "nsIXPConnect.h" #if defined(XP_MAC) || defined(XP_MACOSX) #include @@ -77,6 +81,7 @@ #include "gtk2xtbin.h" #endif +#include "nsJSNPRuntime.h" // POST/GET stream type enum eNPPStreamTypeInternal { @@ -187,9 +192,6 @@ PR_BEGIN_EXTERN_C static jref NP_EXPORT _getJavaPeer(NPP npp); - static java_lang_Class* NP_EXPORT - _getJavaClass(void* handle); - #endif #endif /* OJI */ @@ -241,7 +243,6 @@ static void* FP2TV(void *fp) //////////////////////////////////////////////////////////////////////// // Globals NPNetscapeFuncs ns4xPlugin::CALLBACKS; -static nsIServiceManagerObsolete* gServiceMgr = nsnull; static nsIMemory* gMalloc = nsnull; //////////////////////////////////////////////////////////////////////// @@ -257,29 +258,115 @@ ns4xPlugin::CheckClassInitialized(void) CALLBACKS.size = sizeof(CALLBACKS); CALLBACKS.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; - CALLBACKS.geturl = NewNPN_GetURLProc(FP2TV(_geturl)); - CALLBACKS.posturl = NewNPN_PostURLProc(FP2TV(_posturl)); - CALLBACKS.requestread = NewNPN_RequestReadProc(FP2TV(_requestread)); - CALLBACKS.newstream = NewNPN_NewStreamProc(FP2TV(_newstream)); - CALLBACKS.write = NewNPN_WriteProc(FP2TV(_write)); - CALLBACKS.destroystream = NewNPN_DestroyStreamProc(FP2TV(_destroystream)); - CALLBACKS.status = NewNPN_StatusProc(FP2TV(_status)); - CALLBACKS.uagent = NewNPN_UserAgentProc(FP2TV(_useragent)); - CALLBACKS.memalloc = NewNPN_MemAllocProc(FP2TV(_memalloc)); - CALLBACKS.memfree = NewNPN_MemFreeProc(FP2TV(_memfree)); - CALLBACKS.memflush = NewNPN_MemFlushProc(FP2TV(_memflush)); - CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(FP2TV(_reloadplugins)); + CALLBACKS.geturl = + NewNPN_GetURLProc(FP2TV(_geturl)); + + CALLBACKS.posturl = + NewNPN_PostURLProc(FP2TV(_posturl)); + + CALLBACKS.requestread = + NewNPN_RequestReadProc(FP2TV(_requestread)); + + CALLBACKS.newstream = + NewNPN_NewStreamProc(FP2TV(_newstream)); + + CALLBACKS.write = + NewNPN_WriteProc(FP2TV(_write)); + + CALLBACKS.destroystream = + NewNPN_DestroyStreamProc(FP2TV(_destroystream)); + + CALLBACKS.status = + NewNPN_StatusProc(FP2TV(_status)); + + CALLBACKS.uagent = + NewNPN_UserAgentProc(FP2TV(_useragent)); + + CALLBACKS.memalloc = + NewNPN_MemAllocProc(FP2TV(_memalloc)); + + CALLBACKS.memfree = + NewNPN_MemFreeProc(FP2TV(_memfree)); + + CALLBACKS.memflush = + NewNPN_MemFlushProc(FP2TV(_memflush)); + + CALLBACKS.reloadplugins = + NewNPN_ReloadPluginsProc(FP2TV(_reloadplugins)); + #ifdef OJI - CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(FP2TV(_getJavaEnv)); - CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(FP2TV(_getJavaPeer)); + CALLBACKS.getJavaEnv = + NewNPN_GetJavaEnvProc(FP2TV(_getJavaEnv)); + + CALLBACKS.getJavaPeer = + NewNPN_GetJavaPeerProc(FP2TV(_getJavaPeer)); #endif - CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(FP2TV(_geturlnotify)); - CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(FP2TV(_posturlnotify)); - CALLBACKS.getvalue = NewNPN_GetValueProc(FP2TV(_getvalue)); - CALLBACKS.setvalue = NewNPN_SetValueProc(FP2TV(_setvalue)); - CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(FP2TV(_invalidaterect)); - CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(FP2TV(_invalidateregion)); - CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(FP2TV(_forceredraw)); + + CALLBACKS.geturlnotify = + NewNPN_GetURLNotifyProc(FP2TV(_geturlnotify)); + + CALLBACKS.posturlnotify = + NewNPN_PostURLNotifyProc(FP2TV(_posturlnotify)); + + CALLBACKS.getvalue = + NewNPN_GetValueProc(FP2TV(_getvalue)); + + CALLBACKS.setvalue = + NewNPN_SetValueProc(FP2TV(_setvalue)); + + CALLBACKS.invalidaterect = + NewNPN_InvalidateRectProc(FP2TV(_invalidaterect)); + + CALLBACKS.invalidateregion = + NewNPN_InvalidateRegionProc(FP2TV(_invalidateregion)); + + CALLBACKS.forceredraw = + NewNPN_ForceRedrawProc(FP2TV(_forceredraw)); + + CALLBACKS.getstringidentifier = + NewNPN_GetStringIdentifierProc(FP2TV(_getstringidentifier)); + + CALLBACKS.getstringidentifiers = + NewNPN_GetStringIdentifiersProc(FP2TV(_getstringidentifiers)); + + CALLBACKS.getintidentifier = + NewNPN_GetIntIdentifierProc(FP2TV(_getintidentifier)); + + CALLBACKS.identifierisstring = + NewNPN_IdentifierIsStringProc(FP2TV(_identifierisstring)); + + CALLBACKS.utf8fromidentifier = + NewNPN_UTF8FromIdentifierProc(FP2TV(_utf8fromidentifier)); + + CALLBACKS.createobject = + NewNPN_CreateObjectProc(FP2TV(_createobject)); + + CALLBACKS.retainobject = + NewNPN_RetainObjectProc(FP2TV(_retainobject)); + + CALLBACKS.releaseobject = + NewNPN_ReleaseObjectProc(FP2TV(_releaseobject)); + + CALLBACKS.call = + NewNPN_CallProc(FP2TV(_call)); + + CALLBACKS.evaluate = + NewNPN_EvaluateProc(FP2TV(_evaluate)); + + CALLBACKS.getproperty = + NewNPN_GetPropertyProc(FP2TV(_getproperty)); + + CALLBACKS.setproperty = + NewNPN_SetPropertyProc(FP2TV(_setproperty)); + + CALLBACKS.removeproperty = + NewNPN_RemovePropertyProc(FP2TV(_removeproperty)); + + CALLBACKS.releasevariantvalue = + NewNPN_ReleaseVariantValueProc(FP2TV(_releasevariantvalue)); + + CALLBACKS.setexception = + NewNPN_SetExceptionProc(FP2TV(_setexception)); initialized = TRUE; @@ -294,7 +381,6 @@ NS_IMPL_ISUPPORTS2(ns4xPlugin, nsIPlugin, nsIFactory) ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManagerObsolete* serviceMgr) { memset((void*) &fCallbacks, 0, sizeof(fCallbacks)); - gServiceMgr = serviceMgr; fLibrary = nsnull; #if defined(XP_WIN) || defined(XP_OS2) @@ -801,9 +887,8 @@ ns4xPlugin::GetValue(nsPluginVariable variable, void *value) if (npGetValue && NPERR_NO_ERROR == npGetValue(nsnull, variable, value)) { return NS_OK; } - else { - return NS_ERROR_FAILURE; - } + + return NS_ERROR_FAILURE; } // Create a new NPP GET or POST url stream that may have a notify callback @@ -1106,10 +1191,6 @@ void NP_EXPORT _reloadplugins(NPBool reloadPages) { NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_ReloadPlugins: reloadPages=%d\n", reloadPages)); - NS_ASSERTION(gServiceMgr != NULL, "null service manager"); - - if(gServiceMgr == nsnull) - return; nsCOMPtr pm(do_GetService(kPluginManagerCID)); @@ -1190,6 +1271,375 @@ _forceredraw(NPP npp) } } +static JSContext * +GetJSContextFromNPP(NPP npp) +{ + NS_ENSURE_TRUE(npp, nsnull); + + ns4xPluginInstance *inst = (ns4xPluginInstance *)npp->ndata; + NS_ENSURE_TRUE(inst, nsnull); + + nsCOMPtr pip; + inst->GetPeer(getter_AddRefs(pip)); + nsCOMPtr pp(do_QueryInterface(pip)); + NS_ENSURE_TRUE(pp, nsnull); + + nsCOMPtr owner; + pp->GetOwner(getter_AddRefs(owner)); + NS_ENSURE_TRUE(owner, nsnull); + + nsCOMPtr doc; + owner->GetDocument(getter_AddRefs(doc)); + NS_ENSURE_TRUE(doc, nsnull); + + nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject(); + NS_ENSURE_TRUE(sgo, nsnull); + + nsIScriptContext *scx = sgo->GetContext(); + NS_ENSURE_TRUE(scx, nsnull); + + return (JSContext *)scx->GetNativeContext(); +} + +NPObject* NP_EXPORT +_getwindowobject(NPP npp) +{ + JSContext *cx = GetJSContextFromNPP(npp); + NS_ENSURE_TRUE(cx, nsnull); + + return nsJSObjWrapper::GetNewOrUsed(npp, cx, ::JS_GetGlobalObject(cx)); +} + +NPObject* NP_EXPORT +_getpluginelement(NPP npp) +{ + nsIDOMElement *elementp = nsnull; + NPError nperr = _getvalue(npp, NPNVDOMElement, &elementp); + + if (nperr != NPERR_NO_ERROR) { + return nsnull; + } + + // Pass ownership of elementp to element + nsCOMPtr element; + element.swap(elementp); + + JSContext *cx = GetJSContextFromNPP(npp); + NS_ENSURE_TRUE(cx, nsnull); + + nsCOMPtr xpc(do_GetService(nsIXPConnect::GetCID())); + NS_ENSURE_TRUE(xpc, nsnull); + + nsCOMPtr holder; + xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), element, + NS_GET_IID(nsIDOMElement), + getter_AddRefs(holder)); + NS_ENSURE_TRUE(holder, nsnull); + + JSObject* obj = nsnull; + holder->GetJSObject(&obj); + NS_ENSURE_TRUE(obj, nsnull); + + return nsJSObjWrapper::GetNewOrUsed(npp, cx, obj); +} + +static NPIdentifier +doGetIdentifier(JSContext *cx, const NPUTF8* name) +{ + NS_ConvertUTF8toUTF16 utf16name(name); + + JSString *str = ::JS_InternUCStringN(cx, (jschar *)utf16name.get(), + utf16name.Length()); + + if (!str) + return nsnull; + + return (NPIdentifier)STRING_TO_JSVAL(str); +} + +NPIdentifier NP_EXPORT +_getstringidentifier(const NPUTF8* name) +{ + nsCOMPtr stack = + do_GetService("@mozilla.org/js/xpc/ContextStack;1"); + if (!stack) + return NULL; + + JSContext *cx = nsnull; + stack->GetSafeJSContext(&cx); + if (!cx) + return NULL; + + return doGetIdentifier(cx, name); +} + +void NP_EXPORT +_getstringidentifiers(const NPUTF8** names, int32_t nameCount, + NPIdentifier *identifiers) +{ + nsCOMPtr stack = + do_GetService("@mozilla.org/js/xpc/ContextStack;1"); + if (!stack) + return; + + JSContext *cx = nsnull; + stack->GetSafeJSContext(&cx); + if (!cx) + return; + + for (int32_t i = 0; i < nameCount; ++i) { + identifiers[i] = doGetIdentifier(cx, names[i]); + } +} + +NPIdentifier NP_EXPORT +_getintidentifier(int32_t intid) +{ + return (NPIdentifier)INT_TO_JSVAL(intid); +} + +NPUTF8* NP_EXPORT +_utf8fromidentifier(NPIdentifier identifier) +{ + if (!identifier) + return NULL; + + jsval v = (jsval)identifier; + + if (!JSVAL_IS_STRING(v)) { + return nsnull; + } + + JSString *str = JSVAL_TO_STRING(v); + + return + ToNewUTF8String(nsDependentString((PRUnichar *)::JS_GetStringChars(str), + ::JS_GetStringLength(str))); +} + +int32_t NP_EXPORT +_intfromidentifier(NPIdentifier identifier) +{ + jsval v = (jsval)identifier; + + if (!JSVAL_IS_INT(v)) { + return PR_INT32_MIN; + } + + return JSVAL_TO_INT(v); +} + +bool NP_EXPORT +_identifierisstring(NPIdentifier identifier) +{ + jsval v = (jsval)identifier; + + return JSVAL_IS_STRING(v); +} + +NPObject* NP_EXPORT +_createobject(NPClass* aClass) +{ + if (!aClass) { + NS_ERROR("Null class passed to _createobject()!"); + + return 0; + } + + NPObject *npobj; + + if (aClass->allocate) { + npobj = aClass->allocate(); + } else { + npobj = (NPObject *)PR_Malloc(sizeof(NPObject)); + } + + if (npobj) { + npobj->_class = aClass; + npobj->referenceCount = 1; + } + + return npobj; +} + +NPObject* NP_EXPORT +_retainobject(NPObject* npobj) +{ + if (npobj) { + PR_AtomicIncrement((PRInt32*)&npobj->referenceCount); + } + + return npobj; +} + +void NP_EXPORT +_releaseobject(NPObject* npobj) +{ + if (!npobj) + return; + + int32_t refCnt = PR_AtomicDecrement((PRInt32*)&npobj->referenceCount); + + if (refCnt == 0) { + if (npobj->_class && npobj->_class->deallocate) { + npobj->_class->deallocate(npobj); + } else { + PR_Free(npobj); + } + } +} + +bool NP_EXPORT +_call(NPObject* npobj, NPIdentifier method, const NPVariant *args, + uint32_t argCount, NPVariant *result) +{ + if (!npobj || !npobj->_class || !npobj->_class->invoke) + return PR_FALSE; + + return npobj->_class->invoke(npobj, method, args, argCount, result); +} + +bool NP_EXPORT +_evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result) +{ + JSContext *cx = GetJSContextFromNPP(npp); + NS_ENSURE_TRUE(cx, false); + + JSObject *obj = + nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj); + + if (!obj) { + return false; + } + + if (result) { + // Initialize the out param to void + VOID_TO_NPVARIANT(*result); + } + + if (!script || !script->utf8length || !script->utf8characters) { + // Nothing to evaluate. + + return true; + } + + NS_ConvertUTF8toUTF16 utf16script(script->utf8characters, + script->utf8length); + + nsCOMPtr scx = GetScriptContextFromJSContext(cx); + NS_ENSURE_TRUE(scx, false); + + nsIPrincipal *principal = nsnull; + // XXX: Get the principal from the security stack (TBD) + + jsval rval; + nsresult rv = scx->EvaluateStringWithValue(utf16script, obj, principal, + nsnull, 0, nsnull, &rval, + nsnull); + NS_ENSURE_SUCCESS(rv, false); + + if (result) { + return JSValToNPVariant(npp, cx, rval, result); + } + + return true; +} + +bool NP_EXPORT +_getproperty(NPObject* npobj, NPIdentifier property, NPVariant *result) +{ + if (!npobj || !npobj->_class || !npobj->_class->getProperty) + return PR_FALSE; + + return npobj->_class->getProperty(npobj, property, result); +} + +bool NP_EXPORT +_setproperty(NPObject* npobj, NPIdentifier property, + const NPVariant *value) +{ + if (!npobj || !npobj->_class || !npobj->_class->setProperty) + return PR_FALSE; + + return npobj->_class->setProperty(npobj, property, value); +} + +bool NP_EXPORT +_removeproperty(NPObject* npobj, NPIdentifier property) +{ + if (!npobj || !npobj->_class || !npobj->_class->removeProperty) + return PR_FALSE; + + return npobj->_class->removeProperty(npobj, property); +} + +bool NP_EXPORT +_hasproperty(NPObject* npobj, NPIdentifier propertyName) +{ + if (!npobj || !npobj->_class || !npobj->_class->hasProperty) + return PR_FALSE; + + return npobj->_class->hasProperty(npobj, propertyName); +} + +bool NP_EXPORT +_hasmethod(NPObject* npobj, NPIdentifier methodName) +{ + if (!npobj || !npobj->_class || !npobj->_class->hasMethod) + return PR_FALSE; + + return npobj->_class->hasProperty(npobj, methodName); +} + +void NP_EXPORT +_releasevariantvalue(NPVariant* variant) +{ + switch (variant->type) { + case NPVariantType_Void : + case NPVariantType_Null : + case NPVariantType_Bool : + case NPVariantType_Int32 : + case NPVariantType_Double : + break; + case NPVariantType_String : + { + const NPString *s = &NPVARIANT_TO_STRING(*variant); + + if (s->utf8characters) + PR_Free((void *)s->utf8characters); + + break; + } + case NPVariantType_Object: + { + NPObject *npobj = NPVARIANT_TO_OBJECT(*variant); + + if (npobj) + _releaseobject(npobj); + + break; + } + default: + NS_ERROR("Unknown NPVariant type!"); + } + + VOID_TO_NPVARIANT(*variant); +} + +bool NP_EXPORT +_tostring(NPObject* npobj, NPVariant *result) +{ + NS_ERROR("Write me!"); + + return PR_FALSE; +} + +void NP_EXPORT +_setexception(NPObject* npobj, const NPUTF8 *message) +{ + // XXX: Write me! +} + //////////////////////////////////////////////////////////////////////// NPError NP_EXPORT @@ -1347,6 +1797,19 @@ _getvalue(NPP npp, NPNVariable variable, void *result) #endif return NPERR_NO_ERROR; } + + case NPNVWindowNPObject: { + *(NPObject **)result = _getwindowobject(npp); + + return NPERR_NO_ERROR; + } + + case NPNVPluginElementNPObject: { + *(NPObject **)result = _getpluginelement(npp); + + return NPERR_NO_ERROR; + } + default : return NPERR_GENERIC_ERROR; } } @@ -1482,10 +1945,6 @@ _useragent(NPP npp) { NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_UserAgent: npp=%p\n", (void*)npp)); - NS_ASSERTION(gServiceMgr != NULL, "null service manager"); - if (gServiceMgr == NULL) - return NULL; - char *retstr; nsCOMPtr pm(do_GetService(kPluginManagerCID)); @@ -1505,15 +1964,6 @@ _memalloc (uint32 size) } #ifdef OJI -//////////////////////////////////////////////////////////////////////// -java_lang_Class* NP_EXPORT -_getJavaClass(void* handle) -{ - NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaClass\n")); - return NULL; -} - - //////////////////////////////////////////////////////////////////////// jref NP_EXPORT _getJavaPeer(NPP npp) diff --git a/mozilla/modules/plugin/base/src/ns4xPlugin.h b/mozilla/modules/plugin/base/src/ns4xPlugin.h index 2fa99251a75..c2eafd23d12 100644 --- a/mozilla/modules/plugin/base/src/ns4xPlugin.h +++ b/mozilla/modules/plugin/base/src/ns4xPlugin.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -96,8 +96,9 @@ class nsIMemory; class ns4xPlugin : public nsIPlugin { public: - - ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManagerObsolete* serviceMgr); + ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, + NP_PLUGINSHUTDOWN aShutdown, + nsIServiceManagerObsolete* serviceMgr); virtual ~ns4xPlugin(void); static void ReleaseStatics(); @@ -123,17 +124,13 @@ public: const char* aPluginMIMEType, void **aResult); - NS_IMETHOD - Initialize(void); + NS_IMETHOD Initialize(void); - NS_IMETHOD - Shutdown(void); + NS_IMETHOD Shutdown(void); - NS_IMETHOD - GetMIMEDescription(const char* *resultingDesc); + NS_IMETHOD GetMIMEDescription(const char* *resultingDesc); - NS_IMETHOD - GetValue(nsPluginVariable variable, void *value); + NS_IMETHOD GetValue(nsPluginVariable variable, void *value); //////////////////////////////////////////////////////////////////// // ns4xPlugin-specific methods @@ -182,4 +179,70 @@ protected: static NPNetscapeFuncs CALLBACKS; }; + +PR_BEGIN_EXTERN_C +NPObject* NP_EXPORT +_getwindowobject(NPP npp); + +NPObject* NP_EXPORT +_getpluginelement(NPP npp); + +NPIdentifier NP_EXPORT +_getstringidentifier(const NPUTF8* name); + +void NP_EXPORT +_getstringidentifiers(const NPUTF8** names, int32_t nameCount, + NPIdentifier *identifiers); + +bool NP_EXPORT +_identifierisstring(NPIdentifier identifiers); + +NPIdentifier NP_EXPORT +_getintidentifier(int32_t intid); + +NPUTF8* NP_EXPORT +_utf8fromidentifier(NPIdentifier identifier); + +int32_t NP_EXPORT +_intfromidentifier(NPIdentifier identifier); + +NPObject* NP_EXPORT +_createobject(NPClass* aClass); + +NPObject* NP_EXPORT +_retainobject(NPObject* npobj); + +void NP_EXPORT +_releaseobject(NPObject* npobj); + +bool NP_EXPORT +_call(NPObject* npobj, NPIdentifier method, const NPVariant *args, + uint32_t argCount, NPVariant *result); + +bool NP_EXPORT +_evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result); + +bool NP_EXPORT +_getproperty(NPObject* npobj, NPIdentifier property, NPVariant *result); + +bool NP_EXPORT +_setproperty(NPObject* npobj, NPIdentifier property, const NPVariant *value); + +bool NP_EXPORT +_removeproperty(NPObject* npobj, NPIdentifier property); + +bool NP_EXPORT +_hasproperty(NPObject* npobj, NPIdentifier propertyName); + +bool NP_EXPORT +_hasmethod(NPObject* npobj, NPIdentifier methodName); + +void NP_EXPORT +_releasevariantvalue(NPVariant *variant); + +void NP_EXPORT +_setexception(NPObject* npobj, const NPUTF8 *message); + +PR_END_EXTERN_C + #endif // ns4xPlugin_h__ diff --git a/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp b/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp index 776b476940e..1597057b06f 100644 --- a/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp @@ -48,6 +48,8 @@ #include "nsPluginSafety.h" #include "nsPluginLogging.h" +#include "nsJSNPRuntime.h" + #ifdef XP_OS2 #include "nsILegacyPluginWrapperOS2.h" #endif @@ -760,7 +762,8 @@ nsInstanceStream::~nsInstanceStream() /////////////////////////////////////////////////////////////////////////////// -NS_IMPL_ISUPPORTS2(ns4xPluginInstance, nsIPluginInstance, nsIScriptablePlugin) +NS_IMPL_ISUPPORTS3(ns4xPluginInstance, nsIPluginInstance, nsIScriptablePlugin, + nsINPRuntimePlugin) /////////////////////////////////////////////////////////////////////////////// @@ -915,6 +918,8 @@ NS_IMETHODIMP ns4xPluginInstance::Stop(void) mStarted = PR_FALSE; + nsJSNPRuntime::OnPluginDestroy(&fNPP); + if(error != NPERR_NO_ERROR) return NS_ERROR_FAILURE; else @@ -1512,6 +1517,9 @@ NS_IMETHODIMP ns4xPluginInstance::GetScriptablePeer(void * *aScriptablePeer) return GetValueInternal(NPPVpluginScriptableInstance, aScriptablePeer); } +PR_BEGIN_EXTERN_C +void _releaseobject(NPObject *obj); +PR_END_EXTERN_C //////////////////////////////////////////////////////////////////////// /* readonly attribute nsIIDPtr scriptableInterface; */ @@ -1523,3 +1531,20 @@ NS_IMETHODIMP ns4xPluginInstance::GetScriptableInterface(nsIID * *aScriptableInt *aScriptableInterface = nsnull; return GetValueInternal(NPPVpluginScriptableIID, (void*)aScriptableInterface); } + +JSObject * +ns4xPluginInstance::GetJSObject(JSContext *cx) +{ + JSObject *obj = nsnull; + NPObject *npobj = nsnull; + + nsresult rv = GetValueInternal(NPPVpluginScriptableNPObject, &npobj); + + if (NS_SUCCEEDED(rv) && npobj) { + obj = nsNPObjWrapper::GetNewOrUsed(&fNPP, cx, npobj); + + _releaseobject(npobj); + } + + return obj; +} diff --git a/mozilla/modules/plugin/base/src/ns4xPluginInstance.h b/mozilla/modules/plugin/base/src/ns4xPluginInstance.h index 7d3e7ca248f..40c4db0e35d 100644 --- a/mozilla/modules/plugin/base/src/ns4xPluginInstance.h +++ b/mozilla/modules/plugin/base/src/ns4xPluginInstance.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -54,6 +54,7 @@ #include "nsIPluginInstancePeer.h" #include "nsIPluginTagInfo2.h" #include "nsIScriptablePlugin.h" +#include "nsINPRuntimePlugin.h" #include "npupp.h" #ifdef OJI @@ -73,15 +74,16 @@ class ns4xPluginStreamListener; struct nsInstanceStream { - nsInstanceStream *mNext; - ns4xPluginStreamListener *mPluginStreamListener; + nsInstanceStream *mNext; + ns4xPluginStreamListener *mPluginStreamListener; - nsInstanceStream(); - ~nsInstanceStream(); + nsInstanceStream(); + ~nsInstanceStream(); }; class ns4xPluginInstance : public nsIPluginInstance, - public nsIScriptablePlugin + public nsIScriptablePlugin, + public nsINPRuntimePlugin { public: @@ -159,6 +161,8 @@ public: // cache this 4.x plugin like an XPCOM plugin nsresult SetCached(PRBool aCache) { mCached = aCache; return NS_OK; }; + + virtual JSObject *GetJSObject(JSContext *cx); protected: diff --git a/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp b/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp new file mode 100644 index 00000000000..158af4e8ae1 --- /dev/null +++ b/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp @@ -0,0 +1,1221 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsJSNPRuntime.h" +#include "ns4xPlugin.h" +#include "ns4xPluginInstance.h" +#include "nsIPluginInstancePeer2.h" +#include "nsPIPluginInstancePeer.h" +#include "nsIScriptGlobalObject.h" +#include "nsIScriptContext.h" +#include "nsIDocument.h" +#include "nsIJSRuntimeService.h" +#include "nsIJSContextStack.h" +#include "prmem.h" + +// Hash of NPObject wrappers that wrap JSObjects. +static PLDHashTable sJSObjWrappers; + +// Hash of JSObject wrappers that wrap NPObjects. +static PLDHashTable sNPObjWrappers; + +// Global wrapper count. This includes JSObject wrappers *and* +// NPObject wrappers. When this count goes to zero, there are no more +// wrappers and we can kill off hash tables etc. +static PRInt32 sWrapperCount; + +// The JSRuntime. Used to unroot JSObjects when no JSContext is +// reachable. +static JSRuntime *sJSRuntime; + +// The JS context stack, we use this to push a plugin's JSContext onto +// while executing JS on the context. +static nsIJSContextStack *sContextStack; + +class AutoCXPusher +{ +public: + AutoCXPusher(JSContext *cx) + { + if (sContextStack) + sContextStack->Push(cx); + } + + ~AutoCXPusher() + { + if (sContextStack) + sContextStack->Pop(nsnull); + } +}; + +NPClass nsJSObjWrapper::sJSObjWrapperNPClass = + { + NP_CLASS_STRUCT_VERSION, + nsJSObjWrapper::NP_Allocate, + nsJSObjWrapper::NP_Deallocate, + nsJSObjWrapper::NP_Invalidate, + nsJSObjWrapper::NP_HasMethod, + nsJSObjWrapper::NP_Invoke, + nsJSObjWrapper::NP_HasProperty, + nsJSObjWrapper::NP_GetProperty, + nsJSObjWrapper::NP_SetProperty, + nsJSObjWrapper::NP_RemoveProperty + }; + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp); + +JS_STATIC_DLL_CALLBACK(void) +NPObjWrapper_Finalize(JSContext *cx, JSObject *obj); + +static JSClass sNPObjectJSWrapperClass = + { + "NPObject JS wrapper class", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE, + NPObjWrapper_AddProperty, NPObjWrapper_DelProperty, + NPObjWrapper_GetProperty, NPObjWrapper_SetProperty, JS_EnumerateStub, + (JSResolveOp)NPObjWrapper_NewResolve, JS_ConvertStub, + NPObjWrapper_Finalize, nsnull, nsnull, nsnull, nsnull, nsnull, nsnull + }; + + +static void +OnWrapperCreated() +{ + if (sWrapperCount++ == 0) { + static const char rtsvc_id[] = "@mozilla.org/js/xpc/RuntimeService;1"; + nsCOMPtr rtsvc(do_GetService(rtsvc_id)); + if (!rtsvc) + return; + + rtsvc->GetRuntime(&sJSRuntime); + NS_ASSERTION(sJSRuntime != nsnull, "no JSRuntime?!"); + + CallGetService("@mozilla.org/js/xpc/ContextStack;1", &sContextStack); + } +} + +static void +OnWrapperDestroyed() +{ + NS_ASSERTION(sWrapperCount, "Whaaa, unbalanced created/destroyed calls!"); + + if (--sWrapperCount == 0) { + if (sJSObjWrappers.ops) { + NS_ASSERTION(sJSObjWrappers.entryCount == 0, "Uh, hash not empty?"); + + // No more wrappers, and our hash was initalized. Finish the + // hash to prevent leaking it. + PL_DHashTableFinish(&sJSObjWrappers); + + sJSObjWrappers.ops = nsnull; + } + + if (sNPObjWrappers.ops) { + NS_ASSERTION(sNPObjWrappers.entryCount == 0, "Uh, hash not empty?"); + + // No more wrappers, and our hash was initalized. Finish the + // hash to prevent leaking it. + PL_DHashTableFinish(&sNPObjWrappers); + + sNPObjWrappers.ops = nsnull; + } + + // No more need for this. + sJSRuntime = nsnull; + + NS_IF_RELEASE(sContextStack); + } +} + +static JSContext * +GetJSContext(NPP npp) +{ + ns4xPluginInstance *inst = (ns4xPluginInstance *)npp->ndata; + NS_ENSURE_TRUE(inst, nsnull); + + nsCOMPtr pip; + inst->GetPeer(getter_AddRefs(pip)); + nsCOMPtr pp (do_QueryInterface(pip)); + NS_ENSURE_TRUE(pp, nsnull); + + nsCOMPtr owner; + pp->GetOwner(getter_AddRefs(owner)); + NS_ENSURE_TRUE(owner, nsnull); + + nsCOMPtr doc; + owner->GetDocument(getter_AddRefs(doc)); + NS_ENSURE_TRUE(doc, nsnull); + + nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject(); + NS_ENSURE_TRUE(sgo, nsnull); + + nsIScriptContext *scx = sgo->GetContext(); + NS_ENSURE_TRUE(scx, nsnull); + + return (JSContext *)scx->GetNativeContext(); +} + + +static NPP +FindNPPForJSObject(JSObject *obj, NPObject *npobj); + + +static jsval +NPVariantToJSVal(NPP npp, JSContext *cx, const NPVariant *variant) +{ + switch (variant->type) { + case NPVariantType_Void : + return JSVAL_VOID; + case NPVariantType_Null : + return JSVAL_NULL; + case NPVariantType_Bool : + return BOOLEAN_TO_JSVAL(NPVARIANT_TO_BOOLEAN(*variant)); + case NPVariantType_Int32 : + return INT_TO_JSVAL(NPVARIANT_TO_INT32(*variant)); + case NPVariantType_Double : + { + jsval val; + if (::JS_NewNumberValue(cx, NPVARIANT_TO_DOUBLE(*variant), &val)) { + return val; + } + + break; + } + case NPVariantType_String : + { + const NPString *s = &NPVARIANT_TO_STRING(*variant); + PRUint32 len; + PRUnichar *p = + UTF8ToNewUnicode(nsDependentCString(s->utf8characters, s->utf8length), + &len); + + JSString *str = ::JS_NewUCString(cx, (jschar *)p, len); + + if (str) { + return STRING_TO_JSVAL(str); + } + + break; + } + case NPVariantType_Object: + { + if (npp) { + JSObject *obj = + nsNPObjWrapper::GetNewOrUsed(npp, cx, NPVARIANT_TO_OBJECT(*variant)); + + if (obj) { + return OBJECT_TO_JSVAL(obj); + } + } + + NS_ERROR("Error wrapping NPObject!"); + + break; + } + default: + NS_ERROR("Unknown NPVariant type!"); + } + + NS_ERROR("Unable to convert NPVariant to jsval!"); + + return JSVAL_VOID; +} + +bool +JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant) +{ + if (JSVAL_IS_PRIMITIVE(val)) { + if (val == JSVAL_VOID) { + VOID_TO_NPVARIANT(*variant); + } else if (JSVAL_IS_NULL(val)) { + NULL_TO_NPVARIANT(*variant); + } else if (JSVAL_IS_BOOLEAN(val)) { + BOOLEAN_TO_NPVARIANT(JSVAL_TO_BOOLEAN(val), *variant); + } else if (JSVAL_IS_INT(val)) { + INT32_TO_NPVARIANT(JSVAL_TO_INT(val), *variant); + } else if (JSVAL_IS_DOUBLE(val)) { + DOUBLE_TO_NPVARIANT(*JSVAL_TO_DOUBLE(val), *variant); + } else if (JSVAL_IS_STRING(val)) { + JSString *jsstr = JSVAL_TO_STRING(val); + nsDependentString str((PRUnichar *)::JS_GetStringChars(jsstr), + ::JS_GetStringLength(jsstr)); + + PRUint32 len; + char *p = ToNewUTF8String(str, &len); + + if (!p) { + return false; + } + + STRINGN_TO_NPVARIANT(p, len, *variant); + } else { + NS_ERROR("Unknown primitive type!"); + + return false; + } + + return true; + } + + if (!npp) { + npp = FindNPPForJSObject(JSVAL_TO_OBJECT(val), nsnull); + + if (!npp) { + NS_ERROR("Must have an NPP to wrap a JSObject!"); + + return false; + } + } + + NPObject *npobj = nsJSObjWrapper::GetNewOrUsed(npp, cx, + JSVAL_TO_OBJECT(val)); + if (!npobj) { + return false; + } + + // Pass over ownership of npobj to *variant + OBJECT_TO_NPVARIANT(npobj, *variant); + + return true; +} + +static void +ThrowJSException(JSContext *cx, const char *message) +{ + // Add exception throwing code here. + + printf ("JS Error: %s\n", message); +} + + +nsJSObjWrapper::nsJSObjWrapper() + : mJSObj(nsnull), mCx(nsnull), mNpp(nsnull) +{ + OnWrapperCreated(); +} + +nsJSObjWrapper::~nsJSObjWrapper() +{ + // Invalidate first, since it relies on sJSRuntime and sJSObjWrappers. + NP_Invalidate(this); + + OnWrapperDestroyed(); +} + +// static +NPObject * +nsJSObjWrapper::NP_Allocate() +{ + return new nsJSObjWrapper; +} + +// static +void +nsJSObjWrapper::NP_Deallocate(NPObject *npobj) +{ + // nsJSObjWrapper::~nsJSObjWrapper() will call NP_Invalidate(). + delete (nsJSObjWrapper *)npobj; +} + +// static +void +nsJSObjWrapper::NP_Invalidate(NPObject *npobj) +{ + nsJSObjWrapper *jsnpobj = (nsJSObjWrapper *)npobj; + + if (jsnpobj && jsnpobj->mJSObj) { + // Unroot the object's JSObject + ::JS_RemoveRootRT(sJSRuntime, &jsnpobj->mJSObj); + + if (sJSObjWrappers.ops) { + // Remove the wrapper from the hash + PL_DHashTableOperate(&sJSObjWrappers, jsnpobj->mJSObj, PL_DHASH_REMOVE); + } + + // Forget our reference to the JSObject etc. + jsnpobj->mJSObj = nsnull; + jsnpobj->mCx = nsnull; + jsnpobj->mNpp = nsnull; + } +} + +static JSBool +GetProperty(JSContext *cx, JSObject *obj, NPIdentifier identifier, jsval *rval) +{ + jsval id = (jsval)identifier; + + AutoCXPusher pusher(cx); + + if (JSVAL_IS_STRING(id)) { + JSString *str = JSVAL_TO_STRING(id); + + return ::JS_GetUCProperty(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), rval); + } + + NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n"); + + return ::JS_GetElement(cx, obj, JSVAL_TO_INT(id), rval); +} + +// static +bool +nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier identifier) +{ + if (!npobj) { + return PR_FALSE; + } + + nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; + jsval v; + JSBool ok = GetProperty(npjsobj->mCx, npjsobj->mJSObj, identifier, &v); + + return ok && !JSVAL_IS_PRIMITIVE(v) && + ::JS_ObjectIsFunction(npjsobj->mCx, JSVAL_TO_OBJECT(v)); +} + +// static +bool +nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier, + const NPVariant *args, uint32_t argCount, + NPVariant *result) +{ + if (!npobj || !result) { + // XXX: Throw null-ptr exception + + return PR_FALSE; + } + + // Initialize *result + VOID_TO_NPVARIANT(*result); + + nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; + jsval fv; + + AutoCXPusher pusher(npjsobj->mCx); + + if (!GetProperty(npjsobj->mCx, npjsobj->mJSObj, identifier, &fv) || + ::JS_TypeOfValue(npjsobj->mCx, fv) != JSTYPE_FUNCTION) { + return PR_FALSE; + } + + jsval jsargs_buf[8]; + jsval *jsargs = jsargs_buf; + + if (argCount > (sizeof(jsargs_buf) / sizeof(jsval))) { + // Our stack buffer isn't large enough to hold all arguments, + // malloc a buffer. + jsargs = (jsval *)PR_Malloc(argCount * sizeof(jsval)); + + if (!jsargs) { + // XXX: throw an OOM exception! + + return PR_FALSE; + } + } + + // Convert args + for (PRUint32 i = 0; i < argCount; ++i) { + jsargs[i] = NPVariantToJSVal(npjsobj->mNpp, npjsobj->mCx, args + i); + } + + jsval v; + JSBool ok = ::JS_CallFunctionValue(npjsobj->mCx, npjsobj->mJSObj, fv, + argCount, jsargs, &v); + + if (jsargs != jsargs_buf) + PR_Free(jsargs); + + if (ok) + ok = JSValToNPVariant(npjsobj->mNpp, npjsobj->mCx, v, result); + + // return ok == JS_TRUE to quiet down compiler warning, even if + // return ok is what we really want. + return ok == JS_TRUE; +} + +// static +bool +nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier identifier) +{ + if (!npobj) { + return PR_FALSE; + } + + nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; + jsval id = (jsval)identifier; + jsval found; + JSBool ok = JS_FALSE; + + if (JSVAL_IS_STRING(id)) { + JSString *str = JSVAL_TO_STRING(id); + + ok = ::JS_LookupUCProperty(npjsobj->mCx, npjsobj->mJSObj, + ::JS_GetStringChars(str), + ::JS_GetStringLength(str), &found); + } else { + NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n"); + + ok = ::JS_LookupElement(npjsobj->mCx, npjsobj->mJSObj, JSVAL_TO_INT(id), + &found); + } + + return ok && !JSVAL_IS_VOID(found); +} + +// static +bool +nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier identifier, + NPVariant *result) +{ + if (!npobj) + return PR_FALSE; + + nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; + + AutoCXPusher pusher(npjsobj->mCx); + + jsval v; + return GetProperty(npjsobj->mCx, npjsobj->mJSObj, identifier, &v) && + JSValToNPVariant(npjsobj->mNpp, npjsobj->mCx, v, result); +} + +// static +bool +nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier, + const NPVariant *value) +{ + if (!npobj) + return PR_FALSE; + + nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; + jsval id = (jsval)identifier; + JSBool ok = JS_FALSE; + + AutoCXPusher pusher(npjsobj->mCx); + + jsval v = NPVariantToJSVal(npjsobj->mNpp, npjsobj->mCx, value); + + if (JSVAL_IS_STRING(id)) { + JSString *str = JSVAL_TO_STRING(id); + + ok = ::JS_SetUCProperty(npjsobj->mCx, npjsobj->mJSObj, + ::JS_GetStringChars(str), + ::JS_GetStringLength(str), &v); + } else { + NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n"); + + ok = ::JS_SetElement(npjsobj->mCx, npjsobj->mJSObj, JSVAL_TO_INT(id), &v); + } + + // return ok == JS_TRUE to quiet down compiler warning, even if + // return ok is what we really want. + return ok == JS_TRUE; +} + +// static +bool +nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier) +{ + if (!npobj) + return PR_FALSE; + + nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; + jsval id = (jsval)identifier; + JSBool ok = JS_FALSE; + + AutoCXPusher pusher(npjsobj->mCx); + + if (JSVAL_IS_STRING(id)) { + JSString *str = JSVAL_TO_STRING(id); + + jsval unused; + ok = ::JS_DeleteUCProperty2(npjsobj->mCx, npjsobj->mJSObj, + ::JS_GetStringChars(str), + ::JS_GetStringLength(str), &unused); + } else { + NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n"); + + ok = ::JS_DeleteElement(npjsobj->mCx, npjsobj->mJSObj, JSVAL_TO_INT(id)); + } + + // return ok == JS_TRUE to quiet down compiler warning, even if + // return ok is what we really want. + return ok == JS_TRUE; +} + +class JSObjWrapperHashEntry : public PLDHashEntryHdr +{ +public: + nsJSObjWrapper *mNPObj; +}; + + +PR_STATIC_CALLBACK(const void *) +NPObjWrapperHashGetKey(PLDHashTable *table, PLDHashEntryHdr *entry) +{ + JSObjWrapperHashEntry *e = + NS_STATIC_CAST(JSObjWrapperHashEntry *, entry); + + return e->mNPObj->mJSObj; +} + +PR_STATIC_CALLBACK(PRBool) +NPObjWrapperHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry, + const void *key) +{ + const JSObjWrapperHashEntry *e = + NS_STATIC_CAST(const JSObjWrapperHashEntry *, entry); + + return e->mNPObj->mJSObj == key; +} + + +// Look up or create an NPObject that wraps the JSObject obj. + +// static +NPObject * +nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj) +{ + if (!npp) { + NS_ERROR("Null NPP passed to nsJSObjWrapper::GetNewOrUsed()!"); + + return nsnull; + } + + if (!cx) { + cx = GetJSContext(npp); + + if (!cx) { + NS_ERROR("Unable to find a JSContext in " + "nsJSObjWrapper::GetNewOrUsed()!"); + + return nsnull; + } + } + + JSClass *clazz = JS_GET_CLASS(cx, obj); + + if (clazz == &sNPObjectJSWrapperClass) { + // obj is one of our own, its private data is the NPObject we're + // looking for. + + NPObject *npobj = (NPObject *)::JS_GetPrivate(cx, obj); + + return _retainobject(npobj); + } + + if (!sJSObjWrappers.ops) { + // No hash yet (or any more), initalize it. + + static PLDHashTableOps ops = + { + PL_DHashAllocTable, + PL_DHashFreeTable, + NPObjWrapperHashGetKey, + PL_DHashVoidPtrKeyStub, + NPObjWrapperHashMatchEntry, + PL_DHashMoveEntryStub, + PL_DHashClearEntryStub, + PL_DHashFinalizeStub + }; + + if (!PL_DHashTableInit(&sJSObjWrappers, &ops, nsnull, + sizeof(JSObjWrapperHashEntry), 16)) { + NS_ERROR("Error initializing PLDHashTable!"); + + return nsnull; + } + } + + JSObjWrapperHashEntry *entry = + NS_STATIC_CAST(JSObjWrapperHashEntry *, + PL_DHashTableOperate(&sJSObjWrappers, obj, PL_DHASH_ADD)); + + if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mNPObj) { + // Found a live nsJSObjWrapper, return it. + + return _retainobject(entry->mNPObj); + } + + // No existing nsJSObjWrapper, create one. + + nsJSObjWrapper *npobj = + (nsJSObjWrapper *)_createobject(&sJSObjWrapperNPClass); + + if (!npobj) { + // OOM? Remove the stale entry from the hash. + + PL_DHashTableRawRemove(&sJSObjWrappers, entry); + + return nsnull; + } + + entry->mNPObj = npobj; + + npobj->mJSObj = obj; + npobj->mCx = cx; + npobj->mNpp = npp; + + // Root the JSObject, its lifetime is now tied to that of the + // NPObject. + if (!::JS_AddNamedRoot(cx, &npobj->mJSObj, "nsJSObjWrapper::mJSObject")) { + NS_ERROR("Failed to root JSObject!"); + + _releaseobject(npobj); + + PL_DHashTableRawRemove(&sJSObjWrappers, entry); + + return nsnull; + } + + return npobj; +} + +static NPObject * +GetNPObject(JSContext *cx, JSObject *obj) +{ + while (JS_GET_CLASS(cx, obj) != &sNPObjectJSWrapperClass) { + obj = ::JS_GetPrototype(cx, obj); + } + + if (!obj) { + return nsnull; + } + + return (NPObject *)::JS_GetPrivate(cx, obj); +} + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + NPObject *npobj = GetNPObject(cx, obj); + + if (!npobj || !npobj->_class || !npobj->_class->hasProperty || + !npobj->_class->hasMethod) { + ThrowJSException(cx, "Bad NPObject as private data!"); + + return JS_FALSE; + } + + // We must permit methods here since JS_DefineUCFunction() will add + // the function as a property + if (!npobj->_class->hasProperty(npobj, (NPIdentifier)id) && + !npobj->_class->hasMethod(npobj, (NPIdentifier)id)) { + ThrowJSException(cx, "Trying to add unsupported property on scriptable " + "plugin object!"); + + return JS_FALSE; + } + + return JS_TRUE; +} + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + NPObject *npobj = GetNPObject(cx, obj); + + if (!npobj || !npobj->_class || !npobj->_class->hasProperty) { + ThrowJSException(cx, "Bad NPObject as private data!"); + + return JS_FALSE; + } + + if (!npobj->_class->hasProperty(npobj, (NPIdentifier)id)) { + ThrowJSException(cx, "Trying to remove unsupported property on scriptable " + "plugin object!"); + + return JS_FALSE; + } + + return JS_TRUE; +} + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + NPObject *npobj = GetNPObject(cx, obj); + + if (!npobj || !npobj->_class || !npobj->_class->hasProperty || + !npobj->_class->setProperty) { + ThrowJSException(cx, "Bad NPObject as private data!"); + + return JS_FALSE; + } + + if (!npobj->_class->hasProperty(npobj, (NPIdentifier)id)) { + ThrowJSException(cx, "Trying to set unsupported property on scriptable " + "plugin object!"); + + return JS_FALSE; + } + + NPVariant npv; + if (!JSValToNPVariant(nsnull, cx, *vp, &npv)) { + ThrowJSException(cx, "Error converting jsval to NPVariant!"); + + return JS_FALSE; + } + + JSBool ok = npobj->_class->setProperty(npobj, (NPIdentifier)id, &npv); + + // Release the variant + _releasevariantvalue(&npv); + + if (!ok) { + ThrowJSException(cx, "Error setting property on scriptable plugin " + "object!"); + } + + return ok; +} + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + NPObject *npobj = GetNPObject(cx, obj); + + if (!npobj || !npobj->_class || !npobj->_class->hasProperty || + !npobj->_class->hasMethod || !npobj->_class->getProperty) { + ThrowJSException(cx, "Bad NPObject as private data!"); + + return JS_FALSE; + } + + if (npobj->_class->hasProperty(npobj, (NPIdentifier)id)) { + NPVariant npv; + VOID_TO_NPVARIANT(npv); + + if (!npobj->_class->getProperty(npobj, (NPIdentifier)id, &npv)) { + ThrowJSException(cx, "Error setting property on scriptable plugin " + "object!"); + + return JS_FALSE; + } + + NPP npp = nsnull; + + if (NPVARIANT_IS_OBJECT(npv)) { + // We'll only need an npp if npv is an object, so don't waste time + // looking it up in other cases. + + npp = FindNPPForJSObject(obj, npobj); + } + + *vp = NPVariantToJSVal(npp, cx, &npv); + + // *vp now owns the value, release our reference. + _releasevariantvalue(&npv); + + return JS_TRUE; + } + + if (npobj->_class->hasMethod(npobj, (NPIdentifier)id)) { + return PR_TRUE; + } + + ThrowJSException(cx, "Trying to get unsupported property on scriptable " + "plugin object!"); + + return JS_FALSE; +} + +JS_STATIC_DLL_CALLBACK(JSBool) +CallNPMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + while (JS_GET_CLASS(cx, obj) != &sNPObjectJSWrapperClass) { + obj = ::JS_GetPrototype(cx, obj); + } + + if (!obj) { + ThrowJSException(cx, "NPMethod called on non-NPObject wrapped JSObject!"); + + return JS_FALSE; + } + + NPObject *npobj = (NPObject *)::JS_GetPrivate(cx, obj); + + if (!npobj || !npobj->_class || !npobj->_class->invoke) { + ThrowJSException(cx, "Bad NPObject as private data!"); + + return JS_FALSE; + } + + NPP npp = FindNPPForJSObject(obj, npobj); + + if (!npp) { + ThrowJSException(cx, "Error finding NPP for JSObject!"); + + return JS_FALSE; + } + + JSObject *funobj = JSVAL_TO_OBJECT(argv[-2]); + JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj); + + jsval method = STRING_TO_JSVAL(::JS_GetFunctionId(fun)); + + NPVariant npargs_buf[8]; + NPVariant *npargs = npargs_buf; + + if (argc > (sizeof(npargs_buf) / sizeof(NPVariant))) { + // Our stack buffer isn't large enough to hold all arguments, + // malloc a buffer. + npargs = (NPVariant *)PR_Malloc(argc * sizeof(NPVariant)); + + if (!npargs) { + ThrowJSException(cx, "Out of memory!"); + + return JS_FALSE; + } + } + + // Convert arguments + PRUint32 i; + for (i = 0; i < argc; ++i) { + if (!JSValToNPVariant(npp, cx, argv[i], npargs + i)) { + ThrowJSException(cx, "Error converting jsvals to NPVariants!"); + + return JS_FALSE; + } + } + + NPVariant v; + VOID_TO_NPVARIANT(v); + + JSBool ok = npobj->_class->invoke(npobj, (NPIdentifier)method, npargs, argc, + &v); + + // Release arguments. + for (i = 0; i < argc; ++i) { + _releasevariantvalue(npargs + i); + } + + if (npargs != npargs_buf) + PR_Free(npargs); + + if (!ok) { + ThrowJSException(cx, "Error calling method on NPObject!"); + + return JS_FALSE; + } + + *rval = NPVariantToJSVal(npp, cx, &v); + + // *rval now owns the value, release our reference. + _releasevariantvalue(&v); + + return JS_TRUE; +} + + +JS_STATIC_DLL_CALLBACK(JSBool) +NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp) +{ + NPObject *npobj = GetNPObject(cx, obj); + + if (!npobj || !npobj->_class || !npobj->_class->hasProperty || + !npobj->_class->hasMethod) { + ThrowJSException(cx, "Bad NPObject as private data!"); + + return JS_FALSE; + } + + if (npobj->_class->hasProperty(npobj, (NPIdentifier)id)) { + *objp = obj; + } else if (npobj->_class->hasMethod(npobj, (NPIdentifier)id)) { + JSString *str = nsnull; + + if (JSVAL_IS_STRING(id)) { + str = JSVAL_TO_STRING(id); + } else { + NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n"); + + str = ::JS_ValueToString(cx, id); + + if (!str) { + // OOM. The JS engine throws exceptions for us in this case. + + return JS_FALSE; + } + } + + JSFunction *fnc = + ::JS_DefineUCFunction(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), CallNPMethod, 0, + JSPROP_ENUMERATE); + + *objp = obj; + + return fnc != nsnull; + } + + return JS_TRUE; +} + +JS_STATIC_DLL_CALLBACK(void) +NPObjWrapper_Finalize(JSContext *cx, JSObject *obj) +{ + NPObject *npobj = (NPObject *)::JS_GetPrivate(cx, obj); + + if (npobj) { + if (sNPObjWrappers.ops) { + PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_REMOVE); + } + + // Let go of our NPObject + _releaseobject(npobj); + } + + OnWrapperDestroyed(); +} + + +class NPObjWrapperHashEntry : public PLDHashEntryHdr +{ +public: + NPObject *mNPObj; // Must be the first member for the PLDHash stubs to work + JSObject *mJSObj; + NPP mNpp; +}; + + +// Look up or create a JSObject that wraps the NPObject npobj. + +// static +JSObject * +nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj) +{ + if (!npobj) { + NS_ERROR("Null NPObject passed to nsNPObjWrapper::GetNewOrUsed()!"); + + return nsnull; + } + + if (npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass) { + // npobj is one of our own, return its existing JSObject. + + return ((nsJSObjWrapper *)npobj)->mJSObj; + } + + if (!npp) { + NS_ERROR("No npp passed to nsNPObjWrapper::GetNewOrUsed()!"); + + return nsnull; + } + + if (!sNPObjWrappers.ops) { + // No hash yet (or any more), initalize it. + + if (!PL_DHashTableInit(&sNPObjWrappers, PL_DHashGetStubOps(), nsnull, + sizeof(NPObjWrapperHashEntry), 16)) { + NS_ERROR("Error initializing PLDHashTable!"); + + return nsnull; + } + } + + NPObjWrapperHashEntry *entry = + NS_STATIC_CAST(NPObjWrapperHashEntry *, + PL_DHashTableOperate(&sNPObjWrappers, npobj, + PL_DHASH_ADD)); + + if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mJSObj) { + // Found a live NPObject wrapper, return it. + return entry->mJSObj; + } + + entry->mNPObj = npobj; + entry->mNpp = npp; + + // No existing JSObject, create one. + + JSObject *obj = ::JS_NewObject(cx, &sNPObjectJSWrapperClass, nsnull, nsnull); + + if (!obj) { + // OOM? Remove the stale entry from the hash. + + PL_DHashTableRawRemove(&sJSObjWrappers, entry); + + return nsnull; + } + + OnWrapperCreated(); + + entry->mJSObj = obj; + + if (!::JS_SetPrivate(cx, obj, npobj)) { + NS_ERROR("Error setting private NPObject data in JS wrapper!"); + + PL_DHashTableRawRemove(&sJSObjWrappers, entry); + + return nsnull; + } + + // The new JSObject now holds on to npobj + _retainobject(npobj); + + return obj; +} + + +// PLDHashTable enumeration callbacks for destruction code. +PR_STATIC_CALLBACK(PLDHashOperator) +JSObjWrapperPluginDestroyedCallback(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + JSObjWrapperHashEntry *entry = (JSObjWrapperHashEntry *)hdr; + + nsJSObjWrapper *npobj = entry->mNPObj; + + if (npobj->mNpp == arg) { + // Prevent invalidate() and _releaseobject() from touching the hash + // we're enumerating. + const PLDHashTableOps *ops = table->ops; + table->ops = nsnull; + + if (npobj->_class && npobj->_class->invalidate) { + npobj->_class->invalidate(npobj); + } + + _releaseobject(npobj); + + table->ops = ops; + + return PL_DHASH_REMOVE; + } + + return PL_DHASH_NEXT; +} + +PR_STATIC_CALLBACK(PLDHashOperator) +NPObjWrapperPluginDestroyedCallback(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + NPObjWrapperHashEntry *entry = (NPObjWrapperHashEntry *)hdr; + + if (entry->mNpp == arg) { + NPObject *npobj = entry->mNPObj; + + if (npobj->_class && npobj->_class->invalidate) { + npobj->_class->invalidate(npobj); + } + + // Force deallocation of plugin objects since the plugin they came + // from is being torn down. + if (npobj->_class && npobj->_class->deallocate) { + npobj->_class->deallocate(npobj); + } else { + PR_Free(npobj); + } + + JSContext *cx = GetJSContext((NPP)arg); + + ::JS_SetPrivate(cx, entry->mJSObj, nsnull); + + return PL_DHASH_REMOVE; + } + + return PL_DHASH_NEXT; +} + +// static +void +nsJSNPRuntime::OnPluginDestroy(NPP npp) +{ + if (sJSObjWrappers.ops) { + PL_DHashTableEnumerate(&sJSObjWrappers, + JSObjWrapperPluginDestroyedCallback, npp); + } + + if (sNPObjWrappers.ops) { + PL_DHashTableEnumerate(&sNPObjWrappers, + NPObjWrapperPluginDestroyedCallback, npp); + } +} + +// Find the NPP for a JSObject or from its NPObject counter-part, if any. +static NPP +FindNPPForJSObject(JSObject *obj, NPObject *npobj) +{ + if (npobj) { + if (npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass) { + nsJSObjWrapper *jsnpobj = (nsJSObjWrapper *)npobj; + + return jsnpobj->mNpp; + } + + NPObjWrapperHashEntry *entry = + NS_STATIC_CAST(NPObjWrapperHashEntry *, + PL_DHashTableOperate(&sNPObjWrappers, npobj, + PL_DHASH_ADD)); + + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + return entry->mNpp; + } + } + + if (sNPObjWrappers.ops) { + NPObjWrapperHashEntry *entry = + NS_STATIC_CAST(NPObjWrapperHashEntry *, + PL_DHashTableOperate(&sNPObjWrappers, npobj, + PL_DHASH_ADD)); + + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + return entry->mNpp; + } + } + + return nsnull; +} + + diff --git a/mozilla/modules/plugin/base/src/nsJSNPRuntime.h b/mozilla/modules/plugin/base/src/nsJSNPRuntime.h new file mode 100644 index 00000000000..bd65d3e7069 --- /dev/null +++ b/mozilla/modules/plugin/base/src/nsJSNPRuntime.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsJSNPRuntime_h__ +#define nsJSNPRuntime_h__ + +#include "nscore.h" +#include "jsapi.h" +#include "npapi.h" +#include "npruntime.h" +#include "pldhash.h" + +class nsJSNPRuntime +{ +public: + static void OnPluginDestroy(NPP npp); +}; + +class nsJSObjWrapper : public NPObject +{ +public: + static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj); + +protected: + nsJSObjWrapper(); + ~nsJSObjWrapper(); + + static NPObject * NP_Allocate(); + static void NP_Deallocate(NPObject *obj); + static void NP_Invalidate(NPObject *obj); + static bool NP_HasMethod(NPObject *, NPIdentifier identifier); + static bool NP_Invoke(NPObject *obj, NPIdentifier method, + const NPVariant *args, uint32_t argCount, + NPVariant *result); + static bool NP_HasProperty(NPObject * obj, NPIdentifier property); + static bool NP_GetProperty(NPObject *obj, NPIdentifier property, + NPVariant *result); + static bool NP_SetProperty(NPObject *obj, NPIdentifier property, + const NPVariant *value); + static bool NP_RemoveProperty(NPObject *obj, NPIdentifier property); + +public: + JSObject *mJSObj; + JSContext *mCx; + NPP mNpp; + + static NPClass sJSObjWrapperNPClass; +}; + +class nsNPObjWrapper +{ +public: + static JSObject *GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj); +}; + +bool +JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant); + +#endif // nsJSNPRuntime_h__ diff --git a/mozilla/modules/plugin/base/src/win32.order b/mozilla/modules/plugin/base/src/win32.order deleted file mode 100644 index 332be428fe9..00000000000 --- a/mozilla/modules/plugin/base/src/win32.order +++ /dev/null @@ -1,134 +0,0 @@ -?do_GetService@@YA?BVnsGetServiceByCID@@ABUnsID@@PAI@Z ; 566 -?GetCallbacks@ns4xPluginInstance@@QAEIPAPBU_NPPluginFuncs@@@Z ; 281 -?GetURL@nsPluginStreamInfo@@UAGIPAPBD@Z ; 281 -?GetNPP@ns4xPluginInstance@@QAEIPAPAU_NPP@@@Z ; 281 -?IsStarted@ns4xPluginInstance@@QAEHXZ ; 281 -?GetLastModified@nsPluginStreamInfo@@UAGIPAI@Z ; 280 -?SetURL@nsPluginStreamInfo@@QAEXPBD@Z ; 280 -?OnDataAvailable@nsPluginStreamListenerPeer@@UAGIPAVnsIRequest@@PAVnsISupports@@PAVnsIInputStream@@II@Z ; 278 -?OnDataAvailable@ns4xPluginStreamListener@@UAGIPAVnsIPluginStreamInfo@@PAVnsIInputStream@@I@Z ; 278 -?new_str@@YAPADPBD@Z ; 252 -?OnDataAvailable@nsPluginCacheListener@@UAGIPAVnsIRequest@@PAVnsISupports@@PAVnsIInputStream@@II@Z ; 57 -?IsPluginFile@nsPluginsDir@@QAEHABVnsFileSpec@@@Z ; 22 -?LoadPlugins@nsPluginHostImpl@@UAGIXZ ; 21 -?AddRef@ns4xPluginStreamListener@@UAGKXZ ; 18 -?AddRef@nsPluginHostImpl@@UAGKXZ ; 15 -??0nsPluginFile@@QAE@ABVnsFileSpec@@@Z ; 15 -??1nsPluginFile@@UAE@XZ ; 15 -?GetPluginCount@nsPluginHostImpl@@UAGIPAI@Z ; 15 -?GetPluginInfo@nsPluginFile@@QAEIAAUnsPluginInfo@@@Z ; 14 -??1nsPluginTag@@QAE@XZ ; 14 -??0nsPluginTag@@QAE@PAUnsPluginInfo@@@Z ; 14 -?FreePluginInfo@nsPluginFile@@QAEIAAUnsPluginInfo@@@Z ; 14 -?Release@nsPluginHostImpl@@UAGKXZ ; 13 -?AddRef@ns4xPluginInstance@@UAGKXZ ; 13 -?Release@ns4xPluginInstance@@UAGKXZ ; 11 -?QueryInterface@nsPluginHostImpl@@UAGIABUnsID@@PAPAX@Z ; 9 -?GetLength@DOMPluginImpl@@UAGIPAI@Z ; 9 -?GetName@DOMPluginImpl@@UAGIAAVnsAString@@@Z ; 9 -??0nsPluginTag@@QAE@PAV0@@Z ; 6 -?Item@DOMPluginImpl@@UAGIIPAPAVnsIDOMMimeType@@@Z ; 4 -?AddRef@nsPluginInstancePeerImpl@@UAGKXZ ; 4 -?SetWindow@ns4xPluginInstance@@UAGIPAUnsPluginWindow@@@Z ; 4 -?Release@ns4xPlugin@@UAGKXZ ; 4 -?Release@nsPluginInstancePeerImpl@@UAGKXZ ; 4 -??0DOMMimeTypeImpl@@QAE@PAVnsPluginTag@@I@Z ; 4 -?do_GetService@@YA?BVnsGetServiceByContractID@@PBDPAI@Z ; 3 -?RegisterPluginMimeTypesWithLayout@nsPluginHostImpl@@AAEIPAVnsPluginTag@@PAVnsIComponentManager@@PAVnsIFile@@@Z ; 3 -?GetValue@ns4xPluginInstance@@UAGIW4nsPluginInstanceVariable@@PAX@Z ; 3 -?Release@nsPluginStreamListenerPeer@@UAGKXZ ; 2 -?QueryInterface@nsPluginInstancePeerImpl@@UAGIABUnsID@@PAPAX@Z ; 2 -?GetType@DOMMimeTypeImpl@@UAGIAAVnsAString@@@Z ; 2 -?IsPluginEnabledForType@nsPluginHostImpl@@UAGIPBD@Z ; 2 -?NS_OpenURI@@YAIPAPAVnsIChannel@@PAVnsIURI@@PAVnsIIOService@@PAVnsILoadGroup@@PAVnsIInterfaceRequestor@@I@Z ; 2 -?GetPlugins@nsPluginHostImpl@@UAGIIQAPAVnsIDOMPlugin@@@Z ; 2 -?Release@ns4xPluginStreamListener@@UAGKXZ ; 2 -?CleanUnloadedLibraries@nsPluginHostImpl@@AAEXXZ ; 2 -?assign_assuming_AddRef@nsCOMPtr_base@@IAEXPAVnsISupports@@@Z ; 2 -??0nsPluginsDir@@QAE@G@Z ; 2 -?do_GetIOService@@YA?BVnsGetServiceByCID@@PAI@Z ; 2 -?ScanPluginsDirectory@nsPluginHostImpl@@AAEIAAVnsPluginsDir@@PAVnsIComponentManager@@PAVnsIFile@@H@Z ; 2 -?SetContentType@nsPluginStreamInfo@@QAEXQBD@Z ; 2 -??1nsPluginsDir@@UAE@XZ ; 2 -?QueryInterface@ns4xPluginStreamListener@@UAGIABUnsID@@PAPAX@Z ; 2 -??0?$nsCOMPtr@VnsIPlugin@@@@QAE@ABV0@@Z ; 2 -?Init@nsPluginHostImpl@@UAGIXZ ; 2 -?NS_OpenURI@@YAIPAVnsIStreamListener@@PAVnsISupports@@PAVnsIURI@@PAVnsIIOService@@PAVnsILoadGroup@@PAVnsIInterfaceRequestor@@I@Z ; 2 -?GetDescription@DOMPluginImpl@@UAGIAAVnsAString@@@Z ; 2 -??_GnsPluginInstancePeerImpl@@UAEPAXI@Z ; 1 -?GetMode@nsPluginInstancePeerImpl@@UAGIPAW4nsPluginMode@@@Z ; 1 -?IsLastInstance@nsActivePluginList@@QAEHPAUnsActivePlugin@@@Z ; 1 -?Shutdown@ns4xPlugin@@UAGIXZ ; 1 -??1nsPluginCacheListener@@UAE@XZ ; 1 -??_GnsPluginStreamListenerPeer@@UAEPAXI@Z ; 1 -??2PluginViewerImpl@@SAPAXI@Z ; 1 -?QueryInterface@ns4xPluginInstance@@UAGIABUnsID@@PAPAX@Z ; 1 -?NewEmbededPluginStream@nsPluginHostImpl@@AAEIPAVnsIURI@@PAUnsIPluginInstanceOwner@@PAVnsIPluginInstance@@@Z ; 1 -??_GnsPluginCacheListener@@UAEPAXI@Z ; 1 -?Destroy@nsPluginHostImpl@@UAGIXZ ; 1 -?OnStopRequest@nsPluginStreamListenerPeer@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 1 -?OnStartRequest@nsPluginStreamListenerPeer@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 1 -?find@nsActivePluginList@@QAEPAUnsActivePlugin@@PAVnsIPluginInstance@@@Z ; 1 -?CreatePlugin@ns4xPlugin@@SAIPAVnsIServiceManager@@PBDPAUPRLibrary@@PAPAVnsIPlugin@@@Z ; 1 -?OnStopBinding@ns4xPluginStreamListener@@UAGIPAVnsIPluginStreamInfo@@I@Z ; 1 -?SetUpStreamListener@nsPluginStreamListenerPeer@@AAEIPAVnsIRequest@@PAVnsIURI@@@Z ; 1 -?OnStopRequest@nsPluginCacheListener@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 1 -?SetLastModified@nsPluginStreamInfo@@QAEXI@Z ; 1 -?AddInstanceToActiveList@nsPluginHostImpl@@AAEXV?$nsCOMPtr@VnsIPlugin@@@@PAVnsIPluginInstance@@PAVnsIURI@@H@Z ; 1 -??0nsPluginCacheListener@@QAE@PAVnsPluginStreamListenerPeer@@@Z ; 1 -?GetLength@nsPluginStreamInfo@@UAGIPAI@Z ; 1 -??_Ens4xPluginInstance@@UAEPAXI@Z ; 1 -?findStopped@nsActivePluginList@@QAEPAUnsActivePlugin@@PAD@Z ; 1 -??0nsPluginStreamInfo@@QAE@XZ ; 1 -?OnStartBinding@ns4xPluginStreamListener@@UAGIPAVnsIPluginStreamInfo@@@Z ; 1 -?remove@nsActivePluginList@@QAEHPAUnsActivePlugin@@PAH@Z ; 1 -?GetStreamType@ns4xPluginStreamListener@@UAGIPAW4nsPluginStreamType@@@Z ; 1 -?StopPluginInstance@nsPluginHostImpl@@UAGIPAVnsIPluginInstance@@@Z ; 1 -?InitializeEmbeded@nsPluginStreamListenerPeer@@QAEIPAVnsIURI@@PAVnsIPluginInstance@@PAUnsIPluginInstanceOwner@@PAUnsIPluginHost@@@Z ; 1 -?GetMIMEType@nsPluginInstancePeerImpl@@UAGIPAPBD@Z ; 1 -??_Ens4xPluginStreamListener@@UAEPAXI@Z ; 1 -?GetAttributes@nsPluginInstancePeerImpl@@UAGIAAGAAPBQBD1@Z ; 1 -?Observe@nsPluginHostImpl@@UAGIPAVnsISupports@@PBG1@Z ; 1 -?NewStream@ns4xPluginInstance@@UAGIPAPAVnsIPluginStreamListener@@@Z ; 1 -?OnFileAvailable@ns4xPluginStreamListener@@UAGIPAVnsIPluginStreamInfo@@PBD@Z ; 1 -?LoadXPCOMPlugins@nsPluginHostImpl@@AAEIPAVnsIComponentManager@@PAVnsIFile@@@Z ; 1 -??1ns4xPluginStreamListener@@UAE@XZ ; 1 -?Release@PluginListener@@UAGKXZ ; 1 -_NSGetModule ; 1 -?LoadPlugin@nsPluginFile@@QAEIAAPAUPRLibrary@@@Z ; 1 -?SetSeekable@nsPluginStreamInfo@@QAEXH@Z ; 1 -?GetPeer@ns4xPluginInstance@@UAGIPAPAVnsIPluginInstancePeer@@@Z ; 1 -?Initialize@nsPluginInstancePeerImpl@@QAEIPAUnsIPluginInstanceOwner@@QBD@Z ; 1 -??1nsPluginInstancePeerImpl@@UAE@XZ ; 1 -??0nsPluginInstancePeerImpl@@QAE@XZ ; 1 -?InitializePlugin@ns4xPluginInstance@@IAEIPAVnsIPluginInstancePeer@@@Z ; 1 -?InstantiateEmbededPlugin@nsPluginHostImpl@@UAGIPBDPAVnsIURI@@PAUnsIPluginInstanceOwner@@@Z ; 1 -??0ns4xPluginStreamListener@@QAE@PAVnsIPluginInstance@@PAX@Z ; 1 -??0ns4xPluginInstance@@QAE@PAU_NPPluginFuncs@@PAUPRLibrary@@@Z ; 1 -?IsSeekable@nsPluginStreamInfo@@UAGIPAH@Z ; 1 -?SetUpCache@nsPluginStreamListenerPeer@@AAEIPAVnsIURI@@@Z ; 1 -?OnStartRequest@nsPluginCacheListener@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 1 -?Initialize@ns4xPluginInstance@@UAGIPAVnsIPluginInstancePeer@@@Z ; 1 -?Stop@ns4xPluginInstance@@UAGIXZ ; 1 -?CreateInstance@ns4xPlugin@@UAGIPAVnsISupports@@ABUnsID@@PAPAX@Z ; 1 -?OnFileAvailable@nsPluginStreamListenerPeer@@QAEIPBD@Z ; 1 -??0nsActivePluginList@@QAE@XZ ; 1 -?SetUpPluginInstance@nsPluginHostImpl@@UAGIPBDPAVnsIURI@@PAUnsIPluginInstanceOwner@@@Z ; 1 -?FindStoppedPluginForURL@nsPluginHostImpl@@AAEIPAVnsIURI@@PAUnsIPluginInstanceOwner@@@Z ; 1 -?SetLength@nsPluginStreamInfo@@QAEXI@Z ; 1 -?GetContentType@nsPluginStreamInfo@@UAGIPAPBD@Z ; 1 -??1ns4xPluginInstance@@UAE@XZ ; 1 -?add@nsActivePluginList@@QAEHPAUnsActivePlugin@@@Z ; 1 -?Start@ns4xPluginInstance@@UAGIXZ ; 1 -?FindPluginEnabledForType@nsPluginHostImpl@@AAEIPBDAAPAVnsPluginTag@@@Z ; 1 -??0ns4xPlugin@@QAE@PAU_NPPluginFuncs@@PAUPRLibrary@@P6GFXZPAVnsIServiceManager@@@Z ; 1 -?Create@nsPluginHostImpl@@SGIPAVnsISupports@@ABUnsID@@PAPAX@Z ; 1 -??0nsActivePlugin@@QAE@V?$nsCOMPtr@VnsIPlugin@@@@PAVnsIPluginInstance@@PADH@Z ; 1 -??0nsPluginHostImpl@@QAE@XZ ; 1 -??1nsPluginStreamListenerPeer@@UAE@XZ ; 1 -?GetPluginFactory@nsPluginHostImpl@@UAGIPBDPAPAVnsIPlugin@@@Z ; 1 -?ReleaseStatics@ns4xPlugin@@SAXXZ ; 1 -?CheckClassInitialized@ns4xPlugin@@KAXXZ ; 1 -?shut@nsActivePluginList@@QAEXXZ ; 1 -??1nsActivePlugin@@QAE@XZ ; 1 -??0nsPluginStreamListenerPeer@@QAE@XZ ; 1