NOT YET PART OF SEAMONKEY - more conversion stuff implemented

This commit is contained in:
jband%netscape.com 1999-02-13 19:28:38 +00:00
Родитель 50b4c17f6d
Коммит b65de451d8
11 изменённых файлов: 288 добавлений и 144 удалений

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

@ -1 +1,4 @@
Makefile Makefile
convert
mk.bat
set_env.bat

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

@ -33,7 +33,7 @@ class nsXPTConstant;
class nsIInterfaceInfo : public nsISupports class nsIInterfaceInfo : public nsISupports
{ {
public: public:
NS_IMETHOD GetName(char** name) = 0; // returns IAllocatator alloc'd copy NS_IMETHOD GetName(char** name) = 0; // returns IAllocatator alloc'd copy
NS_IMETHOD GetIID(nsIID** iid) = 0; // returns IAllocatator alloc'd copy NS_IMETHOD GetIID(nsIID** iid) = 0; // returns IAllocatator alloc'd copy

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

@ -51,8 +51,8 @@ nsXPConnect::GetXPConnect()
return mSelf; return mSelf;
} }
// static // static
nsIAllocator* nsIAllocator*
nsXPConnect::GetAllocator(nsXPConnect* xpc /*= NULL*/) nsXPConnect::GetAllocator(nsXPConnect* xpc /*= NULL*/)
{ {
nsIAllocator* al; nsIAllocator* al;
@ -67,8 +67,8 @@ nsXPConnect::GetAllocator(nsXPConnect* xpc /*= NULL*/)
return al; return al;
} }
// static // static
nsIInterfaceInfoManager* nsIInterfaceInfoManager*
nsXPConnect::GetInterfaceInfoManager(nsXPConnect* xpc /*= NULL*/) nsXPConnect::GetInterfaceInfoManager(nsXPConnect* xpc /*= NULL*/)
{ {
nsIInterfaceInfoManager* iim; nsIInterfaceInfoManager* iim;
@ -83,6 +83,25 @@ nsXPConnect::GetInterfaceInfoManager(nsXPConnect* xpc /*= NULL*/)
return iim; return iim;
} }
// static
XPCContext*
nsXPConnect::GetContext(JSContext* cx, nsXPConnect* xpc /*= NULL*/)
{
NS_PRECONDITION(cx,"bad param");
XPCContext* xpcc;
nsXPConnect* xpcl = xpc;
if(!xpcl && !(xpcl = GetXPConnect()))
return NULL;
xpcc = xpcl->mContextMap->Find(cx);
if(!xpcc)
xpcc = xpcl->NewContext(cx, JS_GetGlobalObject(cx));
if(!xpc)
NS_RELEASE(xpcl);
return xpcc;
}
nsXPConnect::nsXPConnect() nsXPConnect::nsXPConnect()
: mContextMap(NULL), : mContextMap(NULL),
mAllocator(NULL), mAllocator(NULL),
@ -130,17 +149,6 @@ nsXPConnect::InitJSContext(JSContext* aJSContext,
return NS_OK; return NS_OK;
} }
XPCContext*
nsXPConnect::GetContext(JSContext* cx)
{
XPCContext* xpcc;
NS_PRECONDITION(cx,"bad param");
xpcc = mContextMap->Find(cx);
if(!xpcc)
xpcc = NewContext(cx, JS_GetGlobalObject(cx));
return xpcc;
}
XPCContext* XPCContext*
nsXPConnect::NewContext(JSContext* cx, JSObject* global) nsXPConnect::NewContext(JSContext* cx, JSObject* global)
{ {
@ -171,7 +179,7 @@ nsXPConnect::WrapNative(JSContext* aJSContext,
*aWrapper = NULL; *aWrapper = NULL;
XPCContext* xpcc = GetContext(aJSContext); XPCContext* xpcc = nsXPConnect::GetContext(aJSContext, this);
if(!xpcc) if(!xpcc)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -197,7 +205,7 @@ nsXPConnect::WrapJS(JSContext* aJSContext,
*aWrapper = NULL; *aWrapper = NULL;
XPCContext* xpcc = GetContext(aJSContext); XPCContext* xpcc = nsXPConnect::GetContext(aJSContext, this);
if(!xpcc) if(!xpcc)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

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

@ -20,8 +20,10 @@
#include "xpcprivate.h" #include "xpcprivate.h"
// static static NS_DEFINE_IID(kWrappedJSMethodsIID, NS_IXPCONNECT_WRAPPED_JS_METHODS_IID);
JSBool
// static
JSBool
XPCConvert::IsMethodReflectable(const nsXPTMethodInfo& info) XPCConvert::IsMethodReflectable(const nsXPTMethodInfo& info)
{ {
if(info.IsHidden()) if(info.IsHidden())
@ -166,7 +168,7 @@ XPCConvert::IsMethodReflectable(const nsXPTMethodInfo& info)
} }
} }
return JS_TRUE; return JS_TRUE;
} }
// XXX these conversion functions need to be finished. // XXX these conversion functions need to be finished.
// XXX conversion functions may still need paramInfo to handle the additional // XXX conversion functions may still need paramInfo to handle the additional
@ -178,10 +180,10 @@ XPCConvert::IsMethodReflectable(const nsXPTMethodInfo& info)
// Win32 can't handle uint64 to double conversion // Win32 can't handle uint64 to double conversion
#define JAM_DOUBLE_U64(v,d) JAM_DOUBLE(((int64)v),d) #define JAM_DOUBLE_U64(v,d) JAM_DOUBLE(((int64)v),d)
// static // static
JSBool JSBool
XPCConvert::NativeData2JS(jsval* d, const void* s, XPCConvert::NativeData2JS(JSContext* cx, jsval* d, const void* s,
const nsXPTType& type) const nsXPTType& type, const nsID* iid)
{ {
NS_PRECONDITION(s, "bad param"); NS_PRECONDITION(s, "bad param");
NS_PRECONDITION(d, "bad param"); NS_PRECONDITION(d, "bad param");
@ -209,40 +211,96 @@ XPCConvert::NativeData2JS(jsval* d, const void* s,
NS_ASSERTION(0,"unsupported type"); NS_ASSERTION(0,"unsupported type");
return JS_FALSE; return JS_FALSE;
} }
// set the default result
*d = JSVAL_NULL;
switch(type.TagPart()) switch(type.TagPart())
{ {
case nsXPTType::T_VOID: case nsXPTType::T_VOID:
// XXX implement void* // XXX implement void* ?
NS_ASSERTION(0,"void* params not supported"); NS_ASSERTION(0,"void* params not supported");
return JS_FALSE; return JS_FALSE;
case nsXPTType::T_IID: case nsXPTType::T_IID:
// XXX implement IID {
NS_ASSERTION(0,"iid params not supported"); nsID* iid = *((nsID**)s);
return JS_FALSE; if(!iid)
break;
JSObject* obj;
if(!(obj = xpc_NewIDObject(cx, *iid)))
break;
*d = OBJECT_TO_JSVAL(obj);
break;
}
case nsXPTType::T_BSTR: case nsXPTType::T_BSTR:
// XXX implement BSTR // XXX implement BSTR ?
NS_ASSERTION(0,"string params not supported"); NS_ASSERTION(0,"'BSTR' string params not supported");
return JS_FALSE; return JS_FALSE;
case nsXPTType::T_CHAR_STR: case nsXPTType::T_CHAR_STR:
// XXX implement CHAR_STR {
NS_ASSERTION(0,"string params not supported"); char* p = *((char**)s);
return JS_FALSE; if(!p)
break;
JSString* str;
if(!(str = JS_NewStringCopyZ(cx, p)))
break;
*d = STRING_TO_JSVAL(str);
break;
}
case nsXPTType::T_WCHAR_STR: case nsXPTType::T_WCHAR_STR:
// XXX implement WCHAR_STR {
NS_ASSERTION(0,"string params not supported"); jschar* p = *((jschar**)s);
return JS_FALSE; if(!p)
break;
JSString* str;
if(!(str = JS_NewUCStringCopyZ(cx, p)))
break;
*d = STRING_TO_JSVAL(str);
break;
}
case nsXPTType::T_INTERFACE: case nsXPTType::T_INTERFACE:
// XXX implement INTERFACE
// make sure 'src' is an object
// get the nsIInterfaceInfo* from the param and
// build a wrapper and then hand over the wrapper.
// XXX remember to release the wrapper in cleanup below
NS_ASSERTION(0,"interface params not supported");
return JS_FALSE;
case nsXPTType::T_INTERFACE_IS: case nsXPTType::T_INTERFACE_IS:
// XXX implement INTERFACE_IS {
NS_ASSERTION(0,"interface_is params not supported"); nsISupports* iface = *((nsISupports**)s);
return JS_FALSE; if(!iface)
break;
JSObject* aJSObj;
// is this a wrapped JS object?
if(nsXPCWrappedJSClass::IsWrappedJS(iface))
{
nsIXPConnectWrappedJSMethods* methods;
if(NS_SUCCEEDED(iface->QueryInterface(kWrappedJSMethodsIID,
(void**)&methods)) &&
NS_SUCCEEDED(methods->GetJSObject(&aJSObj)))
{
NS_RELEASE(methods);
*d = OBJECT_TO_JSVAL(aJSObj);
}
}
else
{
// we need to build a wrapper
nsXPCWrappedNative* wrapper;
XPCContext* xpcc;
if(!iid || !(xpcc = nsXPConnect::GetContext(cx)) ||
!(wrapper = nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc,
iface, *iid)))
{
break;
}
aJSObj = wrapper->GetJSObject();
NS_RELEASE(wrapper);
if(aJSObj)
*d = OBJECT_TO_JSVAL(aJSObj);
}
break;
}
default: default:
NS_ASSERTION(0, "bad type"); NS_ASSERTION(0, "bad type");
return JS_FALSE; return JS_FALSE;
@ -251,10 +309,10 @@ XPCConvert::NativeData2JS(jsval* d, const void* s,
return JS_TRUE; return JS_TRUE;
} }
// static // static
JSBool JSBool
XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s, XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
const nsXPTType& type, const nsXPTType& type,
nsIAllocator* al, const nsID* iid) nsIAllocator* al, const nsID* iid)
{ {
NS_PRECONDITION(d, "bad param"); NS_PRECONDITION(d, "bad param");
@ -430,17 +488,47 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
} }
case nsXPTType::T_INTERFACE: case nsXPTType::T_INTERFACE:
// XXX implement INTERFACE
// make sure 'src' is an object
// get the nsIInterfaceInfo* from the param and
// build a wrapper and then hand over the wrapper.
// XXX remember to release the wrapper in cleanup below
NS_ASSERTION(0,"interface params not supported");
return JS_FALSE;
case nsXPTType::T_INTERFACE_IS: case nsXPTType::T_INTERFACE_IS:
// XXX implement INTERFACE_IS {
NS_ASSERTION(0,"interface_is params not supported"); NS_ASSERTION(iid,"can't do interface conversions without iid");
JSObject* obj;
nsISupports* iface = NULL;
// only wrpa JSObjects
if(!JSVAL_IS_OBJECT(s) ||
(!(obj = JSVAL_TO_OBJECT(s))))
{
// XXX should report error
return JS_FALSE;
}
// is this really a native xpcom object with a wrapper?
nsXPCWrappedNative* wrapper;
if(NULL != (wrapper =
nsXPCWrappedNativeClass::GetWrappedNativeOfJSObject(cx,obj)))
{
iface = wrapper->GetNative();
// is the underlying object the right interface?
if(wrapper->GetIID().Equals(*iid))
NS_ADDREF(iface);
else
iface->QueryInterface(*iid, (void**)&iface);
}
else
{
// lets try to build a wrapper around the JSObject
XPCContext* xpcc;
if(NULL != (xpcc = nsXPConnect::GetContext(cx)))
iface = nsXPCWrappedJS::GetNewOrUsedWrapper(xpcc, obj, *iid);
}
if(iface)
{
// one AddRef has already been done
*((nsISupports**)d) = iface;
return JS_TRUE;
}
return JS_FALSE; return JS_FALSE;
}
default: default:
NS_ASSERTION(0, "bad type"); NS_ASSERTION(0, "bad type");
return JS_FALSE; return JS_FALSE;

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

