diff --git a/mozilla/dom/src/base/nsDOMClassInfo.cpp b/mozilla/dom/src/base/nsDOMClassInfo.cpp index 721aca116e1..a37bfc35472 100644 --- a/mozilla/dom/src/base/nsDOMClassInfo.cpp +++ b/mozilla/dom/src/base/nsDOMClassInfo.cpp @@ -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 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 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 diff --git a/mozilla/dom/src/base/nsDOMClassInfo.h b/mozilla/dom/src/base/nsDOMClassInfo.h index 0ba7de304bf..11dd0671b4f 100644 --- a/mozilla/dom/src/base/nsDOMClassInfo.h +++ b/mozilla/dom/src/base/nsDOMClassInfo.h @@ -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); }; diff --git a/mozilla/modules/plugin/base/public/npruntime.h b/mozilla/modules/plugin/base/public/npruntime.h index dc53d5fed09..2d1dc0253f4 100644 --- a/mozilla/modules/plugin/base/public/npruntime.h +++ b/mozilla/modules/plugin/base/public/npruntime.h @@ -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, diff --git a/mozilla/modules/plugin/base/public/npupp.h b/mozilla/modules/plugin/base/public/npupp.h index f9c182c5954..dc8dbb3f5ca 100644 --- a/mozilla/modules/plugin/base/public/npupp.h +++ b/mozilla/modules/plugin/base/public/npupp.h @@ -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; diff --git a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp index aeb82e1f28a..66a0b0134d8 100644 --- a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp @@ -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) { diff --git a/mozilla/modules/plugin/base/src/ns4xPlugin.h b/mozilla/modules/plugin/base/src/ns4xPlugin.h index 459529398a5..2468b77ea52 100644 --- a/mozilla/modules/plugin/base/src/ns4xPlugin.h +++ b/mozilla/modules/plugin/base/src/ns4xPlugin.h @@ -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); diff --git a/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp b/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp index 5af38839a6e..0fb1fc46e34 100644 --- a/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp +++ b/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp @@ -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 { diff --git a/mozilla/modules/plugin/base/src/nsJSNPRuntime.h b/mozilla/modules/plugin/base/src/nsJSNPRuntime.h index daa19a77673..a432299ff5a 100644 --- a/mozilla/modules/plugin/base/src/nsJSNPRuntime.h +++ b/mozilla/modules/plugin/base/src/nsJSNPRuntime.h @@ -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);