From 9fbe63dd9938b67ed15565d7cc33d43fe2a66e5f Mon Sep 17 00:00:00 2001 From: "jband%netscape.com" Date: Wed, 20 Jan 1999 06:38:00 +0000 Subject: [PATCH] NOT PART OF SEAMONKEY. Workingon dealing with more types. Added access to WrappedNative from JSObject --- js/src/xpconnect/makefile.win | 1 + js/src/xpconnect/nsIXPConnect.h | 4 + js/src/xpconnect/nsXPConnect.cpp | 29 +- js/src/xpconnect/xpcbogusii.h | 15 +- js/src/xpconnect/xpcbogusmem.cpp | 0 js/src/xpconnect/xpcbogusmem.h | 0 js/src/xpconnect/xpcconvert.cpp | 305 ++++++++++----------- js/src/xpconnect/xpcprivate.h | 19 +- js/src/xpconnect/xpcwrappednativeclass.cpp | 18 ++ 9 files changed, 228 insertions(+), 163 deletions(-) create mode 100644 js/src/xpconnect/xpcbogusmem.cpp create mode 100644 js/src/xpconnect/xpcbogusmem.h diff --git a/js/src/xpconnect/makefile.win b/js/src/xpconnect/makefile.win index 2353904fe94..015cc760f03 100644 --- a/js/src/xpconnect/makefile.win +++ b/js/src/xpconnect/makefile.win @@ -38,6 +38,7 @@ OBJS= \ .\$(OBJDIR)\xpccontext.obj \ .\$(OBJDIR)\xpcbogusjs.obj \ .\$(OBJDIR)\xpcbogusii.obj \ + .\$(OBJDIR)\xpcbogusmem.obj \ .\$(OBJDIR)\xpcinvoke.obj \ .\$(OBJDIR)\xpcwrappedjs.obj \ .\$(OBJDIR)\xpcwrappedjsclass.obj \ diff --git a/js/src/xpconnect/nsIXPConnect.h b/js/src/xpconnect/nsIXPConnect.h index 1eae765c5e4..42d27ffd7c0 100644 --- a/js/src/xpconnect/nsIXPConnect.h +++ b/js/src/xpconnect/nsIXPConnect.h @@ -153,6 +153,10 @@ public: NS_IMETHOD GetNativeOfWrappedNative(nsIXPConnectWrappedNative* aWrapper, nsISupports** aObj) = 0; + NS_IMETHOD GetWrappedNativeOfJSObject(nsIJSContext* aJSContext, + nsIJSObject* aJSObj, + nsIXPConnectWrappedNative** aWrapper) = 0; + // other stuff... }; diff --git a/js/src/xpconnect/nsXPConnect.cpp b/js/src/xpconnect/nsXPConnect.cpp index 18a78522121..9e493705742 100644 --- a/js/src/xpconnect/nsXPConnect.cpp +++ b/js/src/xpconnect/nsXPConnect.cpp @@ -35,11 +35,13 @@ nsXPConnect* nsXPConnect::GetXPConnect() { if(mSelf) + { NS_ADDREF(mSelf); + } else { mSelf = new nsXPConnect(); - if(mSelf && !mSelf->mContextMap) + if(mSelf && (!mSelf->mContextMap || !mSelf->mAllocator)) { NS_RELEASE(mSelf); // XXX two line macro (bug in nsISupports.h) } @@ -52,12 +54,17 @@ nsXPConnect::nsXPConnect() NS_INIT_REFCNT(); NS_ADDREF_THIS(); mContextMap = JSContext2XPCContextMap::newMap(CONTEXT_MAP_SIZE); + mAllocator = new nsMalloc(); } nsXPConnect::~nsXPConnect() { if(mContextMap) delete mContextMap; + if(mAllocator) + { + NS_RELEASE(mAllocator); // XXX two line macro (bug in nsISupports.h) + } mSelf = NULL; } @@ -237,6 +244,26 @@ nsXPConnect::GetNativeOfWrappedNative(nsIXPConnectWrappedNative* aWrapper, return NS_OK; } +nsresult +nsXPConnect::GetWrappedNativeOfJSObject(nsIJSContext* aJSContext, + nsIJSObject* aJSObj, + nsIXPConnectWrappedNative** aWrapper) +{ + JSContext* cx; + JSObject* jsobj; + NS_PRECONDITION(aJSContext,"bad param"); + NS_PRECONDITION(aJSObj,"bad param"); + NS_PRECONDITION(aWrapper,"bad param"); + + if(aWrapper && aJSObj && + NS_SUCCEEDED(aJSObj->GetNative(&jsobj)) && jsobj && + NS_SUCCEEDED(aJSContext->GetNative(&cx)) && cx) + *aWrapper = nsXPCWrappedNativeClass::GetWrappedNativeOfJSObject(cx,jsobj); + else + *aWrapper = NULL; + return *aWrapper ? NS_OK : NS_ERROR_FAILURE; +} + XPC_PUBLIC_API(nsIXPConnect*) XPC_GetXPConnect() { diff --git a/js/src/xpconnect/xpcbogusii.h b/js/src/xpconnect/xpcbogusii.h index 81ac9c1db6c..84488040efe 100644 --- a/js/src/xpconnect/xpcbogusii.h +++ b/js/src/xpconnect/xpcbogusii.h @@ -38,8 +38,7 @@ public: IS_POINTER = 0x80, IS_UNIQUE_POINTER = 0x40, IS_REFERENCE = 0x20, - SPECIAL_BIT = 0x10, - TYPE_MASK = 0xf, + TYPE_MASK = 0x1f, T_I8 = 0, T_I16 = 1, @@ -71,10 +70,12 @@ public: T_P_WCHAR = IS_POINTER | 12, T_P_VOID = IS_POINTER | 13, T_P_IID = IS_POINTER | 14, - T_STRING = IS_POINTER | 15, + T_BSTR = IS_POINTER | 15, + T_P_CHAR_STR = IS_POINTER | 16, + T_P_WCHAR_STR = IS_POINTER | 17, - T_INTERFACE = 16, /* SPECIAL_BIT | 0 */ - T_INTERFACE_IS = 17 /* SPECIAL_BIT | 1 */ + T_INTERFACE = 18, + T_INTERFACE_IS = 19 }; }; @@ -201,13 +202,15 @@ public: IS_GETTER = 0x80, IS_SETTER = 0x40, IS_VAR_ARGS = 0x20, - IS_CONSTRUCTOR = 0x10 + IS_CONSTRUCTOR = 0x10, + IS_HIDDEN = 0x08 }; JSBool IsGetter() const {return (JSBool) (mFlags & IS_GETTER);} JSBool IsSetter() const {return (JSBool) (mFlags & IS_SETTER);} JSBool IsVarArgs() const {return (JSBool) (mFlags & IS_VAR_ARGS);} JSBool IsConstructor() const {return (JSBool) (mFlags & IS_CONSTRUCTOR);} + JSBool IsHidden() const {return (JSBool) (mFlags & IS_HIDDEN);} const char* GetName() const {return mName;} uint8 GetParamCount() const {return mParamCount;} const nsXPCParamInfo& GetParam(uint8 index) const diff --git a/js/src/xpconnect/xpcbogusmem.cpp b/js/src/xpconnect/xpcbogusmem.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/js/src/xpconnect/xpcbogusmem.h b/js/src/xpconnect/xpcbogusmem.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/js/src/xpconnect/xpcconvert.cpp b/js/src/xpconnect/xpcconvert.cpp index 2a015a5e7e7..2bc4e879df6 100644 --- a/js/src/xpconnect/xpcconvert.cpp +++ b/js/src/xpconnect/xpcconvert.cpp @@ -36,66 +36,63 @@ xpc_ConvertNativeData2JS(jsval* d, const void* s, const nsXPCType& type) NS_PRECONDITION(s, "bad param"); NS_PRECONDITION(d, "bad param"); - if(type == nsXPCType::T_INTERFACE) - { - // XXX implement INTERFACE + jsdouble dbl; - // 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; - } - else if(type == nsXPCType::T_INTERFACE_IS) + switch(type & nsXPCType::TYPE_MASK) { - // XXX implement INTERFACE_IS - NS_ASSERTION(0,"interface_is params not supported"); - return JS_FALSE; - } - else if(type == nsXPCType::T_STRING) - { - // XXX implement STRING - NS_ASSERTION(0,"string params not supported"); - return JS_FALSE; - } - else if(type == nsXPCType::T_P_IID) - { - // XXX implement IID - NS_ASSERTION(0,"iid params not supported"); - return JS_FALSE; - } - else if(type == nsXPCType::T_P_VOID) - { - // XXX implement void* - NS_ASSERTION(0,"void* params not supported"); - return JS_FALSE; - } - else { - jsdouble dbl; - - switch(type & nsXPCType::TYPE_MASK) + case nsXPCType::T_I8 : *d = INT_TO_JSVAL((int32)*((int8*)s)); break; + case nsXPCType::T_I16 : *d = INT_TO_JSVAL((int32)*((int16*)s)); break; + case nsXPCType::T_I32 : *d = FIT_32(*((int32*)s),dbl); break; + case nsXPCType::T_I64 : *d = JAM_DOUBLE(*((int64*)s),dbl); break; + case nsXPCType::T_U8 : *d = INT_TO_JSVAL((int32)*((uint8*)s)); break; + case nsXPCType::T_U16 : *d = INT_TO_JSVAL((int32)*((uint16*)s)); break; + case nsXPCType::T_U32 : *d = FIT_32(*((uint32*)s),dbl); break; + case nsXPCType::T_U64 : *d = JAM_DOUBLE_U64(*((uint64*)s),dbl); break; + case nsXPCType::T_FLOAT : *d = JAM_DOUBLE(*((float*)s),dbl); break; + case nsXPCType::T_DOUBLE: *d = DOUBLE_TO_JSVAL(*((double*)s)); break; + case nsXPCType::T_BOOL : *d = *((PRBool*)s)?JSVAL_TRUE:JSVAL_FALSE; break; + case nsXPCType::T_CHAR : *d = INT_TO_JSVAL((int32)*((char*)s)); break; + case nsXPCType::T_WCHAR : *d = INT_TO_JSVAL((int32)*((wchar_t*)s)); break; + default: + switch(type) { - case nsXPCType::T_I8 : *d = INT_TO_JSVAL((int32)*((int8*)s)); break; - case nsXPCType::T_I16 : *d = INT_TO_JSVAL((int32)*((int16*)s)); break; - case nsXPCType::T_I32 : *d = FIT_32(*((int32*)s),dbl); break; - case nsXPCType::T_I64 : *d = JAM_DOUBLE(*((int64*)s),dbl); break; - case nsXPCType::T_U8 : *d = INT_TO_JSVAL((int32)*((uint8*)s)); break; - case nsXPCType::T_U16 : *d = INT_TO_JSVAL((int32)*((uint16*)s)); break; - case nsXPCType::T_U32 : *d = FIT_32(*((uint32*)s),dbl); break; - case nsXPCType::T_U64 : *d = JAM_DOUBLE_U64(*((uint64*)s),dbl); break; - case nsXPCType::T_FLOAT : *d = JAM_DOUBLE(*((float*)s),dbl); break; - case nsXPCType::T_DOUBLE: *d = DOUBLE_TO_JSVAL(*((double*)s)); break; - case nsXPCType::T_BOOL : *d = *((PRBool*)s)?JSVAL_TRUE:JSVAL_FALSE; break; - // XXX need to special case char* and wchar_t* - case nsXPCType::T_CHAR : *d = INT_TO_JSVAL((int32)*((char*)s)); break; - case nsXPCType::T_WCHAR : *d = INT_TO_JSVAL((int32)*((wchar_t*)s)); break; + case nsXPCType::T_P_VOID: + // XXX implement void* + NS_ASSERTION(0,"void* params not supported"); + return JS_FALSE; + case nsXPCType::T_P_IID: + // XXX implement IID + NS_ASSERTION(0,"iid params not supported"); + return JS_FALSE; + case nsXPCType::T_BSTR: + // XXX implement BSTR + NS_ASSERTION(0,"string params not supported"); + return JS_FALSE; + case nsXPCType::T_P_CHAR_STR: + // XXX implement CHAR_STR + NS_ASSERTION(0,"string params not supported"); + return JS_FALSE; + case nsXPCType::T_P_WCHAR_STR: + // XXX implement WCHAR_STR + NS_ASSERTION(0,"string params not supported"); + return JS_FALSE; + case nsXPCType::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 nsXPCType::T_INTERFACE_IS: + // XXX implement INTERFACE_IS + NS_ASSERTION(0,"interface_is params not supported"); + return JS_FALSE; default: NS_ASSERTION(0, "bad type"); return JS_FALSE; } - } + } return JS_TRUE; } @@ -106,111 +103,113 @@ xpc_ConvertJSData2Native(JSContext* cx, void* d, const jsval* s, NS_PRECONDITION(s, "bad param"); NS_PRECONDITION(d, "bad param"); - if(type == nsXPCType::T_INTERFACE) - { - // XXX implement INTERFACE + int32 ti; + uint32 tu; + jsdouble td; + JSBool r; - // 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; - } - else if(type == nsXPCType::T_INTERFACE_IS) + switch(type & nsXPCType::TYPE_MASK) { - // XXX implement INTERFACE_IS - NS_ASSERTION(0,"interface_is params not supported"); - return JS_FALSE; - } - else if(type == nsXPCType::T_STRING) - { - // XXX implement STRING - NS_ASSERTION(0,"string params not supported"); - return JS_FALSE; - } - else if(type == nsXPCType::T_P_IID) - { - // XXX implement IID - NS_ASSERTION(0,"iid params not supported"); - return JS_FALSE; - } - else if(type == nsXPCType::T_P_VOID) - { - // XXX implement void* - NS_ASSERTION(0,"void* params not supported"); - return JS_FALSE; - } - else { - int32 ti; - uint32 tu; - jsdouble td; - JSBool r; - - switch(type & nsXPCType::TYPE_MASK) + case nsXPCType::T_I8 : + r = JS_ValueToECMAInt32(cx, *s, &ti); + *((int8*)d) = (int8) ti; + break; + case nsXPCType::T_I16 : + r = JS_ValueToECMAInt32(cx, *s, &ti); + *((int16*)d) = (int16) ti; + break; + case nsXPCType::T_I32 : + r = JS_ValueToECMAInt32(cx, *s, (int32*)d); + break; + case nsXPCType::T_I64 : + if(JSVAL_IS_INT(*s)) { - case nsXPCType::T_I8 : r = JS_ValueToECMAInt32(cx, *s, &ti); - *((int8*)d) = (int8) ti; - break; - case nsXPCType::T_I16 : - r = JS_ValueToECMAInt32(cx, *s, &ti); - *((int16*)d) = (int16) ti; - break; - case nsXPCType::T_I32 : - r = JS_ValueToECMAInt32(cx, *s, (int32*)d); - break; - case nsXPCType::T_I64 : - if(JSVAL_IS_INT(*s)) - { - r = JS_ValueToECMAInt32(cx, *s, &ti); - *((int64*)d) = (int64) ti; - } - else - { - r = JS_ValueToNumber(cx, *s, &td); - if(r) *((int64*)d) = (int64) td; - } - break; - case nsXPCType::T_U8 : - r = JS_ValueToECMAUint32(cx, *s, &tu); - *((uint8*)d) = (uint8) tu; - break; - case nsXPCType::T_U16 : - r = JS_ValueToECMAUint32(cx, *s, &tu); - *((uint16*)d) = (uint16) tu; - break; - case nsXPCType::T_U32 : - r = JS_ValueToECMAUint32(cx, *s, (uint32*)d); - break; - case nsXPCType::T_U64 : - if(JSVAL_IS_INT(*s)) - { - r = JS_ValueToECMAUint32(cx, *s, &tu); - *((uint64*)d) = (uint64) tu; - } - else - { - r = JS_ValueToNumber(cx, *s, &td); - // XXX Win32 can't handle double to uint64 directly - if(r) *((uint64*)d) = (uint64)((int64) td); - } - break; - case nsXPCType::T_FLOAT : + *((int64*)d) = (int64) ti; + } + else + { r = JS_ValueToNumber(cx, *s, &td); - if(r) *((float*)d) = (float) td; - break; - case nsXPCType::T_DOUBLE : - r = JS_ValueToNumber(cx, *s, (double*)d); - break; - case nsXPCType::T_BOOL : - r = JS_ValueToBoolean(cx, *s, (PRBool*)d); - break; - - // XXX should we special case char* and wchar_t* to be strings? - case nsXPCType::T_CHAR : - case nsXPCType::T_WCHAR : + if(r) *((int64*)d) = (int64) td; + } + break; + case nsXPCType::T_U8 : + r = JS_ValueToECMAUint32(cx, *s, &tu); + *((uint8*)d) = (uint8) tu; + break; + case nsXPCType::T_U16 : + r = JS_ValueToECMAUint32(cx, *s, &tu); + *((uint16*)d) = (uint16) tu; + break; + case nsXPCType::T_U32 : + r = JS_ValueToECMAUint32(cx, *s, (uint32*)d); + break; + case nsXPCType::T_U64 : + if(JSVAL_IS_INT(*s)) + { + r = JS_ValueToECMAUint32(cx, *s, &tu); + *((uint64*)d) = (uint64) tu; + } + else + { + r = JS_ValueToNumber(cx, *s, &td); + // XXX Win32 can't handle double to uint64 directly + if(r) *((uint64*)d) = (uint64)((int64) td); + } + break; + case nsXPCType::T_FLOAT : + r = JS_ValueToNumber(cx, *s, &td); + if(r) *((float*)d) = (float) td; + break; + case nsXPCType::T_DOUBLE : + r = JS_ValueToNumber(cx, *s, (double*)d); + break; + case nsXPCType::T_BOOL : + r = JS_ValueToBoolean(cx, *s, (PRBool*)d); + break; + case nsXPCType::T_CHAR : + r = JS_ValueToECMAUint32(cx, *s, &tu); + *((char*)d) = (char) tu; + break; + case nsXPCType::T_WCHAR : + r = JS_ValueToECMAUint32(cx, *s, &tu); + *((uint16*)d) = (uint16) tu; + break; + default: + switch(type) + { + case nsXPCType::T_P_VOID: + // XXX implement void* + NS_ASSERTION(0,"void* params not supported"); + return JS_FALSE; + case nsXPCType::T_P_IID: + // XXX implement IID + NS_ASSERTION(0,"iid params not supported"); + return JS_FALSE; + case nsXPCType::T_BSTR: + // XXX implement BSTR + NS_ASSERTION(0,"string params not supported"); + return JS_FALSE; + case nsXPCType::T_P_CHAR_STR: + // XXX implement CHAR_STR + NS_ASSERTION(0,"string params not supported"); + return JS_FALSE; + case nsXPCType::T_P_WCHAR_STR: + // XXX implement WCHAR_STR + NS_ASSERTION(0,"string params not supported"); + return JS_FALSE; + case nsXPCType::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 nsXPCType::T_INTERFACE_IS: + // XXX implement INTERFACE_IS + NS_ASSERTION(0,"interface_is params not supported"); + return JS_FALSE; default: NS_ASSERTION(0, "bad type"); return JS_FALSE; diff --git a/js/src/xpconnect/xpcprivate.h b/js/src/xpconnect/xpcprivate.h index 6de29276eac..a015e013ace 100644 --- a/js/src/xpconnect/xpcprivate.h +++ b/js/src/xpconnect/xpcprivate.h @@ -32,6 +32,7 @@ #include "xpcbogusjs.h" #include "xpcbogusii.h" +#include "xpcbogusmem.h" extern const char* XPC_VAL_STR; // 'val' property name for out params @@ -67,13 +68,22 @@ class nsXPConnect : public nsIXPConnect NS_IMETHOD GetNativeOfWrappedNative(nsIXPConnectWrappedNative* aWrapper, nsISupports** aObj); + NS_IMETHOD GetWrappedNativeOfJSObject(nsIJSContext* aJSContext, + nsIJSObject* aJSObj, + nsIXPConnectWrappedNative** aWrapper); - /// non-interface implementation + // non-interface implementation public: static nsXPConnect* GetXPConnect(); - JSContext2XPCContextMap* GetContextMap() {return mContextMap;} XPCContext* GetContext(JSContext* cx); + JSContext2XPCContextMap* GetContextMap() {return mContextMap;} + nsIMalloc* GetAllocator() + { + if(mAllocator) + NS_ADDREF(mAllocator); + return mAllocator; + } virtual ~nsXPConnect(); private: @@ -81,8 +91,9 @@ private: XPCContext* NewContext(JSContext* cx, JSObject* global); private: + static nsXPConnect* mSelf; JSContext2XPCContextMap* mContextMap; - static nsXPConnect* mSelf; + nsIMalloc* mAllocator; }; /***************************************************************************/ @@ -270,6 +281,8 @@ public: static JSBool InitForContext(XPCContext* xpcc); JSObject* NewInstanceJSObject(nsXPCWrappedNative* self); + static nsXPCWrappedNative* GetWrappedNativeOfJSObject(JSContext* cx, + JSObject* jsobj); int GetMemberCount() const {return mMemberCount;} const XPCNativeMemberDescriptor* GetMemberDescriptor(int i) const diff --git a/js/src/xpconnect/xpcwrappednativeclass.cpp b/js/src/xpconnect/xpcwrappednativeclass.cpp index 56756a868e9..af5c14fc97c 100644 --- a/js/src/xpconnect/xpcwrappednativeclass.cpp +++ b/js/src/xpconnect/xpcwrappednativeclass.cpp @@ -105,6 +105,8 @@ nsXPCWrappedNativeClass::BuildMemberDescriptors() return JS_TRUE; } + // XXX since getters and setters share a descriptor, we might not use all + // of the objects that get alloc'd here mMembers = new XPCNativeMemberDescriptor[totalCount]; if(!mMembers) return JS_FALSE; @@ -119,6 +121,11 @@ nsXPCWrappedNativeClass::BuildMemberDescriptors() if(NS_FAILED(mInfo->GetMethodInfo(i, &info))) return JS_FALSE; + // XX perhaps this should be extended to be 'CanBeReflected()' to + // also cover methods with non-complient signatures. + if(info->IsHidden()) + continue; + idval = STRING_TO_JSVAL(JS_InternString(cx, info->GetName())); JS_ValueToId(cx, idval, &id); if(!id) @@ -130,6 +137,7 @@ nsXPCWrappedNativeClass::BuildMemberDescriptors() if(info->IsSetter()) { NS_ASSERTION(mMemberCount,"bad setter"); + // XXX ASSUMES Getter/Setter pairs are next to each other desc = &mMembers[mMemberCount-1]; NS_ASSERTION(desc->id == id,"bad setter"); NS_ASSERTION(desc->category == XPCNativeMemberDescriptor::ATTRIB_RO,"bad setter"); @@ -880,3 +888,13 @@ nsXPCWrappedNativeClass::NewInstanceJSObject(nsXPCWrappedNative* self) return jsobj; } +// static +nsXPCWrappedNative* +nsXPCWrappedNativeClass::GetWrappedNativeOfJSObject(JSContext* cx, + JSObject* jsobj) +{ + NS_PRECONDITION(jsobj, "bad param"); + if(jsobj && JS_InstanceOf(cx, jsobj, &WrappedNative_class, NULL)) + return (nsXPCWrappedNative*) JS_GetPrivate(cx, jsobj); + return NULL; +}