@ -215,4 +215,4 @@ xpc_JSObjectToID(JSContext *cx, JSObject* obj)
return NULL; return NULL;
return &data->GetID(); return &data->GetID();
} }

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

@ -68,8 +68,8 @@ public:
static nsXPConnect* GetXPConnect(); static nsXPConnect* GetXPConnect();
static nsIAllocator* GetAllocator(nsXPConnect* xpc = NULL); static nsIAllocator* GetAllocator(nsXPConnect* xpc = NULL);
static nsIInterfaceInfoManager* GetInterfaceInfoManager(nsXPConnect* xpc = NULL); static nsIInterfaceInfoManager* GetInterfaceInfoManager(nsXPConnect* xpc = NULL);
static XPCContext* GetContext(JSContext* cx, nsXPConnect* xpc = NULL);
XPCContext* GetContext(JSContext* cx);
JSContext2XPCContextMap* GetContextMap() {return mContextMap;} JSContext2XPCContextMap* GetContextMap() {return mContextMap;}
nsIXPCScriptable* GetArbitraryScriptable() {return mArbitraryScriptable;} nsIXPCScriptable* GetArbitraryScriptable() {return mArbitraryScriptable;}
@ -144,26 +144,6 @@ class nsIXPCWrappedJSClass : public nsISupports
/*************************/ /*************************/
// nsXPCWrappedJSClass maintains an array of these things
class XPCJSMemberDescriptor
{
private:
enum {
// these are all bitwise flags!
JSMD_REFLECTABLE = 0x1
};
public:
JSBool IsReflectable() const {return flags & JSMD_REFLECTABLE;}
void SetReflectable(JSBool b) {if(b) flags |= JSMD_REFLECTABLE;
else flags &= ~JSMD_REFLECTABLE;}
XPCJSMemberDescriptor(){}
private:
uint16 flags;
};
/*************************/
class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass
{ {
// all the interface method declarations... // all the interface method declarations...
@ -177,7 +157,7 @@ public:
nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;} nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
static JSBool InitForContext(XPCContext* xpcc); static JSBool InitForContext(XPCContext* xpcc);
JSBool IsWrappedJS(nsISupports* aPtr); static JSBool IsWrappedJS(nsISupports* aPtr);
NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID, NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID,
void** aInstancePtr); void** aInstancePtr);
@ -200,9 +180,9 @@ private:
JSObject* CallQueryInterfaceOnJSObject(JSObject* jsobj, REFNSIID aIID); JSObject* CallQueryInterfaceOnJSObject(JSObject* jsobj, REFNSIID aIID);
JSBool IsReflectable(uint16 i) const JSBool IsReflectable(uint16 i) const
{return mDescriptors[i/32] & (1 << (i%32));} {return mDescriptors[i/32] & (1 << (i%32));}
void SetReflectable(uint16 i, JSBool b) void SetReflectable(uint16 i, JSBool b)
{if(b) mDescriptors[i/32] |= (1 << (i%32)); {if(b) mDescriptors[i/32] |= (1 << (i%32));
else mDescriptors[i/32] &= ~(1 << (i%32));} else mDescriptors[i/32] &= ~(1 << (i%32));}
@ -276,7 +256,7 @@ private:
// these are all bitwise flags! // these are all bitwise flags!
NMD_CONSTANT = 0x0, // categories... NMD_CONSTANT = 0x0, // categories...
NMD_METHOD = 0x1, NMD_METHOD = 0x1,
NMD_ATTRIB_RO = 0x2, NMD_ATTRIB_RO = 0x2,
NMD_ATTRIB_RW = 0x3, NMD_ATTRIB_RW = 0x3,
NMD_CAT_MASK = 0x3, // & mask for the categories above NMD_CAT_MASK = 0x3, // & mask for the categories above
// any new bits start at 0x04 // any new bits start at 0x04
@ -351,7 +331,8 @@ public:
const XPCNativeMemberDescriptor* LookupMemberByID(jsid id) const; const XPCNativeMemberDescriptor* LookupMemberByID(jsid id) const;
JSBool GetConstantAsJSVal(nsXPCWrappedNative* wrapper, JSBool GetConstantAsJSVal(JSContext* cx,
nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc, const XPCNativeMemberDescriptor* desc,
jsval* vp); jsval* vp);
@ -409,15 +390,6 @@ private:
/*************************/ /*************************/
class nsXPCArbitraryScriptable : public nsIXPCScriptable
{
public:
// all the interface method declarations...
NS_DECL_ISUPPORTS;
XPC_DECLARE_IXPCSCRIPTABLE;
nsXPCArbitraryScriptable() {NS_INIT_REFCNT();NS_ADDREF_THIS();}
};
class nsXPCWrappedNative : public nsIXPConnectWrappedNative class nsXPCWrappedNative : public nsIXPConnectWrappedNative
{ {
// all the interface method declarations... // all the interface method declarations...
@ -465,6 +437,17 @@ private:
nsXPCWrappedNative* mNext; nsXPCWrappedNative* mNext;
}; };
/***************************************************************************/
class nsXPCArbitraryScriptable : public nsIXPCScriptable
{
public:
// all the interface method declarations...
NS_DECL_ISUPPORTS;
XPC_DECLARE_IXPCSCRIPTABLE;
nsXPCArbitraryScriptable() {NS_INIT_REFCNT();NS_ADDREF_THIS();}
};
/***************************************************************************/ /***************************************************************************/
// nsID JavaScript class functions // nsID JavaScript class functions
@ -486,11 +469,11 @@ class XPCConvert
public: public:
static JSBool IsMethodReflectable(const nsXPTMethodInfo& info); static JSBool IsMethodReflectable(const nsXPTMethodInfo& info);
static JSBool NativeData2JS(jsval* d, const void* s, static JSBool NativeData2JS(JSContext* cx, jsval* d, const void* s,
const nsXPTType& type); const nsXPTType& type, const nsID* iid);
static JSBool JSData2Native(JSContext* cx, void* d, jsval s, static JSBool JSData2Native(JSContext* cx, void* d, jsval s,
const nsXPTType& type, const nsXPTType& type,
nsIAllocator* al, const nsID* iid); nsIAllocator* al, const nsID* iid);
private: private:
XPCConvert(); // not implemented XPCConvert(); // not implemented

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

