Fixing bug 257191. Adding NPN_InvokeDefault() and renaming NPN_Call() to NPN_Invoke() in the npruntime plugin scriptability API. Also fix a problem with property getters on plugin objects. r+sr=brendan@mozilla.org

This commit is contained in:
jst%mozilla.jstenback.com 2004-08-30 04:31:16 +00:00
Родитель 4f147d417a
Коммит 2e81de8496
8 изменённых файлов: 199 добавлений и 39 удалений

Просмотреть файл

@ -380,7 +380,8 @@ static const char kDOMStringBundleURL[] =
#define EXTERNAL_OBJ_SCRIPTABLE_FLAGS \
(ELEMENT_SCRIPTABLE_FLAGS & ~nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY | \
nsIXPCScriptable::WANT_SETPROPERTY)
nsIXPCScriptable::WANT_SETPROPERTY | \
nsIXPCScriptable::WANT_CALL)
#define DOCUMENT_SCRIPTABLE_FLAGS \
(NODE_SCRIPTABLE_FLAGS | \
@ -6895,7 +6896,6 @@ nsHTMLExternalObjSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPluginInstance> pi;
rv = GetPluginInstance(wrapper, getter_AddRefs(pi));
NS_ENSURE_SUCCESS(rv, rv);
@ -7037,6 +7037,40 @@ nsHTMLExternalObjSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
return nsElementSH::SetProperty(wrapper, cx, obj, id, vp, _retval);
}
NS_IMETHODIMP
nsHTMLExternalObjSH::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 argc, jsval *argv, jsval *vp,
PRBool *_retval)
{
nsCOMPtr<nsIPluginInstance> pi;
nsresult rv = GetPluginInstance(wrapper, getter_AddRefs(pi));
NS_ENSURE_SUCCESS(rv, rv);
if (!pi) {
// No plugin around for this object.
return NS_ERROR_NOT_AVAILABLE;
}
JSObject *pi_obj = nsnull;
JSObject *pi_proto = nsnull;
rv = GetPluginJSObject(cx, obj, pi, &pi_obj, &pi_proto);
NS_ENSURE_SUCCESS(rv, rv);
if (!pi) {
return NS_ERROR_NOT_AVAILABLE;
}
// XPConnect passes us the XPConnect wrapper JSObject as obj, and
// not the 'this' parameter that the JS engine passes in. Pass in
// the real this parameter from JS (argv[-1]) here.
*_retval = ::JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(argv[-1]),
OBJECT_TO_JSVAL(pi_obj), argc, argv, vp);
return NS_OK;
}
// HTMLAppletElement helper

Просмотреть файл

@ -866,6 +866,9 @@ public:
JSObject *obj);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 argc, jsval *argv, jsval *vp,
PRBool *_retval);
};

Просмотреть файл

@ -281,6 +281,10 @@ typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
const NPVariant *args, uint32_t argCount,
NPVariant *result);
typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
const NPVariant *args,
uint32_t argCount,
NPVariant *result);
typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
NPVariant *result);
@ -315,6 +319,7 @@ struct NPClass
NPInvalidateFunctionPtr invalidate;
NPHasMethodFunctionPtr hasMethod;
NPInvokeFunctionPtr invoke;
NPInvokeDefaultFunctionPtr invokeDefault;
NPHasPropertyFunctionPtr hasProperty;
NPGetPropertyFunctionPtr getProperty;
NPSetPropertyFunctionPtr setProperty;
@ -363,8 +368,10 @@ void NPN_ReleaseObject(NPObject *npobj);
on which the plugin was initialized.
*/
bool NPN_Call(NPP npp, NPObject *npobj, NPIdentifier methodName,
const NPVariant *args, uint32_t argCount, NPVariant *result);
bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
const NPVariant *args, uint32_t argCount, NPVariant *result);
bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result);
bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,
NPVariant *result);
bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,

Просмотреть файл

