Bug 1475699 - Support invoking JS-implemented XPIDL methods/attributes marked as [implicit_jscontext]. r=mccr8

This commit is contained in:
Jan de Mooij 2018-07-17 18:11:03 +02:00
parent cdb074baf3
commit ef23676856
35 changed files with 308 additions and 35 deletions

View File

@ -953,11 +953,11 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
if (!cx || !IsReflectable(methodIndex))
return NS_ERROR_FAILURE;
// [implicit_jscontext] and [optional_argc] have a different calling
// convention, which we don't support for JS-implemented components.
if (info->WantsOptArgc() || info->WantsContext()) {
const char* str = "IDL methods marked with [implicit_jscontext] "
"or [optional_argc] may not be implemented in JS";
// [optional_argc] has a different calling convention, which we don't
// support for JS-implemented components.
if (info->WantsOptArgc()) {
const char* str = "IDL methods marked with [optional_argc] may not "
"be implemented in JS";
// Throw and warn for good measure.
JS_ReportErrorASCII(cx, "%s", str);
NS_WARNING(str);

View File

@ -1442,17 +1442,16 @@ CallMethodHelper::InitializeDispatchParams()
const uint8_t wantsJSContext = mMethodInfo->WantsContext() ? 1 : 0;
const uint8_t paramCount = mMethodInfo->GetParamCount();
uint8_t requiredArgs = paramCount;
uint8_t hasRetval = 0;
// XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
if (mMethodInfo->HasRetval()) {
hasRetval = 1;
if (mMethodInfo->HasRetval())
requiredArgs--;
}
if (mArgc < requiredArgs || wantsOptArgc) {
if (wantsOptArgc)
mOptArgcIndex = requiredArgs;
if (wantsOptArgc) {
// The implicit JSContext*, if we have one, comes first.
mOptArgcIndex = requiredArgs + wantsJSContext;
}
// skip over any optional arguments
while (requiredArgs && mMethodInfo->GetParam(requiredArgs-1).IsOptional())
@ -1464,16 +1463,7 @@ CallMethodHelper::InitializeDispatchParams()
}
}
if (wantsJSContext) {
if (wantsOptArgc)
// Need to bump mOptArgcIndex up one here.
mJSContextIndex = mOptArgcIndex++;
else if (mMethodInfo->IsSetter() || mMethodInfo->IsGetter())
// For attributes, we always put the JSContext* first.
mJSContextIndex = 0;
else
mJSContextIndex = paramCount - hasRetval;
}
mJSContextIndex = mMethodInfo->IndexOfJSContext();
// iterate through the params to clear flags (for safe cleanup later)
for (uint8_t i = 0; i < paramCount + wantsJSContext + wantsOptArgc; i++) {

View File

@ -12,7 +12,30 @@ TestBug809674.prototype = {
classID: Components.ID("{2df46559-da21-49bf-b863-0d7b7bbcbc73}"),
/* nsIXPCTestBug809674 */
jsvalProperty: {},
methodWithOptionalArgc() {},
addArgs(x, y) {
return x + y;
},
addSubMulArgs(x, y, subOut, mulOut) {
subOut.value = x - y;
mulOut.value = x * y;
return x + y;
},
addVals(x, y) {
return x + y;
},
addMany(x1, x2, x3, x4, x5, x6, x7, x8) {
return x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8;
},
methodNoArgs() {
return 7;
},
methodNoArgsNoRetVal() {},
valProperty: {value: 42},
uintProperty: 123,
};

View File

@ -8,11 +8,40 @@
/*
* Test interface for https://bugzilla.mozilla.org/show_bug.cgi?id=809674 .
*
* This test makes sure that accessing an attribute marked with
* [implicit_jscontext] will throw without crashing.
* This test makes sure that accessing JS-implemented attributes or methods
* marked with [implicit_jscontext] works as expected.
*
* It also makes sure [optional_argc] is not supported on JS-implemented
* methods.
*/
[scriptable, uuid(2df46559-da21-49bf-b863-0d7b7bbcbc73)]
interface nsIXPCTestBug809674 : nsISupports {
[implicit_jscontext] attribute jsval jsvalProperty;
// Various interesting [implicit_jscontext] cases.
[implicit_jscontext] unsigned long addArgs(in unsigned long x, in unsigned long y);
[implicit_jscontext] unsigned long addSubMulArgs(in unsigned long x, in unsigned long y,
out unsigned long subOut,
out unsigned long mulOut);
[implicit_jscontext] jsval addVals(in jsval x, in jsval y);
[implicit_jscontext] unsigned long methodNoArgs();
[implicit_jscontext] void methodNoArgsNoRetVal();
// When there are many arguments, the context is passed on the stack on
// most platforms.
[implicit_jscontext] unsigned long addMany(in unsigned long x1,
in unsigned long x2,
in unsigned long x3,
in unsigned long x4,
in unsigned long x5,
in unsigned long x6,
in unsigned long x7,
in unsigned long x8);
// Attributes can use [implicit_jscontext], too.
[implicit_jscontext] attribute jsval valProperty;
[implicit_jscontext] attribute unsigned long uintProperty;
// [optional_argc] is not supported.
[optional_argc] void methodWithOptionalArgc();
};

View File

@ -7,22 +7,44 @@ function run_test() {
// Load the component manifest.
Components.manager.autoRegister(do_get_file('../components/js/xpctest.manifest'));
// Test for each component.
test_property_throws("@mozilla.org/js/xpc/test/js/Bug809674;1");
}
function test_property_throws(contractid) {
// Instantiate the object.
var o = Cc[contractid].createInstance(Ci["nsIXPCTestBug809674"]);
var o = Cc["@mozilla.org/js/xpc/test/js/Bug809674;1"].createInstance(Ci["nsIXPCTestBug809674"]);
// Test the initial values.
// Methods marked [implicit_jscontext].
Assert.equal(o.addArgs(12, 34), 46);
var subRes = {}, mulRes = {};
Assert.equal(o.addSubMulArgs(9, 7, subRes, mulRes), 16);
Assert.equal(subRes.value, 2);
Assert.equal(mulRes.value, 63);
Assert.equal(o.addVals("foo", "x"), "foox");
Assert.equal(o.addVals("foo", 1.2), "foo1.2");
Assert.equal(o.addVals(1234, "foo"), "1234foo");
Assert.equal(o.addMany(1, 2, 4, 8, 16, 32, 64, 128), 255);
Assert.equal(o.methodNoArgs(), 7);
Assert.equal(o.methodNoArgsNoRetVal(), undefined);
// Attributes marked [implicit_jscontext].
Assert.equal(o.valProperty.value, 42);
o.valProperty = o;
Assert.equal(o.valProperty, o);
Assert.equal(o.uintProperty, 123);
o.uintProperty++;
Assert.equal(o.uintProperty, 124);
// [optional_argc] is not supported.
try {
o.jsvalProperty;
o.methodWithOptionalArgc();
Assert.ok(false);
} catch (e) {
Assert.ok(true);
Assert.ok(/implicit_jscontext/.test(e))
Assert.ok(/optional_argc/.test(e))
}
}

View File

@ -44,6 +44,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
}
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t next_gpr = 1; // skip first arg which is 'self'
uint32_t next_fpr = 0;
@ -52,6 +54,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (next_gpr < PARAM_GPR_COUNT)
next_gpr++;
else
ap++;
}
if (param.IsOut() || !type.IsArithmetic()) {
if (next_gpr < PARAM_GPR_COUNT) {
dp->val.p = (void*)gprData[next_gpr++];

View File

@ -41,6 +41,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args)
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
// args[0] to args[NUM_ARG_REGS] hold floating point register values
uint64_t* ap = args + NUM_ARG_REGS;
for(i = 0; i < paramCount; i++, ap++)
@ -49,6 +51,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -62,6 +62,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -69,6 +71,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -50,6 +50,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -57,6 +59,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -34,6 +34,8 @@ PrepareAndDispatch(uint32_t methodIndex, nsXPTCStubBase* self, uint32_t* args)
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -41,6 +43,9 @@ PrepareAndDispatch(uint32_t methodIndex, nsXPTCStubBase* self, uint32_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -47,6 +47,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
if (! dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
for(i = 0; i < paramCount; ++i)
{
int isfloat = 0;
@ -54,6 +56,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
MOZ_CRASH("NYI: support implicit JSContext*, bug 1475699");
if(param.IsOut() || !type.IsArithmetic())
{
#ifdef __LP64__

View File

@ -50,6 +50,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
if (! dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
for(i = 0; i < paramCount; ++i)
{
int isfloat = 0;
@ -57,6 +59,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
MOZ_CRASH("NYI: support implicit JSContext*, bug 1475699");
if(param.IsOut() || !type.IsArithmetic())
{
#ifdef __LP64__

View File

@ -38,6 +38,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args)
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
// args[0] to args[NUM_ARG_REGS] hold floating point register values
uint64_t* ap = args + NUM_ARG_REGS;
for(i = 0; i < paramCount; i++, ap++)
@ -46,6 +48,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -34,6 +34,8 @@ extern "C" {
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -41,6 +43,9 @@ extern "C" {
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -35,6 +35,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t gpr = 1, fpr = 0;
for(i = 0; i < paramCount; i++)
@ -43,6 +45,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (gpr < 5)
a_gpr++, gpr++;
else
a_ov++;
}
if(param.IsOut() || !type.IsArithmetic())
{
if (gpr < 5)

View File

@ -35,6 +35,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t gpr = 1, fpr = 0;
for(i = 0; i < paramCount; i++)
@ -43,6 +45,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (gpr < 5)
a_gpr++, gpr++;
else
a_ov++;
}
if(param.IsOut() || !type.IsArithmetic())
{
if (gpr < 5)

View File

@ -42,6 +42,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -49,6 +51,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -48,6 +48,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t iCount = 0;
for(i = 0; i < paramCount; i++)
@ -56,6 +58,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (iCount < PARAM_GPR_COUNT)
iCount++;
else
ap++;
}
if(param.IsOut() || !type.IsArithmetic())
{
if (iCount < PARAM_GPR_COUNT)

View File

@ -51,12 +51,16 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
for(i = 0; i < paramCount; ++i, --args)
{
const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
MOZ_CRASH("NYI: support implicit JSContext*, bug 1475699");
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *args;

View File

@ -64,6 +64,8 @@ PrepareAndDispatch(nsXPTCStubBase* self,
if (! dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint64_t tempu64;
@ -72,6 +74,8 @@ PrepareAndDispatch(nsXPTCStubBase* self,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
MOZ_CRASH("NYI: support implicit JSContext*, bug 1475699");
if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
if (i < FPR_COUNT)
dp->val.d = fprData[i];

View File

@ -47,6 +47,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args, u
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
uint32_t iCount = 0;
uint32_t fpCount = 0;
@ -56,6 +58,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args, u
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (iCount < PARAM_GPR_COUNT)
iCount++;
else
ap++;
}
if(param.IsOut() || !type.IsArithmetic())
{
if (iCount < PARAM_GPR_COUNT)

View File

@ -42,6 +42,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args, u
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t iCount = 0;
uint32_t fpCount = 0;
@ -51,6 +53,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args, u
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (iCount < PARAM_GPR_COUNT)
iCount++;
else
ap++;
}
if(param.IsOut() || !type.IsArithmetic())
{
if (iCount < PARAM_GPR_COUNT)

View File

@ -63,6 +63,8 @@ PrepareAndDispatch(nsXPTCStubBase* self,
if (! dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
uint32_t gpr = 1; // skip one GPR register
#ifndef __NO_FPRS__
@ -76,6 +78,13 @@ PrepareAndDispatch(nsXPTCStubBase* self,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (gpr < GPR_COUNT)
gpr++;
else
ap++;
}
if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
#ifndef __NO_FPRS__
if (fpr < FPR_COUNT)

View File

@ -60,6 +60,8 @@ PrepareAndDispatch(nsXPTCStubBase* self,
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
uint32_t gpr = 1; // skip one GPR register
uint32_t fpr = 0;
@ -71,6 +73,13 @@ PrepareAndDispatch(nsXPTCStubBase* self,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (gpr < GPR_COUNT)
gpr++;
else
ap++;
}
if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
if (fpr < FPR_COUNT)
dp->val.d = fprData[fpr++];

View File

@ -40,6 +40,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -47,6 +49,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -42,6 +42,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -49,6 +51,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
if (type == nsXPTType::T_JSVAL)

View File

@ -37,6 +37,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -44,6 +46,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -59,6 +59,8 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t nr_gpr = 1; // skip one GPR register for 'that'
uint32_t nr_fpr = 0;
@ -69,6 +71,13 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (nr_gpr < GPR_COUNT)
nr_gpr++;
else
ap++;
}
if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
if (nr_fpr < FPR_COUNT)
dp->val.d = fpregs[nr_fpr++];

View File

@ -59,6 +59,8 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t nr_gpr = 1; // skip one GPR register for 'that'
uint32_t nr_fpr = 0;
@ -69,6 +71,13 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (nr_gpr < GPR_COUNT)
nr_gpr++;
else
ap++;
}
if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
if (nr_fpr < FPR_COUNT)
dp->val.d = fpregs[nr_fpr++];

View File

@ -59,6 +59,8 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
if (!dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t nr_gpr = 1; // skip one GPR register for 'that'
uint32_t nr_fpr = 0;
@ -69,6 +71,13 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (nr_gpr < GPR_COUNT)
nr_gpr++;
else
ap++;
}
if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
if (nr_fpr < FPR_COUNT)
dp->val.d = fpregs[nr_fpr++];

View File

@ -34,6 +34,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -41,6 +43,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -46,6 +46,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint32_t* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
@ -53,6 +55,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;

View File

@ -47,6 +47,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t iCount = 0;
@ -56,6 +58,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (iCount < PARAM_GPR_COUNT)
iCount++;
else
ap++;
}
if(param.IsOut() || !type.IsArithmetic())
{
if (iCount < PARAM_GPR_COUNT)

View File

@ -51,6 +51,8 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
NS_ASSERTION(dispatchParams,"no place for params");
const uint8_t indexOfJSContext = info->IndexOfJSContext();
uint64_t* ap = args;
uint32_t iCount = 0;
@ -60,6 +62,13 @@ PrepareAndDispatch(nsXPTCStubBase * self, uint32_t methodIndex,
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if (i == indexOfJSContext) {
if (iCount < PARAM_GPR_COUNT)
iCount++;
else
ap++;
}
if(param.IsOut() || !type.IsArithmetic())
{
if (iCount < PARAM_GPR_COUNT)

View File

@ -423,6 +423,22 @@ struct nsXPTMethodInfo
return mHasRetval ? &Param(mNumParams - 1) : nullptr;
}
// If this is an [implicit_jscontext] method, returns the index of the
// implicit JSContext* argument in the C++ method's argument list.
// Otherwise returns UINT8_MAX.
uint8_t IndexOfJSContext() const {
if (!WantsContext()) {
return UINT8_MAX;
}
if (IsGetter() || IsSetter()) {
// Getters/setters always have the context as first argument.
return 0;
}
// The context comes before the return value, if there is one.
MOZ_ASSERT_IF(HasRetval(), ParamCount() > 0);
return ParamCount() - uint8_t(HasRetval());
}
/////////////////////////////////////////////
// nsXPTMethodInfo backwards compatibility //
/////////////////////////////////////////////