@ -57,13 +57,15 @@ struct nsXPCVariant : public nsXPCMiniVariant
enum enum
{ {
PTR_IS_DATA = 0x1, // used for OUT params of Arithmetic types, // these are bitflags!
// ptr points to data in val PTR_IS_DATA = 0x1, // ptr points to 'real' data in val
VAL_IS_OWNED = 0x2 // val.p holds an alloced ptr that must be freed VAL_IS_OWNED = 0x2, // val.p holds alloced ptr that must be freed
VAL_IS_IFACE = 0x4 // val.p holds interface ptr that must be released
}; };
JSBool IsPtrData() const {return (JSBool) (flags & PTR_IS_DATA);} JSBool IsPtrData() const {return (JSBool) (flags & PTR_IS_DATA);}
JSBool IsValOwned() const {return (JSBool) (flags & VAL_IS_OWNED);} JSBool IsValOwned() const {return (JSBool) (flags & VAL_IS_OWNED);}
JSBool IsValInterface() const {return (JSBool) (flags & VAL_IS_IFACE);}
}; };
#endif /* xpcvariant_h___ */ #endif /* xpcvariant_h___ */

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

@ -97,7 +97,7 @@ nsXPCWrappedJSClass::nsXPCWrappedJSClass(XPCContext* xpcc, REFNSIID aIID,
mDescriptors = NULL; mDescriptors = NULL;
break; break;
} }
} }
} }
} }
else else
@ -110,7 +110,7 @@ nsXPCWrappedJSClass::nsXPCWrappedJSClass(XPCContext* xpcc, REFNSIID aIID,
nsXPCWrappedJSClass::~nsXPCWrappedJSClass() nsXPCWrappedJSClass::~nsXPCWrappedJSClass()
{ {
if(mDescriptors && mDescriptors != &zero_methods_descriptor) if(mDescriptors && mDescriptors != &zero_methods_descriptor)
delete [] mDescriptors; delete [] mDescriptors;
mXPCContext->GetWrappedJSClassMap()->Remove(this); mXPCContext->GetWrappedJSClassMap()->Remove(this);
NS_RELEASE(mInfo); NS_RELEASE(mInfo);
} }
@ -195,6 +195,7 @@ public:
/***************************************************************************/ /***************************************************************************/
// static
JSBool JSBool
nsXPCWrappedJSClass::IsWrappedJS(nsISupports* aPtr) nsXPCWrappedJSClass::IsWrappedJS(nsISupports* aPtr)
{ {
@ -317,7 +318,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
if(type.IsPointer()) if(type.IsPointer())
pv = (nsXPCMiniVariant*) pv->val.p; pv = (nsXPCMiniVariant*) pv->val.p;
if(!XPCConvert::NativeData2JS(&val, &pv->val, type)) if(!XPCConvert::NativeData2JS(cx, &val, &pv->val, type, NULL))
{ {
retval = NS_ERROR_FAILURE; retval = NS_ERROR_FAILURE;
goto done; goto done;

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

@ -307,7 +307,8 @@ nsXPCWrappedNativeClass::GetInterfaceName()
} }
JSBool JSBool
nsXPCWrappedNativeClass::GetConstantAsJSVal(nsXPCWrappedNative* wrapper, nsXPCWrappedNativeClass::GetConstantAsJSVal(JSContext *cx,
nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc, const XPCNativeMemberDescriptor* desc,
jsval* vp) jsval* vp)
{ {
@ -328,7 +329,8 @@ nsXPCWrappedNativeClass::GetConstantAsJSVal(nsXPCWrappedNative* wrapper,
v.type = constant->GetType(); v.type = constant->GetType();
memcpy(&v.val, &mv.val, sizeof(mv.val)); memcpy(&v.val, &mv.val, sizeof(mv.val));
return XPCConvert::NativeData2JS(vp, &v.val, v.type); // XXX if iid consts are supported, then coditionally fill it in here
return XPCConvert::NativeData2JS(cx, vp, &v.val, v.type, NULL);
} }
void void
@ -362,7 +364,7 @@ nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper,
uint8 vtblIndex; uint8 vtblIndex;
nsresult invokeResult; nsresult invokeResult;
nsIAllocator* al = NULL; nsIAllocator* al = NULL;
*vp = JSVAL_NULL; *vp = JSVAL_NULL;
if(!(al = nsXPConnect::GetAllocator())) if(!(al = nsXPConnect::GetAllocator()))
@ -443,8 +445,12 @@ nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper,
if(!param.IsIn()) if(!param.IsIn())
continue; continue;
// in the future there may be a param flag indicating 'stingy'
if(type.IsPointer()) if(type.IsPointer())
{
conditional_al = al; conditional_al = al;
dp->flags |= nsXPCVariant::VAL_IS_OWNED;
}
} }
else else
{ {
@ -458,14 +464,33 @@ nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper,
if(type.TagPart() == nsXPTType::T_INTERFACE) if(type.TagPart() == nsXPTType::T_INTERFACE)
{ {
// XXX get the iid dp->flags |= nsXPCVariant::VAL_IS_IFACE;
if(!(conditional_iid = param.GetInterfaceIID()))
{
// XXX this (and others!) should throw rather than report error
ReportError(desc, "could not get interface type");
goto done;
}
} }
else if(type.TagPart() == nsXPTType::T_INTERFACE_IS) else if(type.TagPart() == nsXPTType::T_INTERFACE_IS)
{ {
// XXX get the iid dp->flags |= nsXPCVariant::VAL_IS_IFACE;
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 ||
!XPCConvert::JSData2Native(cx, &conditional_iid, argv[arg_num],
type, NULL, NULL))
{
// XXX this (and others!) should throw rather than report error
ReportError(desc, "could not get interface type");
goto done;
}
} }
if(!XPCConvert::JSData2Native(cx, &dp->val, src, type, if(!XPCConvert::JSData2Native(cx, &dp->val, src, type,
conditional_al, conditional_iid)) conditional_al, conditional_iid))
{ {
NS_ASSERTION(0, "bad type"); NS_ASSERTION(0, "bad type");
@ -489,13 +514,38 @@ nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper,
{ {
const nsXPTParamInfo& param = info->GetParam(i); const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType(); const nsXPTType& type = param.GetType();
nsID* conditional_iid = NULL;
nsXPCVariant* dp = &dispatchParams[i]; nsXPCVariant* dp = &dispatchParams[i];
if(param.IsOut()) if(param.IsOut())
{ {
jsval v; jsval v;
if(!XPCConvert::NativeData2JS(&v, &dp->val, type)) if(type.TagPart() == nsXPTType::T_INTERFACE)
{
if(!(conditional_iid = param.GetInterfaceIID()))
{
// XXX this (and others!) should throw rather than report error
ReportError(desc, "could not get interface type");
goto done;
}
}
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*)dispatchParams[arg_num].val.p))
{
// XXX this (and others!) should throw rather than report error
ReportError(desc, "could not get interface type");
goto done;
}
}
if(!XPCConvert::NativeData2JS(cx, &v, &dp->val, type,
conditional_iid))
{ {
retval = NS_ERROR_FAILURE; retval = NS_ERROR_FAILURE;
goto done; goto done;
@ -524,12 +574,11 @@ done:
{ {
nsXPCVariant* dp = &dispatchParams[i]; nsXPCVariant* dp = &dispatchParams[i];
void* p = dp->val.p; void* p = dp->val.p;
// XXX verify that ALL this this stuff is right
if(!p) if(!p)
continue; continue;
if(dp->flags & nsXPCVariant::VAL_IS_OWNED) if(dp->IsValOwned() && al)
delete [] p; al->Free(p);
else if(info->GetParam(i).GetType() == nsXPTType::T_INTERFACE) if(dp->IsValInterface())
((nsISupports*)p)->Release(); ((nsISupports*)p)->Release();
} }
@ -619,7 +668,7 @@ WrappedNative_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
if(desc) if(desc)
{ {
if(desc->IsConstant()) if(desc->IsConstant())
return clazz->GetConstantAsJSVal(wrapper, desc, vp); return clazz->GetConstantAsJSVal(cx, wrapper, desc, vp);
else if(desc->IsMethod()) else if(desc->IsMethod())
{ {
// allow for lazy creation of 'prototypical' function invoke object // allow for lazy creation of 'prototypical' function invoke object

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

@ -168,6 +168,13 @@ nsXPTParamInfo::GetInterface() const
return info; return info;
} }
nsIID*
nsXPTParamInfo::GetInterfaceIID() const
{
NS_PRECONDITION(GetType() == nsXPTType::T_INTERFACE,"not an interface");
return &InterfaceDirectoryEntryTable[type.type.interface].iid;
}
/***************************************************************************/ /***************************************************************************/
// VERY simple implementations... // VERY simple implementations...
@ -179,8 +186,8 @@ XPT_GetInterfaceInfoManager()
return InterfaceInfoManagerImpl::GetInterfaceInfoManager(); return InterfaceInfoManagerImpl::GetInterfaceInfoManager();
} }
// static // static
InterfaceInfoManagerImpl* InterfaceInfoManagerImpl*
InterfaceInfoManagerImpl::GetInterfaceInfoManager() InterfaceInfoManagerImpl::GetInterfaceInfoManager()
{ {
static InterfaceInfoManagerImpl* impl = NULL; static InterfaceInfoManagerImpl* impl = NULL;
@ -192,10 +199,10 @@ InterfaceInfoManagerImpl::GetInterfaceInfoManager()
if(impl) if(impl)
NS_ADDREF(impl); NS_ADDREF(impl);
return impl; return impl;
} }
// static // static
nsIAllocator* nsIAllocator*
InterfaceInfoManagerImpl::GetAllocator(InterfaceInfoManagerImpl* iim /*= NULL*/) InterfaceInfoManagerImpl::GetAllocator(InterfaceInfoManagerImpl* iim /*= NULL*/)
{ {
nsIAllocator* al; nsIAllocator* al;
@ -208,7 +215,7 @@ InterfaceInfoManagerImpl::GetAllocator(InterfaceInfoManagerImpl* iim /*= NULL*/)
if(!iim) if(!iim)
NS_RELEASE(iiml); NS_RELEASE(iiml);
return al; return al;
} }
static NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID); static NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID);
@ -228,17 +235,17 @@ InterfaceInfoManagerImpl::InterfaceInfoManagerImpl()
nsServiceManager::GetService(kAllocatorCID, nsServiceManager::GetService(kAllocatorCID,
kIAllocatorIID, kIAllocatorIID,
(nsISupports **)&mAllocator); (nsISupports **)&mAllocator);
} }
InterfaceInfoManagerImpl::~InterfaceInfoManagerImpl() InterfaceInfoManagerImpl::~InterfaceInfoManagerImpl()
{ {
// let the singleton leak // let the singleton leak
} }
PRBool PRBool
InterfaceInfoManagerImpl::BuildInterfaceForEntry(uint16 i) InterfaceInfoManagerImpl::BuildInterfaceForEntry(uint16 i)
{ {
XPTInterfaceDirectoryEntry *parent_interface = XPTInterfaceDirectoryEntry *parent_interface =
InterfaceDirectoryEntryTable[i].interface_descriptor->parent_interface; InterfaceDirectoryEntryTable[i].interface_descriptor->parent_interface;
uint16 parent_index = 0; uint16 parent_index = 0;
@ -252,7 +259,7 @@ InterfaceInfoManagerImpl::BuildInterfaceForEntry(uint16 i)
parent_interface ? parent_interface ?
mInfoArray[parent_index] : NULL); mInfoArray[parent_index] : NULL);
return (PRBool) mInfoArray[i]; return (PRBool) mInfoArray[i];
} }
NS_IMETHODIMP NS_IMETHODIMP
InterfaceInfoManagerImpl::GetInfoForIID(const nsIID* iid, nsIInterfaceInfo** info) InterfaceInfoManagerImpl::GetInfoForIID(const nsIID* iid, nsIInterfaceInfo** info)
@ -263,7 +270,7 @@ InterfaceInfoManagerImpl::GetInfoForIID(const nsIID* iid, nsIInterfaceInfo** inf
if(iid->Equals(entry->iid)) if(iid->Equals(entry->iid))
{ {
if(!mInfoArray[i] && !BuildInterfaceForEntry(i)) if(!mInfoArray[i] && !BuildInterfaceForEntry(i))
break; break;
*info = mInfoArray[i]; *info = mInfoArray[i];
NS_ADDREF(*info); NS_ADDREF(*info);
return NS_OK; return NS_OK;
@ -282,7 +289,7 @@ InterfaceInfoManagerImpl::GetInfoForName(const char* name, nsIInterfaceInfo** in
if(!strcmp(name, entry->name)) if(!strcmp(name, entry->name))
{ {
if(!mInfoArray[i] && !BuildInterfaceForEntry(i)) if(!mInfoArray[i] && !BuildInterfaceForEntry(i))
break; break;
*info = mInfoArray[i]; *info = mInfoArray[i];
NS_ADDREF(*info); NS_ADDREF(*info);
return NS_OK; return NS_OK;
@ -338,7 +345,7 @@ NS_IMPL_ISUPPORTS(InterfaceInfoImpl, NS_IINTERFACEINFO_IID)
InterfaceInfoImpl::InterfaceInfoImpl(XPTInterfaceDirectoryEntry* entry, InterfaceInfoImpl::InterfaceInfoImpl(XPTInterfaceDirectoryEntry* entry,
InterfaceInfoImpl* parent) InterfaceInfoImpl* parent)
: mEntry(entry), : mEntry(entry),
mParent(parent) mParent(parent)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
@ -349,7 +356,7 @@ InterfaceInfoImpl::InterfaceInfoImpl(XPTInterfaceDirectoryEntry* entry,
{ {
mMethodBaseIndex = mParent->mMethodBaseIndex + mParent->mMethodCount; mMethodBaseIndex = mParent->mMethodBaseIndex + mParent->mMethodCount;
mConstantBaseIndex = mParent->mConstantBaseIndex + mParent->mConstantCount; mConstantBaseIndex = mParent->mConstantBaseIndex + mParent->mConstantCount;
} }
else else
mMethodBaseIndex = mConstantBaseIndex = 0; mMethodBaseIndex = mConstantBaseIndex = 0;
@ -361,7 +368,7 @@ InterfaceInfoImpl::~InterfaceInfoImpl()
{ {
if(mParent) if(mParent)
NS_RELEASE(mParent); NS_RELEASE(mParent);
} }
NS_IMETHODIMP NS_IMETHODIMP
InterfaceInfoImpl::GetName(char** name) InterfaceInfoImpl::GetName(char** name)
@ -381,10 +388,10 @@ InterfaceInfoImpl::GetName(char** name)
return NS_OK; return NS_OK;
} }
} }
*name = NULL; *name = NULL;
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
NS_IMETHODIMP NS_IMETHODIMP
InterfaceInfoImpl::GetIID(nsIID** iid) InterfaceInfoImpl::GetIID(nsIID** iid)
@ -403,7 +410,7 @@ InterfaceInfoImpl::GetIID(nsIID** iid)
return NS_OK; return NS_OK;
} }
} }
*iid = NULL; *iid = NULL;
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -436,7 +443,7 @@ InterfaceInfoImpl::GetConstantCount(uint16* count)
NS_PRECONDITION(count, "bad param"); NS_PRECONDITION(count, "bad param");
*count = mConstantBaseIndex + mConstantCount; *count = mConstantBaseIndex + mConstantCount;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -456,7 +463,7 @@ InterfaceInfoImpl::GetMethodInfo(uint16 index, const nsXPTMethodInfo** info)
// else... // else...
*info = NS_STATIC_CAST(nsXPTMethodInfo*, &mEntry->interface_descriptor->method_descriptors[index-mMethodBaseIndex]); *info = NS_STATIC_CAST(nsXPTMethodInfo*, &mEntry->interface_descriptor->method_descriptors[index-mMethodBaseIndex]);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -30,7 +30,7 @@ class nsXPTType : public XPTTypeDescriptorPrefix
{ {
// NO DATA - this a flyweight wrapper // NO DATA - this a flyweight wrapper
public: public:
nsXPTType() nsXPTType()
{} // random contents {} // random contents
nsXPTType(const XPTTypeDescriptorPrefix& prefix) nsXPTType(const XPTTypeDescriptorPrefix& prefix)
{*(XPTTypeDescriptorPrefix*)this = prefix;} {*(XPTTypeDescriptorPrefix*)this = prefix;}
@ -38,10 +38,10 @@ public:
nsXPTType(const uint8& prefix) nsXPTType(const uint8& prefix)
{*(uint8*)this = prefix;} {*(uint8*)this = prefix;}
nsXPTType& operator=(uint8 val) nsXPTType& operator=(uint8 val)
{flags = val; return *this;} {flags = val; return *this;}
operator uint8() const operator uint8() const
{return flags;} {return flags;}
JSBool IsPointer() const JSBool IsPointer() const
@ -57,7 +57,7 @@ public:
{return flags <= T_WCHAR;} {return flags <= T_WCHAR;}
JSBool IsInterfacePointer() const JSBool IsInterfacePointer() const
{return (JSBool) (TagPart() == T_INTERFACE || {return (JSBool) (TagPart() == T_INTERFACE ||
TagPart() == T_INTERFACE_IS);} TagPart() == T_INTERFACE_IS);}
uint8 TagPart() const uint8 TagPart() const
@ -117,6 +117,9 @@ public:
// find (or build) the appropriate nsIInterfaceInfo. Simple :) // find (or build) the appropriate nsIInterfaceInfo. Simple :)
nsIInterfaceInfo* GetInterface() const ; nsIInterfaceInfo* GetInterface() const ;
// a *little* simpler than the above
nsIID* GetInterfaceIID() const ;
private: private:
nsXPTParamInfo(); // no implementation nsXPTParamInfo(); // no implementation
// NO DATA - this a flyweight wrapper // NO DATA - this a flyweight wrapper
@ -141,7 +144,7 @@ public:
NS_PRECONDITION(index < GetParamCount(),"bad arg"); NS_PRECONDITION(index < GetParamCount(),"bad arg");
return params[index]; return params[index];
} }
const nsXPTParamInfo GetResult() const const nsXPTParamInfo GetResult() const
{return *result;} {return *result;}
private: private:
nsXPTMethodInfo(); // no implementation nsXPTMethodInfo(); // no implementation
@ -159,14 +162,14 @@ public:
nsXPTConstant(const XPTConstDescriptor& desc) nsXPTConstant(const XPTConstDescriptor& desc)
{*(XPTConstDescriptor*)this = desc;} {*(XPTConstDescriptor*)this = desc;}
const char* GetName() const const char* GetName() const
{return name;} {return name;}
const nsXPTType GetType() const const nsXPTType GetType() const
{return type.prefix;} {return type.prefix;}
// XXX this is ugly // XXX this is ugly
const nsXPCMiniVariant* GetValue() const const nsXPCMiniVariant* GetValue() const
{return (nsXPCMiniVariant*) &value;} {return (nsXPCMiniVariant*) &value;}
private: private:
nsXPTConstant(); // no implementation nsXPTConstant(); // no implementation