@ -37,7 +37,7 @@
/*
* npupp.h $Revision: 3.18 $
* npupp.h $Revision: 3.19 $
* function call mecahnics needed by platform specific glue code.
*/
@ -1300,13 +1300,13 @@ typedef void (* NP_LOADDS NPN_ReleaseObjectUPP)(NPObject *obj);
#endif
/* NPN_Call */
/* NPN_Invoke */
#if _NPUPP_USE_UPP_
typedef UniversalProcPtr NPN_CallUPP;
typedef UniversalProcPtr NPN_InvokeUPP;
enum {
uppNPN_CallProcInfo = kThinkCStackBased
uppNPN_InvokeProcInfo = 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)))
@ -1316,21 +1316,51 @@ enum {
| 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, ARG6) \
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_CallProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6))
#define NewNPN_InvokeProc(FUNC) \
(NPN_InvokeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_InvokeProcInfo, GetCurrentArchitecture())
#define CallNPN_InvokeProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_InvokeProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6))
#else
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, ARG6) \
typedef bool (* NP_LOADDS NPN_InvokeUPP)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
#define NewNPN_InvokeProc(FUNC) \
((NPN_InvokeUPP) (FUNC))
#define CallNPN_InvokeProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
(*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6))
#endif
/* NPN_InvokeDefault */
#if _NPUPP_USE_UPP_
typedef UniversalProcPtr NPN_InvokeDefaultUPP;
enum {
uppNPN_InvokeDefaultProcInfo = kThinkCStackBased
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPObject*)))
| 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_InvokeDefaultProc(FUNC) \
(NPN_InvokeDefaultUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_InvokeDefaultProcInfo, GetCurrentArchitecture())
#define CallNPN_InvokeDefaultProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_InvokeDefaultProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5))
#else
typedef bool (* NP_LOADDS NPN_InvokeDefaultUPP)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
#define NewNPN_InvokeDefaultProc(FUNC) \
((NPN_InvokeDefaultUPP) (FUNC))
#define CallNPN_InvokeDefaultProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \
(*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5))
#endif
/* NPN_Evaluate */
#if _NPUPP_USE_UPP_
@ -1620,7 +1650,8 @@ typedef struct _NPNetscapeFuncs {
NPN_CreateObjectUPP createobject;
NPN_RetainObjectUPP retainobject;
NPN_ReleaseObjectUPP releaseobject;
NPN_CallUPP call;
NPN_InvokeUPP invoke;
NPN_InvokeDefaultUPP invokeDefault;
NPN_EvaluateUPP evaluate;
NPN_GetPropertyUPP getproperty;
NPN_SetPropertyUPP setproperty;

Просмотреть файл

@ -350,8 +350,11 @@ ns4xPlugin::CheckClassInitialized(void)
CALLBACKS.releaseobject =
NewNPN_ReleaseObjectProc(FP2TV(_releaseobject));
CALLBACKS.call =
NewNPN_CallProc(FP2TV(_call));
CALLBACKS.invoke =
NewNPN_InvokeProc(FP2TV(_invoke));
CALLBACKS.invokeDefault =
NewNPN_InvokeDefaultProc(FP2TV(_invokeDefault));
CALLBACKS.evaluate =
NewNPN_EvaluateProc(FP2TV(_evaluate));
@ -1507,8 +1510,8 @@ _releaseobject(NPObject* npobj)
}
bool NP_EXPORT
_call(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
uint32_t argCount, NPVariant *result)
_invoke(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
if (!npp || !npobj || !npobj->_class || !npobj->_class->invoke)
return false;
@ -1519,6 +1522,19 @@ _call(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
return npobj->_class->invoke(npobj, method, args, argCount, result);
}
bool NP_EXPORT
_invokeDefault(NPP npp, NPObject* npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
if (!npp || !npobj || !npobj->_class || !npobj->_class->invokeDefault)
return false;
NPPExceptionAutoHolder nppExceptionHolder;
NPPAutoPusher nppPusher(npp);
return npobj->_class->invokeDefault(npobj, args, argCount, result);
}
bool NP_EXPORT
_evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
{

Просмотреть файл

@ -216,8 +216,12 @@ void NP_EXPORT
_releaseobject(NPObject* npobj);
bool NP_EXPORT
_call(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
uint32_t argCount, NPVariant *result);
_invoke(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
uint32_t argCount, NPVariant *result);
bool NP_EXPORT
_invokeDefault(NPP npp, NPObject* npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result);
bool NP_EXPORT
_evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result);

Просмотреть файл

@ -96,6 +96,7 @@ NPClass nsJSObjWrapper::sJSObjWrapperNPClass =
nsJSObjWrapper::NP_Invalidate,
nsJSObjWrapper::NP_HasMethod,
nsJSObjWrapper::NP_Invoke,
nsJSObjWrapper::NP_InvokeDefault,
nsJSObjWrapper::NP_HasProperty,
nsJSObjWrapper::NP_GetProperty,
nsJSObjWrapper::NP_SetProperty,
@ -121,13 +122,18 @@ NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JS_STATIC_DLL_CALLBACK(void)
NPObjWrapper_Finalize(JSContext *cx, JSObject *obj);
JS_STATIC_DLL_CALLBACK(JSBool)
NPObjWrapper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
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
NPObjWrapper_Finalize, nsnull, nsnull, NPObjWrapper_Call, nsnull, nsnull,
nsnull
};
@ -464,11 +470,9 @@ nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier identifier)
::JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(v));
}
// static
bool
nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier,
const NPVariant *args, uint32_t argCount,
NPVariant *result)
static bool
doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
@ -487,9 +491,13 @@ nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier,
AutoCXPusher pusher(cx);
if (!GetProperty(cx, npjsobj->mJSObj, identifier, &fv) ||
::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
return PR_FALSE;
if ((jsval)method != JSVAL_VOID) {
if (!GetProperty(cx, npjsobj->mJSObj, method, &fv) ||
::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
return PR_FALSE;
}
} else {
fv = OBJECT_TO_JSVAL(npjsobj->mJSObj);
}
jsval jsargs_buf[8];
@ -527,6 +535,27 @@ nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier identifier,
return ok == JS_TRUE;
}
// static
bool
nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier method,
const NPVariant *args, uint32_t argCount,
NPVariant *result)
{
if ((jsval)method == JSVAL_VOID) {
return PR_FALSE;
}
return doInvoke(npobj, method, args, argCount, result);
}
// static
bool
nsJSObjWrapper::NP_InvokeDefault(NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
return doInvoke(npobj, (NPIdentifier)JSVAL_VOID, args, argCount, result);
}
// static
bool
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier identifier)
@ -982,11 +1011,6 @@ CallNPMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
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;
@ -1015,8 +1039,23 @@ CallNPMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
NPVariant v;
VOID_TO_NPVARIANT(v);
JSBool ok = npobj->_class->invoke(npobj, (NPIdentifier)method, npargs, argc,
&v);
JSObject *funobj = JSVAL_TO_OBJECT(argv[-2]);
JSBool ok;
if (funobj != obj) {
// A obj.function() style call is made, get the method name from
// the function object.
JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj);
jsval method = STRING_TO_JSVAL(::JS_GetFunctionId(fun));
ok = npobj->_class->invoke(npobj, (NPIdentifier)method, npargs, argc, &v);
} else {
// obj is a callable object that is being called, no method name
// available then. Invoke the default method.
ok = npobj->_class->invokeDefault(npobj, npargs, argc, &v);
}
// Release arguments.
for (i = 0; i < argc; ++i) {
@ -1056,6 +1095,24 @@ NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
}
if (npobj->_class->hasProperty(npobj, (NPIdentifier)id)) {
JSBool ok;
if (JSVAL_IS_STRING(id)) {
JSString *str = JSVAL_TO_STRING(id);
ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE);
} else {
ok = ::JS_DefineElement(cx, obj, JSVAL_TO_INT(id), JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE);
}
if (!ok) {
return JS_FALSE;
}
*objp = obj;
} else if (npobj->_class->hasMethod(npobj, (NPIdentifier)id)) {
JSString *str = nsnull;
@ -1104,6 +1161,12 @@ NPObjWrapper_Finalize(JSContext *cx, JSObject *obj)
OnWrapperDestroyed();
}
JS_STATIC_DLL_CALLBACK(JSBool)
NPObjWrapper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
return CallNPMethod(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
}
class NPObjWrapperHashEntry : public PLDHashEntryHdr
{

Просмотреть файл

@ -80,6 +80,8 @@ protected:
static bool NP_Invoke(NPObject *obj, NPIdentifier method,
const NPVariant *args, uint32_t argCount,
NPVariant *result);
static bool NP_InvokeDefault(NPObject *obj, 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);