зеркало из https://github.com/mozilla/gecko-dev.git
Bug 574872 - 'Allow XPConnect to pass the JSContext through XPIDL when requested'. r=jst
This commit is contained in:
Родитель
41bf7c2d61
Коммит
24407948af
|
@ -202,7 +202,7 @@ def removeStubMember(memberId, member):
|
|||
|
||||
def addStubMember(memberId, member, traceable):
|
||||
mayTrace = False
|
||||
if member.kind == 'method':
|
||||
if member.kind == 'method' and not member.implicit_jscontext:
|
||||
# This code MUST match writeTraceableQuickStub
|
||||
haveCallee = memberNeedsCallee(member)
|
||||
# Traceable natives support up to MAX_TRACEABLE_NATIVE_ARGS
|
||||
|
@ -255,7 +255,8 @@ def checkStubMember(member, isCustom):
|
|||
|
||||
# Check for unknown properties.
|
||||
for attrname, value in vars(member).items():
|
||||
if value is True and attrname not in ('readonly','optional_argc','traceable'):
|
||||
if value is True and attrname not in ('readonly','optional_argc',
|
||||
'traceable','implicit_jscontext'):
|
||||
raise UserError("%s %s: unrecognized property %r"
|
||||
% (member.kind.capitalize(), memberId,
|
||||
attrname))
|
||||
|
@ -940,6 +941,8 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
|||
if isMethod:
|
||||
comName = header.methodNativeName(member)
|
||||
argv = ['arg' + str(i) for i, p in enumerate(member.params)]
|
||||
if member.implicit_jscontext:
|
||||
argv.append('cx')
|
||||
if member.optional_argc:
|
||||
argv.append('argc - %d' % requiredArgs)
|
||||
if not isVoidType(member.realtype):
|
||||
|
@ -951,6 +954,8 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
|||
args = outParamForm(resultname, member.realtype)
|
||||
else:
|
||||
args = "arg0"
|
||||
if member.implicit_jscontext:
|
||||
args = "cx, " + args
|
||||
|
||||
f.write(" ")
|
||||
if canFail or debugGetter:
|
||||
|
|
|
@ -2120,6 +2120,7 @@ class CallMethodHelper
|
|||
const jsid mIdxValueId;
|
||||
|
||||
nsAutoTArray<nsXPTCVariant, 8> mDispatchParams;
|
||||
uint8 mJSContextIndex; // TODO make const
|
||||
uint8 mOptArgcIndex; // TODO make const
|
||||
|
||||
// Reserve space for one nsAutoString. We don't want the string itself
|
||||
|
@ -2169,6 +2170,8 @@ class CallMethodHelper
|
|||
nsXPTCVariant*
|
||||
GetDispatchParam(uint8 paramIndex)
|
||||
{
|
||||
if (paramIndex >= mJSContextIndex)
|
||||
paramIndex += 1;
|
||||
if (paramIndex >= mOptArgcIndex)
|
||||
paramIndex += 1;
|
||||
return &mDispatchParams[paramIndex];
|
||||
|
@ -2195,6 +2198,7 @@ public:
|
|||
, mCallee(ccx.GetTearOff()->GetNative())
|
||||
, mVTableIndex(ccx.GetMethodIndex())
|
||||
, mIdxValueId(ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_VALUE))
|
||||
, mJSContextIndex(PR_UINT8_MAX)
|
||||
, mOptArgcIndex(PR_UINT8_MAX)
|
||||
, mArgv(ccx.GetArgv())
|
||||
, mArgc(ccx.GetArgc())
|
||||
|
@ -2656,12 +2660,17 @@ JSBool
|
|||
CallMethodHelper::InitializeDispatchParams()
|
||||
{
|
||||
const uint8 wantsOptArgc = mMethodInfo->WantsOptArgc() ? 1 : 0;
|
||||
const uint8 wantsJSContext = mMethodInfo->WantsContext() ? 1 : 0;
|
||||
const uint8 paramCount = mMethodInfo->GetParamCount();
|
||||
uint8 requiredArgs = paramCount;
|
||||
uint8 hasRetval = 0;
|
||||
|
||||
// XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
|
||||
if(paramCount && mMethodInfo->GetParam(paramCount-1).IsRetval())
|
||||
{
|
||||
hasRetval = 1;
|
||||
requiredArgs--;
|
||||
}
|
||||
|
||||
if(mArgc < requiredArgs || wantsOptArgc)
|
||||
{
|
||||
|
@ -2678,14 +2687,31 @@ CallMethodHelper::InitializeDispatchParams()
|
|||
}
|
||||
}
|
||||
|
||||
if(wantsJSContext)
|
||||
{
|
||||
if(wantsOptArgc)
|
||||
// Need to bump mOptArgcIndex up one here.
|
||||
mJSContextIndex = mOptArgcIndex++;
|
||||
else
|
||||
mJSContextIndex = paramCount - hasRetval;
|
||||
}
|
||||
|
||||
// iterate through the params to clear flags (for safe cleanup later)
|
||||
for(uint8 i = 0; i < paramCount + wantsOptArgc; i++)
|
||||
for(uint8 i = 0; i < paramCount + wantsJSContext + wantsOptArgc; i++)
|
||||
{
|
||||
nsXPTCVariant* dp = mDispatchParams.AppendElement();
|
||||
dp->ClearFlags();
|
||||
dp->val.p = nsnull;
|
||||
}
|
||||
|
||||
// Fill in the JSContext argument
|
||||
if(wantsJSContext)
|
||||
{
|
||||
nsXPTCVariant* dp = &mDispatchParams[mJSContextIndex];
|
||||
dp->type = nsXPTType::T_VOID;
|
||||
dp->val.p = mCallContext;
|
||||
}
|
||||
|
||||
// Fill in the optional_argc argument
|
||||
if(wantsOptArgc)
|
||||
{
|
||||
|
|
|
@ -640,6 +640,7 @@ class Attribute(object):
|
|||
noscript = False
|
||||
notxpcom = False
|
||||
readonly = False
|
||||
implicit_jscontext = False
|
||||
binaryname = None
|
||||
null = None
|
||||
undefined = None
|
||||
|
@ -689,6 +690,8 @@ class Attribute(object):
|
|||
self.noscript = True
|
||||
elif name == 'notxpcom':
|
||||
self.notxpcom = True
|
||||
elif name == 'implicit_jscontext':
|
||||
self.implicit_jscontext = True
|
||||
else:
|
||||
raise IDLError("Unexpected attribute '%s'", aloc)
|
||||
|
||||
|
@ -722,6 +725,7 @@ class Method(object):
|
|||
noscript = False
|
||||
notxpcom = False
|
||||
binaryname = None
|
||||
implicit_jscontext = False
|
||||
optional_argc = False
|
||||
|
||||
def __init__(self, type, name, attlist, paramlist, location, doccomments, raises):
|
||||
|
@ -749,6 +753,8 @@ class Method(object):
|
|||
self.noscript = True
|
||||
elif name == 'notxpcom':
|
||||
self.notxpcom = True
|
||||
elif name == 'implicit_jscontext':
|
||||
self.implicit_jscontext = True
|
||||
elif name == 'optional_argc':
|
||||
self.optional_argc = True
|
||||
else:
|
||||
|
|
|
@ -183,6 +183,7 @@ public:
|
|||
PRBool IsConstructor() const {return 0 != (XPT_MD_IS_CTOR(flags) );}
|
||||
PRBool IsHidden() const {return 0 != (XPT_MD_IS_HIDDEN(flags) );}
|
||||
PRBool WantsOptArgc() const {return 0 != (XPT_MD_WANTS_OPT_ARGC(flags));}
|
||||
PRBool WantsContext() const {return 0 != (XPT_MD_WANTS_CONTEXT(flags));}
|
||||
const char* GetName() const {return name;}
|
||||
PRUint8 GetParamCount() const {return num_args;}
|
||||
/* idx was index before I got _sick_ of the warnings on Unix, sorry jband */
|
||||
|
|
|
@ -778,6 +778,11 @@ write_attr_accessor(IDL_tree attr_tree, FILE * outfile,
|
|||
toupper(*attrname),
|
||||
attrname + 1);
|
||||
}
|
||||
if (IDL_tree_property_get(ident, "implicit_jscontext")) {
|
||||
if (mode == AS_DECL || mode == AS_IMPL)
|
||||
fputs("JSContext *", outfile);
|
||||
fputs("cx, ", outfile);
|
||||
}
|
||||
if (mode == AS_DECL || mode == AS_IMPL) {
|
||||
/* Setters for string, wstring, nsid, domstring, utf8string,
|
||||
* cstring and astring get const.
|
||||
|
@ -1041,6 +1046,8 @@ write_method_signature(IDL_tree method_tree, FILE *outfile, int mode,
|
|||
(IDL_tree_property_get(op->ident, "notxpcom") != NULL);
|
||||
gboolean op_opt_argc =
|
||||
(IDL_tree_property_get(op->ident, "optional_argc") != NULL);
|
||||
gboolean op_context =
|
||||
(IDL_tree_property_get(op->ident, "implicit_jscontext") != NULL);
|
||||
const char *name;
|
||||
const char *binaryname;
|
||||
IDL_tree iter;
|
||||
|
@ -1097,6 +1104,19 @@ write_method_signature(IDL_tree method_tree, FILE *outfile, int mode,
|
|||
no_generated_args = FALSE;
|
||||
}
|
||||
|
||||
if (op_context) {
|
||||
if ((op_notxpcom || !op->op_type_spec) && !op->f_varargs)
|
||||
fputs(", ", outfile);
|
||||
|
||||
if (mode == AS_DECL || mode == AS_IMPL)
|
||||
fputs("JSContext *", outfile);
|
||||
|
||||
fputs("cx", outfile);
|
||||
|
||||
if ((!op_notxpcom && op->op_type_spec) || op->f_varargs)
|
||||
fputs(", ", outfile);
|
||||
}
|
||||
|
||||
if (op_opt_argc) {
|
||||
if ((op_notxpcom || !op->op_type_spec) && !op->f_varargs)
|
||||
fputs(", ", outfile);
|
||||
|
|
|
@ -1017,13 +1017,14 @@ fill_pd_as_nsresult(XPTParamDescriptor *pd)
|
|||
|
||||
static gboolean
|
||||
typelib_attr_accessor(TreeState *state, XPTMethodDescriptor *meth,
|
||||
gboolean getter, gboolean hidden)
|
||||
gboolean getter, gboolean hidden, gboolean wantsJSContext)
|
||||
{
|
||||
uint8 methflags = 0;
|
||||
uint8 pdflags = 0;
|
||||
|
||||
methflags |= getter ? XPT_MD_GETTER : XPT_MD_SETTER;
|
||||
methflags |= hidden ? XPT_MD_HIDDEN : 0;
|
||||
methflags |= wantsJSContext ? XPT_MD_CONTEXT : 0;
|
||||
if (!XPT_FillMethodDescriptor(ARENA(state), meth, methflags,
|
||||
ATTR_IDENT(state->tree).str, 1))
|
||||
return FALSE;
|
||||
|
@ -1061,6 +1062,9 @@ typelib_attr_dcl(TreeState *state)
|
|||
/* If it's marked [noscript], mark it as hidden in the typelib. */
|
||||
gboolean hidden = (IDL_tree_property_get(ident, "noscript") != NULL);
|
||||
|
||||
gboolean wantsJSContext =
|
||||
(IDL_tree_property_get(ident, "implicit_jscontext") != NULL);
|
||||
|
||||
if (!verify_attribute_declaration(state->tree))
|
||||
return FALSE;
|
||||
|
||||
|
@ -1070,8 +1074,9 @@ typelib_attr_dcl(TreeState *state)
|
|||
|
||||
meth = &id->method_descriptors[NEXT_METH(state)];
|
||||
|
||||
return typelib_attr_accessor(state, meth, TRUE, hidden) &&
|
||||
(read_only || typelib_attr_accessor(state, meth + 1, FALSE, hidden));
|
||||
return typelib_attr_accessor(state, meth, TRUE, hidden, wantsJSContext) &&
|
||||
(read_only ||
|
||||
typelib_attr_accessor(state, meth + 1, FALSE, hidden, wantsJSContext));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1087,6 +1092,8 @@ typelib_op_dcl(TreeState *state)
|
|||
!= NULL);
|
||||
gboolean op_noscript = (IDL_tree_property_get(op->ident, "noscript")
|
||||
!= NULL);
|
||||
gboolean op_context = (IDL_tree_property_get(op->ident,
|
||||
"implicit_jscontext") != NULL);
|
||||
gboolean op_opt_argc = (IDL_tree_property_get(op->ident, "optional_argc")
|
||||
!= NULL);
|
||||
|
||||
|
@ -1109,6 +1116,8 @@ typelib_op_dcl(TreeState *state)
|
|||
op_flags |= XPT_MD_NOTXPCOM;
|
||||
if (op_opt_argc)
|
||||
op_flags |= XPT_MD_OPT_ARGC;
|
||||
if (op_context)
|
||||
op_flags |= XPT_MD_CONTEXT;
|
||||
|
||||
/* XXXshaver constructor? */
|
||||
|
||||
|
|
|
@ -487,7 +487,8 @@ struct XPTMethodDescriptor {
|
|||
#define XPT_MD_CTOR 0x10
|
||||
#define XPT_MD_HIDDEN 0x08
|
||||
#define XPT_MD_OPT_ARGC 0x04
|
||||
#define XPT_MD_FLAGMASK 0xfc
|
||||
#define XPT_MD_CONTEXT 0x02
|
||||
#define XPT_MD_FLAGMASK 0xfe
|
||||
|
||||
#define XPT_MD_IS_GETTER(flags) (flags & XPT_MD_GETTER)
|
||||
#define XPT_MD_IS_SETTER(flags) (flags & XPT_MD_SETTER)
|
||||
|
@ -495,6 +496,7 @@ struct XPTMethodDescriptor {
|
|||
#define XPT_MD_IS_CTOR(flags) (flags & XPT_MD_CTOR)
|
||||
#define XPT_MD_IS_HIDDEN(flags) (flags & XPT_MD_HIDDEN)
|
||||
#define XPT_MD_WANTS_OPT_ARGC(flags) (flags & XPT_MD_OPT_ARGC)
|
||||
#define XPT_MD_WANTS_CONTEXT(flags) (flags & XPT_MD_CONTEXT)
|
||||
|
||||
extern XPT_PUBLIC_API(PRBool)
|
||||
XPT_FillMethodDescriptor(XPTArena *arena,
|
||||
|
|
|
@ -63,7 +63,7 @@ static char *type_array[32] =
|
|||
"wchar_t", "void", "reserved", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"reserved", "reserved", "jsval", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved"};
|
||||
|
||||
static char *ptype_array[32] =
|
||||
|
@ -73,7 +73,7 @@ static char *ptype_array[32] =
|
|||
"wchar_t *", "void *", "nsIID *", "DOMString *",
|
||||
"string", "wstring", "Interface *", "InterfaceIs *",
|
||||
"array", "string_s", "wstring_s", "UTF8String *",
|
||||
"CString *", "AString *", "reserved", "reserved",
|
||||
"CString *", "AString *", "jsval *", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved"};
|
||||
|
||||
static char *rtype_array[32] =
|
||||
|
@ -83,7 +83,7 @@ static char *rtype_array[32] =
|
|||
"wchar_t &", "void &", "nsIID &", "DOMString &",
|
||||
"string &", "wstring &", "Interface &", "InterfaceIs &",
|
||||
"array &", "string_s &", "wstring_s &", "UTF8String &",
|
||||
"CString &", "AString &", "reserved", "reserved",
|
||||
"CString &", "AString &", "jsval &", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved"};
|
||||
|
||||
PRBool param_problems = PR_FALSE;
|
||||
|
@ -579,6 +579,12 @@ XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
|
|||
else
|
||||
fprintf(stdout, "FALSE\n");
|
||||
|
||||
fprintf(stdout, "%*sWants JSContext? ", indent, " ");
|
||||
if (XPT_MD_WANTS_CONTEXT(md->flags))
|
||||
fprintf(stdout, "TRUE\n");
|
||||
else
|
||||
fprintf(stdout, "FALSE\n");
|
||||
|
||||
fprintf(stdout, "%*s# of arguments: %d\n", indent, " ", md->num_args);
|
||||
fprintf(stdout, "%*sParameter Descriptors:\n", indent, " ");
|
||||
|
||||
|
@ -602,13 +608,14 @@ XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
|
|||
if (!XPT_GetStringForType(header, &md->result->type, id, ¶m_type)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
fprintf(stdout, "%*s%c%c%c%c%c%c %s %s(", indent - 6, " ",
|
||||
fprintf(stdout, "%*s%c%c%c%c%c%c%c %s %s(", indent - 6, " ",
|
||||
XPT_MD_IS_GETTER(md->flags) ? 'G' : ' ',
|
||||
XPT_MD_IS_SETTER(md->flags) ? 'S' : ' ',
|
||||
XPT_MD_IS_HIDDEN(md->flags) ? 'H' : ' ',
|
||||
XPT_MD_IS_NOTXPCOM(md->flags) ? 'N' : ' ',
|
||||
XPT_MD_IS_CTOR(md->flags) ? 'C' : ' ',
|
||||
XPT_MD_WANTS_OPT_ARGC(md->flags) ? 'O' : ' ',
|
||||
XPT_MD_WANTS_CONTEXT(md->flags) ? 'J' : ' ',
|
||||
param_type, md->name);
|
||||
for (i=0; i<md->num_args; i++) {
|
||||
if (i!=0) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче