diff --git a/mozilla/js/src/xpconnect/genstubs.pl b/mozilla/js/src/xpconnect/genstubs.pl new file mode 100644 index 00000000000..47f544f4472 --- /dev/null +++ b/mozilla/js/src/xpconnect/genstubs.pl @@ -0,0 +1,55 @@ +#!/usr/local/bin/perl + +# This is used to generate entry points for WrappedJS. We generate a file to +# be included in the declaraion and a file to be used for expanding macros +# to represent the implementation of the stubs. + +$entry_count = 256; +$sentinel_count = 10; + +$decl_name = "xpcstubsdecl.inc"; +$def_name = "xpcstubsdef.inc"; + +## +## Write the declarations include file +## + +die "Can't open $decl_name" if !open(OUTFILE, ">$decl_name"); + +print OUTFILE "// generated file - DO NOT EDIT \n\n"; +print OUTFILE "// includes ",$entry_count," stub entries, and ", + $sentinel_count," sentinel entries\n\n"; +print OUTFILE "// declarations of normal stubs...\n"; +print OUTFILE "// 0 is QueryInterface\n"; +print OUTFILE "// 1 is AddRef\n"; +print OUTFILE "// 2 is Release\n"; +for($i = 0; $i < $entry_count; $i++) { + print OUTFILE "NS_IMETHOD Stub",$i+3,"();\n"; +} + +print OUTFILE "\n// declarations of sentinel stubs\n"; + +for($i = 0; $i < $sentinel_count; $i++) { + print OUTFILE "NS_IMETHOD Sentinel",$i,"();\n"; +} +close(OUTFILE); + + +## +## Write the definitions include file. This assumes a macro will be used to +## expand the entries written... +## + +die "Can't open $def_name" if !open(OUTFILE, ">$def_name"); + +print OUTFILE "// generated file - DO NOT EDIT \n\n"; +print OUTFILE "// includes ",$entry_count," stub entries, and ", + $sentinel_count," sentinel entries\n\n"; + +for($i = 0; $i < $entry_count; $i++) { + print OUTFILE "STUB_ENTRY(",$i+3,")\n"; +} + +for($i = 0; $i < $sentinel_count; $i++) { + print OUTFILE "SENTINEL_ENTRY(",$i,")\n"; +} diff --git a/mozilla/js/src/xpconnect/makefile.win b/mozilla/js/src/xpconnect/makefile.win index a6a8ccacdda..5b6133a37a1 100644 --- a/mozilla/js/src/xpconnect/makefile.win +++ b/mozilla/js/src/xpconnect/makefile.win @@ -31,11 +31,15 @@ REQUIRES=xpcom js DEFINES=-DWIN32_LEAN_AND_MEAN -DEXPORT_XPC_API OBJS= \ + .\$(OBJDIR)\xpcnsid.obj \ + .\$(OBJDIR)\xpcstubs.obj \ .\$(OBJDIR)\xpcmaps.obj \ .\$(OBJDIR)\xpccontext.obj \ .\$(OBJDIR)\xpcbogusjs.obj \ .\$(OBJDIR)\xpcbogusii.obj \ .\$(OBJDIR)\xpcinvoke.obj \ + .\$(OBJDIR)\xpcwrappedjs.obj \ + .\$(OBJDIR)\xpcwrappedjsclass.obj \ .\$(OBJDIR)\xpcwrappednative.obj \ .\$(OBJDIR)\xpcwrappednativeclass.obj \ .\$(OBJDIR)\nsXPConnect.obj \ diff --git a/mozilla/js/src/xpconnect/nsIXPConnect.h b/mozilla/js/src/xpconnect/nsIXPConnect.h index 20c3cf6ce19..1eae765c5e4 100644 --- a/mozilla/js/src/xpconnect/nsIXPConnect.h +++ b/mozilla/js/src/xpconnect/nsIXPConnect.h @@ -170,7 +170,7 @@ XPC_NewJSObject(nsIJSContext* aJSContext, JSObject* jsobj); #ifdef DEBUG // XXX temprary forawrd declaration -class nsXPCVarient; +struct nsXPCVarient; XPC_PUBLIC_API(nsresult) XPC_TestInvoke(void* that, PRUint32 index, uint32 paramCount, nsXPCVarient* params); diff --git a/mozilla/js/src/xpconnect/nsXPConnect.cpp b/mozilla/js/src/xpconnect/nsXPConnect.cpp index 920d510aabf..18a78522121 100644 --- a/mozilla/js/src/xpconnect/nsXPConnect.cpp +++ b/mozilla/js/src/xpconnect/nsXPConnect.cpp @@ -156,7 +156,34 @@ nsXPConnect::WrapJS(nsIJSContext* aJSContext, REFNSIID aIID, nsIXPConnectWrappedJS** aWrapper) { - // XXX implement... + NS_PRECONDITION(aJSContext,"bad param"); + NS_PRECONDITION(aJSObj,"bad param"); + NS_PRECONDITION(aWrapper,"bad param"); + + *aWrapper = NULL; + + JSObject* jsobj; + if(NS_FAILED(aJSObj->GetNative(&jsobj)) || !jsobj) + { + NS_ASSERTION(0, "bad nsIJSObject*"); + return NS_ERROR_FAILURE; + } + + JSContext* cx; + if(NS_FAILED(aJSContext->GetNative(&cx))) + return NS_ERROR_FAILURE; + + XPCContext* xpcc = GetContext(cx); + if(!xpcc) + return NS_ERROR_FAILURE; + + nsXPCWrappedJS* wrapper = + nsXPCWrappedJS::GetNewOrUsedWrapper(xpcc, jsobj, aIID); + + if(!wrapper) + return NS_ERROR_FAILURE; + + *aWrapper = wrapper; return NS_OK; } @@ -213,5 +240,8 @@ nsXPConnect::GetNativeOfWrappedNative(nsIXPConnectWrappedNative* aWrapper, XPC_PUBLIC_API(nsIXPConnect*) XPC_GetXPConnect() { + // temp test... +// nsXPCWrappedJS* p = new nsXPCWrappedJS(); +// p->Stub5(); return nsXPConnect::GetXPConnect(); } diff --git a/mozilla/js/src/xpconnect/test/TestXPC.cpp b/mozilla/js/src/xpconnect/test/TestXPC.cpp index fc4e64f90f2..449074f91bc 100644 --- a/mozilla/js/src/xpconnect/test/TestXPC.cpp +++ b/mozilla/js/src/xpconnect/test/TestXPC.cpp @@ -15,7 +15,7 @@ class nsITestXPCFoo : public nsISupports { public: - NS_IMETHOD Test(int p1, int p2) = 0; + NS_IMETHOD Test(int p1, int p2, int* retval) = 0; NS_IMETHOD Test2() = 0; }; @@ -33,7 +33,7 @@ public: class nsTestXPCFoo : public nsITestXPCFoo2 { NS_DECL_ISUPPORTS; - NS_IMETHOD Test(int p1, int p2); + NS_IMETHOD Test(int p1, int p2, int* retval); NS_IMETHOD Test2(); nsTestXPCFoo(); }; @@ -46,9 +46,10 @@ nsresult nsTestXPCFoo::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_OK; } -nsresult nsTestXPCFoo::Test(int p1, int p2) +nsresult nsTestXPCFoo::Test(int p1, int p2, int* retval) { printf("nsTestXPCFoo::Test called with p1 = %d and p2 = %d\n", p1, p2); + *retval = p1+p2; return NS_OK; } nsresult nsTestXPCFoo::Test2() @@ -171,16 +172,40 @@ int main() JS_SetProperty(cx, glob, "foo", &v); char* txt[] = { + "print('foo = '+foo)", "print('foo.five = '+ foo.five)", "print('foo.six = '+ foo.six)", "print('foo.bogus = '+ foo.bogus)", - "foo.Test(10,20)", + "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", 0, }; for(char** p = txt; *p; p++) JS_EvaluateScript(cx, glob, *p, strlen(*p), "builtin", 1, &rval); + if(JS_GetProperty(cx, glob, "bar", &v) && JSVAL_IS_OBJECT(v)) + { + JSObject* bar = JSVAL_TO_OBJECT(v); + nsIXPConnectWrappedJS* wrapper; + if(NS_SUCCEEDED(xpc->WrapJS(xpccx, + XPC_NewJSObject(xpccx, JSVAL_TO_OBJECT(v)), + kIFooIID, &wrapper))) + { + nsITestXPCFoo* ptr = (nsITestXPCFoo*)wrapper; + int result; + ptr->Test(11, 13, &result); + printf("call to ptr->Test returned %d\n", result); + NS_RELEASE(wrapper); + + } + } + NS_RELEASE(obj); NS_RELEASE(com_obj); diff --git a/mozilla/js/src/xpconnect/xpcbogusii.cpp b/mozilla/js/src/xpconnect/xpcbogusii.cpp index fd55f8ea792..f733b77a48f 100644 --- a/mozilla/js/src/xpconnect/xpcbogusii.cpp +++ b/mozilla/js/src/xpconnect/xpcbogusii.cpp @@ -46,9 +46,10 @@ nsInterfaceInfo::nsInterfaceInfo(REFNSIID aIID, const char* aName, mMethodCount = 4; mMethods = new nsXPCMethodInfo[4]; - nsXPCParamInfo* params = new nsXPCParamInfo[2]; + nsXPCParamInfo* params = new nsXPCParamInfo[3]; params[0] = nsXPCParamInfo(nsXPCParamInfo::IS_IN, nsXPCType::T_I32); params[1] = nsXPCParamInfo(nsXPCParamInfo::IS_IN, nsXPCType::T_I32); + params[2] = nsXPCParamInfo(nsXPCParamInfo::IS_OUT | nsXPCParamInfo::IS_RETVAL, nsXPCType::T_I32); nsXPCParamInfo result = nsXPCParamInfo(nsXPCParamInfo::IS_OUT, nsXPCType::T_U32); // XXX these are bogus declarations - don't call! @@ -56,7 +57,7 @@ nsInterfaceInfo::nsInterfaceInfo(REFNSIID aIID, const char* aName, mMethods[1] = nsXPCMethodInfo(0, "AddRef", 0, NULL, result); mMethods[2] = nsXPCMethodInfo(0, "Release", 0, NULL, result); // this one should be callable (in test/TestXPC.cpp) - mMethods[3] = nsXPCMethodInfo(0, "Test", 2, params, result); + mMethods[3] = nsXPCMethodInfo(0, "Test", 3, params, result); /////// diff --git a/mozilla/js/src/xpconnect/xpcbogusii.h b/mozilla/js/src/xpconnect/xpcbogusii.h index e94df9ce069..81ac9c1db6c 100644 --- a/mozilla/js/src/xpconnect/xpcbogusii.h +++ b/mozilla/js/src/xpconnect/xpcbogusii.h @@ -76,40 +76,13 @@ public: T_INTERFACE = 16, /* SPECIAL_BIT | 0 */ T_INTERFACE_IS = 17 /* SPECIAL_BIT | 1 */ }; - - uint8 WordCount() const - { - static uint8 word_table[] = - { - 1, // T_I8 - 1, // T_I16 - 1, // T_I32 - 2, // T_I64 - 1, // T_U8 - 1, // T_U16 - 1, // T_U32 - 2, // T_U64 - 1, // T_FLOAT - 2, // T_DOUBLE - 1, // T_BOOL - 1, // T_CHAR - 1 // T_WCHAR - }; - if(t & IS_POINTER) - return 1; - if(t & SPECIAL_BIT) - { - NS_ASSERTION(0,"net yet implemented"); - return 1; - } - return word_table[t & TYPE_MASK]; - } }; -class nsXPCVarient +// this is used only for WrappedJS stub param repackaging +struct nsXPCMiniVarient { -public: - // val must come first! +// No ctors or dtors so that we can use arrays of these on the stack +// with no penalty. union { int8 i8; @@ -126,9 +99,45 @@ public: char c; wchar_t wc; void* p; - } val; + } val; +}; +struct nsXPCVarient +{ +// No ctors or dtors so that we can use arrays of these on the stack +// with no penalty. + union + { + int8 i8; + int16 i16; + int32 i32; + int64 i64; + uint8 u8; + uint16 u16; + uint32 u32; + uint64 u64; + float f; + double d; + PRBool b; + char c; + wchar_t wc; + void* p; + nsID id; + + } val; + void* ptr; + void* ptr2; nsXPCType type; + uint8 flags; + + enum + { + PTR_IS_DATA = 0x1, // used for OUT params, ptr points to data in val + VAL_IS_OWNED = 0x2 // val.p holds an alloced ptr that must be freed + }; + + JSBool IsPtrData() const {return (JSBool) (flags & PTR_IS_DATA);} + JSBool IsValOwned() const {return (JSBool) (flags & VAL_IS_OWNED);} }; diff --git a/mozilla/js/src/xpconnect/xpccontext.cpp b/mozilla/js/src/xpconnect/xpccontext.cpp index e2b08610f97..14d63a2a434 100644 --- a/mozilla/js/src/xpconnect/xpccontext.cpp +++ b/mozilla/js/src/xpconnect/xpccontext.cpp @@ -50,6 +50,8 @@ XPCContext::newXPCContext(JSContext* aJSContext, xpcc->GetWrappedNativeMap() && xpcc->GetWrappedJSClassMap() && xpcc->GetWrappedNativeClassMap() && + xpc_InitIDClass(xpcc) && + nsXPCWrappedJSClass::InitForContext(xpcc) && nsXPCWrappedNativeClass::InitForContext(xpcc)) { return xpcc; diff --git a/mozilla/js/src/xpconnect/xpcinvoke.cpp b/mozilla/js/src/xpconnect/xpcinvoke.cpp index 7d7b80d287b..462c74bb748 100644 --- a/mozilla/js/src/xpconnect/xpcinvoke.cpp +++ b/mozilla/js/src/xpconnect/xpcinvoke.cpp @@ -25,12 +25,17 @@ // Remember that on Win32 these 'words' are 32bit DWORDS static uint32 __stdcall -invoke_count_words(uint32 paramCount, nsXPCVarient* src) +invoke_count_words(uint32 paramCount, nsXPCVarient* s) { uint32 result = 0; - for(uint32 i = 0; i < paramCount; i++, src++) + for(uint32 i = 0; i < paramCount; i++, s++) { - switch(src->type) + if(s->IsPtrData()) + { + result++; + continue; + } + switch(s->type) { case nsXPCType::T_I8 : case nsXPCType::T_I16 : @@ -56,7 +61,7 @@ invoke_count_words(uint32 paramCount, nsXPCVarient* src) result++; break; default: - NS_ASSERTION(src->type & nsXPCType::IS_POINTER, "bad type"); + NS_ASSERTION(s->type & nsXPCType::IS_POINTER, "bad type"); result++; break; } @@ -69,6 +74,11 @@ invoke_copy_to_stack(uint32* d, uint32 paramCount, nsXPCVarient* s) { for(uint32 i = 0; i < paramCount; i++, d++, s++) { + if(s->IsPtrData()) + { + *((void**)d) = s->ptr; + continue; + } switch(s->type) { case nsXPCType::T_I8 : *((int8*) d) = s->val.i8; break; diff --git a/mozilla/js/src/xpconnect/xpcnsid.cpp b/mozilla/js/src/xpconnect/xpcnsid.cpp new file mode 100644 index 00000000000..abf2b11176a --- /dev/null +++ b/mozilla/js/src/xpconnect/xpcnsid.cpp @@ -0,0 +1,204 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* Implement the nsID JavaScript class. */ + +#include "xpcprivate.h" + +// IDData hold the private data +class IDData +{ +public: + IDData(); // not implemented + IDData(const nsID& aID); + IDData(JSContext *cx, const IDData& r); + ~IDData(); // no virtual functions + + JSBool GetString(JSContext *cx, jsval *rval); + JSBool Equals(const IDData& r); + void Cleanup(JSContext *cx); +private: + nsID mID; + JSString* mStr; +}; + +IDData::IDData(const nsID& aID) : mID(aID), mStr(NULL) {} + +IDData::IDData(JSContext *cx, const IDData& r) : mID(r.mID), mStr(r.mStr) +{ + if(mStr) + JS_AddRoot(cx, &mStr); +} +IDData::~IDData() +{ + NS_ASSERTION(!mStr, "deleting IDData without calling Cleanup first"); +} + +void +IDData::Cleanup(JSContext *cx) +{ + if(mStr) + { + JS_RemoveRoot(cx, &mStr); + mStr = NULL; + } +} + +JSBool +IDData::GetString(JSContext *cx, jsval *rval) +{ + if(!mStr) + { + char* str = mID.ToString(); + NS_ASSERTION(str, "nsID.ToString failed"); + if(str) + { + if(NULL != (mStr = JS_NewStringCopyZ(cx, str))) + JS_AddRoot(cx, &mStr); + delete [] str; + } + } + *rval = STRING_TO_JSVAL(mStr); + return (JSBool) mStr; +} + +JSBool +IDData::Equals(const IDData& r) +{ + return (JSBool) mID.Equals(r.mID); +} + +/***************************************************************************/ + +JS_STATIC_DLL_CALLBACK(void) +nsID_finalize(JSContext *cx, JSObject *obj) +{ + IDData* data = (IDData*) JS_GetPrivate(cx, obj); + if(data) + { + data->Cleanup(cx); + delete data; + } +} + +static JSClass nsID_class = { + "nsID", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nsID_finalize +}; + +JS_STATIC_DLL_CALLBACK(JSBool) +nsID_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + IDData* data; + + if(!JS_InstanceOf(cx, obj, &nsID_class, NULL) || + !(data = (IDData*) JS_GetPrivate(cx, obj))) + return JS_FALSE; + + return data->GetString(cx, rval); +} + +JS_STATIC_DLL_CALLBACK(JSBool) +nsID_equals(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *obj2; + IDData* data1; + IDData* data2; + + if(!JS_InstanceOf(cx, obj, &nsID_class, NULL) || + !argc || !JSVAL_IS_OBJECT(argv[0]) || + !(obj2 = JSVAL_TO_OBJECT(argv[0])) || + !JS_InstanceOf(cx, obj2, &nsID_class, NULL) || + !(data1 = (IDData*) JS_GetPrivate(cx, obj)) || + !(data2 = (IDData*) JS_GetPrivate(cx, obj2))) + return JS_FALSE; + + return data1->Equals(*data2); +} + +static JSFunctionSpec nsID_methods[] = { + {"toString", nsID_toString, 0}, + {"equals", nsID_equals, 0}, + {0} +}; + +JS_STATIC_DLL_CALLBACK(JSBool) +nsID_ctor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + IDData* data = NULL; + JSString* str; + nsID id; + + if(argc == 0) + { + JS_ReportError(cx, "nsID has no constructor that takes zero arguments"); + return JS_FALSE; + } + + if(JSVAL_IS_OBJECT(argv[0]) && + JS_InstanceOf(cx, JSVAL_TO_OBJECT(argv[0]), &nsID_class, NULL)) + { + IDData* src = (IDData*)JS_GetPrivate(cx,JSVAL_TO_OBJECT(argv[0])); + if(src) + data = new IDData(cx, *src); + } + else if(NULL != (str = JS_ValueToString(cx, argv[0])) && + id.Parse(JS_GetStringBytes(str))) + { + data = new IDData(id); + } + + if(!data) + { + JS_ReportError(cx, "could not constuct nsID"); + return JS_FALSE; + } + + if(!JS_IsConstructing(cx)) + { + obj = JS_NewObject(cx, &nsID_class, NULL, NULL); + if (!obj) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(obj); + } + + JS_SetPrivate(cx, obj, data); + return JS_TRUE; +} + +JSBool +xpc_InitIDClass(XPCContext* xpcc) +{ + if (!JS_InitClass(xpcc->GetJSContext(), xpcc->GetGlobalObject(), + NULL, &nsID_class, nsID_ctor, 1, NULL, nsID_methods, NULL, NULL)) + return JS_FALSE; + return JS_TRUE; +} + +JSObject * +xpc_NewIDObject(JSContext *cx, const nsID& aID) +{ + JSObject *obj; + + obj = JS_NewObject(cx, &nsID_class, NULL, NULL); + if(obj) + JS_SetPrivate(cx, obj, new IDData(aID)); + return obj; +} diff --git a/mozilla/js/src/xpconnect/xpcprivate.h b/mozilla/js/src/xpconnect/xpcprivate.h index 686016672f9..3dd6fd13289 100644 --- a/mozilla/js/src/xpconnect/xpcprivate.h +++ b/mozilla/js/src/xpconnect/xpcprivate.h @@ -33,6 +33,7 @@ #include "xpcbogusjs.h" #include "xpcbogusii.h" +extern const char* XPC_VAL_STR; // 'val' property name for out params /***************************************************************************/ @@ -84,7 +85,7 @@ private: static nsXPConnect* mSelf; }; -/*************************/ +/***************************************************************************/ // XPCContext is mostly a dumb class to hold JSContext specific data and // maps that let us find wrappers created for the given JSContext. @@ -125,34 +126,98 @@ private: IID2WrappedNativeClassMap* mWrappedNativeClassMap; }; +/***************************************************************************/ + +// this interfaces exists so we can refcount nsXPCWrappedJSClass +// {2453EBA0-A9B8-11d2-BA64-00805F8A5DD7} +#define NS_IXPCONNECT_WRAPPED_JS_CLASS_IID \ +{ 0x2453eba0, 0xa9b8, 0x11d2, \ + { 0xba, 0x64, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } } + +class nsIXPCWrappedJSClass : public nsISupports +{ + // no methods +}; + +/*************************/ + +class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass +{ + // all the interface method declarations... + NS_DECL_ISUPPORTS; +public: + + static nsXPCWrappedJSClass* GetNewOrUsedClass(XPCContext* xpcc, + REFNSIID aIID); + REFNSIID GetIID(){return mIID;} + XPCContext* GetXPCContext() {return mXPCContext;} + nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;} + + static JSBool InitForContext(XPCContext* xpcc); + JSBool IsWrappedJS(nsISupports* aPtr); + + nsresult DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID, + void** aInstancePtr); + + JSObject* GetRootJSObject(JSObject* aJSObj); + + nsresult CallMethod(nsXPCWrappedJS* wrapper, + const nsXPCMethodInfo* info, + nsXPCMiniVarient* params); + + ~nsXPCWrappedJSClass(); +private: + nsXPCWrappedJSClass(); // not implemented + nsXPCWrappedJSClass(XPCContext* xpcc, REFNSIID aIID, + nsIInterfaceInfo* aInfo); + + JSContext* GetJSContext() {return mXPCContext->GetJSContext();} + JSObject* CreateIIDJSObject(REFNSIID aIID); + JSObject* NewOutObject(); + + JSObject* CallQueryInterfaceOnJSObject(JSObject* jsobj, REFNSIID aIID); + +private: + XPCContext* mXPCContext; + nsIInterfaceInfo* mInfo; + nsIID mIID; +}; + /*************************/ class nsXPCWrappedJS : public nsIXPConnectWrappedJS { - // our vtbl stubs here... - - // XXX implement... public: - JSObject* GetJSObject(){return NULL;} - nsXPCWrappedJSClass* GetClass() {return NULL;} + NS_DECL_ISUPPORTS; + // include our generated vtbl stub declarations +#include "xpcstubsdecl.inc" -}; + static nsXPCWrappedJS* GetNewOrUsedWrapper(XPCContext* xpcc, + JSObject* aJSObj, + REFNSIID aIID); -class nsXPCWrappedJSClass : public nsISupports -{ - // XXX implement... -public: + JSObject* GetJSObject() {return mJSObj;} + nsXPCWrappedJSClass* GetClass() {return mClass;} + REFNSIID GetIID() {return GetClass()->GetIID();} + nsXPCWrappedJS* GetRootWrapper() {return mRoot;} - REFNSIID GetIID(){return mIID;} - XPCContext* GetXPCContext() {return mXPCContext;} + virtual ~nsXPCWrappedJS(); +private: + nsXPCWrappedJS(); // not implemented + nsXPCWrappedJS(JSObject* aJSObj, + nsXPCWrappedJSClass* aClass, + nsXPCWrappedJS* root); + + nsXPCWrappedJS* Find(REFNSIID aIID); private: - XPCContext* mXPCContext; - nsIID mIID; - + JSObject* mJSObj; + nsXPCWrappedJSClass* mClass; + nsXPCWrappedJS* mRoot; + nsXPCWrappedJS* mNext; }; -/*************************/ +/***************************************************************************/ // nsXPCWrappedNativeClass maintains an array of these things struct XPCNativeMemberDescriptor @@ -169,15 +234,13 @@ struct XPCNativeMemberDescriptor uintN index; /* in InterfaceInfo for const, method, and get */ uintN index2; /* in InterfaceInfo for set */ MemberCategory category; - uintN maxParamCount; - uintN maxScratchWordCount; XPCNativeMemberDescriptor() - : invokeFuncObj(NULL), id(0), - maxParamCount(-1), - maxScratchWordCount(-1){} + : invokeFuncObj(NULL), id(0){} }; +/*************************/ + // this interfaces exists just so we can refcount nsXPCWrappedNativeClass // {C9E36280-954A-11d2-BA5A-00805F8A5DD7} #define NS_IXPCONNECT_WRAPPED_NATIVE_CLASS_IID \ @@ -189,6 +252,8 @@ class nsIXPCWrappedNativeClass : public nsISupports // no methods }; +/*************************/ + class nsXPCWrappedNativeClass : public nsIXPCWrappedNativeClass { // all the interface method declarations... @@ -249,21 +314,6 @@ private: const char* GetMemberName(const XPCNativeMemberDescriptor* desc) const; JSContext* GetJSContext() {return mXPCContext->GetJSContext();} - uintN GetMaxParamCount(const XPCNativeMemberDescriptor* desc) - { - if(-1 == desc->maxParamCount) - SetDescriptorCounts(NS_CONST_CAST(XPCNativeMemberDescriptor*,desc)); - return desc->maxParamCount; - } - - uintN GetMaxScratchWordCount(const XPCNativeMemberDescriptor* desc) - { - if(-1 == desc->maxScratchWordCount) - SetDescriptorCounts(NS_CONST_CAST(XPCNativeMemberDescriptor*,desc)); - return desc->maxScratchWordCount; - } - - void SetDescriptorCounts(XPCNativeMemberDescriptor* desc); void ReportError(const XPCNativeMemberDescriptor* desc, const char* msg); JSBool BuildMemberDescriptors(); void DestroyMemberDescriptors(); @@ -276,6 +326,8 @@ private: XPCNativeMemberDescriptor* mMembers; }; +/*************************/ + class nsXPCWrappedNative : public nsIXPConnectWrappedNative { // all the interface method declarations... @@ -288,6 +340,7 @@ public: nsISupports* GetNative() {return mObj;} JSObject* GetJSObject() {return mJSObj;} nsXPCWrappedNativeClass* GetClass() {return mClass;} + REFNSIID GetIID() {return GetClass()->GetIID();} void JSObjectFinalized(); virtual ~nsXPCWrappedNative(); @@ -307,7 +360,16 @@ private: nsXPCWrappedNative* mNext; }; -/************************************************/ +/***************************************************************************/ +// utility functions + +JSBool +xpc_InitIDClass(XPCContext* xpcc); + +JSObject* +xpc_NewIDObject(JSContext *cx, const nsID& aID); + +/***************************************************************************/ // platform specific method invoker nsresult diff --git a/mozilla/js/src/xpconnect/xpcstubs.cpp b/mozilla/js/src/xpconnect/xpcstubs.cpp new file mode 100644 index 00000000000..0e4c87daf5f --- /dev/null +++ b/mozilla/js/src/xpconnect/xpcstubs.cpp @@ -0,0 +1,147 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* Implement shared vtbl methods for WrappedJS. */ + +#include "xpcprivate.h" + +#ifdef WIN32 + +static nsresult __stdcall +PrepareAndDispatch(nsXPCWrappedJS* self, uint32 methodIndex, + uint32* args, uint32* stackBytesToPop) +{ +#define PARAM_BUFFER_COUNT 32 + + nsXPCMiniVarient paramBuffer[PARAM_BUFFER_COUNT]; + nsXPCMiniVarient* dispatchParams = NULL; + nsXPCWrappedJSClass* clazz; + nsIInterfaceInfo* iface_info; + const nsXPCMethodInfo* info; + uint8 paramCount; + uint8 i; + nsresult result = NS_ERROR_FAILURE; + + // If anything fails before stackBytesToPop can be set then + // the failure is completely catastrophic! + + NS_ASSERTION(self,"no self"); + + clazz = self->GetClass(); + NS_ASSERTION(clazz,"no class"); + + iface_info = clazz->GetInterfaceInfo(); + NS_ASSERTION(iface_info,"no interface info"); + + iface_info->GetMethodInfo(methodIndex, &info); + NS_ASSERTION(info,"no interface info"); + + paramCount = info->GetParamCount(); + + // setup varient array pointer + if(paramCount > PARAM_BUFFER_COUNT) + dispatchParams = new nsXPCMiniVarient[paramCount]; + else + dispatchParams = paramBuffer; + NS_ASSERTION(dispatchParams,"no place for params"); + + uint32* ap = args; + for(i = 0; i < paramCount; i++, ap++) + { + const nsXPCParamInfo& param = info->GetParam(i); + const nsXPCType& type = param.GetType(); + nsXPCMiniVarient* dp = &dispatchParams[i]; + + if(param.IsOut() || (type & nsXPCType::IS_POINTER)) + { + dp->val.p = (void*) *ap; + continue; + } + // else + switch(type) + { + case nsXPCType::T_I8 : dp->val.i8 = *((int8*) ap); break; + case nsXPCType::T_I16 : dp->val.i16 = *((int16*) ap); break; + case nsXPCType::T_I32 : dp->val.i32 = *((int32*) ap); break; + case nsXPCType::T_I64 : dp->val.i64 = *((int64*) ap); ap++; break; + case nsXPCType::T_U8 : dp->val.u8 = *((uint8*) ap); break; + case nsXPCType::T_U16 : dp->val.u16 = *((uint16*) ap); break; + case nsXPCType::T_U32 : dp->val.u32 = *((uint32*) ap); break; + case nsXPCType::T_U64 : dp->val.u64 = *((uint64*) ap); ap++; break; + case nsXPCType::T_FLOAT : dp->val.f = *((float*) ap); break; + case nsXPCType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break; + case nsXPCType::T_BOOL : dp->val.b = *((PRBool*) ap); break; + case nsXPCType::T_CHAR : dp->val.c = *((char*) ap); break; + case nsXPCType::T_WCHAR : dp->val.wc = *((wchar_t*)ap); break; + default: + // XXX deal with other types + NS_ASSERTION(0, "type not yet supported"); + break; + } + } + *stackBytesToPop = ((uint32)ap) - ((uint32)args); + + result = clazz->CallMethod(self, info, dispatchParams); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +static __declspec(naked) void SharedStub(void) +{ + __asm { + push ebp // set up simple stack frame + mov ebp, esp // stack has: ebp/vtbl_index/retaddr/this/args + push ecx // make room for a ptr + lea eax, [ebp-4] // pointer to stackBytesToPop + push eax + lea ebx, [ebp+16] // pointer to args + push ebx + mov edx, [ebp+4] // vtbl_index + push edx + mov eax, [ebp+12] // this + push eax + call PrepareAndDispatch + mov edx, [ebp+8] // return address + mov ecx, [ebp-4] // stackBytesToPop + add ecx, 12 // for this, the index, and ret address + mov esp, ebp + pop ebp + add esp, ecx // fix up stack pointer + jmp edx // simulate __stdcall return + } +} + +#define STUB_ENTRY(n) \ +__declspec(naked) nsresult nsXPCWrappedJS::Stub##n() \ +{ __asm push n __asm jmp SharedStub } + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPCWrappedJS::Sentinel##n() \ +{ \ + NS_ASSERTION(0,"nsXPCWrappedJS::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#pragma warning(disable : 4035) // OK to have no return value +#include "xpcstubsdef.inc" +#pragma warning(default : 4035) // restore default + +#endif \ No newline at end of file diff --git a/mozilla/js/src/xpconnect/xpcstubsdecl.inc b/mozilla/js/src/xpconnect/xpcstubsdecl.inc new file mode 100644 index 00000000000..e808ba7a452 --- /dev/null +++ b/mozilla/js/src/xpconnect/xpcstubsdecl.inc @@ -0,0 +1,276 @@ +// generated file - DO NOT EDIT + +// includes 256 stub entries, and 10 sentinel entries + +// declarations of normal stubs... +// 0 is QueryInterface +// 1 is AddRef +// 2 is Release +NS_IMETHOD Stub3(); +NS_IMETHOD Stub4(); +NS_IMETHOD Stub5(); +NS_IMETHOD Stub6(); +NS_IMETHOD Stub7(); +NS_IMETHOD Stub8(); +NS_IMETHOD Stub9(); +NS_IMETHOD Stub10(); +NS_IMETHOD Stub11(); +NS_IMETHOD Stub12(); +NS_IMETHOD Stub13(); +NS_IMETHOD Stub14(); +NS_IMETHOD Stub15(); +NS_IMETHOD Stub16(); +NS_IMETHOD Stub17(); +NS_IMETHOD Stub18(); +NS_IMETHOD Stub19(); +NS_IMETHOD Stub20(); +NS_IMETHOD Stub21(); +NS_IMETHOD Stub22(); +NS_IMETHOD Stub23(); +NS_IMETHOD Stub24(); +NS_IMETHOD Stub25(); +NS_IMETHOD Stub26(); +NS_IMETHOD Stub27(); +NS_IMETHOD Stub28(); +NS_IMETHOD Stub29(); +NS_IMETHOD Stub30(); +NS_IMETHOD Stub31(); +NS_IMETHOD Stub32(); +NS_IMETHOD Stub33(); +NS_IMETHOD Stub34(); +NS_IMETHOD Stub35(); +NS_IMETHOD Stub36(); +NS_IMETHOD Stub37(); +NS_IMETHOD Stub38(); +NS_IMETHOD Stub39(); +NS_IMETHOD Stub40(); +NS_IMETHOD Stub41(); +NS_IMETHOD Stub42(); +NS_IMETHOD Stub43(); +NS_IMETHOD Stub44(); +NS_IMETHOD Stub45(); +NS_IMETHOD Stub46(); +NS_IMETHOD Stub47(); +NS_IMETHOD Stub48(); +NS_IMETHOD Stub49(); +NS_IMETHOD Stub50(); +NS_IMETHOD Stub51(); +NS_IMETHOD Stub52(); +NS_IMETHOD Stub53(); +NS_IMETHOD Stub54(); +NS_IMETHOD Stub55(); +NS_IMETHOD Stub56(); +NS_IMETHOD Stub57(); +NS_IMETHOD Stub58(); +NS_IMETHOD Stub59(); +NS_IMETHOD Stub60(); +NS_IMETHOD Stub61(); +NS_IMETHOD Stub62(); +NS_IMETHOD Stub63(); +NS_IMETHOD Stub64(); +NS_IMETHOD Stub65(); +NS_IMETHOD Stub66(); +NS_IMETHOD Stub67(); +NS_IMETHOD Stub68(); +NS_IMETHOD Stub69(); +NS_IMETHOD Stub70(); +NS_IMETHOD Stub71(); +NS_IMETHOD Stub72(); +NS_IMETHOD Stub73(); +NS_IMETHOD Stub74(); +NS_IMETHOD Stub75(); +NS_IMETHOD Stub76(); +NS_IMETHOD Stub77(); +NS_IMETHOD Stub78(); +NS_IMETHOD Stub79(); +NS_IMETHOD Stub80(); +NS_IMETHOD Stub81(); +NS_IMETHOD Stub82(); +NS_IMETHOD Stub83(); +NS_IMETHOD Stub84(); +NS_IMETHOD Stub85(); +NS_IMETHOD Stub86(); +NS_IMETHOD Stub87(); +NS_IMETHOD Stub88(); +NS_IMETHOD Stub89(); +NS_IMETHOD Stub90(); +NS_IMETHOD Stub91(); +NS_IMETHOD Stub92(); +NS_IMETHOD Stub93(); +NS_IMETHOD Stub94(); +NS_IMETHOD Stub95(); +NS_IMETHOD Stub96(); +NS_IMETHOD Stub97(); +NS_IMETHOD Stub98(); +NS_IMETHOD Stub99(); +NS_IMETHOD Stub100(); +NS_IMETHOD Stub101(); +NS_IMETHOD Stub102(); +NS_IMETHOD Stub103(); +NS_IMETHOD Stub104(); +NS_IMETHOD Stub105(); +NS_IMETHOD Stub106(); +NS_IMETHOD Stub107(); +NS_IMETHOD Stub108(); +NS_IMETHOD Stub109(); +NS_IMETHOD Stub110(); +NS_IMETHOD Stub111(); +NS_IMETHOD Stub112(); +NS_IMETHOD Stub113(); +NS_IMETHOD Stub114(); +NS_IMETHOD Stub115(); +NS_IMETHOD Stub116(); +NS_IMETHOD Stub117(); +NS_IMETHOD Stub118(); +NS_IMETHOD Stub119(); +NS_IMETHOD Stub120(); +NS_IMETHOD Stub121(); +NS_IMETHOD Stub122(); +NS_IMETHOD Stub123(); +NS_IMETHOD Stub124(); +NS_IMETHOD Stub125(); +NS_IMETHOD Stub126(); +NS_IMETHOD Stub127(); +NS_IMETHOD Stub128(); +NS_IMETHOD Stub129(); +NS_IMETHOD Stub130(); +NS_IMETHOD Stub131(); +NS_IMETHOD Stub132(); +NS_IMETHOD Stub133(); +NS_IMETHOD Stub134(); +NS_IMETHOD Stub135(); +NS_IMETHOD Stub136(); +NS_IMETHOD Stub137(); +NS_IMETHOD Stub138(); +NS_IMETHOD Stub139(); +NS_IMETHOD Stub140(); +NS_IMETHOD Stub141(); +NS_IMETHOD Stub142(); +NS_IMETHOD Stub143(); +NS_IMETHOD Stub144(); +NS_IMETHOD Stub145(); +NS_IMETHOD Stub146(); +NS_IMETHOD Stub147(); +NS_IMETHOD Stub148(); +NS_IMETHOD Stub149(); +NS_IMETHOD Stub150(); +NS_IMETHOD Stub151(); +NS_IMETHOD Stub152(); +NS_IMETHOD Stub153(); +NS_IMETHOD Stub154(); +NS_IMETHOD Stub155(); +NS_IMETHOD Stub156(); +NS_IMETHOD Stub157(); +NS_IMETHOD Stub158(); +NS_IMETHOD Stub159(); +NS_IMETHOD Stub160(); +NS_IMETHOD Stub161(); +NS_IMETHOD Stub162(); +NS_IMETHOD Stub163(); +NS_IMETHOD Stub164(); +NS_IMETHOD Stub165(); +NS_IMETHOD Stub166(); +NS_IMETHOD Stub167(); +NS_IMETHOD Stub168(); +NS_IMETHOD Stub169(); +NS_IMETHOD Stub170(); +NS_IMETHOD Stub171(); +NS_IMETHOD Stub172(); +NS_IMETHOD Stub173(); +NS_IMETHOD Stub174(); +NS_IMETHOD Stub175(); +NS_IMETHOD Stub176(); +NS_IMETHOD Stub177(); +NS_IMETHOD Stub178(); +NS_IMETHOD Stub179(); +NS_IMETHOD Stub180(); +NS_IMETHOD Stub181(); +NS_IMETHOD Stub182(); +NS_IMETHOD Stub183(); +NS_IMETHOD Stub184(); +NS_IMETHOD Stub185(); +NS_IMETHOD Stub186(); +NS_IMETHOD Stub187(); +NS_IMETHOD Stub188(); +NS_IMETHOD Stub189(); +NS_IMETHOD Stub190(); +NS_IMETHOD Stub191(); +NS_IMETHOD Stub192(); +NS_IMETHOD Stub193(); +NS_IMETHOD Stub194(); +NS_IMETHOD Stub195(); +NS_IMETHOD Stub196(); +NS_IMETHOD Stub197(); +NS_IMETHOD Stub198(); +NS_IMETHOD Stub199(); +NS_IMETHOD Stub200(); +NS_IMETHOD Stub201(); +NS_IMETHOD Stub202(); +NS_IMETHOD Stub203(); +NS_IMETHOD Stub204(); +NS_IMETHOD Stub205(); +NS_IMETHOD Stub206(); +NS_IMETHOD Stub207(); +NS_IMETHOD Stub208(); +NS_IMETHOD Stub209(); +NS_IMETHOD Stub210(); +NS_IMETHOD Stub211(); +NS_IMETHOD Stub212(); +NS_IMETHOD Stub213(); +NS_IMETHOD Stub214(); +NS_IMETHOD Stub215(); +NS_IMETHOD Stub216(); +NS_IMETHOD Stub217(); +NS_IMETHOD Stub218(); +NS_IMETHOD Stub219(); +NS_IMETHOD Stub220(); +NS_IMETHOD Stub221(); +NS_IMETHOD Stub222(); +NS_IMETHOD Stub223(); +NS_IMETHOD Stub224(); +NS_IMETHOD Stub225(); +NS_IMETHOD Stub226(); +NS_IMETHOD Stub227(); +NS_IMETHOD Stub228(); +NS_IMETHOD Stub229(); +NS_IMETHOD Stub230(); +NS_IMETHOD Stub231(); +NS_IMETHOD Stub232(); +NS_IMETHOD Stub233(); +NS_IMETHOD Stub234(); +NS_IMETHOD Stub235(); +NS_IMETHOD Stub236(); +NS_IMETHOD Stub237(); +NS_IMETHOD Stub238(); +NS_IMETHOD Stub239(); +NS_IMETHOD Stub240(); +NS_IMETHOD Stub241(); +NS_IMETHOD Stub242(); +NS_IMETHOD Stub243(); +NS_IMETHOD Stub244(); +NS_IMETHOD Stub245(); +NS_IMETHOD Stub246(); +NS_IMETHOD Stub247(); +NS_IMETHOD Stub248(); +NS_IMETHOD Stub249(); +NS_IMETHOD Stub250(); +NS_IMETHOD Stub251(); +NS_IMETHOD Stub252(); +NS_IMETHOD Stub253(); +NS_IMETHOD Stub254(); +NS_IMETHOD Stub255(); +NS_IMETHOD Stub256(); +NS_IMETHOD Stub257(); +NS_IMETHOD Stub258(); + +// declarations of sentinel stubs +NS_IMETHOD Sentinel0(); +NS_IMETHOD Sentinel1(); +NS_IMETHOD Sentinel2(); +NS_IMETHOD Sentinel3(); +NS_IMETHOD Sentinel4(); +NS_IMETHOD Sentinel5(); +NS_IMETHOD Sentinel6(); +NS_IMETHOD Sentinel7(); +NS_IMETHOD Sentinel8(); +NS_IMETHOD Sentinel9(); diff --git a/mozilla/js/src/xpconnect/xpcstubsdef.inc b/mozilla/js/src/xpconnect/xpcstubsdef.inc new file mode 100644 index 00000000000..0f71610fe70 --- /dev/null +++ b/mozilla/js/src/xpconnect/xpcstubsdef.inc @@ -0,0 +1,270 @@ +// generated file - DO NOT EDIT + +// includes 256 stub entries, and 10 sentinel entries + +STUB_ENTRY(3) +STUB_ENTRY(4) +STUB_ENTRY(5) +STUB_ENTRY(6) +STUB_ENTRY(7) +STUB_ENTRY(8) +STUB_ENTRY(9) +STUB_ENTRY(10) +STUB_ENTRY(11) +STUB_ENTRY(12) +STUB_ENTRY(13) +STUB_ENTRY(14) +STUB_ENTRY(15) +STUB_ENTRY(16) +STUB_ENTRY(17) +STUB_ENTRY(18) +STUB_ENTRY(19) +STUB_ENTRY(20) +STUB_ENTRY(21) +STUB_ENTRY(22) +STUB_ENTRY(23) +STUB_ENTRY(24) +STUB_ENTRY(25) +STUB_ENTRY(26) +STUB_ENTRY(27) +STUB_ENTRY(28) +STUB_ENTRY(29) +STUB_ENTRY(30) +STUB_ENTRY(31) +STUB_ENTRY(32) +STUB_ENTRY(33) +STUB_ENTRY(34) +STUB_ENTRY(35) +STUB_ENTRY(36) +STUB_ENTRY(37) +STUB_ENTRY(38) +STUB_ENTRY(39) +STUB_ENTRY(40) +STUB_ENTRY(41) +STUB_ENTRY(42) +STUB_ENTRY(43) +STUB_ENTRY(44) +STUB_ENTRY(45) +STUB_ENTRY(46) +STUB_ENTRY(47) +STUB_ENTRY(48) +STUB_ENTRY(49) +STUB_ENTRY(50) +STUB_ENTRY(51) +STUB_ENTRY(52) +STUB_ENTRY(53) +STUB_ENTRY(54) +STUB_ENTRY(55) +STUB_ENTRY(56) +STUB_ENTRY(57) +STUB_ENTRY(58) +STUB_ENTRY(59) +STUB_ENTRY(60) +STUB_ENTRY(61) +STUB_ENTRY(62) +STUB_ENTRY(63) +STUB_ENTRY(64) +STUB_ENTRY(65) +STUB_ENTRY(66) +STUB_ENTRY(67) +STUB_ENTRY(68) +STUB_ENTRY(69) +STUB_ENTRY(70) +STUB_ENTRY(71) +STUB_ENTRY(72) +STUB_ENTRY(73) +STUB_ENTRY(74) +STUB_ENTRY(75) +STUB_ENTRY(76) +STUB_ENTRY(77) +STUB_ENTRY(78) +STUB_ENTRY(79) +STUB_ENTRY(80) +STUB_ENTRY(81) +STUB_ENTRY(82) +STUB_ENTRY(83) +STUB_ENTRY(84) +STUB_ENTRY(85) +STUB_ENTRY(86) +STUB_ENTRY(87) +STUB_ENTRY(88) +STUB_ENTRY(89) +STUB_ENTRY(90) +STUB_ENTRY(91) +STUB_ENTRY(92) +STUB_ENTRY(93) +STUB_ENTRY(94) +STUB_ENTRY(95) +STUB_ENTRY(96) +STUB_ENTRY(97) +STUB_ENTRY(98) +STUB_ENTRY(99) +STUB_ENTRY(100) +STUB_ENTRY(101) +STUB_ENTRY(102) +STUB_ENTRY(103) +STUB_ENTRY(104) +STUB_ENTRY(105) +STUB_ENTRY(106) +STUB_ENTRY(107) +STUB_ENTRY(108) +STUB_ENTRY(109) +STUB_ENTRY(110) +STUB_ENTRY(111) +STUB_ENTRY(112) +STUB_ENTRY(113) +STUB_ENTRY(114) +STUB_ENTRY(115) +STUB_ENTRY(116) +STUB_ENTRY(117) +STUB_ENTRY(118) +STUB_ENTRY(119) +STUB_ENTRY(120) +STUB_ENTRY(121) +STUB_ENTRY(122) +STUB_ENTRY(123) +STUB_ENTRY(124) +STUB_ENTRY(125) +STUB_ENTRY(126) +STUB_ENTRY(127) +STUB_ENTRY(128) +STUB_ENTRY(129) +STUB_ENTRY(130) +STUB_ENTRY(131) +STUB_ENTRY(132) +STUB_ENTRY(133) +STUB_ENTRY(134) +STUB_ENTRY(135) +STUB_ENTRY(136) +STUB_ENTRY(137) +STUB_ENTRY(138) +STUB_ENTRY(139) +STUB_ENTRY(140) +STUB_ENTRY(141) +STUB_ENTRY(142) +STUB_ENTRY(143) +STUB_ENTRY(144) +STUB_ENTRY(145) +STUB_ENTRY(146) +STUB_ENTRY(147) +STUB_ENTRY(148) +STUB_ENTRY(149) +STUB_ENTRY(150) +STUB_ENTRY(151) +STUB_ENTRY(152) +STUB_ENTRY(153) +STUB_ENTRY(154) +STUB_ENTRY(155) +STUB_ENTRY(156) +STUB_ENTRY(157) +STUB_ENTRY(158) +STUB_ENTRY(159) +STUB_ENTRY(160) +STUB_ENTRY(161) +STUB_ENTRY(162) +STUB_ENTRY(163) +STUB_ENTRY(164) +STUB_ENTRY(165) +STUB_ENTRY(166) +STUB_ENTRY(167) +STUB_ENTRY(168) +STUB_ENTRY(169) +STUB_ENTRY(170) +STUB_ENTRY(171) +STUB_ENTRY(172) +STUB_ENTRY(173) +STUB_ENTRY(174) +STUB_ENTRY(175) +STUB_ENTRY(176) +STUB_ENTRY(177) +STUB_ENTRY(178) +STUB_ENTRY(179) +STUB_ENTRY(180) +STUB_ENTRY(181) +STUB_ENTRY(182) +STUB_ENTRY(183) +STUB_ENTRY(184) +STUB_ENTRY(185) +STUB_ENTRY(186) +STUB_ENTRY(187) +STUB_ENTRY(188) +STUB_ENTRY(189) +STUB_ENTRY(190) +STUB_ENTRY(191) +STUB_ENTRY(192) +STUB_ENTRY(193) +STUB_ENTRY(194) +STUB_ENTRY(195) +STUB_ENTRY(196) +STUB_ENTRY(197) +STUB_ENTRY(198) +STUB_ENTRY(199) +STUB_ENTRY(200) +STUB_ENTRY(201) +STUB_ENTRY(202) +STUB_ENTRY(203) +STUB_ENTRY(204) +STUB_ENTRY(205) +STUB_ENTRY(206) +STUB_ENTRY(207) +STUB_ENTRY(208) +STUB_ENTRY(209) +STUB_ENTRY(210) +STUB_ENTRY(211) +STUB_ENTRY(212) +STUB_ENTRY(213) +STUB_ENTRY(214) +STUB_ENTRY(215) +STUB_ENTRY(216) +STUB_ENTRY(217) +STUB_ENTRY(218) +STUB_ENTRY(219) +STUB_ENTRY(220) +STUB_ENTRY(221) +STUB_ENTRY(222) +STUB_ENTRY(223) +STUB_ENTRY(224) +STUB_ENTRY(225) +STUB_ENTRY(226) +STUB_ENTRY(227) +STUB_ENTRY(228) +STUB_ENTRY(229) +STUB_ENTRY(230) +STUB_ENTRY(231) +STUB_ENTRY(232) +STUB_ENTRY(233) +STUB_ENTRY(234) +STUB_ENTRY(235) +STUB_ENTRY(236) +STUB_ENTRY(237) +STUB_ENTRY(238) +STUB_ENTRY(239) +STUB_ENTRY(240) +STUB_ENTRY(241) +STUB_ENTRY(242) +STUB_ENTRY(243) +STUB_ENTRY(244) +STUB_ENTRY(245) +STUB_ENTRY(246) +STUB_ENTRY(247) +STUB_ENTRY(248) +STUB_ENTRY(249) +STUB_ENTRY(250) +STUB_ENTRY(251) +STUB_ENTRY(252) +STUB_ENTRY(253) +STUB_ENTRY(254) +STUB_ENTRY(255) +STUB_ENTRY(256) +STUB_ENTRY(257) +STUB_ENTRY(258) +SENTINEL_ENTRY(0) +SENTINEL_ENTRY(1) +SENTINEL_ENTRY(2) +SENTINEL_ENTRY(3) +SENTINEL_ENTRY(4) +SENTINEL_ENTRY(5) +SENTINEL_ENTRY(6) +SENTINEL_ENTRY(7) +SENTINEL_ENTRY(8) +SENTINEL_ENTRY(9) diff --git a/mozilla/js/src/xpconnect/xpcwrappedjs.cpp b/mozilla/js/src/xpconnect/xpcwrappedjs.cpp new file mode 100644 index 00000000000..bf3c0fe247f --- /dev/null +++ b/mozilla/js/src/xpconnect/xpcwrappedjs.cpp @@ -0,0 +1,204 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* Class that wraps JS objects to appear as XPCOM objects. */ + +#include "xpcprivate.h" + +// NOTE: much of the fancy footwork is done in xpcstubs.cpp + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +nsresult +nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + return mClass->DelegatedQueryInterface(this, aIID, aInstancePtr); +} + +// do chained ref counting + +nsrefcnt +nsXPCWrappedJS::AddRef(void) +{ + NS_PRECONDITION(mRoot, "bad root"); + ++mRefCnt; + + if(1 == mRefCnt && mRoot && mRoot != this) + NS_ADDREF(mRoot); + + return mRefCnt; +} + +nsrefcnt +nsXPCWrappedJS::Release(void) +{ + NS_PRECONDITION(mRoot, "bad root"); + NS_PRECONDITION(0 != mRefCnt, "dup release"); + --mRefCnt; + if(0 == mRefCnt) + { + if(mRoot == this) + { + NS_DELETEXPCOM(this); // cascaded delete + } + else + { + NS_RELEASE(mRoot); + } + return 0; + } + return mRefCnt; +} + +// static +nsXPCWrappedJS* +nsXPCWrappedJS::GetNewOrUsedWrapper(XPCContext* xpcc, + JSObject* aJSObj, + REFNSIID aIID) +{ + JSObject2WrappedJSMap* map; + JSObject* rootJSObj; + nsXPCWrappedJS* root; + nsXPCWrappedJS* wrapper = NULL; + nsXPCWrappedJSClass* clazz = NULL; + + NS_PRECONDITION(xpcc, "bad param"); + NS_PRECONDITION(aJSObj, "bad param"); + + map = xpcc->GetWrappedJSMap(); + if(!map) + { + NS_ASSERTION(map,"bad map"); + return NULL; + } + + clazz = nsXPCWrappedJSClass::GetNewOrUsedClass(xpcc, aIID); + if(!clazz) + return NULL; + // from here on we need to return through 'return_wrapper' + + // always find the root JSObject + rootJSObj = clazz->GetRootJSObject(aJSObj); + if(!rootJSObj) + goto return_wrapper; + + // look for the root wrapper + root = map->Find(rootJSObj); + if(root) + { + wrapper = root->Find(aIID); + if(wrapper) + { + NS_ADDREF(wrapper); + goto return_wrapper; + } + } + else + { + // build the root wrapper + if(rootJSObj == aJSObj) + { + // the root will do double duty as the interface wrapper + wrapper = root = new nsXPCWrappedJS(aJSObj, clazz, NULL); + if(root) + map->Add(root); + goto return_wrapper; + } + else + { + // just a root wrapper + nsXPCWrappedJSClass* rootClazz; + rootClazz = nsXPCWrappedJSClass::GetNewOrUsedClass(xpcc, kISupportsIID); + if(!rootClazz) + goto return_wrapper; + + root = new nsXPCWrappedJS(rootJSObj, rootClazz, NULL); + NS_RELEASE(rootClazz); + + if(!root) + goto return_wrapper; + map->Add(root); + } + } + + // at this point we have a root and may need to build the specific wrapper + NS_ASSERTION(root,"bad root"); + NS_ASSERTION(clazz,"bad clazz"); + + if(!wrapper) + { + wrapper = new nsXPCWrappedJS(aJSObj, clazz, root); + if(!wrapper) + goto return_wrapper; + } + + wrapper->mNext = root->mNext; + root->mNext = wrapper; + +return_wrapper: + if(clazz) + NS_RELEASE(clazz); + return wrapper; +} + +#ifdef WIN32 +#pragma warning(disable : 4355) // OK to pass "this" in member initializer +#endif + +nsXPCWrappedJS::nsXPCWrappedJS(JSObject* aJSObj, + nsXPCWrappedJSClass* aClass, + nsXPCWrappedJS* root) + : mJSObj(aJSObj), + mClass(aClass), + mRoot(root ? root : this), + mNext(NULL) + +{ + NS_INIT_REFCNT(); + NS_ADDREF_THIS(); + NS_ADDREF(aClass); + JS_AddRoot(mClass->GetXPCContext()->GetJSContext(), &mJSObj); +} + +nsXPCWrappedJS::~nsXPCWrappedJS() +{ + NS_PRECONDITION(0 == mRefCnt, "refcounting error"); + JS_RemoveRoot(mClass->GetXPCContext()->GetJSContext(), &mJSObj); + NS_RELEASE(mClass); + if(mNext) + NS_DELETEXPCOM(mNext); // cascaded delete +} + +nsXPCWrappedJS* +nsXPCWrappedJS::Find(REFNSIID aIID) +{ + if(aIID.Equals(kISupportsIID)) + return mRoot; + + nsXPCWrappedJS* cur = mRoot; + do + { + if(aIID.Equals(GetIID())) + return cur; + + } while(NULL != (cur = cur->mNext)); + + return NULL; +} + + diff --git a/mozilla/js/src/xpconnect/xpcwrappedjsclass.cpp b/mozilla/js/src/xpconnect/xpcwrappedjsclass.cpp new file mode 100644 index 00000000000..3d15686f79c --- /dev/null +++ b/mozilla/js/src/xpconnect/xpcwrappedjsclass.cpp @@ -0,0 +1,551 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xpcprivate.h" + +static const char* XPC_QUERY_INTERFACE_STR = "QueryInterface"; + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +NS_IMPL_ISUPPORTS(nsXPCWrappedJSClass, NS_IXPCONNECT_WRAPPED_JS_CLASS_IID) + +// static +nsXPCWrappedJSClass* +nsXPCWrappedJSClass::GetNewOrUsedClass(XPCContext* xpcc, + REFNSIID aIID) +{ + IID2WrappedJSClassMap* map; + nsXPCWrappedJSClass* clazz = NULL; + + NS_PRECONDITION(xpcc, "bad param"); + + map = xpcc->GetWrappedJSClassMap(); + NS_ASSERTION(map,"bad map"); + + clazz = map->Find(aIID); + if(clazz) + { + NS_ADDREF(clazz); + } + else + { + nsIInterfaceInfo* info; + nsXPConnect* xpc; + if((xpc = nsXPConnect::GetXPConnect()) != NULL && + NS_SUCCEEDED(xpc->GetInterfaceInfo(aIID, &info))) + { + clazz = new nsXPCWrappedJSClass(xpcc, aIID, info); + } + } + return clazz; +} + +nsXPCWrappedJSClass::nsXPCWrappedJSClass(XPCContext* xpcc, REFNSIID aIID, + nsIInterfaceInfo* aInfo) + : mXPCContext(xpcc), + mIID(aIID), + mInfo(aInfo) +{ + NS_ADDREF(mInfo); + + NS_INIT_REFCNT(); + NS_ADDREF_THIS(); + + mXPCContext->GetWrappedJSClassMap()->Add(this); +} + +nsXPCWrappedJSClass::~nsXPCWrappedJSClass() +{ + mXPCContext->GetWrappedJSClassMap()->Remove(this); + NS_RELEASE(mInfo); +} + +/***************************************************************************/ +// XXX for now IIDs are represented in JS as string objects containing strings +// of the form: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (just like the nsID +// Parse and ToString methods use. + +// XXX lots of room for optimization here! + +// JSObject* +// nsXPCWrappedJSClass::CreateIIDJSObject(REFNSIID aIID) +// { +// JSObject* obj = NULL; +// char* str = aIID.ToString(); +// if(str) +// { +// JSContext* cx = GetJSContext(); +// JSString* jsstr = JS_InternString(cx, str); +// delete [] str; +// if(jsstr) +// JS_ValueToObject(cx, STRING_TO_JSVAL(jsstr), &obj); +// } +// return obj; +// } + +JSObject* +nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSObject* jsobj, REFNSIID aIID) +{ + JSContext* cx = GetJSContext(); + JSObject* id; + jsval retval; + JSObject* retObj; + JSBool success = JS_FALSE; + +// id = CreateIIDJSObject(aIID); + id = xpc_NewIDObject(cx, aIID); + + if(id) + { + JSErrorReporter older = JS_SetErrorReporter(cx, NULL); + jsval args[1] = {OBJECT_TO_JSVAL(id)}; + success = JS_CallFunctionName(cx, jsobj, XPC_QUERY_INTERFACE_STR, + 1, args, &retval); + if(success) + success = JS_ValueToObject(cx, retval, &retObj); + JS_SetErrorReporter(cx, older); + } + + return success ? retObj : NULL; +} + +/***************************************************************************/ +// This 'WrappedJSIdentity' class and singleton allow us to figure out if +// any given nsISupports* is implemented by a WrappedJS object. This is done +// using a QueryInterface call on the interface pointer with our ID. If +// that call returns NS_OK and the pointer is to our singleton, then the +// interface must be implemented by a WrappedJS object. NOTE: the +// 'WrappedJSIdentity' object is not a real XPCOM object and should not be +// used for anything else (hence it is declared in this implementation file). + +// {5C5C3BB0-A9BA-11d2-BA64-00805F8A5DD7} +#define NS_IXPCONNECT_WRAPPED_JS_IDENTITY_CLASS_IID \ +{ 0x5c5c3bb0, 0xa9ba, 0x11d2, \ + { 0xba, 0x64, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } } + +static NS_DEFINE_IID(kIWrappedJSIdentityIID, NS_IXPCONNECT_WRAPPED_JS_IDENTITY_CLASS_IID); + +class WrappedJSIdentity +{ + // no instance methods... +public: + static void* GetSingleton() + { + static WrappedJSIdentity* singleton = NULL; + if(!singleton) + singleton = new WrappedJSIdentity(); + return (void*) singleton; + } +}; + +/***************************************************************************/ + +JSBool +nsXPCWrappedJSClass::IsWrappedJS(nsISupports* aPtr) +{ + void* result; + NS_PRECONDITION(aPtr, "null pointer"); + return aPtr && + NS_OK == aPtr->QueryInterface(kIWrappedJSIdentityIID, &result) && + result == WrappedJSIdentity::GetSingleton(); +} + +nsresult +nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self, + REFNSIID aIID, + void** aInstancePtr) +{ + if(NULL == aInstancePtr) + { + NS_PRECONDITION(0, "null pointer"); + return NS_ERROR_NULL_POINTER; + } + + if(aIID.Equals(kISupportsIID)) + { + nsXPCWrappedJS* root = self->GetRootWrapper(); + *aInstancePtr = (void*) root; + NS_ADDREF(root); + return NS_OK; + } + else if(aIID.Equals(self->GetIID())) + { + *aInstancePtr = (void*) self; + NS_ADDREF(self); + return NS_OK; + } + else if(aIID.Equals(kIWrappedJSIdentityIID)) + { + *aInstancePtr = WrappedJSIdentity::GetSingleton(); + return NS_OK; + } + else + { + JSObject* jsobj = + CallQueryInterfaceOnJSObject(self->GetJSObject(), aIID); + if(jsobj) + { + nsXPCWrappedJS* wrapper = + nsXPCWrappedJS::GetNewOrUsedWrapper(GetXPCContext(), + jsobj, aIID); + if(wrapper) + { + *aInstancePtr = (void*) wrapper; + return NS_OK; + } + } + } + + *aInstancePtr = NULL; + return NS_NOINTERFACE; +} + +JSObject* +nsXPCWrappedJSClass::GetRootJSObject(JSObject* aJSObj) +{ + JSObject* result = CallQueryInterfaceOnJSObject(aJSObj, kISupportsIID); + return result ? result : aJSObj; +} + +#define JAM_DOUBLE(v,d) (d = (jsdouble)v, DOUBLE_TO_JSVAL(&d)) +#define FIT_32(i,d) (INT_FITS_IN_JSVAL(i) ? INT_TO_JSVAL(i) : JAM_DOUBLE(i,d)) +// Win32 can't handle uint64 to double conversion +#define JAM_DOUBLE_U64(v,d) JAM_DOUBLE(((int64)v),d) + +nsresult +nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, + const nsXPCMethodInfo* info, + nsXPCMiniVarient* params) +{ +#define ARGS_BUFFER_COUNT 32 + + jsval argsBuffer[ARGS_BUFFER_COUNT]; + jsval* argv = NULL; + uint8 i; + uint8 argc; + jsval result; + uint8 paramCount; + nsresult retval = NS_ERROR_UNEXPECTED; + JSErrorReporter older; + JSBool success; + JSContext* cx = GetJSContext(); + + + // 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; + } + else + argv = argsBuffer; + // from here on out we exit via 'goto done' + + // build the args + for(i = 0; i < argc; i++) + { + const nsXPCParamInfo& param = info->GetParam(i); + const nsXPCType& type = param.GetType(); + + jsval val; + + if(param.IsIn()) + { + nsXPCMiniVarient* pv; + + if(param.IsOut()) + pv = (nsXPCMiniVarient*) params[i].val.p; + else + pv = ¶ms[i]; + + if(type & nsXPCType::IS_POINTER) + pv = (nsXPCMiniVarient*) pv->val.p; + + // do the actual conversion... + + // handle special cases first + + if(type == 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"); + continue; + } + else if(type == nsXPCType::T_INTERFACE_IS) + { + // XXX implement INTERFACE_IS + NS_ASSERTION(0,"interface_is params not supported"); + continue; + } + else if(type == nsXPCType::T_STRING) + { + // XXX implement STRING + NS_ASSERTION(0,"string params not supported"); + continue; + } + else if(type == nsXPCType::T_P_IID) + { + // XXX implement IID + NS_ASSERTION(0,"iid params not supported"); + continue; + } + else if(type == nsXPCType::T_P_VOID) + { + // XXX implement void* + NS_ASSERTION(0,"void* params not supported"); + continue; + } + else { + jsdouble d; + + switch(type & nsXPCType::TYPE_MASK) + { + case nsXPCType::T_I8 : val = INT_TO_JSVAL((int32)pv->val.i8); break; + case nsXPCType::T_I16 : val = INT_TO_JSVAL((int32)pv->val.i16); break; + case nsXPCType::T_I32 : val = FIT_32(pv->val.i32,d); break; + case nsXPCType::T_I64 : val = JAM_DOUBLE(pv->val.i64,d); break; + case nsXPCType::T_U8 : val = INT_TO_JSVAL((int32)pv->val.u8); break; + case nsXPCType::T_U16 : val = INT_TO_JSVAL((int32)pv->val.u16); break; + case nsXPCType::T_U32 : val = FIT_32(pv->val.u32,d); break; + case nsXPCType::T_U64 : val = JAM_DOUBLE_U64(pv->val.u64,d); break; + case nsXPCType::T_FLOAT : val = JAM_DOUBLE(pv->val.f,d); break; + case nsXPCType::T_DOUBLE : val = DOUBLE_TO_JSVAL(&pv->val.d); break; + case nsXPCType::T_BOOL : val = pv->val.b?JSVAL_TRUE:JSVAL_FALSE; break; + // XXX need to special case cahr* and wchar_t* + case nsXPCType::T_CHAR : val = INT_TO_JSVAL((int32)pv->val.c); break; + case nsXPCType::T_WCHAR : val = INT_TO_JSVAL((int32)pv->val.wc); break; + default: + NS_ASSERTION(0, "bad type"); + continue; + } + } + } + + if(param.IsOut()) + { + // create an 'out' object + JSObject* obj = NewOutObject(); + if(param.IsIn()) + { + if(!JS_SetProperty(cx, obj, XPC_VAL_STR, &val)) + goto done; + } + argv[i] = OBJECT_TO_JSVAL(obj); + } + else + argv[i] = val; + } + + // do the function call + + older = JS_SetErrorReporter(cx, NULL); + success = JS_CallFunctionName(cx, wrapper->GetJSObject(), info->GetName(), + 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 + for(i = 0; i < paramCount; i++) + { + const nsXPCParamInfo& param = info->GetParam(i); + + if(param.IsOut()) + { + jsval val; + const nsXPCType& type = param.GetType(); + nsXPCMiniVarient* pv; + + if(param.IsRetval()) + val = result; + else if(!JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[i]), XPC_VAL_STR, &val)) + goto done; + + pv = (nsXPCMiniVarient*) params[i].val.p; + if(type & nsXPCType::IS_POINTER) + pv = (nsXPCMiniVarient*) pv->val.p; + + // do the actual conversion... + + // handle special cases first + + if(type == 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"); + continue; + } + else if(type == nsXPCType::T_INTERFACE_IS) + { + // XXX implement INTERFACE_IS + NS_ASSERTION(0,"interface_is params not supported"); + continue; + } + else if(type == nsXPCType::T_STRING) + { + // XXX implement STRING + NS_ASSERTION(0,"string params not supported"); + continue; + } + else if(type == nsXPCType::T_P_IID) + { + // XXX implement IID + NS_ASSERTION(0,"iid params not supported"); + continue; + } + else if(type == nsXPCType::T_P_VOID) + { + // XXX implement void* + NS_ASSERTION(0,"void* params not supported"); + continue; + } + else { + int32 ti; + uint32 tu; + jsdouble td; + JSBool r; + + switch(type & nsXPCType::TYPE_MASK) + { + case nsXPCType::T_I8 : + r = JS_ValueToECMAInt32(cx,val,&ti); + pv->val.i8 = (int8) ti; + break; + case nsXPCType::T_I16 : + r = JS_ValueToECMAInt32(cx,val,&ti); + pv->val.i16 = (int16) ti; + break; + case nsXPCType::T_I32 : + r = JS_ValueToECMAInt32(cx,val,&pv->val.i32); + break; + case nsXPCType::T_I64 : + if(JSVAL_IS_INT(val)) + { + r = JS_ValueToECMAInt32(cx,val,&ti); + pv->val.i64 = (int64) ti; + } + else + { + r = JS_ValueToNumber(cx, val, &td); + if(r) pv->val.i64 = (int64) td; + } + break; + case nsXPCType::T_U8 : + r = JS_ValueToECMAUint32(cx,val,&tu); + pv->val.u8 = (uint8) tu; + break; + case nsXPCType::T_U16 : + r = JS_ValueToECMAUint32(cx,val,&tu); + pv->val.u16 = (uint16) tu; + break; + case nsXPCType::T_U32 : + r = JS_ValueToECMAUint32(cx,val,&pv->val.u32); + break; + case nsXPCType::T_U64 : + if(JSVAL_IS_INT(val)) + { + r = JS_ValueToECMAUint32(cx,val,&tu); + pv->val.i64 = (int64) tu; + } + else + { + r = JS_ValueToNumber(cx, val, &td); + // XXX Win32 can't handle double to uint64 directly + if(r) pv->val.u64 = (uint64)((int64) td); + } + break; + case nsXPCType::T_FLOAT : + r = JS_ValueToNumber(cx, val, &td); + if(r) pv->val.f = (float) td; + break; + case nsXPCType::T_DOUBLE : + r = JS_ValueToNumber(cx, val, &pv->val.d); + break; + case nsXPCType::T_BOOL : + r = JS_ValueToBoolean(cx, val, &pv->val.b); + break; + + // XXX should we special case char* and wchar_t* to be strings? + case nsXPCType::T_CHAR : + case nsXPCType::T_WCHAR : + default: + NS_ASSERTION(0, "bad type"); + goto done; + } + continue; + } + } + } + + retval = NS_OK; + +done: + if(argv && argv != argsBuffer) + delete [] argv; + return retval; +} + + +static JSClass WrappedJSOutArg_class = { + "XPCOutArg", 0, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub +}; + +// static +JSBool +nsXPCWrappedJSClass::InitForContext(XPCContext* xpcc) +{ + if (!JS_InitClass(xpcc->GetJSContext(), xpcc->GetGlobalObject(), + 0, &WrappedJSOutArg_class, 0, 0, + 0, 0, + 0, 0)) + return JS_FALSE; + return JS_TRUE; +} + +JSObject* +nsXPCWrappedJSClass::NewOutObject() +{ + return JS_NewObject(GetJSContext(), &WrappedJSOutArg_class, NULL, NULL); +} diff --git a/mozilla/js/src/xpconnect/xpcwrappednative.cpp b/mozilla/js/src/xpconnect/xpcwrappednative.cpp index 332c02df4d9..0ef03b558bf 100644 --- a/mozilla/js/src/xpconnect/xpcwrappednative.cpp +++ b/mozilla/js/src/xpconnect/xpcwrappednative.cpp @@ -112,7 +112,7 @@ nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc, if(!clazz) goto return_wrapper; - // build the root wrapper + // build the root wrapper if(!root) { @@ -153,18 +153,20 @@ nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc, } } - // at this point we have a root and need to build the specific wrapper + // at this point we have a root and may need to build the specific wrapper NS_ASSERTION(root,"bad root"); NS_ASSERTION(clazz,"bad clazz"); - wrapper = new nsXPCWrappedNative(aObj, clazz, root); - if(!wrapper) - goto return_wrapper; - if(!wrapper->mJSObj) { - NS_RELEASE(wrapper); - goto return_wrapper; + wrapper = new nsXPCWrappedNative(aObj, clazz, root); + if(!wrapper) + goto return_wrapper; + if(!wrapper->mJSObj) + { + NS_RELEASE(wrapper); // sets wrapper to NULL + goto return_wrapper; + } } wrapper->mNext = root->mNext; @@ -215,7 +217,6 @@ nsXPCWrappedNative::~nsXPCWrappedNative() NS_DELETEXPCOM(mNext); // cascaded delete } - nsXPCWrappedNative* nsXPCWrappedNative::Find(REFNSIID aIID) { @@ -225,7 +226,7 @@ nsXPCWrappedNative::Find(REFNSIID aIID) nsXPCWrappedNative* cur = mRoot; do { - if(aIID.Equals(cur->GetClass()->GetIID())) + if(aIID.Equals(GetIID())) return cur; } while(NULL != (cur = cur->mNext)); diff --git a/mozilla/js/src/xpconnect/xpcwrappednativeclass.cpp b/mozilla/js/src/xpconnect/xpcwrappednativeclass.cpp index d1802c95221..516f0b91bf9 100644 --- a/mozilla/js/src/xpconnect/xpcwrappednativeclass.cpp +++ b/mozilla/js/src/xpconnect/xpcwrappednativeclass.cpp @@ -12,7 +12,7 @@ * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Copyright (C) 1999 Netscape Communications Corporation. All Rights * Reserved. */ @@ -20,7 +20,7 @@ #include "xpcprivate.h" -static const char* XPC_VAL_STR = "val"; +const char* XPC_VAL_STR = "val"; NS_IMPL_ISUPPORTS(nsXPCWrappedNativeClass, NS_IXPCONNECT_WRAPPED_NATIVE_CLASS_IID) @@ -30,7 +30,7 @@ nsXPCWrappedNativeClass::GetNewOrUsedClass(XPCContext* xpcc, REFNSIID aIID) { IID2WrappedNativeClassMap* map; - nsXPCWrappedNativeClass* clazz; + nsXPCWrappedNativeClass* clazz = NULL; NS_PRECONDITION(xpcc, "bad param"); @@ -215,8 +215,9 @@ WrappedNative_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) case JSTYPE_VOID: case JSTYPE_STRING: - // XXX get the interface name from the InterfaceInfo - *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "WrappedNative")); + // XXX perhaps more expressive toString? + *vp = STRING_TO_JSVAL( + JS_NewStringCopyZ(cx, wrapper->GetClass()->GetInterfaceName())); return JS_TRUE; case JSTYPE_NUMBER: @@ -298,51 +299,10 @@ nsXPCWrappedNativeClass::GetInterfaceName() const return name; } -void -nsXPCWrappedNativeClass::SetDescriptorCounts(XPCNativeMemberDescriptor* desc) -{ - // XXX this is subject to serious improvement! - switch(desc->category) - { - case XPCNativeMemberDescriptor::CONSTANT: - NS_ASSERTION(0,"bad call"); - break; - case XPCNativeMemberDescriptor::METHOD: - { - const nsXPCMethodInfo* info; - if(NS_FAILED(mInfo->GetMethodInfo(desc->index, &info))) - break; - - uintN scratchWords = 0; - for(int i = info->GetParamCount()-1 ; i >= 0; i--) - { - const nsXPCParamInfo& param = info->GetParam(i); - if(param.IsOut()) - { - // XXX what about space for IIDs? - scratchWords += param.GetType().WordCount(); - } - } - desc->maxParamCount = info->GetParamCount(); - desc->maxScratchWordCount = scratchWords; - break; - } - case XPCNativeMemberDescriptor::ATTRIB_RO: - case XPCNativeMemberDescriptor::ATTRIB_RW: - // just set these for the max possible... - desc->maxParamCount = 1; - desc->maxScratchWordCount = 2; - break; - default: - NS_ASSERTION(0,"bad category"); - break; - } -} - -// Win32 can't handle u64 to double conversion -#define JAM_DOUBLE_U64(v,d) (d = (jsdouble)(int64)v, DOUBLE_TO_JSVAL(&d)) #define JAM_DOUBLE(v,d) (d = (jsdouble)v, DOUBLE_TO_JSVAL(&d)) #define FIT_32(i,d) (INT_FITS_IN_JSVAL(i) ? INT_TO_JSVAL(i) : JAM_DOUBLE(i,d)) +// Win32 can't handle uint64 to double conversion +#define JAM_DOUBLE_U64(v,d) JAM_DOUBLE(((int64)v),d) JSBool nsXPCWrappedNativeClass::GetConstantAsJSVal(nsXPCWrappedNative* wrapper, @@ -377,6 +337,7 @@ nsXPCWrappedNativeClass::GetConstantAsJSVal(nsXPCWrappedNative* wrapper, case nsXPCType::T_CHAR : *vp = INT_TO_JSVAL((int32)var.val.c); break; case nsXPCType::T_WCHAR : *vp = INT_TO_JSVAL((int32)var.val.wc); break; default: + // XXX need to support string constants NS_ASSERTION(0, "bad type"); ReportError(desc, "invalid constant type"); } @@ -398,43 +359,23 @@ nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper, JSBool isAttributeSet, uintN argc, jsval *argv, jsval *vp) { -#define PARAM_COUNT 32 -#define SCRATCH_WORDS 32 +#define PARAM_BUFFER_COUNT 32 - nsXPCVarient paramBuffer[PARAM_COUNT]; - uint32 scratchBuffer[SCRATCH_WORDS]; + nsXPCVarient paramBuffer[PARAM_BUFFER_COUNT]; JSBool retval = JS_FALSE; nsXPCVarient* dispatchParams = NULL; - uint32* scratch = NULL; - uint32 scratchIndex = 0; JSContext* cx = GetJSContext(); uint8 i; const nsXPCMethodInfo* info; uint8 requiredArgs; uint8 paramCount; + uint8 dispatchParamsInitedCount = 0; jsval src; - jsdouble num; uint8 vtblIndex; nsresult invokeResult; - // setup buffers - - if(GetMaxParamCount(desc) > PARAM_COUNT) - dispatchParams = new nsXPCVarient[GetMaxParamCount(desc)]; - else - dispatchParams = paramBuffer; - - if(GetMaxScratchWordCount(desc) > SCRATCH_WORDS) - scratch = new uint32[GetMaxScratchWordCount(desc)]; - else - scratch = scratchBuffer; - if(!dispatchParams || !scratch) - { - ReportError(desc, "out of memeory"); - goto done; - } - + *vp = JSVAL_NULL; // make sure we have what we need if(isAttributeSet) @@ -463,94 +404,312 @@ nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper, goto done; } + // setup varient array pointer + if(paramCount > PARAM_BUFFER_COUNT) + { + if(!(dispatchParams = new nsXPCVarient[paramCount])) + { + ReportError(desc, "out of memory"); + goto done; + } + } + else + dispatchParams = paramBuffer; + // iterate through the params doing conversions for(i = 0; i < paramCount; i++) { const nsXPCParamInfo& param = info->GetParam(i); const nsXPCType& type = param.GetType(); - nsXPCVarient* dp; + nsXPCVarient* dp = &dispatchParams[i]; + dp->type = type; + dp->flags = 0; + dp->val.p = NULL; + dispatchParamsInitedCount++; - dispatchParams[i].type = type; + // set 'src' to be the object from which we get the value and + // prepare for out param if(param.IsOut()) { - dispatchParams[i].val.p = &scratch[scratchIndex]; - scratchIndex += type.WordCount(); - if(!param.IsIn()) - continue; - dp = (nsXPCVarient*)dispatchParams[i].val.p; - } - else - dp = &dispatchParams[i]; + dp->flags = nsXPCVarient::PTR_IS_DATA; - // XXX fix this mess... - - if(type & ~nsXPCType::TYPE_MASK) - { - NS_ASSERTION(0,"not supported"); - continue; - } - - // set 'src' to be the object from which we get the value - - if(param.IsOut() /* implicit && param.IsIn() */ ) - { - if(!JSVAL_IS_OBJECT(argv[i]) || - !JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[i]), XPC_VAL_STR, &src)) + // XXX are there no type alignment issues here? + if(type & nsXPCType::IS_POINTER) { - ReportError(desc, "no out val"); + dp->ptr = &dp->ptr2; + dp->ptr2 = &dp->val; + } + else + dp->ptr = &dp->val; + + if(!param.IsRetval() && + (!JSVAL_IS_OBJECT(argv[i]) || + !JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[i]), XPC_VAL_STR, &src))) + { + ReportError(desc, "out argument must be object"); goto done; } + if(!param.IsIn()) + { + // We don't need to convert the jsval. + + // XXX for an out param *I think* I might need to set the flags + // to VAL_IS_OWNED (after clearing val.p) if the type is + // 'IS_POINTER' because I think the caller may have to take + // over ownership of a pointer. But, this depends on the + // type of the thing. + + continue; + } } else - src = argv[i]; - - // XXX just ASSUME a number - - if(!JS_ValueToNumber(cx, src, &num)) { - ReportError(desc, "could not convert argument to a number"); - goto done; + if(type & nsXPCType::IS_POINTER) + { + dp->ptr = &dp->val; + dp->flags = nsXPCVarient::PTR_IS_DATA; + } + src = argv[i]; } - switch(type) + // do the actual conversion... + + // handle special cases first + + if(type == nsXPCType::T_INTERFACE) { - case nsXPCType::T_I8 : dp->val.i8 = (int8) num; break; - case nsXPCType::T_I16 : dp->val.i16 = (int16) num; break; - case nsXPCType::T_I32 : dp->val.i32 = (int32) num; break; - case nsXPCType::T_I64 : dp->val.i64 = (int64) num; break; - case nsXPCType::T_U8 : dp->val.u8 = (uint8) num; break; - case nsXPCType::T_U16 : dp->val.u16 = (uint16) num; break; - case nsXPCType::T_U32 : dp->val.u32 = (uint32) num; break; - case nsXPCType::T_U64 : dp->val.u64 = (uint64) num; break; - case nsXPCType::T_FLOAT : dp->val.f = (float) num; break; - case nsXPCType::T_DOUBLE : dp->val.d = (double) num; break; - case nsXPCType::T_BOOL : dp->val.b = (PRBool) num; break; - case nsXPCType::T_CHAR : dp->val.c = (char) num; break; - case nsXPCType::T_WCHAR : dp->val.wc = (wchar_t) num; break; - default: - NS_ASSERTION(0, "bad type"); - ReportError(desc, "could not convert argument to a number"); - goto done; + // 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"); + continue; + } + else if(type == nsXPCType::T_INTERFACE_IS) + { + // XXX implement INTERFACE_IS + NS_ASSERTION(0,"interface_is params not supported"); + continue; + } + else if(type == nsXPCType::T_STRING) + { + // XXX implement STRING + NS_ASSERTION(0,"string params not supported"); + continue; + } + else if(type == nsXPCType::T_P_IID) + { + // XXX implement IID + NS_ASSERTION(0,"iid params not supported"); + continue; + } + else if(type == nsXPCType::T_P_VOID) + { + // XXX implement void* + NS_ASSERTION(0,"void* params not supported"); + continue; + } + else { + int32 ti; + uint32 tu; + jsdouble td; + JSBool r; + + switch(type & nsXPCType::TYPE_MASK) + { + case nsXPCType::T_I8 : + r = JS_ValueToECMAInt32(cx,src,&ti); + dp->val.i8 = (int8) ti; + break; + case nsXPCType::T_I16 : + r = JS_ValueToECMAInt32(cx,src,&ti); + dp->val.i16 = (int16) ti; + break; + case nsXPCType::T_I32 : + r = JS_ValueToECMAInt32(cx,src,&dp->val.i32); + break; + case nsXPCType::T_I64 : + if(JSVAL_IS_INT(src)) + { + r = JS_ValueToECMAInt32(cx,src,&ti); + dp->val.i64 = (int64) ti; + } + else + { + r = JS_ValueToNumber(cx, src, &td); + if(r) dp->val.i64 = (int64) td; + } + break; + case nsXPCType::T_U8 : + r = JS_ValueToECMAUint32(cx,src,&tu); + dp->val.u8 = (uint8) tu; + break; + case nsXPCType::T_U16 : + r = JS_ValueToECMAUint32(cx,src,&tu); + dp->val.u16 = (uint16) tu; + break; + case nsXPCType::T_U32 : + r = JS_ValueToECMAUint32(cx,src,&dp->val.u32); + break; + case nsXPCType::T_U64 : + if(JSVAL_IS_INT(src)) + { + r = JS_ValueToECMAUint32(cx,src,&tu); + dp->val.i64 = (int64) tu; + } + else + { + r = JS_ValueToNumber(cx, src, &td); + // XXX Win32 can't handle double to uint64 directly + if(r) dp->val.u64 = (uint64)((int64) td); + } + break; + case nsXPCType::T_FLOAT : + r = JS_ValueToNumber(cx, src, &td); + if(r) dp->val.f = (float) td; + break; + case nsXPCType::T_DOUBLE : + r = JS_ValueToNumber(cx, src, &dp->val.d); + break; + case nsXPCType::T_BOOL : + r = JS_ValueToBoolean(cx, src, &dp->val.b); + break; + + // XXX should we special case char* and wchar_t* to be strings? + case nsXPCType::T_CHAR : + case nsXPCType::T_WCHAR : + default: + NS_ASSERTION(0, "bad type"); + ReportError(desc, "could not convert argument"); + goto done; + } + continue; } } // do the invoke - invokeResult = xpc_InvokeNativeMethod(wrapper->GetNative(),vtblIndex, + invokeResult = xpc_InvokeNativeMethod(wrapper->GetNative(), vtblIndex, paramCount, dispatchParams); + if(NS_FAILED(invokeResult)) + { + // XXX this (and others!) should throw rather than report error + ReportError(desc, "XPCOM object returned failure"); + goto done; + } // iterate through the params to gather the results + for(i = 0; i < paramCount; i++) + { + const nsXPCParamInfo& param = info->GetParam(i); + const nsXPCType& type = param.GetType(); - // set the retval for success + nsXPCVarient* dp = &dispatchParams[i]; + if(param.IsOut()) + { + jsval v; + if(type == 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"); + goto done; + continue; + } + else if(type == nsXPCType::T_INTERFACE_IS) + { + // XXX implement INTERFACE_IS + NS_ASSERTION(0,"interface_is params not supported"); + continue; + } + else if(type == nsXPCType::T_STRING) + { + // XXX implement STRING + NS_ASSERTION(0,"string params not supported"); + continue; + } + else if(type == nsXPCType::T_P_IID) + { + // XXX implement IID + NS_ASSERTION(0,"iid params not supported"); + continue; + } + else if(type == nsXPCType::T_P_VOID) + { + // XXX implement void* + NS_ASSERTION(0,"void* params not supported"); + continue; + } + else + { + jsdouble d; + switch(type & nsXPCType::TYPE_MASK) + { + case nsXPCType::T_I8 :v = INT_TO_JSVAL((int32)dp->val.i8); break; + case nsXPCType::T_I16 :v = INT_TO_JSVAL((int32)dp->val.i16); break; + case nsXPCType::T_I32 :v = FIT_32(dp->val.i32,d); break; + case nsXPCType::T_I64 :v = JAM_DOUBLE(dp->val.i64,d); break; + case nsXPCType::T_U8 :v = INT_TO_JSVAL((int32)dp->val.u8); break; + case nsXPCType::T_U16 :v = INT_TO_JSVAL((int32)dp->val.u16); break; + case nsXPCType::T_U32 :v = FIT_32(dp->val.u32,d); break; + case nsXPCType::T_U64 :v = JAM_DOUBLE_U64(dp->val.u64,d); break; + case nsXPCType::T_FLOAT :v = JAM_DOUBLE(dp->val.f,d); break; + case nsXPCType::T_DOUBLE:v = DOUBLE_TO_JSVAL(&dp->val.d); break; + case nsXPCType::T_BOOL :v = dp->val.b?JSVAL_TRUE:JSVAL_FALSE; break; + // XXX should we special case char* and wchar_t* to be strings? + case nsXPCType::T_CHAR :/*v = INT_TO_JSVAL((int32)dp->val.c); */ break; + case nsXPCType::T_WCHAR :/*v = INT_TO_JSVAL((int32)dp->val.wc);*/ break; + default: + // XXX need to support string constants + NS_ASSERTION(0, "bad type"); + ReportError(desc, "invalid out type"); + goto done; + } + } + if(param.IsRetval()) + *vp = v; + else + { + // we actually assured this before doing the invoke + NS_ASSERTION(JSVAL_IS_OBJECT(argv[i]), "out var is not object"); + if(!JS_SetProperty(cx, JSVAL_TO_OBJECT(argv[i]), XPC_VAL_STR, &v)) + { + ReportError(desc, "Can't set val on out param object"); + goto done; + } + } + } + } + retval = JS_TRUE; done: + // iterate through the params that were init'd (again!) and clean up + // any alloc'd stuff and release wrappers of params + for(i = 0; i < dispatchParamsInitedCount; i++) + { + nsXPCVarient* dp = &dispatchParams[i]; + void* p = dp->val.p; + // XXX verify that ALL this this stuff is right + if(!p) + continue; + if(dp->flags & nsXPCVarient::VAL_IS_OWNED) + delete [] p; + else if(info->GetParam(i).GetType() == nsXPCType::T_INTERFACE) + ((nsISupports*)p)->Release(); + } + if(dispatchParams && dispatchParams != paramBuffer) delete [] dispatchParams; - if(scratch && scratch != scratchBuffer) - delete [] scratch; return retval; } @@ -848,7 +1007,7 @@ WrappedNative_finalize(JSContext *cx, JSObject *obj) wrapper->JSObjectFinalized(); } -JSObjectOps WrappedNative_ops = { +static JSObjectOps WrappedNative_ops = { /* Mandatory non-null function pointer members. */ NULL, /* newObjectMap */ NULL, /* destroyObjectMap */ @@ -878,7 +1037,7 @@ WrappedNative_getObjectOps(JSContext *cx, JSClass *clazz) return &WrappedNative_ops; } -JSClass WrappedNative_class = { +static JSClass WrappedNative_class = { "XPCWrappedNative", JSCLASS_HAS_PRIVATE, NULL, NULL, NULL, NULL, NULL, NULL, WrappedNative_convert, WrappedNative_finalize, @@ -907,9 +1066,8 @@ nsXPCWrappedNativeClass::InitForContext(XPCContext* xpcc) JSObject* nsXPCWrappedNativeClass::NewInstanceJSObject(nsXPCWrappedNative* self) { - JSContext* cx = GetXPCContext()->GetJSContext(); + JSContext* cx = GetJSContext(); JSObject* jsobj = JS_NewObject(cx, &WrappedNative_class, NULL, NULL); -// GetXPCContext()->GetGlobalObject()); if(!jsobj || !JS_SetPrivate(cx, jsobj, self)) return NULL; return jsobj;