Fixing bug 253570. Add NPP arguments to select new NPN_ methods to make implementation easier and safer. r+sr=brendan@mozilla.org
git-svn-id: svn://10.0.0.236/trunk@160110 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -274,7 +274,7 @@ int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
|
||||
The NPVariant *result argument of these functions (where
|
||||
applicable) should be released using NPN_ReleaseVariantValue().
|
||||
*/
|
||||
typedef NPObject *(*NPAllocateFunctionPtr)();
|
||||
typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp);
|
||||
typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
|
||||
typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
|
||||
typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
|
||||
@@ -286,7 +286,8 @@ 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);
|
||||
typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
|
||||
NPIdentifier name);
|
||||
|
||||
/*
|
||||
NPObjects returned by create, retain, invoke, and getProperty pass
|
||||
@@ -336,7 +337,7 @@ struct NPObject {
|
||||
returned. This method will initialize the referenceCount member of
|
||||
the NPObject to 1.
|
||||
*/
|
||||
NPObject *NPN_CreateObject(NPClass *aClass);
|
||||
NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);
|
||||
|
||||
/*
|
||||
Increment the NPObject's reference count.
|
||||
@@ -362,17 +363,17 @@ void NPN_ReleaseObject(NPObject *npobj);
|
||||
on which the plugin was initialized.
|
||||
*/
|
||||
|
||||
bool NPN_Call(NPObject *npobj, NPIdentifier methodName,
|
||||
bool NPN_Call(NPP npp, 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,
|
||||
bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
|
||||
NPVariant *result);
|
||||
bool NPN_SetProperty(NPObject *npobj, NPIdentifier propertyName,
|
||||
bool NPN_SetProperty(NPP npp, 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);
|
||||
bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
|
||||
bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
|
||||
bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);
|
||||
|
||||
/*
|
||||
NPN_SetException may be called to trigger a script exception upon
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* npupp.h $Revision: 3.17 $
|
||||
* npupp.h $Revision: 3.18 $
|
||||
* function call mecahnics needed by platform specific glue code.
|
||||
*/
|
||||
|
||||
@@ -1228,22 +1228,23 @@ typedef int32_t (* NP_LOADDS NPN_IntFromIdentifierUPP)(NPIdentifier identifier);
|
||||
typedef UniversalProcPtr NPN_CreateObjectUPP;
|
||||
enum {
|
||||
uppNPN_CreateObjectProcInfo = kThinkCStackBased
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPClass*)))
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, 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))
|
||||
#define CallNPN_CreateObjectProc(FUNC, ARG1, ARG2) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_CreateObjectProcInfo, (ARG1), (ARG2))
|
||||
|
||||
#else
|
||||
|
||||
typedef NPObject* (* NP_LOADDS NPN_CreateObjectUPP)(NPClass *aClass);
|
||||
typedef NPObject* (* NP_LOADDS NPN_CreateObjectUPP)(NPP npp, NPClass *aClass);
|
||||
#define NewNPN_CreateObjectProc(FUNC) \
|
||||
((NPN_CreateObjectUPP) (FUNC))
|
||||
#define CallNPN_CreateObjectProc(FUNC, ARG1) \
|
||||
(*(FUNC))((ARG1))
|
||||
#define CallNPN_CreateObjectProc(FUNC, ARG1, ARG2) \
|
||||
(*(FUNC))((ARG1), (ARG2))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1306,26 +1307,27 @@ typedef void (* NP_LOADDS NPN_ReleaseObjectUPP)(NPObject *obj);
|
||||
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*)))
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*)))
|
||||
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPIdentifier)))
|
||||
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(const NPVariant*)))
|
||||
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(uint32_t)))
|
||||
| STACK_ROUTINE_PARAMETER(6, 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))
|
||||
#define CallNPN_CallProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_CallProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_CallUPP)(NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||
typedef bool (* NP_LOADDS NPN_CallUPP)(NPP npp, 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))
|
||||
#define CallNPN_CallProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
|
||||
(*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1365,24 +1367,25 @@ typedef bool (* NP_LOADDS NPN_EvaluateUPP)(NPP npp, NPObject *obj, NPString *scr
|
||||
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*)))
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*)))
|
||||
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPIdentifier)))
|
||||
| STACK_ROUTINE_PARAMETER(4, 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))
|
||||
#define CallNPN_GetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetPropertyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_GetPropertyUPP)(NPObject *obj, NPIdentifier propertyName, NPVariant *result);
|
||||
typedef bool (* NP_LOADDS NPN_GetPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result);
|
||||
#define NewNPN_GetPropertyProc(FUNC) \
|
||||
((NPN_GetPropertyUPP) (FUNC))
|
||||
#define CallNPN_GetPropertyProc(FUNC, ARG1, ARG2, ARG3) \
|
||||
(*(FUNC))((ARG1), (ARG2), (ARG3))
|
||||
#define CallNPN_GetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
|
||||
(*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1393,24 +1396,25 @@ typedef bool (* NP_LOADDS NPN_GetPropertyUPP)(NPObject *obj, NPIdentifier proper
|
||||
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*)))
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*)))
|
||||
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPIdentifier)))
|
||||
| STACK_ROUTINE_PARAMETER(4, 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))
|
||||
#define CallNPN_SetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_SetPropertyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_SetPropertyUPP)(NPObject *obj, NPIdentifier propertyName, const NPVariant *value);
|
||||
typedef bool (* NP_LOADDS NPN_SetPropertyUPP)(NPP npp, 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))
|
||||
#define CallNPN_SetPropertyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
|
||||
(*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1421,23 +1425,80 @@ typedef bool (* NP_LOADDS NPN_SetPropertyUPP)(NPObject *obj, NPIdentifier proper
|
||||
typedef UniversalProcPtr NPN_RemovePropertyUPP;
|
||||
enum {
|
||||
uppNPN_RemovePropertyProcInfo = kThinkCStackBased
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPObject*)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPIdentifier)))
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*)))
|
||||
| STACK_ROUTINE_PARAMETER(3, 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))
|
||||
#define CallNPN_RemovePropertyProc(FUNC, ARG1, ARG2, ARG3) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_RemovePropertyProcInfo, (ARG1), (ARG2), (ARG3))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_RemovePropertyUPP)(NPObject *obj, NPIdentifier propertyName);
|
||||
typedef bool (* NP_LOADDS NPN_RemovePropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||
#define NewNPN_RemovePropertyProc(FUNC) \
|
||||
((NPN_RemovePropertyUPP) (FUNC))
|
||||
#define CallNPN_RemovePropertyProc(FUNC, ARG1, ARG2) \
|
||||
(*(FUNC))((ARG1), (ARG2))
|
||||
#define CallNPN_RemovePropertyProc(FUNC, ARG1, ARG2, ARG3) \
|
||||
(*(FUNC))((ARG1), (ARG2), (ARG3))
|
||||
|
||||
#endif
|
||||
|
||||
/* NPN_HasProperty */
|
||||
|
||||
#if _NPUPP_USE_UPP_
|
||||
|
||||
typedef UniversalProcPtr NPN_HasPropertyUPP;
|
||||
enum {
|
||||
uppNPN_HasPropertyProcInfo = kThinkCStackBased
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*)))
|
||||
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPIdentifier)))
|
||||
| RESULT_SIZE(SIZE_CODE(sizeof(bool)))
|
||||
};
|
||||
|
||||
#define NewNPN_HasPropertyProc(FUNC) \
|
||||
(NPN_HasPropertyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_HasPropertyProcInfo, GetCurrentArchitecture())
|
||||
#define CallNPN_HasPropertyProc(FUNC, ARG1, ARG2, ARG3) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_HasPropertyProcInfo, (ARG1), (ARG2), (ARG3))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_HasPropertyUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||
#define NewNPN_HasPropertyProc(FUNC) \
|
||||
((NPN_HasPropertyUPP) (FUNC))
|
||||
#define CallNPN_HasPropertyProc(FUNC, ARG1, ARG2, ARG3) \
|
||||
(*(FUNC))((ARG1), (ARG2), (ARG3))
|
||||
|
||||
#endif
|
||||
|
||||
/* NPN_HasMethod */
|
||||
|
||||
#if _NPUPP_USE_UPP_
|
||||
|
||||
typedef UniversalProcPtr NPN_HasMethodUPP;
|
||||
enum {
|
||||
uppNPN_HasMethodProcInfo = kThinkCStackBased
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*)))
|
||||
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPIdentifier)))
|
||||
| RESULT_SIZE(SIZE_CODE(sizeof(bool)))
|
||||
};
|
||||
|
||||
#define NewNPN_HasMethodProc(FUNC) \
|
||||
(NPN_HasMethodUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_HasMethodProcInfo, GetCurrentArchitecture())
|
||||
#define CallNPN_HasMethodProc(FUNC, ARG1, ARG2, ARG3) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_HasMethodProcInfo, (ARG1), (ARG2), (ARG3))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_HasMethodUPP)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||
#define NewNPN_HasMethodProc(FUNC) \
|
||||
((NPN_HasMethodUPP) (FUNC))
|
||||
#define CallNPN_HasMethodProc(FUNC, ARG1, ARG2, ARG3) \
|
||||
(*(FUNC))((ARG1), (ARG2), (ARG3))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1564,6 +1625,8 @@ typedef struct _NPNetscapeFuncs {
|
||||
NPN_GetPropertyUPP getproperty;
|
||||
NPN_SetPropertyUPP setproperty;
|
||||
NPN_RemovePropertyUPP removeproperty;
|
||||
NPN_HasPropertyUPP hasproperty;
|
||||
NPN_HasMethodUPP hasmethod;
|
||||
NPN_ReleaseVariantValueUPP releasevariantvalue;
|
||||
NPN_SetExceptionUPP setexception;
|
||||
} NPNetscapeFuncs;
|
||||
|
||||
@@ -1438,18 +1438,26 @@ _identifierisstring(NPIdentifier identifier)
|
||||
}
|
||||
|
||||
NPObject* NP_EXPORT
|
||||
_createobject(NPClass* aClass)
|
||||
_createobject(NPP npp, NPClass* aClass)
|
||||
{
|
||||
if (!npp) {
|
||||
NS_ERROR("Null npp passed to _createobject()!");
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!aClass) {
|
||||
NS_ERROR("Null class passed to _createobject()!");
|
||||
|
||||
return 0;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
NPObject *npobj;
|
||||
|
||||
if (aClass->allocate) {
|
||||
npobj = aClass->allocate();
|
||||
npobj = aClass->allocate(npp);
|
||||
} else {
|
||||
npobj = (NPObject *)PR_Malloc(sizeof(NPObject));
|
||||
}
|
||||
@@ -1490,11 +1498,14 @@ _releaseobject(NPObject* npobj)
|
||||
}
|
||||
|
||||
bool NP_EXPORT
|
||||
_call(NPObject* npobj, NPIdentifier method, const NPVariant *args,
|
||||
_call(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
|
||||
uint32_t argCount, NPVariant *result)
|
||||
{
|
||||
if (!npobj || !npobj->_class || !npobj->_class->invoke)
|
||||
return PR_FALSE;
|
||||
if (!npp || !npobj || !npobj->_class || !npobj->_class->invoke)
|
||||
return false;
|
||||
|
||||
NPPExceptionAutoHolder nppExceptionHolder;
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
return npobj->_class->invoke(npobj, method, args, argCount, result);
|
||||
}
|
||||
@@ -1502,6 +1513,11 @@ _call(NPObject* npobj, NPIdentifier method, const NPVariant *args,
|
||||
bool NP_EXPORT
|
||||
_evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
|
||||
{
|
||||
if (!npp)
|
||||
return false;
|
||||
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
JSContext *cx = GetJSContextFromNPP(npp);
|
||||
NS_ENSURE_TRUE(cx, false);
|
||||
|
||||
@@ -1534,8 +1550,7 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
|
||||
|
||||
jsval rval;
|
||||
nsresult rv = scx->EvaluateStringWithValue(utf16script, obj, principal,
|
||||
nsnull, 0, nsnull, &rval,
|
||||
nsnull);
|
||||
nsnull, 0, nsnull, &rval, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
if (result) {
|
||||
@@ -1546,47 +1561,63 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
|
||||
}
|
||||
|
||||
bool NP_EXPORT
|
||||
_getproperty(NPObject* npobj, NPIdentifier property, NPVariant *result)
|
||||
_getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
|
||||
NPVariant *result)
|
||||
{
|
||||
if (!npobj || !npobj->_class || !npobj->_class->getProperty)
|
||||
return PR_FALSE;
|
||||
if (!npp || !npobj || !npobj->_class || !npobj->_class->getProperty)
|
||||
return false;
|
||||
|
||||
NPPExceptionAutoHolder nppExceptionHolder;
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
return npobj->_class->getProperty(npobj, property, result);
|
||||
}
|
||||
|
||||
bool NP_EXPORT
|
||||
_setproperty(NPObject* npobj, NPIdentifier property,
|
||||
_setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
|
||||
const NPVariant *value)
|
||||
{
|
||||
if (!npobj || !npobj->_class || !npobj->_class->setProperty)
|
||||
return PR_FALSE;
|
||||
if (!npp || !npobj || !npobj->_class || !npobj->_class->setProperty)
|
||||
return false;
|
||||
|
||||
NPPExceptionAutoHolder nppExceptionHolder;
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
return npobj->_class->setProperty(npobj, property, value);
|
||||
}
|
||||
|
||||
bool NP_EXPORT
|
||||
_removeproperty(NPObject* npobj, NPIdentifier property)
|
||||
_removeproperty(NPP npp, NPObject* npobj, NPIdentifier property)
|
||||
{
|
||||
if (!npobj || !npobj->_class || !npobj->_class->removeProperty)
|
||||
return PR_FALSE;
|
||||
if (!npp || !npobj || !npobj->_class || !npobj->_class->removeProperty)
|
||||
return false;
|
||||
|
||||
NPPExceptionAutoHolder nppExceptionHolder;
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
return npobj->_class->removeProperty(npobj, property);
|
||||
}
|
||||
|
||||
bool NP_EXPORT
|
||||
_hasproperty(NPObject* npobj, NPIdentifier propertyName)
|
||||
_hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName)
|
||||
{
|
||||
if (!npobj || !npobj->_class || !npobj->_class->hasProperty)
|
||||
return PR_FALSE;
|
||||
if (!npp || !npobj || !npobj->_class || !npobj->_class->hasProperty)
|
||||
return false;
|
||||
|
||||
NPPExceptionAutoHolder nppExceptionHolder;
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
return npobj->_class->hasProperty(npobj, propertyName);
|
||||
}
|
||||
|
||||
bool NP_EXPORT
|
||||
_hasmethod(NPObject* npobj, NPIdentifier methodName)
|
||||
_hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName)
|
||||
{
|
||||
if (!npobj || !npobj->_class || !npobj->_class->hasMethod)
|
||||
return PR_FALSE;
|
||||
if (!npp || !npobj || !npobj->_class || !npobj->_class->hasMethod)
|
||||
return false;
|
||||
|
||||
NPPExceptionAutoHolder nppExceptionHolder;
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
return npobj->_class->hasProperty(npobj, methodName);
|
||||
}
|
||||
@@ -1634,12 +1665,50 @@ _tostring(NPObject* npobj, NPVariant *result)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static char *gNPPException;
|
||||
|
||||
void NP_EXPORT
|
||||
_setexception(NPObject* npobj, const NPUTF8 *message)
|
||||
{
|
||||
// XXX: Write me!
|
||||
if (gNPPException) {
|
||||
// If a plugin throws multiple exceptions, we'll only report the
|
||||
// last one for now.
|
||||
free(gNPPException);
|
||||
}
|
||||
|
||||
gNPPException = strdup(message);
|
||||
}
|
||||
|
||||
const char *
|
||||
PeekException()
|
||||
{
|
||||
return gNPPException;
|
||||
}
|
||||
|
||||
void
|
||||
PopException()
|
||||
{
|
||||
NS_ASSERTION(!gNPPException, "Uh, no NPP exception to pop!");
|
||||
|
||||
if (gNPPException) {
|
||||
free(gNPPException);
|
||||
|
||||
gNPPException = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NPPExceptionAutoHolder::NPPExceptionAutoHolder()
|
||||
: mOldException(gNPPException)
|
||||
{
|
||||
gNPPException = nsnull;
|
||||
}
|
||||
|
||||
NPPExceptionAutoHolder::~NPPExceptionAutoHolder()
|
||||
{
|
||||
NS_ASSERTION(!gNPPException, "NPP exception not properly cleared!");
|
||||
|
||||
gNPPException = mOldException;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
NPError NP_EXPORT
|
||||
@@ -1973,3 +2042,6 @@ _getJavaPeer(NPP npp)
|
||||
}
|
||||
|
||||
#endif /* OJI */
|
||||
|
||||
|
||||
NPP NPPStack::sCurrentNPP = nsnull;
|
||||
|
||||
@@ -207,7 +207,7 @@ int32_t NP_EXPORT
|
||||
_intfromidentifier(NPIdentifier identifier);
|
||||
|
||||
NPObject* NP_EXPORT
|
||||
_createobject(NPClass* aClass);
|
||||
_createobject(NPP npp, NPClass* aClass);
|
||||
|
||||
NPObject* NP_EXPORT
|
||||
_retainobject(NPObject* npobj);
|
||||
@@ -216,26 +216,28 @@ void NP_EXPORT
|
||||
_releaseobject(NPObject* npobj);
|
||||
|
||||
bool NP_EXPORT
|
||||
_call(NPObject* npobj, NPIdentifier method, const NPVariant *args,
|
||||
_call(NPP npp, 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);
|
||||
_getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
|
||||
NPVariant *result);
|
||||
|
||||
bool NP_EXPORT
|
||||
_setproperty(NPObject* npobj, NPIdentifier property, const NPVariant *value);
|
||||
_setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
|
||||
const NPVariant *value);
|
||||
|
||||
bool NP_EXPORT
|
||||
_removeproperty(NPObject* npobj, NPIdentifier property);
|
||||
_removeproperty(NPP npp, NPObject* npobj, NPIdentifier property);
|
||||
|
||||
bool NP_EXPORT
|
||||
_hasproperty(NPObject* npobj, NPIdentifier propertyName);
|
||||
_hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName);
|
||||
|
||||
bool NP_EXPORT
|
||||
_hasmethod(NPObject* npobj, NPIdentifier methodName);
|
||||
_hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName);
|
||||
|
||||
void NP_EXPORT
|
||||
_releasevariantvalue(NPVariant *variant);
|
||||
@@ -245,4 +247,52 @@ _setexception(NPObject* npobj, const NPUTF8 *message);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
const char *
|
||||
PeekException();
|
||||
|
||||
void
|
||||
PopException();
|
||||
|
||||
class NPPStack
|
||||
{
|
||||
public:
|
||||
static NPP Peek()
|
||||
{
|
||||
return sCurrentNPP;
|
||||
}
|
||||
|
||||
protected:
|
||||
static NPP sCurrentNPP;
|
||||
};
|
||||
|
||||
class NPPAutoPusher : public NPPStack
|
||||
{
|
||||
public:
|
||||
NPPAutoPusher(NPP npp)
|
||||
: mOldNPP(sCurrentNPP)
|
||||
{
|
||||
NS_ASSERTION(npp, "Uh, null npp passed to NPPAutoPusher!");
|
||||
|
||||
sCurrentNPP = npp;
|
||||
}
|
||||
|
||||
~NPPAutoPusher()
|
||||
{
|
||||
sCurrentNPP = mOldNPP;
|
||||
}
|
||||
|
||||
private:
|
||||
NPP mOldNPP;
|
||||
};
|
||||
|
||||
class NPPExceptionAutoHolder
|
||||
{
|
||||
public:
|
||||
NPPExceptionAutoHolder();
|
||||
~NPPExceptionAutoHolder();
|
||||
|
||||
protected:
|
||||
char *mOldException;
|
||||
};
|
||||
|
||||
#endif // ns4xPlugin_h__
|
||||
|
||||
@@ -163,6 +163,12 @@ public:
|
||||
nsresult SetCached(PRBool aCache) { mCached = aCache; return NS_OK; };
|
||||
|
||||
virtual JSObject *GetJSObject(JSContext *cx);
|
||||
|
||||
// Non-refcounting accessor for faster access to the peer.
|
||||
nsIPluginInstancePeer *Peer()
|
||||
{
|
||||
return mPeer;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -47,10 +47,16 @@
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "prmem.h"
|
||||
|
||||
// Hash of NPObject wrappers that wrap JSObjects.
|
||||
// Hash of JSObject wrappers that wraps JSObjects as NPObjects. There
|
||||
// will be one wrapper per JSObject per plugin instance, i.e. if two
|
||||
// plugins access the JSObject x, two wrappers for x will be
|
||||
// created. This is needed to be able to properly drop the wrappers
|
||||
// when a plugin is torn down in case there's a leak in the plugin (we
|
||||
// don't want to leak the world just because a plugin leaks an
|
||||
// NPObject).
|
||||
static PLDHashTable sJSObjWrappers;
|
||||
|
||||
// Hash of JSObject wrappers that wrap NPObjects.
|
||||
// Hash of NPObject wrappers that wrap NPObjects as JSObjects.
|
||||
static PLDHashTable sNPObjWrappers;
|
||||
|
||||
// Global wrapper count. This includes JSObject wrappers *and*
|
||||
@@ -177,12 +183,12 @@ OnWrapperDestroyed()
|
||||
static JSContext *
|
||||
GetJSContext(NPP npp)
|
||||
{
|
||||
NS_ENSURE_TRUE(npp, nsnull);
|
||||
|
||||
ns4xPluginInstance *inst = (ns4xPluginInstance *)npp->ndata;
|
||||
NS_ENSURE_TRUE(inst, nsnull);
|
||||
|
||||
nsCOMPtr<nsIPluginInstancePeer> pip;
|
||||
inst->GetPeer(getter_AddRefs(pip));
|
||||
nsCOMPtr<nsPIPluginInstancePeer> pp (do_QueryInterface(pip));
|
||||
nsCOMPtr<nsPIPluginInstancePeer> pp(do_QueryInterface(inst->Peer()));
|
||||
NS_ENSURE_TRUE(pp, nsnull);
|
||||
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
@@ -204,7 +210,7 @@ GetJSContext(NPP npp)
|
||||
|
||||
|
||||
static NPP
|
||||
FindNPPForJSObject(JSObject *obj, NPObject *npobj);
|
||||
LookupNPP(NPObject *npobj);
|
||||
|
||||
|
||||
static jsval
|
||||
@@ -271,6 +277,8 @@ NPVariantToJSVal(NPP npp, JSContext *cx, const NPVariant *variant)
|
||||
bool
|
||||
JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant)
|
||||
{
|
||||
NS_ASSERTION(npp, "Must have an NPP to wrap a jsval!");
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(val)) {
|
||||
if (val == JSVAL_VOID) {
|
||||
VOID_TO_NPVARIANT(*variant);
|
||||
@@ -304,18 +312,8 @@ JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant)
|
||||
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));
|
||||
NPObject *npobj =
|
||||
nsJSObjWrapper::GetNewOrUsed(npp, cx, JSVAL_TO_OBJECT(val));
|
||||
if (!npobj) {
|
||||
return false;
|
||||
}
|
||||
@@ -329,14 +327,53 @@ JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant)
|
||||
static void
|
||||
ThrowJSException(JSContext *cx, const char *message)
|
||||
{
|
||||
// Add exception throwing code here.
|
||||
const char *ex = PeekException();
|
||||
|
||||
printf ("JS Error: %s\n", message);
|
||||
if (ex) {
|
||||
nsAutoString ucex;
|
||||
|
||||
if (message) {
|
||||
AppendASCIItoUTF16(message, ucex);
|
||||
|
||||
AppendASCIItoUTF16(" [plugin exception: ", ucex);
|
||||
}
|
||||
|
||||
AppendUTF8toUTF16(ex, ucex);
|
||||
|
||||
if (message) {
|
||||
AppendASCIItoUTF16("].", ucex);
|
||||
}
|
||||
|
||||
JSString *str = ::JS_NewUCStringCopyN(cx, (jschar *)ucex.get(),
|
||||
ucex.Length());
|
||||
|
||||
if (str) {
|
||||
::JS_SetPendingException(cx, STRING_TO_JSVAL(str));
|
||||
}
|
||||
|
||||
PopException();
|
||||
} else {
|
||||
::JS_ReportError(cx, message);
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ReportExceptionIfPending(JSContext *cx)
|
||||
{
|
||||
const char *ex = PeekException();
|
||||
|
||||
if (!ex) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
ThrowJSException(cx, nsnull);
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
nsJSObjWrapper::nsJSObjWrapper()
|
||||
: mJSObj(nsnull), mCx(nsnull), mNpp(nsnull)
|
||||
nsJSObjWrapper::nsJSObjWrapper(NPP npp)
|
||||
: nsJSObjWrapperKey(nsnull, npp)
|
||||
{
|
||||
OnWrapperCreated();
|
||||
}
|
||||
@@ -351,9 +388,9 @@ nsJSObjWrapper::~nsJSObjWrapper()
|
||||
|
||||
// static
|
||||
NPObject *
|
||||
nsJSObjWrapper::NP_Allocate()
|
||||
nsJSObjWrapper::NP_Allocate(NPP npp)
|
||||
{
|
||||
return new nsJSObjWrapper;
|
||||
return new nsJSObjWrapper(npp);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -376,13 +413,13 @@ nsJSObjWrapper::NP_Invalidate(NPObject *npobj)
|
||||
|
||||
if (sJSObjWrappers.ops) {
|
||||
// Remove the wrapper from the hash
|
||||
PL_DHashTableOperate(&sJSObjWrappers, jsnpobj->mJSObj, PL_DHASH_REMOVE);
|
||||
|
||||
nsJSObjWrapperKey key(jsnpobj->mJSObj, jsnpobj->mNpp);
|
||||
PL_DHashTableOperate(&sJSObjWrappers, &key, PL_DHASH_REMOVE);
|
||||
}
|
||||
|
||||
// Forget our reference to the JSObject etc.
|
||||
// Forget our reference to the JSObject.
|
||||
jsnpobj->mJSObj = nsnull;
|
||||
jsnpobj->mCx = nsnull;
|
||||
jsnpobj->mNpp = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,16 +446,19 @@ GetProperty(JSContext *cx, JSObject *obj, NPIdentifier identifier, jsval *rval)
|
||||
bool
|
||||
nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier identifier)
|
||||
{
|
||||
if (!npobj) {
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx || !npobj) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
jsval v;
|
||||
JSBool ok = GetProperty(npjsobj->mCx, npjsobj->mJSObj, identifier, &v);
|
||||
JSBool ok = GetProperty(cx, npjsobj->mJSObj, identifier, &v);
|
||||
|
||||
return ok && !JSVAL_IS_PRIMITIVE(v) &&
|
||||
::JS_ObjectIsFunction(npjsobj->mCx, JSVAL_TO_OBJECT(v));
|
||||
::JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(v));
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -427,7 +467,10 @@ nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier,
|
||||
const NPVariant *args, uint32_t argCount,
|
||||
NPVariant *result)
|
||||
{
|
||||
if (!npobj || !result) {
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx || !npobj || !result) {
|
||||
// XXX: Throw null-ptr exception
|
||||
|
||||
return PR_FALSE;
|
||||
@@ -439,10 +482,10 @@ nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier,
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
jsval fv;
|
||||
|
||||
AutoCXPusher pusher(npjsobj->mCx);
|
||||
AutoCXPusher pusher(cx);
|
||||
|
||||
if (!GetProperty(npjsobj->mCx, npjsobj->mJSObj, identifier, &fv) ||
|
||||
::JS_TypeOfValue(npjsobj->mCx, fv) != JSTYPE_FUNCTION) {
|
||||
if (!GetProperty(cx, npjsobj->mJSObj, identifier, &fv) ||
|
||||
::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
@@ -463,18 +506,18 @@ nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier,
|
||||
|
||||
// Convert args
|
||||
for (PRUint32 i = 0; i < argCount; ++i) {
|
||||
jsargs[i] = NPVariantToJSVal(npjsobj->mNpp, npjsobj->mCx, args + i);
|
||||
jsargs[i] = NPVariantToJSVal(npp, cx, args + i);
|
||||
}
|
||||
|
||||
jsval v;
|
||||
JSBool ok = ::JS_CallFunctionValue(npjsobj->mCx, npjsobj->mJSObj, fv,
|
||||
argCount, jsargs, &v);
|
||||
JSBool ok = ::JS_CallFunctionValue(cx, npjsobj->mJSObj, fv, argCount, jsargs,
|
||||
&v);
|
||||
|
||||
if (jsargs != jsargs_buf)
|
||||
PR_Free(jsargs);
|
||||
|
||||
if (ok)
|
||||
ok = JSValToNPVariant(npjsobj->mNpp, npjsobj->mCx, v, result);
|
||||
ok = JSValToNPVariant(npp, cx, v, result);
|
||||
|
||||
// return ok == JS_TRUE to quiet down compiler warning, even if
|
||||
// return ok is what we really want.
|
||||
@@ -485,29 +528,31 @@ nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier,
|
||||
bool
|
||||
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier identifier)
|
||||
{
|
||||
if (!npobj) {
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx || !npobj) {
|
||||
// XXX: Throw null ptr exception
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
jsval id = (jsval)identifier;
|
||||
jsval found;
|
||||
JSBool ok = JS_FALSE;
|
||||
JSBool found, 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);
|
||||
ok = ::JS_HasUCProperty(cx, 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);
|
||||
ok = ::JS_HasElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &found);
|
||||
}
|
||||
|
||||
return ok && !JSVAL_IS_VOID(found);
|
||||
return ok && found;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -515,16 +560,19 @@ bool
|
||||
nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier identifier,
|
||||
NPVariant *result)
|
||||
{
|
||||
if (!npobj)
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx || !npobj)
|
||||
return PR_FALSE;
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
|
||||
AutoCXPusher pusher(npjsobj->mCx);
|
||||
AutoCXPusher pusher(cx);
|
||||
|
||||
jsval v;
|
||||
return GetProperty(npjsobj->mCx, npjsobj->mJSObj, identifier, &v) &&
|
||||
JSValToNPVariant(npjsobj->mNpp, npjsobj->mCx, v, result);
|
||||
return (GetProperty(cx, npjsobj->mJSObj, identifier, &v) &&
|
||||
JSValToNPVariant(npp, cx, v, result));
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -532,27 +580,29 @@ bool
|
||||
nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier,
|
||||
const NPVariant *value)
|
||||
{
|
||||
if (!npobj)
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx || !npobj)
|
||||
return PR_FALSE;
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
jsval id = (jsval)identifier;
|
||||
JSBool ok = JS_FALSE;
|
||||
|
||||
AutoCXPusher pusher(npjsobj->mCx);
|
||||
AutoCXPusher pusher(cx);
|
||||
|
||||
jsval v = NPVariantToJSVal(npjsobj->mNpp, npjsobj->mCx, value);
|
||||
jsval v = NPVariantToJSVal(npp, cx, value);
|
||||
|
||||
if (JSVAL_IS_STRING(id)) {
|
||||
JSString *str = JSVAL_TO_STRING(id);
|
||||
|
||||
ok = ::JS_SetUCProperty(npjsobj->mCx, npjsobj->mJSObj,
|
||||
::JS_GetStringChars(str),
|
||||
ok = ::JS_SetUCProperty(cx, 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);
|
||||
ok = ::JS_SetElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &v);
|
||||
}
|
||||
|
||||
// return ok == JS_TRUE to quiet down compiler warning, even if
|
||||
@@ -564,26 +614,28 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier,
|
||||
bool
|
||||
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier)
|
||||
{
|
||||
if (!npobj)
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx || !npobj)
|
||||
return PR_FALSE;
|
||||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
jsval id = (jsval)identifier;
|
||||
JSBool ok = JS_FALSE;
|
||||
|
||||
AutoCXPusher pusher(npjsobj->mCx);
|
||||
AutoCXPusher pusher(cx);
|
||||
|
||||
if (JSVAL_IS_STRING(id)) {
|
||||
JSString *str = JSVAL_TO_STRING(id);
|
||||
|
||||
jsval unused;
|
||||
ok = ::JS_DeleteUCProperty2(npjsobj->mCx, npjsobj->mJSObj,
|
||||
::JS_GetStringChars(str),
|
||||
ok = ::JS_DeleteUCProperty2(cx, 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));
|
||||
ok = ::JS_DeleteElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id));
|
||||
}
|
||||
|
||||
// return ok == JS_TRUE to quiet down compiler warning, even if
|
||||
@@ -594,27 +646,38 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier identifier)
|
||||
class JSObjWrapperHashEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
nsJSObjWrapper *mNPObj;
|
||||
nsJSObjWrapper *mJSObjWrapper;
|
||||
};
|
||||
|
||||
|
||||
PR_STATIC_CALLBACK(PLDHashNumber)
|
||||
JSObjWrapperHash(PLDHashTable *table, const void *key)
|
||||
{
|
||||
const nsJSObjWrapperKey *e = NS_STATIC_CAST(const nsJSObjWrapperKey *, key);
|
||||
|
||||
return (PLDHashNumber)((PRWord)e->mJSObj ^ (PRWord)e->mNpp) >> 2;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(const void *)
|
||||
NPObjWrapperHashGetKey(PLDHashTable *table, PLDHashEntryHdr *entry)
|
||||
JSObjWrapperHashGetKey(PLDHashTable *table, PLDHashEntryHdr *entry)
|
||||
{
|
||||
JSObjWrapperHashEntry *e =
|
||||
NS_STATIC_CAST(JSObjWrapperHashEntry *, entry);
|
||||
|
||||
return e->mNPObj->mJSObj;
|
||||
return NS_STATIC_CAST(nsJSObjWrapperKey *, e->mJSObjWrapper);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(PRBool)
|
||||
NPObjWrapperHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
|
||||
JSObjWrapperHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
|
||||
const void *key)
|
||||
{
|
||||
const nsJSObjWrapperKey *objWrapperKey =
|
||||
NS_STATIC_CAST(const nsJSObjWrapperKey *, key);
|
||||
const JSObjWrapperHashEntry *e =
|
||||
NS_STATIC_CAST(const JSObjWrapperHashEntry *, entry);
|
||||
|
||||
return e->mNPObj->mJSObj == key;
|
||||
return (e->mJSObjWrapper->mJSObj == objWrapperKey->mJSObj &&
|
||||
e->mJSObjWrapper->mNpp == objWrapperKey->mNpp);
|
||||
}
|
||||
|
||||
|
||||
@@ -659,9 +722,9 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
|
||||
{
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
NPObjWrapperHashGetKey,
|
||||
PL_DHashVoidPtrKeyStub,
|
||||
NPObjWrapperHashMatchEntry,
|
||||
JSObjWrapperHashGetKey,
|
||||
JSObjWrapperHash,
|
||||
JSObjWrapperHashMatchEntry,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub
|
||||
@@ -675,22 +738,24 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
|
||||
}
|
||||
}
|
||||
|
||||
nsJSObjWrapperKey key(obj, npp);
|
||||
|
||||
JSObjWrapperHashEntry *entry =
|
||||
NS_STATIC_CAST(JSObjWrapperHashEntry *,
|
||||
PL_DHashTableOperate(&sJSObjWrappers, obj, PL_DHASH_ADD));
|
||||
PL_DHashTableOperate(&sJSObjWrappers, &key, PL_DHASH_ADD));
|
||||
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mNPObj) {
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mJSObjWrapper) {
|
||||
// Found a live nsJSObjWrapper, return it.
|
||||
|
||||
return _retainobject(entry->mNPObj);
|
||||
return _retainobject(entry->mJSObjWrapper);
|
||||
}
|
||||
|
||||
// No existing nsJSObjWrapper, create one.
|
||||
|
||||
nsJSObjWrapper *npobj =
|
||||
(nsJSObjWrapper *)_createobject(&sJSObjWrapperNPClass);
|
||||
nsJSObjWrapper *wrapper =
|
||||
(nsJSObjWrapper *)_createobject(npp, &sJSObjWrapperNPClass);
|
||||
|
||||
if (!npobj) {
|
||||
if (!wrapper) {
|
||||
// OOM? Remove the stale entry from the hash.
|
||||
|
||||
PL_DHashTableRawRemove(&sJSObjWrappers, entry);
|
||||
@@ -698,25 +763,25 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
entry->mNPObj = npobj;
|
||||
wrapper->mJSObj = obj;
|
||||
|
||||
npobj->mJSObj = obj;
|
||||
npobj->mCx = cx;
|
||||
npobj->mNpp = npp;
|
||||
entry->mJSObjWrapper = wrapper;
|
||||
|
||||
NS_ASSERTION(wrapper->mNpp == npp, "nsJSObjWrapper::mNpp not initialized!");
|
||||
|
||||
// Root the JSObject, its lifetime is now tied to that of the
|
||||
// NPObject.
|
||||
if (!::JS_AddNamedRoot(cx, &npobj->mJSObj, "nsJSObjWrapper::mJSObject")) {
|
||||
if (!::JS_AddNamedRoot(cx, &wrapper->mJSObj, "nsJSObjWrapper::mJSObject")) {
|
||||
NS_ERROR("Failed to root JSObject!");
|
||||
|
||||
_releaseobject(npobj);
|
||||
_releaseobject(wrapper);
|
||||
|
||||
PL_DHashTableRawRemove(&sJSObjWrappers, entry);
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return npobj;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
static NPObject *
|
||||
@@ -755,7 +820,7 @@ NPObjWrapper_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return ReportExceptionIfPending(cx);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
@@ -776,7 +841,7 @@ NPObjWrapper_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return ReportExceptionIfPending(cx);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
@@ -798,8 +863,18 @@ NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
// Find out what plugin (NPP) is the owner of the object we're
|
||||
// manipulating, and make it own any JSObject wrappers created here.
|
||||
NPP npp = LookupNPP(npobj);
|
||||
|
||||
if (!npp) {
|
||||
ThrowJSException(cx, "No NPP found for NPObject!");
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
NPVariant npv;
|
||||
if (!JSValToNPVariant(nsnull, cx, *vp, &npv)) {
|
||||
if (!JSValToNPVariant(npp, cx, *vp, &npv)) {
|
||||
ThrowJSException(cx, "Error converting jsval to NPVariant!");
|
||||
|
||||
return JS_FALSE;
|
||||
@@ -813,9 +888,11 @@ NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
if (!ok) {
|
||||
ThrowJSException(cx, "Error setting property on scriptable plugin "
|
||||
"object!");
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return ok;
|
||||
return ReportExceptionIfPending(cx);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
@@ -841,13 +918,15 @@ NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
NPP npp = nsnull;
|
||||
// Find out what plugin (NPP) is the owner of the object we're
|
||||
// manipulating, and make it own any JSObject wrappers created
|
||||
// here.
|
||||
NPP npp = LookupNPP(npobj);
|
||||
|
||||
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.
|
||||
if (!npp) {
|
||||
ThrowJSException(cx, "No NPP found for NPObject!");
|
||||
|
||||
npp = FindNPPForJSObject(obj, npobj);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*vp = NPVariantToJSVal(npp, cx, &npv);
|
||||
@@ -858,14 +937,14 @@ NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (npobj->_class->hasMethod(npobj, (NPIdentifier)id)) {
|
||||
return PR_TRUE;
|
||||
if (!npobj->_class->hasMethod(npobj, (NPIdentifier)id)) {
|
||||
ThrowJSException(cx, "Trying to get unsupported property on scriptable "
|
||||
"plugin object!");
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
ThrowJSException(cx, "Trying to get unsupported property on scriptable "
|
||||
"plugin object!");
|
||||
|
||||
return JS_FALSE;
|
||||
return ReportExceptionIfPending(cx);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
@@ -890,10 +969,12 @@ CallNPMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
NPP npp = FindNPPForJSObject(obj, npobj);
|
||||
// Find out what plugin (NPP) is the owner of the object we're
|
||||
// manipulating, and make it own any JSObject wrappers created here.
|
||||
NPP npp = LookupNPP(npobj);
|
||||
|
||||
if (!npp) {
|
||||
ThrowJSException(cx, "Error finding NPP for JSObject!");
|
||||
ThrowJSException(cx, "Error finding NPP for NPObject!");
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
@@ -939,8 +1020,9 @@ CallNPMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
_releasevariantvalue(npargs + i);
|
||||
}
|
||||
|
||||
if (npargs != npargs_buf)
|
||||
if (npargs != npargs_buf) {
|
||||
PR_Free(npargs);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
ThrowJSException(cx, "Error calling method on NPObject!");
|
||||
@@ -953,7 +1035,7 @@ CallNPMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
// *rval now owns the value, release our reference.
|
||||
_releasevariantvalue(&v);
|
||||
|
||||
return JS_TRUE;
|
||||
return ReportExceptionIfPending(cx);
|
||||
}
|
||||
|
||||
|
||||
@@ -999,7 +1081,7 @@ NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
||||
return fnc != nsnull;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return ReportExceptionIfPending(cx);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
@@ -1115,7 +1197,7 @@ JSObjWrapperPluginDestroyedCallback(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
{
|
||||
JSObjWrapperHashEntry *entry = (JSObjWrapperHashEntry *)hdr;
|
||||
|
||||
nsJSObjWrapper *npobj = entry->mNPObj;
|
||||
nsJSObjWrapper *npobj = entry->mJSObjWrapper;
|
||||
|
||||
if (npobj->mNpp == arg) {
|
||||
// Prevent invalidate() and _releaseobject() from touching the hash
|
||||
@@ -1183,39 +1265,30 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp)
|
||||
}
|
||||
}
|
||||
|
||||
// Find the NPP for a JSObject or from its NPObject counter-part, if any.
|
||||
|
||||
// Find the NPP for a NPObject.
|
||||
static NPP
|
||||
FindNPPForJSObject(JSObject *obj, NPObject *npobj)
|
||||
LookupNPP(NPObject *npobj)
|
||||
{
|
||||
if (npobj) {
|
||||
if (npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass) {
|
||||
nsJSObjWrapper *jsnpobj = (nsJSObjWrapper *)npobj;
|
||||
if (npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass) {
|
||||
NS_ERROR("NPP requested for NPObject of class "
|
||||
"nsJSObjWrapper::sJSObjWrapperNPClass!\n");
|
||||
|
||||
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;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NPObjWrapperHashEntry *entry =
|
||||
NS_STATIC_CAST(NPObjWrapperHashEntry *,
|
||||
PL_DHashTableOperate(&sNPObjWrappers, npobj,
|
||||
PL_DHASH_ADD));
|
||||
|
||||
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
NS_ASSERTION(entry->mNpp, "Live NPObject entry w/o an NPP!");
|
||||
|
||||
return entry->mNpp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,16 +50,30 @@ public:
|
||||
static void OnPluginDestroy(NPP npp);
|
||||
};
|
||||
|
||||
class nsJSObjWrapper : public NPObject
|
||||
class nsJSObjWrapperKey
|
||||
{
|
||||
public:
|
||||
nsJSObjWrapperKey(JSObject *obj, NPP npp)
|
||||
: mJSObj(obj), mNpp(npp)
|
||||
{
|
||||
}
|
||||
|
||||
JSObject *mJSObj;
|
||||
|
||||
const NPP mNpp;
|
||||
};
|
||||
|
||||
class nsJSObjWrapper : public NPObject,
|
||||
public nsJSObjWrapperKey
|
||||
{
|
||||
public:
|
||||
static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj);
|
||||
|
||||
protected:
|
||||
nsJSObjWrapper();
|
||||
nsJSObjWrapper(NPP npp);
|
||||
~nsJSObjWrapper();
|
||||
|
||||
static NPObject * NP_Allocate();
|
||||
static NPObject * NP_Allocate(NPP npp);
|
||||
static void NP_Deallocate(NPObject *obj);
|
||||
static void NP_Invalidate(NPObject *obj);
|
||||
static bool NP_HasMethod(NPObject *, NPIdentifier identifier);
|
||||
@@ -74,10 +88,6 @@ protected:
|
||||
static bool NP_RemoveProperty(NPObject *obj, NPIdentifier property);
|
||||
|
||||
public:
|
||||
JSObject *mJSObj;
|
||||
JSContext *mCx;
|
||||
NPP mNpp;
|
||||
|
||||
static NPClass sJSObjWrapperNPClass;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user