зеркало из https://github.com/mozilla/gecko-dev.git
NOT YET PART Of SEAMONKEY - fixes for conversions, added 'load' to test program to breakout js code into its own file, added support for global object being a wrapped native, fixed parent interface support, change makefiles for JS_THREADSAFE, add missing dropProperty support to my Ops, added more tests
This commit is contained in:
Родитель
fe8a88eaf3
Коммит
cc5872f551
|
@ -28,7 +28,7 @@ DLL =.\$(OBJDIR)\$(DLLNAME).dll
|
|||
MODULE=xpconnect
|
||||
REQUIRES=xpcom js
|
||||
|
||||
DEFINES=-DWIN32_LEAN_AND_MEAN -DEXPORT_XPC_API
|
||||
DEFINES=-DWIN32_LEAN_AND_MEAN -DEXPORT_XPC_API -DJS_THREADSAFE -DDEBUG
|
||||
|
||||
OBJS= \
|
||||
.\$(OBJDIR)\xpt_cpp.obj \
|
||||
|
|
|
@ -114,6 +114,11 @@ public:
|
|||
NS_IMETHOD InitJSContext(JSContext* aJSContext,
|
||||
JSObject* aGlobalJSObj) = 0;
|
||||
|
||||
NS_IMETHOD InitJSContextWithNewWrappedGlobal(JSContext* aJSContext,
|
||||
nsISupports* aCOMObj,
|
||||
REFNSIID aIID,
|
||||
nsIXPConnectWrappedNative** aWrapper) = 0;
|
||||
|
||||
NS_IMETHOD WrapNative(JSContext* aJSContext,
|
||||
nsISupports* aCOMObj,
|
||||
REFNSIID aIID,
|
||||
|
|
|
@ -110,6 +110,8 @@ nsXPConnect::nsXPConnect()
|
|||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
nsXPCWrappedNativeClass::OneTimeInit();
|
||||
mContextMap = JSContext2XPCContextMap::newMap(CONTEXT_MAP_SIZE);
|
||||
mArbitraryScriptable = new nsXPCArbitraryScriptable();
|
||||
|
||||
|
@ -140,21 +142,60 @@ NS_IMETHODIMP
|
|||
nsXPConnect::InitJSContext(JSContext* aJSContext,
|
||||
JSObject* aGlobalJSObj)
|
||||
{
|
||||
if(!aJSContext || !aGlobalJSObj ||
|
||||
mContextMap->Find(aJSContext) || !NewContext(aJSContext, aGlobalJSObj))
|
||||
if(aJSContext)
|
||||
{
|
||||
NS_ASSERTION(0,"nsXPConnect::InitJSContext failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
if(!aGlobalJSObj)
|
||||
aGlobalJSObj = JS_GetGlobalObject(aJSContext);
|
||||
if(aGlobalJSObj &&
|
||||
!mContextMap->Find(aJSContext) &&
|
||||
NewContext(aJSContext, aGlobalJSObj))
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(0,"nsXPConnect::InitJSContext failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::InitJSContextWithNewWrappedGlobal(JSContext* aJSContext,
|
||||
nsISupports* aCOMObj,
|
||||
REFNSIID aIID,
|
||||
nsIXPConnectWrappedNative** aWrapper)
|
||||
{
|
||||
nsXPCWrappedNative* wrapper = NULL;
|
||||
XPCContext* xpcc = NULL;
|
||||
if(!mContextMap->Find(aJSContext) &&
|
||||
NULL != (xpcc = NewContext(aJSContext, NULL, JS_FALSE)))
|
||||
{
|
||||
wrapper = nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj, aIID);
|
||||
if(wrapper)
|
||||
{
|
||||
if(JS_InitStandardClasses(aJSContext, wrapper->GetJSObject()) &&
|
||||
xpcc->Init(wrapper->GetJSObject()))
|
||||
{
|
||||
*aWrapper = wrapper;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
if(wrapper)
|
||||
NS_RELEASE(wrapper);
|
||||
if(xpcc)
|
||||
{
|
||||
mContextMap->Remove(xpcc);
|
||||
delete xpcc;
|
||||
}
|
||||
*aWrapper = NULL;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
XPCContext*
|
||||
nsXPConnect::NewContext(JSContext* cx, JSObject* global)
|
||||
nsXPConnect::NewContext(JSContext* cx, JSObject* global,
|
||||
JSBool doInit /*= JS_TRUE*/)
|
||||
{
|
||||
XPCContext* xpcc;
|
||||
NS_PRECONDITION(cx,"bad param");
|
||||
NS_PRECONDITION(global,"bad param");
|
||||
NS_PRECONDITION(!mContextMap->Find(cx),"bad param");
|
||||
|
||||
xpcc = XPCContext::newXPCContext(cx, global,
|
||||
|
@ -162,6 +203,11 @@ nsXPConnect::NewContext(JSContext* cx, JSObject* global)
|
|||
NATIVE_MAP_SIZE,
|
||||
JS_CLASS_MAP_SIZE,
|
||||
NATIVE_CLASS_MAP_SIZE);
|
||||
if(doInit && xpcc && !xpcc->Init())
|
||||
{
|
||||
delete xpcc;
|
||||
xpcc = NULL;
|
||||
}
|
||||
if(xpcc)
|
||||
mContextMap->Add(xpcc);
|
||||
return xpcc;
|
||||
|
|
|
@ -141,8 +141,15 @@ class MyScriptable : public nsIXPCScriptable
|
|||
{
|
||||
NS_DECL_ISUPPORTS;
|
||||
XPC_DECLARE_IXPCSCRIPTABLE;
|
||||
MyScriptable();
|
||||
};
|
||||
|
||||
MyScriptable::MyScriptable()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_ADDREF_THIS();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(MyScriptable,NS_IXPCSCRIPTABLE_IID);
|
||||
|
||||
// XPC_IMPLEMENT_FORWARD_IXPCSCRIPTABLE(MyScriptable);
|
||||
|
@ -244,6 +251,7 @@ static NS_DEFINE_IID(kWrappedJSMethodsIID, NS_IXPCONNECT_WRAPPED_JS_METHODS_IID)
|
|||
|
||||
/***************************************************************************/
|
||||
FILE *gOutFile = NULL;
|
||||
FILE *gErrFile = NULL;
|
||||
|
||||
static JSBool
|
||||
Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
|
@ -263,8 +271,38 @@ Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
uintN i;
|
||||
JSString *str;
|
||||
const char *filename;
|
||||
JSScript *script;
|
||||
JSBool ok;
|
||||
jsval result;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
argv[i] = STRING_TO_JSVAL(str);
|
||||
filename = JS_GetStringBytes(str);
|
||||
script = JS_CompileFile(cx, obj, filename);
|
||||
if (!script)
|
||||
ok = JS_FALSE;
|
||||
else {
|
||||
ok = JS_ExecuteScript(cx, obj, script, &result);
|
||||
JS_DestroyScript(cx, script);
|
||||
}
|
||||
if (!ok)
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec glob_functions[] = {
|
||||
{"print", Print, 0},
|
||||
{"load", Load, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -286,6 +324,7 @@ int main()
|
|||
JSContext *cx;
|
||||
JSObject *glob;
|
||||
|
||||
gErrFile = stderr;
|
||||
gOutFile = stdout;
|
||||
|
||||
RegAllocator();
|
||||
|
@ -299,6 +338,10 @@ int main()
|
|||
|
||||
JS_SetErrorReporter(cx, my_ErrorReporter);
|
||||
|
||||
nsIXPConnect* xpc = XPC_GetXPConnect();
|
||||
|
||||
/*
|
||||
// old code where global object was plain object
|
||||
glob = JS_NewObject(cx, &global_class, NULL, NULL);
|
||||
if (!glob)
|
||||
return 1;
|
||||
|
@ -308,8 +351,8 @@ int main()
|
|||
if (!JS_DefineFunctions(cx, glob, glob_functions))
|
||||
return 1;
|
||||
|
||||
nsIXPConnect* xpc = XPC_GetXPConnect();
|
||||
xpc->InitJSContext(cx, glob);
|
||||
*/
|
||||
|
||||
nsTestXPCFoo* foo = new nsTestXPCFoo();
|
||||
|
||||
|
@ -322,8 +365,16 @@ int main()
|
|||
|
||||
nsIXPConnectWrappedNative* wrapper;
|
||||
nsIXPConnectWrappedNative* wrapper2;
|
||||
/*
|
||||
if(NS_SUCCEEDED(xpc->WrapNative(cx, foo, kIFooIID, &wrapper)))
|
||||
*/
|
||||
// new code where global object is a wrapped xpcom object
|
||||
if(NS_SUCCEEDED(xpc->InitJSContextWithNewWrappedGlobal(cx, foo, kIFooIID,
|
||||
&wrapper)))
|
||||
{
|
||||
wrapper->GetJSObject(&glob);
|
||||
JS_DefineFunctions(cx, glob, glob_functions);
|
||||
|
||||
if(NS_SUCCEEDED(xpc->WrapNative(cx, foo, kIFoo2IID, &wrapper2)))
|
||||
{
|
||||
JSObject* js_obj;
|
||||
|
@ -338,27 +389,8 @@ int main()
|
|||
JS_SetProperty(cx, glob, "foo", &v);
|
||||
|
||||
char* txt[] = {
|
||||
"print('foo = '+foo);",
|
||||
"foo.toString = new Function('return \"foo toString called\";')",
|
||||
"foo.toStr = new Function('return \"foo toStr called\";')",
|
||||
"print('foo = '+foo);",
|
||||
"print('foo.toString() = '+foo.toString());",
|
||||
"print('foo.toStr() = '+foo.toStr());",
|
||||
"print('foo.five = '+ foo.five);",
|
||||
"print('foo.six = '+ foo.six);",
|
||||
"print('foo.bogus = '+ foo.bogus);",
|
||||
"foo.bogus = 5;",
|
||||
"print('foo.bogus = '+ foo.bogus);",
|
||||
"print('foo.Test(10,20) returned: '+foo.Test(10,20));",
|
||||
"function Test(p1, p2){print('test called in JS with p1 = '+p1+' and p2 = '+p2);return p1+p2;}",
|
||||
"bar = new Object();",
|
||||
"bar.Test = Test;",
|
||||
// "bar.Test(5,7);",
|
||||
"function QI(iid){print('QueryInterface called in JS with iid = '+iid); return this;}",
|
||||
"bar.QueryInterface = QI;",
|
||||
"print('foo properties:');",
|
||||
"for(i in foo)print(' foo.'+i+' = '+foo[i]);",
|
||||
0,
|
||||
"load('testxpc.js');",
|
||||
0,
|
||||
};
|
||||
|
||||
for(char** p = txt; *p; p++)
|
||||
|
@ -407,3 +439,43 @@ int main()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include "jsatom.h"
|
||||
int
|
||||
DumpAtom(JSHashEntry *he, int i, void *arg)
|
||||
{
|
||||
FILE *fp = (FILE *)arg;
|
||||
JSAtom *atom = (JSAtom *)he;
|
||||
|
||||
fprintf(fp, "%3d %08x %5lu ",
|
||||
i, (uintN)he->keyHash, (unsigned long)atom->number);
|
||||
if (ATOM_IS_STRING(atom))
|
||||
fprintf(fp, "\"%s\"\n", ATOM_BYTES(atom));
|
||||
else if (ATOM_IS_INT(atom))
|
||||
fprintf(fp, "%ld\n", (long)ATOM_TO_INT(atom));
|
||||
else
|
||||
fprintf(fp, "%.16g\n", *ATOM_TO_DOUBLE(atom));
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
int
|
||||
DumpSymbol(JSHashEntry *he, int i, void *arg)
|
||||
{
|
||||
FILE *fp = (FILE *)arg;
|
||||
JSSymbol *sym = (JSSymbol *)he;
|
||||
|
||||
fprintf(fp, "%3d %08x", i, (uintN)he->keyHash);
|
||||
if (JSVAL_IS_INT(sym_id(sym)))
|
||||
fprintf(fp, " [%ld]\n", (long)JSVAL_TO_INT(sym_id(sym)));
|
||||
else
|
||||
fprintf(fp, " \"%s\"\n", ATOM_BYTES(sym_atom(sym)));
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
/* These are callable from gdb. */
|
||||
JS_BEGIN_EXTERN_C
|
||||
void Dsym(JSSymbol *sym) { if (sym) DumpSymbol(&sym->entry, 0, gErrFile); }
|
||||
void Datom(JSAtom *atom) { if (atom) DumpAtom(&atom->entry, 0, gErrFile); }
|
||||
JS_END_EXTERN_C
|
||||
|
|
|
@ -22,8 +22,11 @@ IGNORE_MANIFEST=1
|
|||
MAKE_OBJ_TYPE = EXE
|
||||
PROG1 = .\$(OBJDIR)\TestXPC.exe
|
||||
PROGRAMS = $(PROG1)
|
||||
TESTCASES = testxpc.js
|
||||
|
||||
LCFLAGS=-DUSE_NSREG
|
||||
LCFLAGS=-DUSE_NSREG -DJSFILE
|
||||
|
||||
DEFINES=-DWIN32_LEAN_AND_MEAN -DJS_THREADSAFE -DDEBUG
|
||||
|
||||
REQUIRES=xpcom js xpconnect
|
||||
|
||||
|
@ -43,6 +46,7 @@ include <$(DEPTH)\config\rules.mak>
|
|||
|
||||
install:: $(PROGRAMS)
|
||||
-for %p in ($(PROGRAMS)) do $(MAKE_INSTALL) %p $(DIST)\bin
|
||||
-for %p in ($(TESTCASES)) do $(MAKE_INSTALL) %p $(DIST)\bin
|
||||
|
||||
clobber::
|
||||
-for %p in ($(PROGRAMS)) do $(RM) %p $(DIST)\bin\%p
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// test case...
|
||||
|
||||
var NS_ISUPPORTS_IID = new nsID("{00000000-0000-0000-c000-000000000046}");
|
||||
var NS_ITESTXPC_FOO_IID = new nsID("{159E36D0-991E-11d2-AC3F-00C09300144B}");
|
||||
|
||||
var baz = foo.QueryInterface(NS_ITESTXPC_FOO_IID);
|
||||
print("baz = "+baz);
|
||||
print("distinct wrapper test "+ (foo != baz ? "passed" : "failed"));
|
||||
var baz2 = foo.QueryInterface(NS_ITESTXPC_FOO_IID);
|
||||
print("shared wrapper test "+ (baz == baz2 ? "passed" : "failed"));
|
||||
print("root wrapper identity test "+
|
||||
(foo.QueryInterface(NS_ISUPPORTS_IID) ==
|
||||
baz.QueryInterface(NS_ISUPPORTS_IID) ?
|
||||
"passed" : "failed"));
|
||||
|
||||
print("foo = "+foo);
|
||||
foo.toString = new Function("return 'foo toString called';")
|
||||
foo.toStr = new Function("return 'foo toStr called';")
|
||||
print("foo = "+foo);
|
||||
print("foo.toString() = "+foo.toString());
|
||||
print("foo.toStr() = "+foo.toStr());
|
||||
print("foo.five = "+ foo.five);
|
||||
print("foo.six = "+ foo.six);
|
||||
print("foo.bogus = "+ foo.bogus);
|
||||
print("setting bogus explicitly to '5'...");
|
||||
foo.bogus = 5;
|
||||
print("foo.bogus = "+ foo.bogus);
|
||||
print("foo.Test(10,20) returned: "+foo.Test(10,20));
|
||||
|
||||
function _Test(p1, p2)
|
||||
{
|
||||
print("test called in JS with p1 = "+p1+" and p2 = "+p2);
|
||||
return p1+p2;
|
||||
}
|
||||
|
||||
function _QI(iid)
|
||||
{
|
||||
print("QueryInterface called in JS with iid = "+iid);
|
||||
return this;
|
||||
}
|
||||
|
||||
print("creating bar");
|
||||
bar = new Object();
|
||||
bar.Test = _Test;
|
||||
bar.QueryInterface = _QI;
|
||||
// this 'bar' object is accessed from native code after this script is run
|
||||
|
||||
print("foo properties:");
|
||||
for(i in foo)
|
||||
print(" foo."+i+" = "+foo[i]);
|
||||
|
|
@ -32,7 +32,6 @@ XPCContext::newXPCContext(JSContext* aJSContext,
|
|||
XPCContext* xpcc;
|
||||
|
||||
NS_PRECONDITION(aJSContext,"bad param");
|
||||
NS_PRECONDITION(aGlobalObj,"bad param");
|
||||
NS_PRECONDITION(WrappedJSMapSize,"bad param");
|
||||
NS_PRECONDITION(WrappedNativeMapSize,"bad param");
|
||||
NS_PRECONDITION(WrappedJSClassMapSize,"bad param");
|
||||
|
@ -50,10 +49,7 @@ XPCContext::newXPCContext(JSContext* aJSContext,
|
|||
xpcc->GetWrappedJSMap() &&
|
||||
xpcc->GetWrappedNativeMap() &&
|
||||
xpcc->GetWrappedJSClassMap() &&
|
||||
xpcc->GetWrappedNativeClassMap() &&
|
||||
xpc_InitIDClass(xpcc) &&
|
||||
nsXPCWrappedJSClass::InitForContext(xpcc) &&
|
||||
nsXPCWrappedNativeClass::InitForContext(xpcc))
|
||||
xpcc->GetWrappedNativeClassMap())
|
||||
{
|
||||
return xpcc;
|
||||
}
|
||||
|
@ -90,3 +86,13 @@ XPCContext::~XPCContext()
|
|||
if(mWrappedNativeClassMap)
|
||||
delete mWrappedNativeClassMap;
|
||||
}
|
||||
|
||||
JSBool
|
||||
XPCContext::Init(JSObject* aGlobalObj /*= NULL*/)
|
||||
{
|
||||
if(aGlobalObj)
|
||||
mGlobalObj = aGlobalObj;
|
||||
return xpc_InitIDClass(this) &&
|
||||
nsXPCWrappedJSClass::InitForContext(this) &&
|
||||
nsXPCWrappedNativeClass::InitForContext(this);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,11 @@ class nsXPConnect : public nsIXPConnect
|
|||
NS_IMETHOD InitJSContext(JSContext* aJSContext,
|
||||
JSObject* aGlobalJSObj);
|
||||
|
||||
NS_IMETHOD InitJSContextWithNewWrappedGlobal(JSContext* aJSContext,
|
||||
nsISupports* aCOMObj,
|
||||
REFNSIID aIID,
|
||||
nsIXPConnectWrappedNative** aWrapper);
|
||||
|
||||
NS_IMETHOD WrapNative(JSContext* aJSContext,
|
||||
nsISupports* aCOMObj,
|
||||
REFNSIID aIID,
|
||||
|
@ -76,7 +81,8 @@ public:
|
|||
virtual ~nsXPConnect();
|
||||
private:
|
||||
nsXPConnect();
|
||||
XPCContext* NewContext(JSContext* cx, JSObject* global);
|
||||
XPCContext* NewContext(JSContext* cx, JSObject* global,
|
||||
JSBool doInit = JS_TRUE);
|
||||
|
||||
private:
|
||||
static nsXPConnect* mSelf;
|
||||
|
@ -110,6 +116,8 @@ public:
|
|||
IID2WrappedJSClassMap* GetWrappedJSClassMap() {return mWrappedJSClassMap;}
|
||||
IID2WrappedNativeClassMap* GetWrappedNativeClassMap() {return mWrappedNativeClassMap;}
|
||||
|
||||
JSBool Init(JSObject* aGlobalObj = NULL);
|
||||
|
||||
~XPCContext();
|
||||
private:
|
||||
XPCContext(); // no implementation
|
||||
|
@ -280,7 +288,7 @@ public:
|
|||
void SetWritableAttribute() {flags=(flags&~NMD_CAT_MASK)|NMD_ATTRIB_RW;}
|
||||
|
||||
XPCNativeMemberDescriptor()
|
||||
: invokeFuncObj(NULL), id(0){}
|
||||
: invokeFuncObj(NULL), id(0), flags(0) {}
|
||||
private:
|
||||
uint16 flags;
|
||||
};
|
||||
|
@ -318,6 +326,8 @@ public:
|
|||
{return GetXPCContext()->GetXPConnect()->GetArbitraryScriptable();}
|
||||
|
||||
static JSBool InitForContext(XPCContext* xpcc);
|
||||
static JSBool OneTimeInit();
|
||||
|
||||
JSObject* NewInstanceJSObject(nsXPCWrappedNative* self);
|
||||
static nsXPCWrappedNative* GetWrappedNativeOfJSObject(JSContext* cx,
|
||||
JSObject* jsobj);
|
||||
|
|
|
@ -270,40 +270,42 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
|||
uint8 argc;
|
||||
jsval result;
|
||||
uint8 paramCount;
|
||||
nsresult retval = NS_ERROR_UNEXPECTED;
|
||||
nsresult retval = NS_ERROR_FAILURE;
|
||||
JSErrorReporter older;
|
||||
JSBool success;
|
||||
JSContext* cx = GetJSContext();
|
||||
nsIAllocator* al = NULL;
|
||||
JSBool InConversionsDone = JS_FALSE;
|
||||
|
||||
if(!(al = nsXPConnect::GetAllocator()))
|
||||
goto pre_call_clean_up;
|
||||
|
||||
if(!IsReflectable(methodIndex))
|
||||
{
|
||||
// XXX we need to go through and free and NULL out all 'out' params
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
goto pre_call_clean_up;
|
||||
|
||||
// XXX ASSUMES that retval is last arg.
|
||||
paramCount = info->GetParamCount();
|
||||
argc = paramCount -
|
||||
(paramCount && info->GetParam(paramCount-1).IsRetval() ? 1 : 0);
|
||||
|
||||
// XXX do we need to go through and NULL out all 'out' params?
|
||||
|
||||
// setup argv
|
||||
if(argc > ARGS_BUFFER_COUNT)
|
||||
{
|
||||
if(!(argv = new jsval[argc]))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
{
|
||||
retval = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
}
|
||||
else
|
||||
argv = argsBuffer;
|
||||
// from here on out we exit via 'goto done'
|
||||
|
||||
// build the args
|
||||
for(i = 0; i < argc; i++)
|
||||
{
|
||||
nsID* conditional_iid = NULL;
|
||||
const nsXPTParamInfo& param = info->GetParam(i);
|
||||
const nsXPTType& type = param.GetType();
|
||||
|
||||
jsval val;
|
||||
|
||||
if(param.IsIn())
|
||||
|
@ -315,13 +317,31 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
|||
else
|
||||
pv = ¶ms[i];
|
||||
|
||||
if(type.IsPointer())
|
||||
pv = (nsXPCMiniVariant*) pv->val.p;
|
||||
|
||||
if(!XPCConvert::NativeData2JS(cx, &val, &pv->val, type, NULL))
|
||||
if(type.TagPart() == nsXPTType::T_INTERFACE)
|
||||
{
|
||||
retval = NS_ERROR_FAILURE;
|
||||
goto done;
|
||||
if(!(conditional_iid = param.GetInterfaceIID()))
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
else if(type.TagPart() == nsXPTType::T_INTERFACE_IS)
|
||||
{
|
||||
uint8 arg_num = param.GetInterfaceIsArgNumber();
|
||||
const nsXPTParamInfo& param = info->GetParam(arg_num);
|
||||
const nsXPTType& type = param.GetType();
|
||||
if(type.IsPointer() && type.TagPart() == nsXPTType::T_IID)
|
||||
{
|
||||
if(param.IsOut())
|
||||
conditional_iid = *((nsID**)params[arg_num].val.p);
|
||||
else
|
||||
conditional_iid = (nsID*) params[arg_num].val.p;
|
||||
}
|
||||
if(!conditional_iid)
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
|
||||
if(!XPCConvert::NativeData2JS(cx, &val, &pv->val, type,
|
||||
conditional_iid))
|
||||
{
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,13 +352,56 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
|||
if(param.IsIn())
|
||||
{
|
||||
if(!JS_SetProperty(cx, obj, XPC_VAL_STR, &val))
|
||||
goto done;
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
argv[i] = OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
else
|
||||
argv[i] = val;
|
||||
}
|
||||
InConversionsDone = JS_TRUE;
|
||||
|
||||
pre_call_clean_up:
|
||||
// clean up any 'out' params handed in
|
||||
for(i = 0; i < paramCount; i++)
|
||||
{
|
||||
const nsXPTParamInfo& param = info->GetParam(i);
|
||||
if(!param.IsOut())
|
||||
continue;
|
||||
|
||||
const nsXPTType& type = param.GetType();
|
||||
if(!type.IsPointer())
|
||||
continue;
|
||||
if(!params[i].val.p)
|
||||
continue;
|
||||
|
||||
if(type.IsInterfacePointer())
|
||||
{
|
||||
if(param.IsIn())
|
||||
{
|
||||
nsISupports** pp;
|
||||
if((NULL != (pp = (nsISupports**) params[i].val.p)) &&
|
||||
NULL != *pp)
|
||||
{
|
||||
(*pp)->Release();
|
||||
*pp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
void** pp;
|
||||
if((NULL != (pp = (void**) params[i].val.p)) && NULL != *pp && al)
|
||||
{
|
||||
if(param.IsIn())
|
||||
al->Free(*pp);
|
||||
*pp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!InConversionsDone)
|
||||
goto done;
|
||||
|
||||
// do the function call
|
||||
|
||||
|
@ -347,10 +410,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
|||
argc, argv, &result);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
if(!success)
|
||||
{
|
||||
retval = NS_ERROR_FAILURE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// convert out args and result
|
||||
// NOTE: this is the total number of native params, not just the args
|
||||
|
@ -361,31 +421,59 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
|||
if(param.IsOut())
|
||||
{
|
||||
jsval val;
|
||||
nsIAllocator* conditional_al = NULL;
|
||||
nsID* conditional_iid = NULL;
|
||||
const nsXPTType& type = param.GetType();
|
||||
nsXPCMiniVariant* pv;
|
||||
|
||||
pv = (nsXPCMiniVariant*) params[i].val.p;
|
||||
|
||||
if(param.IsRetval())
|
||||
val = result;
|
||||
else if(!JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[i]), XPC_VAL_STR, &val))
|
||||
goto done;
|
||||
break;
|
||||
|
||||
pv = (nsXPCMiniVariant*) params[i].val.p;
|
||||
if(type.IsPointer())
|
||||
pv = (nsXPCMiniVariant*) pv->val.p;
|
||||
// setup allocator and/or iid
|
||||
|
||||
if(!XPCConvert::JSData2Native(cx, &pv->val, val, type, NULL, NULL))
|
||||
if(type.TagPart() == nsXPTType::T_INTERFACE)
|
||||
{
|
||||
NS_ASSERTION(0, "bad type");
|
||||
goto done;
|
||||
if(!(conditional_iid = param.GetInterfaceIID()))
|
||||
break;
|
||||
}
|
||||
else if(type.TagPart() == nsXPTType::T_INTERFACE_IS)
|
||||
{
|
||||
uint8 arg_num = param.GetInterfaceIsArgNumber();
|
||||
const nsXPTParamInfo& param = info->GetParam(arg_num);
|
||||
const nsXPTType& type = param.GetType();
|
||||
if(!type.IsPointer() || type.TagPart() != nsXPTType::T_IID ||
|
||||
!(conditional_iid = *((nsID**)params[arg_num].val.p)))
|
||||
break;
|
||||
}
|
||||
else if(type.IsPointer())
|
||||
conditional_al = al;
|
||||
|
||||
if(!XPCConvert::JSData2Native(cx, &pv->val, val, type,
|
||||
conditional_al, conditional_iid))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't manage all the result conversions then we have
|
||||
// to cleanup any junk that *did* get converted.
|
||||
if(i != paramCount)
|
||||
{
|
||||
// XXX major spagetti!
|
||||
InConversionsDone = JS_FALSE;
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
|
||||
retval = NS_OK;
|
||||
|
||||
done:
|
||||
if(argv && argv != argsBuffer)
|
||||
delete [] argv;
|
||||
if(al)
|
||||
NS_RELEASE(al);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -454,11 +454,6 @@ nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper,
|
|||
}
|
||||
else
|
||||
{
|
||||
if(type.IsPointer())
|
||||
{
|
||||
dp->flags = nsXPCVariant::PTR_IS_DATA;
|
||||
dp->ptr = &dp->val;
|
||||
}
|
||||
src = argv[i];
|
||||
}
|
||||
|
||||
|
@ -1154,13 +1149,19 @@ static JSClass WrappedNative_class = {
|
|||
|
||||
// static
|
||||
JSBool
|
||||
nsXPCWrappedNativeClass::InitForContext(XPCContext* xpcc)
|
||||
nsXPCWrappedNativeClass::OneTimeInit()
|
||||
{
|
||||
WrappedNative_ops.newObjectMap = js_ObjectOps.newObjectMap;
|
||||
WrappedNative_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
|
||||
WrappedNative_ops.dropProperty = js_ObjectOps.dropProperty;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
JSBool
|
||||
nsXPCWrappedNativeClass::InitForContext(XPCContext* xpcc)
|
||||
{
|
||||
// XXX do we really want this class init'd this way? access to ctor?
|
||||
|
||||
if (!JS_InitClass(xpcc->GetJSContext(), xpcc->GetGlobalObject(),
|
||||
0, &WrappedNative_class, 0, 0,
|
||||
0, 0,
|
||||
|
|
|
@ -133,18 +133,24 @@ XPTInterfaceDescriptor nsISupportsInterfaceDescriptor =
|
|||
XPTInterfaceDescriptor nsITestXPCFooInterfaceDescriptor =
|
||||
{NULL, 2, nsITestXPCFooMethods, 3, nsITestXPCFooConstants};
|
||||
|
||||
XPTInterfaceDescriptor nsITestXPCFoo2InterfaceDescriptor =
|
||||
{NULL, 0, NULL, 0, NULL};
|
||||
|
||||
XPTInterfaceDirectoryEntry InterfaceDirectoryEntryTable[] = {
|
||||
{NS_ISUPPORTS_IID, "nsISupports", "", &nsISupportsInterfaceDescriptor},
|
||||
{NS_ITESTXPC_FOO_IID, "nsITestXPCFoo", "", &nsITestXPCFooInterfaceDescriptor},
|
||||
{NS_ITESTXPC_FOO2_IID, "nsITestXPCFoo2", "", &nsITestXPCFooInterfaceDescriptor}
|
||||
{NS_ITESTXPC_FOO2_IID, "nsITestXPCFoo2", "", &nsITestXPCFoo2InterfaceDescriptor}
|
||||
};
|
||||
|
||||
#define ENTRY_COUNT (sizeof(InterfaceDirectoryEntryTable)/sizeof(InterfaceDirectoryEntryTable[0]))
|
||||
#define TABLE_INDEX(p) ((p-InterfaceDirectoryEntryTable)/sizeof(InterfaceDirectoryEntryTable[0]))
|
||||
#define TABLE_INDEX(p) ((p)-InterfaceDirectoryEntryTable)
|
||||
|
||||
static BogusTableInit()
|
||||
{
|
||||
nsITestXPCFooInterfaceDescriptor.parent_interface =
|
||||
&InterfaceDirectoryEntryTable[0];
|
||||
|
||||
nsITestXPCFoo2InterfaceDescriptor.parent_interface =
|
||||
&InterfaceDirectoryEntryTable[1];
|
||||
}
|
||||
|
||||
|
@ -154,7 +160,7 @@ static BogusTableInit()
|
|||
nsIInterfaceInfo*
|
||||
nsXPTParamInfo::GetInterface() const
|
||||
{
|
||||
NS_PRECONDITION(GetType() == nsXPTType::T_INTERFACE,"not an interface");
|
||||
NS_PRECONDITION(GetType().TagPart() == nsXPTType::T_INTERFACE,"not an interface");
|
||||
|
||||
nsIInterfaceInfoManager* mgr;
|
||||
if(!(mgr = InterfaceInfoManagerImpl::GetInterfaceInfoManager()))
|
||||
|
@ -171,7 +177,7 @@ nsXPTParamInfo::GetInterface() const
|
|||
nsIID*
|
||||
nsXPTParamInfo::GetInterfaceIID() const
|
||||
{
|
||||
NS_PRECONDITION(GetType() == nsXPTType::T_INTERFACE,"not an interface");
|
||||
NS_PRECONDITION(GetType().TagPart() == nsXPTType::T_INTERFACE,"not an interface");
|
||||
return &InterfaceDirectoryEntryTable[type.type.interface].iid;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ public:
|
|||
|
||||
uint8 GetInterfaceIsArgNumber() const
|
||||
{
|
||||
NS_PRECONDITION(GetType() == nsXPTType::T_INTERFACE_IS,"not an interface_is");
|
||||
NS_PRECONDITION(GetType().TagPart() == nsXPTType::T_INTERFACE_IS,"not an interface_is");
|
||||
return type.type.argnum;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче