Initial checkin of XPConnect. This is not yet at all functional nor anywhere near finished.

This commit is contained in:
jband%netscape.com 1999-01-04 03:14:01 +00:00
parent 353da933fb
commit ae072284ac
17 changed files with 2707 additions and 0 deletions

8
js/src/xpconnect/README Normal file
View File

@ -0,0 +1,8 @@
/* jband - 01/03/99 - */
see http://www.mozilla.org/scriptable
This is an initial checkin of a *very* unfinished and not yet functional
implementation of XPConnect. This is not yet part of the Gecko build.
Pretty near everyone in the universe can ignore it for now.

View File

@ -0,0 +1,72 @@
#!nmake
#
# 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.
DEPTH=..\..\..
IGNORE_MANIFEST=1
MAKE_OBJ_TYPE = DLL
DLLNAME = xpc$(MOZ_BITS)$(VERSION_NUMBER)
#PDBFILE = $(DLLNAME).pdb
#MAPFILE = $(DLLNAME).map
#RESFILE = xpc$(MOZ_BITS)$(VERSION_NUMBER).res
DLL =.\$(OBJDIR)\$(DLLNAME).dll
MODULE=xpconnect
REQUIRES=xpcom js
DEFINES=-DWIN32_LEAN_AND_MEAN -DEXPORT_XPC_API
OBJS= \
.\$(OBJDIR)\xpcmaps.obj \
.\$(OBJDIR)\xpccontext.obj \
.\$(OBJDIR)\xpcbogusjs.obj \
.\$(OBJDIR)\xpcbogusii.obj \
.\$(OBJDIR)\xpcwrappednative.obj \
.\$(OBJDIR)\xpcwrappednativeclass.obj \
.\$(OBJDIR)\nsXPConnect.obj \
$(NULL)
EXPORTS = \
nsIXPConnect.h \
$(NULL)
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\js -I$(PUBLIC)\raptor
LCFLAGS = \
$(LCFLAGS) \
$(DEFINES) \
$(NULL)
LLIBS= $(LIBNSPR) \
$(DIST)\lib\js$(MOZ_BITS)$(VERSION_NUMBER).lib \
$(DIST)\lib\xpcom$(MOZ_BITS).lib \
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
!endif
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(DLLNAME).lib
rm -f $(DIST)\bin\$(DLLNAME).dll

View File

@ -0,0 +1,173 @@
/* -*- 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.
*/
/* All the XPConnect public interfaces. */
#ifndef nsIXPConnect_h___
#define nsIXPConnect_h___
// XXX for now...
#include "nsISupports.h"
#include "jsapi.h"
/*
* The linkage of XPC API functions differs depending on whether the file is
* used within the XPC library or not. Any source file within the XPC
* library should define EXPORT_XPC_API whereas any client of the library
* should not.
*/
#ifdef EXPORT_XPC_API
#define XPC_PUBLIC_API(t) JS_EXPORT_API(t)
#define XPC_PUBLIC_DATA(t) JS_EXPORT_DATA(t)
#else
#define XPC_PUBLIC_API(t) JS_IMPORT_API(t)
#define XPC_PUBLIC_DATA(t) JS_IMPORT_DATA(t)
#endif
#define XPC_FRIEND_API(t) XPC_PUBLIC_API(t)
#define XPC_FRIEND_DATA(t) XPC_PUBLIC_DATA(t)
// XXX break these up into separate files...
// XXX declare them in XPIDL :)
/***************************************************************************/
// {215DBE00-94A7-11d2-BA58-00805F8A5DD7}
#define NS_IJSCONTEXT_IID \
{ 0x215dbe00, 0x94a7, 0x11d2, \
{ 0xba, 0x58, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
class nsIJSContext : public nsISupports
{
public:
NS_IMETHOD GetNative(JSContext** cx) = 0;
};
/***************************************************************************/
// {215DBE01-94A7-11d2-BA58-00805F8A5DD7}
#define NS_IJSOBJECT_IID \
{ 0x215dbe01, 0x94a7, 0x11d2, \
{ 0xba, 0x58, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
class nsIJSObject : public nsISupports
{
public:
NS_IMETHOD GetNative(JSObject** jsobj) = 0;
};
/***************************************************************************/
// {215DBE02-94A7-11d2-BA58-00805F8A5DD7}
#define NS_IXPCONNECT_WRAPPED_NATIVE_IID \
{ 0x215dbe02, 0x94a7, 0x11d2, \
{ 0xba, 0x58, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
class nsIXPConnectWrappedNative : public nsISupports
{
// no methods!
};
/***************************************************************************/
// {215DBE03-94A7-11d2-BA58-00805F8A5DD7}
#define NS_IXPCONNECT_WRAPPED_JS_IID \
{ 0x215dbe03, 0x94a7, 0x11d2, \
{ 0xba, 0x58, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
class nsIXPConnectWrappedJS : public nsISupports
{
// no methods!
};
/***************************************************************************/
// forward declarations of 2 non-XPCOM classes...
class nsXPCMethodInfo;
class nsXPCConstant;
// {215DBE04-94A7-11d2-BA58-00805F8A5DD7}
#define NS_IINTERFACEINFO_IID \
{ 0x215dbe04, 0x94a7, 0x11d2, \
{ 0xba, 0x58, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
class nsIInterfaceInfo : public nsISupports
{
public:
NS_IMETHOD GetName(const char** name) = 0;
NS_IMETHOD GetIID(const nsIID** iid) = 0;
NS_IMETHOD GetParent(nsIInterfaceInfo** parent) = 0;
// these include counts of parents
NS_IMETHOD GetMethodCount(int* count) = 0;
NS_IMETHOD GetConstantCount(int* count) = 0;
// these include methods and constants of parents
NS_IMETHOD GetMethodInfo(unsigned index, const nsXPCMethodInfo** info) = 0;
NS_IMETHOD GetConstant(unsigned index, const nsXPCConstant** constant) = 0;
};
/***************************************************************************/
// {EFAE37B0-946D-11d2-BA58-00805F8A5DD7}
#define NS_IXPCONNECT_IID \
{ 0xefae37b0, 0x946d, 0x11d2, \
{0xba, 0x58, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7} }
class nsIXPConnect : public nsISupports
{
public:
NS_IMETHOD InitJSContext(nsIJSContext* aJSContext,
nsIJSObject* aGlobalJSObj) = 0;
NS_IMETHOD GetInterfaceInfo(REFNSIID aIID,
nsIInterfaceInfo** info) = 0;
NS_IMETHOD WrapNative(nsIJSContext* aJSContext,
nsISupports* aCOMObj,
REFNSIID aIID,
nsIXPConnectWrappedNative** aWrapper) = 0;
NS_IMETHOD WrapJS(nsIJSContext* aJSContext,
nsIJSObject* aJSObj,
REFNSIID aIID,
nsIXPConnectWrappedJS** aWrapper) = 0;
NS_IMETHOD GetJSObjectOfWrappedJS(nsIXPConnectWrappedJS* aWrapper,
nsIJSObject** aJSObj) = 0;
NS_IMETHOD GetJSObjectOfWrappedNative(nsIXPConnectWrappedNative* aWrapper,
nsIJSObject** aJSObj) = 0;
NS_IMETHOD GetNativeOfWrappedNative(nsIXPConnectWrappedNative* aWrapper,
nsISupports** aObj) = 0;
// other stuff...
};
JS_BEGIN_EXTERN_C
XPC_PUBLIC_API(nsIXPConnect*)
XPC_GetXPConnect();
XPC_PUBLIC_API(nsIJSContext*)
XPC_NewJSContext(JSContext* cx);
XPC_PUBLIC_API(nsIJSObject*)
XPC_NewJSObject(nsIJSContext* aJSContext, JSObject* jsobj);
JS_END_EXTERN_C
#endif /* nsIXPConnect_h___ */

View File

@ -0,0 +1,217 @@
/* -*- 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.
*/
/* High level class and public functions implementation. */
#include "xpcprivate.h"
#define CONTEXT_MAP_SIZE 16
#define JS_MAP_SIZE 256
#define NATIVE_MAP_SIZE 256
#define JS_CLASS_MAP_SIZE 256
#define NATIVE_CLASS_MAP_SIZE 256
NS_IMPL_ISUPPORTS(nsXPConnect, NS_IXPCONNECT_IID)
nsXPConnect* nsXPConnect::mSelf = NULL;
// static
nsXPConnect*
nsXPConnect::GetXPConnect()
{
if(mSelf)
NS_ADDREF(mSelf);
else
{
mSelf = new nsXPConnect();
if(mSelf && !mSelf->mContextMap)
{
NS_RELEASE(mSelf); // XXX two line macro (bug in nsISupports.h)
}
}
return mSelf;
}
nsXPConnect::nsXPConnect()
{
NS_INIT_REFCNT();
NS_ADDREF_THIS();
mContextMap = JSContext2XPCContextMap::newMap(CONTEXT_MAP_SIZE);
}
nsXPConnect::~nsXPConnect()
{
if(mContextMap)
delete mContextMap;
mSelf = NULL;
}
nsresult
nsXPConnect::InitJSContext(nsIJSContext* aJSContext,
nsIJSObject* aGlobalJSObj)
{
JSContext* cx;
JSObject* global;
if(!aJSContext || !aGlobalJSObj ||
NS_FAILED(aJSContext->GetNative(&cx)) ||
NS_FAILED(aGlobalJSObj->GetNative(&global)) ||
!cx || !global || mContextMap->Find(cx) || !NewContext(cx, global))
{
NS_ASSERTION(0,"nsXPConnect::InitJSContext failed");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
XPCContext*
nsXPConnect::GetContext(JSContext* cx)
{
XPCContext* xpcc;
NS_PRECONDITION(cx,"bad param");
xpcc = mContextMap->Find(cx);
if(!xpcc)
xpcc = NewContext(cx, JS_GetGlobalObject(cx));
return xpcc;
}
XPCContext*
nsXPConnect::NewContext(JSContext* cx, JSObject* global)
{
XPCContext* xpcc;
NS_PRECONDITION(cx,"bad param");
NS_PRECONDITION(global,"bad param");
NS_PRECONDITION(!mContextMap->Find(cx),"bad param");
xpcc = XPCContext::newXPCContext(cx, global,
JS_MAP_SIZE,
NATIVE_MAP_SIZE,
JS_CLASS_MAP_SIZE,
NATIVE_CLASS_MAP_SIZE);
if(xpcc)
mContextMap->Add(xpcc);
return xpcc;
}
nsresult
nsXPConnect::GetInterfaceInfo(REFNSIID aIID,
nsIInterfaceInfo** info)
{
NS_PRECONDITION(info,"bad param");
// XXX implement...FOR REAL...
*info = new nsInterfaceInfo(aIID, "name", NULL);
return NS_OK;
}
nsresult
nsXPConnect::WrapNative(nsIJSContext* aJSContext,
nsISupports* aCOMObj,
REFNSIID aIID,
nsIXPConnectWrappedNative** aWrapper)
{
NS_PRECONDITION(aJSContext,"bad param");
NS_PRECONDITION(aCOMObj,"bad param");
NS_PRECONDITION(aWrapper,"bad param");
*aWrapper = NULL;
JSContext* cx;
if(NS_FAILED(aJSContext->GetNative(&cx)))
return NS_ERROR_FAILURE;
XPCContext* xpcc = GetContext(cx);
if(!xpcc)
return NS_ERROR_FAILURE;
nsXPCWrappedNative* wrapper =
nsXPCWrappedNative::GetNewOrUsedWrapper(xpcc, aCOMObj, aIID);
if(!wrapper)
return NS_ERROR_FAILURE;
*aWrapper = wrapper;
return NS_OK;
}
nsresult
nsXPConnect::WrapJS(nsIJSContext* aJSContext,
nsIJSObject* aJSObj,
REFNSIID aIID,
nsIXPConnectWrappedJS** aWrapper)
{
// XXX implement...
return NS_OK;
}
nsresult
nsXPConnect::GetJSObjectOfWrappedJS(nsIXPConnectWrappedJS* aWrapper,
nsIJSObject** aJSObj)
{
NS_PRECONDITION(aWrapper,"bad param");
NS_PRECONDITION(aJSObj,"bad param");
// MAJOR ASSUMPTION
nsXPCWrappedJS* realWrapper = NS_STATIC_CAST(nsXPCWrappedJS*, aWrapper);
JSObject* jsobj = realWrapper->GetJSObject();
NS_ASSERTION(jsobj,"bad WrappedJS");
nsJSContext* aContext =
new nsJSContext(realWrapper->GetClass()->GetXPCContext()->GetJSContext());
*aJSObj = new nsJSObject(aContext, jsobj);
return NS_OK;
}
nsresult
nsXPConnect::GetJSObjectOfWrappedNative(nsIXPConnectWrappedNative* aWrapper,
nsIJSObject** aJSObj)
{
NS_PRECONDITION(aWrapper,"bad param");
NS_PRECONDITION(aJSObj,"bad param");
// MAJOR ASSUMPTION
nsXPCWrappedNative* realWrapper = NS_STATIC_CAST(nsXPCWrappedNative*, aWrapper);
JSObject* jsobj = realWrapper->GetJSObject();
NS_ASSERTION(jsobj,"bad WrappedNative");
nsJSContext* aContext =
new nsJSContext(realWrapper->GetClass()->GetXPCContext()->GetJSContext());
*aJSObj = new nsJSObject(aContext, jsobj);
return NS_OK;
}
nsresult
nsXPConnect::GetNativeOfWrappedNative(nsIXPConnectWrappedNative* aWrapper,
nsISupports** aObj)
{
NS_PRECONDITION(aWrapper,"bad param");
NS_PRECONDITION(aObj,"bad param");
// MAJOR ASSUMPTION
nsXPCWrappedNative* realWrapper = NS_STATIC_CAST(nsXPCWrappedNative*, aWrapper);
*aObj = realWrapper->GetNative();
NS_ADDREF(*aObj);
return NS_OK;
}
XPC_PUBLIC_API(nsIXPConnect*)
XPC_GetXPConnect()
{
return nsXPConnect::GetXPConnect();
}

View File

@ -0,0 +1,125 @@
#include "nsIXPConnect.h"
#include "jsapi.h"
#include <stdio.h>
/***************************************************************************/
// {159E36D0-991E-11d2-AC3F-00C09300144B}
#define NS_ITESTXPC_FOO_IID \
{ 0x159e36d0, 0x991e, 0x11d2, \
{ 0xac, 0x3f, 0x0, 0xc0, 0x93, 0x0, 0x14, 0x4b } }
class nsITestXPCFoo : public nsISupports
{
public:
};
// {5F9D20C0-9B6B-11d2-9FFE-000064657374}
#define NS_ITESTXPC_FOO2_IID \
{ 0x5f9d20c0, 0x9b6b, 0x11d2, \
{ 0x9f, 0xfe, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
class nsITestXPCFoo2 : public nsITestXPCFoo
{
public:
};
class nsTestXPCFoo : public nsITestXPCFoo2
{
NS_DECL_ISUPPORTS;
nsTestXPCFoo();
};
nsresult nsTestXPCFoo::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
// XXX bogus trust...
*aInstancePtr = (void*) this;
NS_ADDREF_THIS();
return NS_OK;
}
NS_IMPL_ADDREF(nsTestXPCFoo)
NS_IMPL_RELEASE(nsTestXPCFoo)
nsTestXPCFoo::nsTestXPCFoo()
{
NS_INIT_REFCNT();
NS_ADDREF_THIS();
}
NS_DEFINE_IID(kIFooIID, NS_ITESTXPC_FOO_IID);
NS_DEFINE_IID(kIFoo2IID, NS_ITESTXPC_FOO2_IID);
/***************************************************************************/
static JSClass global_class = {
"global", 0,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
static void
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
printf(message);
}
int main()
{
JSRuntime *rt;
JSContext *cx;
JSObject *glob;
rt = JS_NewRuntime(8L * 1024L * 1024L);
if (!rt)
return 1;
cx = JS_NewContext(rt, 8192);
if (!cx)
return 1;
JS_SetErrorReporter(cx, my_ErrorReporter);
glob = JS_NewObject(cx, &global_class, NULL, NULL);
if (!glob)
return 1;
if (!JS_InitStandardClasses(cx, glob))
return 1;
nsIXPConnect* xpc = XPC_GetXPConnect();
nsIJSContext* xpccx = XPC_NewJSContext(cx);
nsIJSObject* xpcglob = XPC_NewJSObject(xpccx, glob);
nsTestXPCFoo* foo = new nsTestXPCFoo();
nsIXPConnectWrappedNative* wrapper;
nsIXPConnectWrappedNative* wrapper2;
if(NS_SUCCEEDED(xpc->WrapNative(xpccx, foo, kIFooIID, &wrapper)))
{
if(NS_SUCCEEDED(xpc->WrapNative(xpccx, foo, kIFoo2IID, &wrapper2)))
{
nsIJSObject* obj;
nsISupports* com_obj;
xpc->GetJSObjectOfWrappedNative(wrapper2, &obj);
xpc->GetNativeOfWrappedNative(wrapper2, &com_obj);
NS_RELEASE(obj);
NS_RELEASE(com_obj);
NS_RELEASE(wrapper2);
}
NS_RELEASE(wrapper);
}
NS_RELEASE(foo);
JS_GC(cx);
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
return 0;
}

View File

@ -0,0 +1,65 @@
#!nmake
#
# 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.
DEPTH=..\..\..\..
IGNORE_MANIFEST=1
MAKE_OBJ_TYPE = EXE
PROG1 = .\$(OBJDIR)\TestXPC.exe
PROGRAMS = $(PROG1)
LCFLAGS=-DUSE_NSREG
REQUIRES=xpcom js xpconnect
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\js -I$(PUBLIC)\xpconnect -I$(PUBLIC)\raptor
LLIBS= \
$(DIST)\lib\xpcom32.lib \
$(LIBNSPR) \
$(DIST)\lib\js3250.lib \
$(DIST)\lib\xpc3250.lib \
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
!endif
include <$(DEPTH)\config\rules.mak>
install:: $(PROGRAMS)
-for %p in ($(PROGRAMS)) do $(MAKE_INSTALL) %p $(DIST)\bin
clobber::
-for %p in ($(PROGRAMS)) do $(RM) %p $(DIST)\bin\%p
# Move this into config/obj.inc when it's allowed
.cpp{.\$(OBJDIR)\}.exe:
$(CC) @<<$(CFGFILE)
$(CFLAGS)
$(LCFLAGS)
$(LINCS)
$(LINCS_1)
$(INCS)
$(LLIBS)
$(OS_LIBS)
-Fd$(PBDFILE)
-Fe.\$(OBJDIR)\
-Fo.\$(OBJDIR)\
$(CURDIR)$(*B).cpp
<<KEEP
$(PROG1): $(OBJDIR) TestXPC.cpp

View File

@ -0,0 +1,139 @@
/* -*- 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.
*/
/* Temporary Interface Info related stuff. */
#include "xpcprivate.h"
NS_IMPL_ISUPPORTS(nsInterfaceInfo, NS_IINTERFACEINFO_IID)
nsInterfaceInfo::nsInterfaceInfo(REFNSIID aIID, const char* aName,
nsInterfaceInfo* aParent)
: mIID(aIID),
mName(strdup(aName)),
mParent(aParent)
{
NS_PRECONDITION(aName, "bad param");
NS_INIT_REFCNT();
NS_ADDREF_THIS();
mMethodBaseIndex = mParent ?
mParent->mMethodBaseIndex +
mParent->mMethodCount : 0;
mConstantBaseIndex = mParent ?
mParent->mConstantBaseIndex +
mParent->mConstantCount : 0;
// XXX implement for real
mMethodCount = 0;
mMethods = NULL;
mConstantCount = 0;
mConstants = NULL;
if(mParent)
NS_ADDREF(mParent);
}
nsInterfaceInfo::~nsInterfaceInfo()
{
if(mName)
free(mName);
if(mParent)
NS_RELEASE(mParent);
}
nsresult
nsInterfaceInfo::GetName(const char** name)
{
NS_PRECONDITION(name, "bad param");
*name = mName;
return NS_OK;
}
nsresult
nsInterfaceInfo::GetIID(const nsIID** iid)
{
NS_PRECONDITION(iid, "bad param");
*iid = &mIID;
return NS_OK;
}
nsresult
nsInterfaceInfo::GetParent(nsIInterfaceInfo** parent)
{
NS_PRECONDITION(parent, "bad param");
*parent = mParent;
return NS_OK;
}
nsresult
nsInterfaceInfo::GetMethodCount(int* count)
{
NS_PRECONDITION(count, "bad param");
*count = mMethodBaseIndex + mMethodCount;
return NS_OK;
}
nsresult
nsInterfaceInfo::GetConstantCount(int* count)
{
NS_PRECONDITION(count, "bad param");
*count = mConstantBaseIndex + mConstantCount;
return NS_OK;
}
nsresult
nsInterfaceInfo::GetMethodInfo(unsigned index, const nsXPCMethodInfo** info)
{
NS_PRECONDITION(info, "bad param");
if(index < mMethodBaseIndex)
return mParent->GetMethodInfo(index, info);
if(index >= mMethodBaseIndex + mMethodCount)
{
NS_PRECONDITION(0, "bad param");
*info = NULL;
return NS_ERROR_INVALID_ARG;
}
// else...
*info = mMethods[mMethodBaseIndex-index];
return NS_OK;
}
nsresult
nsInterfaceInfo::GetConstant(unsigned index, const nsXPCConstant** constant)
{
NS_PRECONDITION(constant, "bad param");
if(index < mConstantBaseIndex)
return mParent->GetConstant(index, constant);
if(index >= mConstantBaseIndex + mConstantCount)
{
NS_PRECONDITION(0, "bad param");
*constant = NULL;
return NS_ERROR_INVALID_ARG;
}
// else...
*constant = mConstants[mConstantBaseIndex-index];
return NS_OK;
}

View File

@ -0,0 +1,211 @@
/* -*- 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.
*/
/* Temporary Interface Info related stuff. */
#ifndef xpcbogusii_h___
#define xpcbogusii_h___
class nsXPCType
{
private:
uint8 t; // only member
public:
nsXPCType(); // no implementation
nsXPCType(uint8 type) : t(type) {}
nsXPCType& operator=(uint8 type) {t = type; return *this;}
operator uint8() const {return t;}
enum
{
IS_POINTER = 0x80,
IS_UNIQUE_POINTER = 0x40,
IS_REFERENCE = 0x20,
SPECIAL_BIT = 0x10,
TYPE_MASK = 0xf,
I8 = 0,
I16 = 1,
I32 = 2,
I64 = 3,
U8 = 4,
U16 = 5,
U32 = 6,
U64 = 7,
FLOAT = 8,
DOUBLE = 9,
BOOL = 10,
CHAR = 11,
WCHAR = 12,
VOID = 13,
P_I8 = IS_POINTER | 0,
P_I16 = IS_POINTER | 1,
P_I32 = IS_POINTER | 2,
P_I64 = IS_POINTER | 3,
P_U8 = IS_POINTER | 4,
P_U16 = IS_POINTER | 5,
P_U32 = IS_POINTER | 6,
P_U64 = IS_POINTER | 7,
P_FLOAT = IS_POINTER | 8,
P_DOUBLE = IS_POINTER | 9,
P_BOOL = IS_POINTER | 10,
P_CHAR = IS_POINTER | 11,
P_WCHAR = IS_POINTER | 12,
P_VOID = IS_POINTER | 13,
P_IID = IS_POINTER | 14,
STRING = IS_POINTER | 15,
INTERFACE = 16, /* SPECIAL_BIT | 0 */
INTERFACE_IS = 17 /* SPECIAL_BIT | 1 */
};
};
class nsVarient
{
nsXPCType type;
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;
} value;
};
class nsXPCParamInfo
{
public:
// add ctor/dtor
enum
{
IS_IN = 0x80,
IS_OUT = 0x40
};
JSBool IsIn() const {return (JSBool) (flags & IS_IN);}
JSBool IsOut() const {return (JSBool) (flags & IS_OUT);}
nsXPCType GetType() const {return type;}
uint8 GetInterfaceIsArgNumber() const
{
NS_PRECONDITION(type == nsXPCType::INTERFACE_IS,"not an interface_is");
return interface_is_arg_num;
}
nsIInterfaceInfo* GetInterface() const
{
NS_PRECONDITION(type == nsXPCType::INTERFACE,"not an interface");
return interface;
}
private:
uint8 flags;
nsXPCType type;
union
{
uint8 interface_is_arg_num;
nsIInterfaceInfo* interface;
};
};
class nsXPCMethodInfo
{
public:
// add ctor/dtor
enum
{
IS_GETTER = 0x80,
IS_SETTER = 0x40,
IS_VAR_ARGS = 0x20,
IS_CONSTRUCTOR = 0x10
};
JSBool IsGetter() const {return (JSBool) (flags & IS_GETTER);}
JSBool IsSetter() const {return (JSBool) (flags & IS_SETTER);}
JSBool IsVarArgs() const {return (JSBool) (flags & IS_VAR_ARGS);}
JSBool IsConstructor() const {return (JSBool) (flags & IS_CONSTRUCTOR);}
const char* GetName() const {return mName;}
uint8 GetParamCount() const {return param_count;}
const nsXPCParamInfo* GetParam(uint8 index) const
{
NS_PRECONDITION(index < param_count,"bad arg");
return &params[index];
}
const nsXPCParamInfo* GetResult() const {return &result;}
private:
uint8 flags;
char* mName;
uint8 param_count;
nsXPCParamInfo* params;
nsXPCParamInfo result;
};
class nsXPCConstant
{
// XXX flesh out
};
class nsInterfaceInfo : public nsIInterfaceInfo
{
NS_DECL_ISUPPORTS;
NS_IMETHOD GetName(const char** name);
NS_IMETHOD GetIID(const nsIID** iid);
NS_IMETHOD GetParent(nsIInterfaceInfo** parent);
// these include counts of parents
NS_IMETHOD GetMethodCount(int* count);
NS_IMETHOD GetConstantCount(int* count);
// these include methods and constants of parents
NS_IMETHOD GetMethodInfo(unsigned index, const nsXPCMethodInfo** info);
NS_IMETHOD GetConstant(unsigned index, const nsXPCConstant** constant);
public:
nsInterfaceInfo(REFNSIID aIID, const char* aName, nsInterfaceInfo* aParent);
virtual ~nsInterfaceInfo();
private:
char* mName;
nsIID mIID;
nsInterfaceInfo* mParent;
unsigned mMethodBaseIndex;
unsigned mMethodCount;
nsXPCMethodInfo** mMethods;
unsigned mConstantBaseIndex;
unsigned mConstantCount;
nsXPCConstant** mConstants;
};
#endif /* xpcbogusii_h___ */

View File

@ -0,0 +1,86 @@
/* -*- 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.
*/
/* Temporary JSAPI interface related stuff. */
#include "xpcprivate.h"
NS_IMPL_ISUPPORTS(nsJSContext, NS_IJSCONTEXT_IID)
nsJSContext::nsJSContext(JSContext* cx)
: mJSContext(cx)
{
NS_INIT_REFCNT();
NS_ADDREF_THIS();
}
nsresult
nsJSContext::GetNative(JSContext** cx)
{
NS_PRECONDITION(cx,"bad param");
*cx = mJSContext;
return NS_OK;
}
/***************************************************************************/
NS_IMPL_ISUPPORTS(nsJSObject, NS_IJSOBJECT_IID)
nsJSObject::nsJSObject(nsIJSContext* aJSContext, JSObject* jsobj)
: mJSContext(aJSContext),
mJSObject(jsobj)
{
NS_INIT_REFCNT();
NS_ADDREF_THIS();
NS_ADDREF(mJSContext);
JSContext* cx;
if(NS_SUCCEEDED(mJSContext->GetNative(&cx)))
JS_AddRoot(cx, &mJSObject);
}
nsJSObject::~nsJSObject()
{
JSContext* cx;
if(NS_SUCCEEDED(mJSContext->GetNative(&cx)))
JS_RemoveRoot(cx, &mJSObject);
NS_RELEASE(mJSContext);
}
nsresult
nsJSObject::GetNative(JSObject** jsobj)
{
NS_PRECONDITION(jsobj,"bad param");
*jsobj = mJSObject;
return NS_OK;
}
/***************************************************************************/
XPC_PUBLIC_API(nsIJSContext*)
XPC_NewJSContext(JSContext* cx)
{
return new nsJSContext(cx);
}
XPC_PUBLIC_API(nsIJSObject*)
XPC_NewJSObject(nsIJSContext* aJSContext, JSObject* jsobj)
{
return new nsJSObject(aJSContext, jsobj);
}

View File

@ -0,0 +1,54 @@
/* -*- 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.
*/
/* Temporary JSAPI interface related stuff. */
#ifndef xpcbogusjs_h___
#define xpcbogusjs_h___
class nsJSContext : public nsIJSContext
{
NS_DECL_ISUPPORTS;
NS_IMETHOD GetNative(JSContext** cx);
// implementation...
nsJSContext(JSContext* cx);
private:
nsJSContext(); // no implementation
private:
JSContext* mJSContext;
};
/***************************************************************************/
class nsJSObject : public nsIJSObject
{
NS_DECL_ISUPPORTS;
NS_IMETHOD GetNative(JSObject** jsobj);
// implementation...
nsJSObject(nsIJSContext* aJSContext, JSObject* jsobj);
~nsJSObject();
private:
nsJSObject(); // no implementation
private:
nsIJSContext* mJSContext;
JSObject* mJSObject;
};
#endif /* xpcbogusjs_h___ */

View File

@ -0,0 +1,86 @@
/* -*- 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.
*/
/* Per JSContext object. */
#include "xpcprivate.h"
// static
XPCContext*
XPCContext::newXPCContext(JSContext* aJSContext,
JSObject* aGlobalObj,
int WrappedJSMapSize,
int WrappedNativeMapSize,
int WrappedJSClassMapSize,
int WrappedNativeClassMapSize)
{
XPCContext* xpcc;
NS_PRECONDITION(aJSContext,"bad param");
NS_PRECONDITION(aGlobalObj,"bad param");
NS_PRECONDITION(WrappedJSMapSize,"bad param");
NS_PRECONDITION(WrappedNativeMapSize,"bad param");
NS_PRECONDITION(WrappedJSClassMapSize,"bad param");
NS_PRECONDITION(WrappedNativeClassMapSize,"bad param");
xpcc = new XPCContext(aJSContext,
aGlobalObj,
WrappedJSMapSize,
WrappedNativeMapSize,
WrappedJSClassMapSize,
WrappedNativeClassMapSize);
if(xpcc &&
xpcc->GetWrappedJSMap() &&
xpcc->GetWrappedNativeMap() &&
xpcc->GetWrappedJSClassMap() &&
xpcc->GetWrappedNativeClassMap() &&
nsXPCWrappedNativeClass::InitForContext(xpcc))
{
return xpcc;
}
delete xpcc;
return NULL;
}
XPCContext::XPCContext(JSContext* aJSContext,
JSObject* aGlobalObj,
int WrappedJSMapSize,
int WrappedNativeMapSize,
int WrappedJSClassMapSize,
int WrappedNativeClassMapSize)
{
mJSContext = aJSContext;
mGlobalObj = aGlobalObj;
mWrappedJSMap = JSObject2WrappedJSMap::newMap(WrappedJSMapSize);
mWrappedNativeMap = Native2WrappedNativeMap::newMap(WrappedNativeMapSize);
mWrappedJSClassMap = IID2WrappedJSClassMap::newMap(WrappedJSClassMapSize);
mWrappedNativeClassMap = IID2WrappedNativeClassMap::newMap(WrappedNativeClassMapSize);
}
XPCContext::~XPCContext()
{
if(mWrappedJSMap)
delete mWrappedJSMap;
if(mWrappedNativeMap)
delete mWrappedNativeMap;
if(mWrappedJSClassMap)
delete mWrappedJSClassMap;
if(mWrappedNativeClassMap)
delete mWrappedNativeClassMap;
}

View File

@ -0,0 +1,39 @@
/* -*- 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.
*/
/* Private forward declarations. */
#ifndef xpcforwards_h___
#define xpcforwards_h___
// forward declarations of interally used classes...
class XPCContext;
class nsXPConnect;
class JSObject2WrappedJSMap;
class Native2WrappedNativeMap;
class IID2WrappedJSClassMap;
class IID2WrappedNativeClassMap;
class JSContext2XPCContextMap;
class nsXPCWrappedJS;
class nsXPCWrappedNative;
class nsXPCWrappedJSClass;
class nsXPCWrappedNativeClass;
#endif /* xpcforwards_h___ */

View File

@ -0,0 +1,187 @@
/* -*- 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.
*/
/* Private maps (hashtables). */
#include "xpcprivate.h"
/***************************************************************************/
// static shared...
JS_STATIC_DLL_CALLBACK(JSHashNumber)
hash_root(const void *key)
{
return ((JSHashNumber) key) >> 2; /* help lame MSVC1.5 on Win16 */
}
// XXX this is just the hacked String hash function, should do better...
JS_STATIC_DLL_CALLBACK(JSHashNumber)
hash_IID(const void *key)
{
JSHashNumber h;
const PRUint8 *s;
int i;
h = 0;
for (s = (const PRUint8 *)key, i = 0; i < 16; s++, i++)
h = (h >> 28) ^ (h << 4) ^ *s;
return h;
}
JS_STATIC_DLL_CALLBACK(intN)
compare_IIDs(const void *v1, const void *v2)
{
return ((const nsID*)v1)->Equals(*((const nsID*)v2));
}
/***************************************************************************/
// implement JSContext2XPCContextMap...
// static
JSContext2XPCContextMap*
JSContext2XPCContextMap::newMap(int size)
{
JSContext2XPCContextMap* map = new JSContext2XPCContextMap(size);
if(map && map->mHashtable)
return map;
delete map;
return NULL;
}
JSContext2XPCContextMap::JSContext2XPCContextMap(int size)
{
mHashtable = JS_NewHashTable(size, hash_root,
JS_CompareValues, JS_CompareValues,
NULL, NULL);
}
JSContext2XPCContextMap::~JSContext2XPCContextMap()
{
if(mHashtable)
JS_HashTableDestroy(mHashtable);
}
/***************************************************************************/
// implement JSObject2WrappedJSMap...
// static
JSObject2WrappedJSMap*
JSObject2WrappedJSMap::newMap(int size)
{
JSObject2WrappedJSMap* map = new JSObject2WrappedJSMap(size);
if(map && map->mHashtable)
return map;
delete map;
return NULL;
}
JSObject2WrappedJSMap::JSObject2WrappedJSMap(int size)
{
mHashtable = JS_NewHashTable(size, hash_root,
JS_CompareValues, JS_CompareValues,
NULL, NULL);
}
JSObject2WrappedJSMap::~JSObject2WrappedJSMap()
{
if(mHashtable)
JS_HashTableDestroy(mHashtable);
}
/***************************************************************************/
// implement Native2WrappedNativeMap...
// static
Native2WrappedNativeMap*
Native2WrappedNativeMap::newMap(int size)
{
Native2WrappedNativeMap* map = new Native2WrappedNativeMap(size);
if(map && map->mHashtable)
return map;
delete map;
return NULL;
}
Native2WrappedNativeMap::Native2WrappedNativeMap(int size)
{
mHashtable = JS_NewHashTable(size, hash_root,
JS_CompareValues, JS_CompareValues,
NULL, NULL);
}
Native2WrappedNativeMap::~Native2WrappedNativeMap()
{
if(mHashtable)
JS_HashTableDestroy(mHashtable);
}
/***************************************************************************/
// implement IID2WrappedJSClassMap...
// static
IID2WrappedJSClassMap*
IID2WrappedJSClassMap::newMap(int size)
{
IID2WrappedJSClassMap* map = new IID2WrappedJSClassMap(size);
if(map && map->mHashtable)
return map;
delete map;
return NULL;
}
IID2WrappedJSClassMap::IID2WrappedJSClassMap(int size)
{
mHashtable = JS_NewHashTable(size, hash_IID,
compare_IIDs, JS_CompareValues,
NULL, NULL);
}
IID2WrappedJSClassMap::~IID2WrappedJSClassMap()
{
if(mHashtable)
JS_HashTableDestroy(mHashtable);
}
/***************************************************************************/
// implement IID2WrappedJSClassMap...
// static
IID2WrappedNativeClassMap*
IID2WrappedNativeClassMap::newMap(int size)
{
IID2WrappedNativeClassMap* map = new IID2WrappedNativeClassMap(size);
if(map && map->mHashtable)
return map;
delete map;
return NULL;
}
IID2WrappedNativeClassMap::IID2WrappedNativeClassMap(int size)
{
mHashtable = JS_NewHashTable(size, hash_IID,
compare_IIDs, JS_CompareValues,
NULL, NULL);
}
IID2WrappedNativeClassMap::~IID2WrappedNativeClassMap()
{
if(mHashtable)
JS_HashTableDestroy(mHashtable);
}

190
js/src/xpconnect/xpcmaps.h Normal file
View File

@ -0,0 +1,190 @@
/* -*- 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.
*/
/* Private maps (hashtables). */
#ifndef xpcmaps_h___
#define xpcmaps_h___
// Maps...
// no virtuals in the maps - all the common stuff inlined
// templates could be used to good effect here.
class JSContext2XPCContextMap
{
public:
static JSContext2XPCContextMap* newMap(int size);
inline XPCContext* Find(JSContext* cx)
{
NS_PRECONDITION(cx,"bad param");
return (XPCContext*) JS_HashTableLookup(mHashtable, cx);
}
inline void Add(XPCContext* xpcc)
{
NS_PRECONDITION(xpcc,"bad param");
JS_HashTableAdd(mHashtable, xpcc->GetJSContext(), xpcc);
}
inline void Remove(XPCContext* xpcc)
{
NS_PRECONDITION(xpcc,"bad param");
JS_HashTableRemove(mHashtable, xpcc->GetJSContext());
}
~JSContext2XPCContextMap();
private:
JSContext2XPCContextMap(); // no implementation
JSContext2XPCContextMap(int size);
private:
JSHashTable *mHashtable;
};
/*************************/
class JSObject2WrappedJSMap
{
public:
static JSObject2WrappedJSMap* newMap(int size);
inline nsXPCWrappedJS* Find(JSObject* Obj)
{
NS_PRECONDITION(Obj,"bad param");
return (nsXPCWrappedJS*) JS_HashTableLookup(mHashtable, Obj);
}
inline void Add(nsXPCWrappedJS* Wrapper)
{
NS_PRECONDITION(Wrapper,"bad param");
JS_HashTableAdd(mHashtable, Wrapper->GetJSObject(), Wrapper);
}
inline void Remove(nsXPCWrappedJS* Wrapper)
{
NS_PRECONDITION(Wrapper,"bad param");
JS_HashTableRemove(mHashtable, Wrapper->GetJSObject());
}
~JSObject2WrappedJSMap();
private:
JSObject2WrappedJSMap(); // no implementation
JSObject2WrappedJSMap(int size);
private:
JSHashTable *mHashtable;
};
/*************************/
class Native2WrappedNativeMap
{
public:
static Native2WrappedNativeMap* newMap(int size);
inline nsXPCWrappedNative* Find(nsISupports* Obj)
{
NS_PRECONDITION(Obj,"bad param");
return (nsXPCWrappedNative*) JS_HashTableLookup(mHashtable, Obj);
}
inline void Add(nsXPCWrappedNative* Wrapper)
{
NS_PRECONDITION(Wrapper,"bad param");
JS_HashTableAdd(mHashtable, Wrapper->GetNative(), Wrapper);
}
inline void Remove(nsXPCWrappedNative* Wrapper)
{
NS_PRECONDITION(Wrapper,"bad param");
JS_HashTableRemove(mHashtable, Wrapper->GetNative());
}
~Native2WrappedNativeMap();
private:
Native2WrappedNativeMap(); // no implementation
Native2WrappedNativeMap(int size);
private:
JSHashTable *mHashtable;
};
/*************************/
class IID2WrappedJSClassMap
{
public:
static IID2WrappedJSClassMap* newMap(int size);
inline nsXPCWrappedJSClass* Find(REFNSIID iid)
{
return (nsXPCWrappedJSClass*) JS_HashTableLookup(mHashtable, &iid);
}
inline void Add(nsXPCWrappedJSClass* Class)
{
NS_PRECONDITION(Class,"bad param");
JS_HashTableAdd(mHashtable, &Class->GetIID(), Class);
}
inline void Remove(nsXPCWrappedJSClass* Class)
{
NS_PRECONDITION(Class,"bad param");
JS_HashTableRemove(mHashtable, &Class->GetIID());
}
~IID2WrappedJSClassMap();
private:
IID2WrappedJSClassMap(); // no implementation
IID2WrappedJSClassMap(int size);
private:
JSHashTable *mHashtable;
};
/*************************/
class IID2WrappedNativeClassMap
{
public:
static IID2WrappedNativeClassMap* newMap(int size);
inline nsXPCWrappedNativeClass* Find(REFNSIID iid)
{
return (nsXPCWrappedNativeClass*) JS_HashTableLookup(mHashtable, &iid);
}
inline void Add(nsXPCWrappedNativeClass* Class)
{
NS_PRECONDITION(Class,"bad param");
JS_HashTableAdd(mHashtable, &Class->GetIID(), Class);
}
inline void Remove(nsXPCWrappedNativeClass* Class)
{
NS_PRECONDITION(Class,"bad param");
JS_HashTableRemove(mHashtable, &Class->GetIID());
}
~IID2WrappedNativeClassMap();
private:
IID2WrappedNativeClassMap(); // no implementation
IID2WrappedNativeClassMap(int size);
private:
JSHashTable *mHashtable;
};
#endif /* xpcmaps_h___ */

View File

@ -0,0 +1,287 @@
/* -*- 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.
*/
/* All the XPConnect private declarations - only include locally. */
#ifndef xpcprivate_h___
#define xpcprivate_h___
#include <string.h>
#include <stdlib.h>
#include "nscore.h"
#include "nsISupports.h"
#include "nsIXPConnect.h"
#include "jsapi.h"
#include "jshash.h"
#include "xpcforwards.h"
#include "xpcbogusjs.h"
#include "xpcbogusii.h"
/***************************************************************************/
class nsXPConnect : public nsIXPConnect
{
// all the interface method declarations...
NS_DECL_ISUPPORTS;
NS_IMETHOD InitJSContext(nsIJSContext* aJSContext,
nsIJSObject* aGlobalJSObj);
NS_IMETHOD GetInterfaceInfo(REFNSIID aIID,
nsIInterfaceInfo** info);
NS_IMETHOD WrapNative(nsIJSContext* aJSContext,
nsISupports* aCOMObj,
REFNSIID aIID,
nsIXPConnectWrappedNative** aWrapper);
NS_IMETHOD WrapJS(nsIJSContext* aJSContext,
nsIJSObject* aJSObj,
REFNSIID aIID,
nsIXPConnectWrappedJS** aWrapper);
NS_IMETHOD GetJSObjectOfWrappedJS(nsIXPConnectWrappedJS* aWrapper,
nsIJSObject** aJSObj);
NS_IMETHOD GetJSObjectOfWrappedNative(nsIXPConnectWrappedNative* aWrapper,
nsIJSObject** aJSObj);
NS_IMETHOD GetNativeOfWrappedNative(nsIXPConnectWrappedNative* aWrapper,
nsISupports** aObj);
/// non-interface implementation
public:
static nsXPConnect* GetXPConnect();
JSContext2XPCContextMap* GetContextMap() {return mContextMap;}
XPCContext* GetContext(JSContext* cx);
virtual ~nsXPConnect();
private:
nsXPConnect();
XPCContext* NewContext(JSContext* cx, JSObject* global);
private:
// data...
private:
JSContext2XPCContextMap* mContextMap;
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.
// no virtuals
class XPCContext
{
public:
static XPCContext* newXPCContext(JSContext* aJSContext,
JSObject* aGlobalObj,
int WrappedJSMapSize,
int WrappedNativeMapSize,
int WrappedJSClassMapSize,
int WrappedNativeClassMapSize);
JSContext* GetJSContext() {return mJSContext;}
JSObject* GetGlobalObject() {return mGlobalObj;}
JSObject2WrappedJSMap* GetWrappedJSMap() {return mWrappedJSMap;}
Native2WrappedNativeMap* GetWrappedNativeMap() {return mWrappedNativeMap;}
IID2WrappedJSClassMap* GetWrappedJSClassMap() {return mWrappedJSClassMap;}
IID2WrappedNativeClassMap* GetWrappedNativeClassMap() {return mWrappedNativeClassMap;}
~XPCContext();
private:
XPCContext(); // no implementation
XPCContext(JSContext* aJSContext,
JSObject* aGlobalObj,
int WrappedJSMapSize,
int WrappedNativeMapSize,
int WrappedJSClassMapSize,
int WrappedNativeClassMapSize);
private:
JSContext* mJSContext;
JSObject* mGlobalObj;
JSObject2WrappedJSMap* mWrappedJSMap;
Native2WrappedNativeMap* mWrappedNativeMap;
IID2WrappedJSClassMap* mWrappedJSClassMap;
IID2WrappedNativeClassMap* mWrappedNativeClassMap;
};
/*************************/
class nsXPCWrappedJS : public nsIXPConnectWrappedJS
{
// our vtbl stubs here...
// XXX implement...
public:
JSObject* GetJSObject(){return NULL;}
nsXPCWrappedJSClass* GetClass() {return NULL;}
};
class nsXPCWrappedJSClass : public nsISupports
{
// XXX implement...
public:
REFNSIID GetIID(){return mIID;}
XPCContext* GetXPCContext() {return mXPCContext;}
private:
XPCContext* mXPCContext;
nsIID mIID;
};
/*************************/
// nsXPCWrappedNativeClass maintains an array of these things
struct XPCNativeMemberDescriptor
{
enum MemberCategory{
CONSTANT,
METHOD,
ATTRIB_RO,
ATTRIB_RW
};
JSObject* invokeFuncObj;
jsid id; /* hashed name for quick JS property lookup */
uintN index; /* in InterfaceInfo for const, method, and get */
uintN index2; /* in InterfaceInfo for set */
MemberCategory category;
};
// this interfaces exists just so we can refcount nsXPCWrappedNativeClass
// {C9E36280-954A-11d2-BA5A-00805F8A5DD7}
#define NS_IXPCONNECT_WRAPPED_NATIVE_CLASS_IID \
{ 0xc9e36280, 0x954a, 0x11d2, \
{ 0xba, 0x5a, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
class nsIXPCWrappedNativeClass : public nsISupports
{
// no methods
};
class nsXPCWrappedNativeClass : public nsIXPCWrappedNativeClass
{
// all the interface method declarations...
NS_DECL_ISUPPORTS;
public:
static nsXPCWrappedNativeClass* GetNewOrUsedClass(XPCContext* xpcc,
REFNSIID aIID);
REFNSIID GetIID() const {return mIID;}
nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
XPCContext* GetXPCContext() const {return mXPCContext;}
static JSBool InitForContext(XPCContext* xpcc);
JSObject* NewInstanceJSObject(nsXPCWrappedNative* self);
int GetMemberCount() const {return mMemberCount;}
const XPCNativeMemberDescriptor* GetMemberDescriptor(int i) const
{
NS_PRECONDITION(i>0&&i<mMemberCount,"bad index");
return &mMembers[i];
}
const XPCNativeMemberDescriptor* LookupMemberByID(jsid id) const;
JSBool GetConstantAsJSVal(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
jsval* vp);
JSBool GetAttributeAsJSVal(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
jsval* vp);
JSBool SetAttributeFromJSVal(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
jsval* vp);
JSBool CallWrappedMethod(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
JSBool isAttributeSet,
uintN argc, jsval *argv, jsval *vp);
JSObject* GetInvokeFunObj(const XPCNativeMemberDescriptor* desc);
~nsXPCWrappedNativeClass();
private:
nsXPCWrappedNativeClass(); // not implemented
nsXPCWrappedNativeClass(XPCContext* xpcc, REFNSIID aIID,
nsIInterfaceInfo* aInfo);
const char* GetMethodName(int MethodIndex) const;
JSContext* GetJSContext() {return mXPCContext->GetJSContext();}
private:
XPCContext* mXPCContext;
nsIID mIID;
nsIInterfaceInfo* mInfo;
int mMemberCount;
XPCNativeMemberDescriptor* mMembers;
};
class nsXPCWrappedNative : public nsIXPConnectWrappedNative
{
// all the interface method declarations...
NS_DECL_ISUPPORTS;
public:
static nsXPCWrappedNative* GetNewOrUsedWrapper(XPCContext* xpcc,
nsISupports* aObj,
REFNSIID aIID);
nsISupports* GetNative() {return mObj;}
JSObject* GetJSObject() {return mJSObj;}
nsXPCWrappedNativeClass* GetClass() {return mClass;}
void JSObjectFinalized();
virtual ~nsXPCWrappedNative();
private:
nsXPCWrappedNative(); // not implemented
nsXPCWrappedNative(nsISupports* aObj,
nsXPCWrappedNativeClass* aClass,
nsXPCWrappedNative* root);
nsXPCWrappedNative* Find(REFNSIID aIID);
private:
nsISupports* mObj;
JSObject* mJSObj;
nsXPCWrappedNativeClass* mClass;
nsXPCWrappedNative* mRoot;
nsXPCWrappedNative* mNext;
};
/***************************************************************************/
// the include of declarations of the maps comes last because they have
// inlines which call methods on classes above.
#include "xpcmaps.h"
#endif /* xpcprivate_h___ */

View File

@ -0,0 +1,235 @@
/* -*- 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 each native interface instance. */
#include "xpcprivate.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
NS_IMPL_QUERY_INTERFACE(nsXPCWrappedNative, NS_IXPCONNECT_WRAPPED_NATIVE_IID)
// do chained ref counting
nsrefcnt
nsXPCWrappedNative::AddRef(void)
{
NS_PRECONDITION(mRoot, "bad root");
++mRefCnt;
if(1 == mRefCnt && mRoot && mRoot != this)
NS_ADDREF(mRoot);
else if(2 == mRefCnt)
JS_AddRoot(mClass->GetXPCContext()->GetJSContext(), &mJSObj);
return mRefCnt;
}
nsrefcnt
nsXPCWrappedNative::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;
}
if(1 == mRefCnt)
JS_RemoveRoot(mClass->GetXPCContext()->GetJSContext(), &mJSObj);
return mRefCnt;
}
void
nsXPCWrappedNative::JSObjectFinalized()
{
NS_PRECONDITION(1 == mRefCnt, "bad JSObject finalization");
Release();
}
// static
nsXPCWrappedNative*
nsXPCWrappedNative::GetNewOrUsedWrapper(XPCContext* xpcc,
nsISupports* aObj,
REFNSIID aIID)
{
Native2WrappedNativeMap* map;
nsISupports* rootObj = NULL;
nsXPCWrappedNative* root;
nsXPCWrappedNative* wrapper = NULL;
nsXPCWrappedNativeClass* clazz = NULL;
NS_PRECONDITION(xpcc, "bad param");
NS_PRECONDITION(aObj, "bad param");
map = xpcc->GetWrappedNativeMap();
if(!map)
{
NS_ASSERTION(map,"bad map");
return NULL;
}
// always find the native root
if(NS_FAILED(aObj->QueryInterface(kISupportsIID, (void**)&rootObj)))
return NULL;
// look for the root wrapper
root = map->Find(rootObj);
if(root)
{
wrapper = root->Find(aIID);
if(wrapper)
{
NS_ADDREF(wrapper);
goto return_wrapper;
}
}
clazz = nsXPCWrappedNativeClass::GetNewOrUsedClass(xpcc, aIID);
if(!clazz)
goto return_wrapper;
// build the root wrapper
if(!root)
{
if(rootObj == aObj)
{
// the root will do double duty as the interface wrapper
wrapper = root = new nsXPCWrappedNative(aObj, clazz, NULL);
if(!wrapper)
goto return_wrapper;
if(!wrapper->mJSObj)
{
NS_RELEASE(wrapper); // sets wrapper to NULL
goto return_wrapper;
}
map->Add(root);
goto return_wrapper;
}
else
{
// just a root wrapper
nsXPCWrappedNativeClass* rootClazz;
rootClazz = nsXPCWrappedNativeClass::GetNewOrUsedClass(xpcc, kISupportsIID);
if(!rootClazz)
goto return_wrapper;
root = new nsXPCWrappedNative(rootObj, rootClazz, NULL);
NS_RELEASE(rootClazz);
if(!root)
goto return_wrapper;
if(!root->mJSObj)
{
NS_RELEASE(root); // sets root to NULL
goto return_wrapper;
}
map->Add(root);
}
}
// at this point we have a root and 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->mNext = root->mNext;
root->mNext = wrapper;
return_wrapper:
if(rootObj)
NS_RELEASE(rootObj);
if(clazz)
NS_RELEASE(clazz);
return wrapper;
}
#ifdef WIN32
#pragma warning(disable : 4355) // OK to pass "this" in member initializer
#endif
nsXPCWrappedNative::nsXPCWrappedNative(nsISupports* aObj,
nsXPCWrappedNativeClass* aClass,
nsXPCWrappedNative* root)
: mObj(aObj),
mClass(aClass),
mJSObj(NULL),
mRoot(root ? root : this),
mNext(NULL)
{
NS_INIT_REFCNT();
NS_ADDREF_THIS();
NS_ADDREF(aClass);
NS_ADDREF(aObj);
mJSObj = aClass->NewInstanceJSObject(this);
if(mJSObj)
{
// intentional second addref to be released when mJSObj is gc'd
NS_ADDREF_THIS();
}
}
nsXPCWrappedNative::~nsXPCWrappedNative()
{
NS_PRECONDITION(0 == mRefCnt, "refcounting error");
NS_RELEASE(mClass);
NS_RELEASE(mObj);
if(mNext)
NS_DELETEXPCOM(mNext); // cascaded delete
}
nsXPCWrappedNative*
nsXPCWrappedNative::Find(REFNSIID aIID)
{
if(aIID.Equals(kISupportsIID))
return mRoot;
nsXPCWrappedNative* cur = mRoot;
do
{
if(aIID.Equals(cur->GetClass()->GetIID()))
return cur;
} while(NULL != (cur = cur->mNext));
return NULL;
}

View File

@ -0,0 +1,533 @@
/* -*- 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 shared by all native interface instances. */
#include "xpcprivate.h"
NS_IMPL_ISUPPORTS(nsXPCWrappedNativeClass, NS_IXPCONNECT_WRAPPED_NATIVE_CLASS_IID)
// static
nsXPCWrappedNativeClass*
nsXPCWrappedNativeClass::GetNewOrUsedClass(XPCContext* xpcc,
REFNSIID aIID)
{
IID2WrappedNativeClassMap* map;
nsXPCWrappedNativeClass* clazz;
NS_PRECONDITION(xpcc, "bad param");
map = xpcc->GetWrappedNativeClassMap();
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 nsXPCWrappedNativeClass(xpcc, aIID, info);
// XXX check for full init
// if failed: NS_RELEASE(map) and set map = NULL
}
}
return clazz;
}
nsXPCWrappedNativeClass::nsXPCWrappedNativeClass(XPCContext* xpcc, REFNSIID aIID,
nsIInterfaceInfo* aInfo)
: mXPCContext(xpcc),
mIID(aIID),
mInfo(aInfo)
{
NS_ADDREF(mInfo);
NS_INIT_REFCNT();
NS_ADDREF_THIS();
mXPCContext->GetWrappedNativeClassMap()->Add(this);
// XXX Do other stuff...
}
nsXPCWrappedNativeClass::~nsXPCWrappedNativeClass()
{
mXPCContext->GetWrappedNativeClassMap()->Remove(this);
// XXX Cleanup other stuff...
// XXX e.g. mMembers
// XXX e.g. functon object of mbers
NS_RELEASE(mInfo);
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if (!wrapper) {
if (type == JSTYPE_OBJECT) {
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
}
JS_ReportError(cx, "illegal operation on WrappedNative prototype object");
return JS_FALSE;
}
switch (type) {
case JSTYPE_OBJECT:
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
case JSTYPE_FUNCTION:
JS_ReportError(cx, "can't convert WrappedNative to function");
return JS_FALSE;
case JSTYPE_VOID:
case JSTYPE_STRING:
// XXX get the interface name from the InterfaceInfo
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "WrappedNative"));
return JS_TRUE;
case JSTYPE_NUMBER:
*vp = JSVAL_ONE;
return JS_TRUE;
case JSTYPE_BOOLEAN:
*vp = JSVAL_TRUE;
return JS_TRUE;
default:
NS_ASSERTION(0,"bad type in conversion");
return JS_FALSE;
}
}
const XPCNativeMemberDescriptor*
nsXPCWrappedNativeClass::LookupMemberByID(jsid id) const
{
for(int i = GetMemberCount()-1; i >= 0; i--)
{
const XPCNativeMemberDescriptor* desc = GetMemberDescriptor(i);
NS_ASSERTION(desc,"member without descriptor");
if(desc->id == id)
return desc;
}
return NULL;
}
const char*
nsXPCWrappedNativeClass::GetMethodName(int MethodIndex) const
{
const nsXPCMethodInfo* info;
if(NS_SUCCEEDED(mInfo->GetMethodInfo(MethodIndex, &info)))
return info->GetName();
return NULL;
}
JSBool
nsXPCWrappedNativeClass::GetConstantAsJSVal(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
jsval* vp)
{
// XXX implement
return JS_FALSE;
}
JSBool
nsXPCWrappedNativeClass::GetAttributeAsJSVal(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
jsval* vp)
{
return CallWrappedMethod(wrapper, desc, JS_FALSE, 0, NULL, vp);
}
JSBool
nsXPCWrappedNativeClass::SetAttributeFromJSVal(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
jsval* vp)
{
return CallWrappedMethod(wrapper, desc, JS_TRUE, 1, vp, NULL);
}
JSBool
nsXPCWrappedNativeClass::CallWrappedMethod(nsXPCWrappedNative* wrapper,
const XPCNativeMemberDescriptor* desc,
JSBool isAttributeSet,
uintN argc, jsval *argv, jsval *vp)
{
// XXX implement
return JS_FALSE;
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_CallMethod(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp)
{
JSFunction *fun;
jsint id;
jsval idval;
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if(!wrapper)
return JS_FALSE;
nsXPCWrappedNativeClass* clazz = wrapper->GetClass();
NS_ASSERTION(clazz,"wrapper without class");
NS_ASSERTION(JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION, "bad function");
fun = (JSFunction*) JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[-2]));
idval = STRING_TO_JSVAL(JS_InternString(cx, JS_GetFunctionName(fun)));
JS_ValueToId(cx, idval, &id);
const XPCNativeMemberDescriptor* desc = clazz->LookupMemberByID(id);
if(!desc || desc->category != XPCNativeMemberDescriptor::METHOD)
return JS_FALSE;
return clazz->CallWrappedMethod(wrapper, desc, JS_FALSE, argc, argv, vp);
}
JSObject*
nsXPCWrappedNativeClass::GetInvokeFunObj(const XPCNativeMemberDescriptor* desc)
{
if(!desc->invokeFuncObj)
{
const char* name = GetMethodName(desc->index);
NS_ASSERTION(name,"bad method name");
JSContext* cx = GetJSContext();
JSFunction *fun = JS_NewFunction(cx, WrappedNative_CallMethod, 0,
JSFUN_BOUND_METHOD, NULL, name);
if(!fun)
return NULL;
XPCNativeMemberDescriptor* descRW =
NS_CONST_CAST(XPCNativeMemberDescriptor*,descRW);
descRW->invokeFuncObj = JS_GetFunctionObject(fun);
// XXX verify released in dtor
JS_AddRoot(cx, &descRW->invokeFuncObj);
}
return desc->invokeFuncObj;
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if(!wrapper)
return JS_FALSE;
nsXPCWrappedNativeClass* clazz = wrapper->GetClass();
NS_ASSERTION(clazz,"wrapper without class");
const XPCNativeMemberDescriptor* desc = clazz->LookupMemberByID(id);
if(!desc)
return JS_FALSE;
switch(desc->category)
{
case XPCNativeMemberDescriptor::CONSTANT:
return clazz->GetConstantAsJSVal(wrapper, desc, vp);
case XPCNativeMemberDescriptor::METHOD:
{
// allow for lazy creation of 'prototypical' function invoke object
JSObject* invokeFunObj = clazz->GetInvokeFunObj(desc);
if(!invokeFunObj)
return JS_FALSE;
// Create a function object with this wrapper as its parent, so that
// JSFUN_BOUND_METHOD binds it as the default 'this' for the function.
JSObject *funobj = JS_CloneFunctionObject(cx, invokeFunObj, obj);
if (!funobj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(funobj);
return JS_TRUE;
}
case XPCNativeMemberDescriptor::ATTRIB_RO:
case XPCNativeMemberDescriptor::ATTRIB_RW:
return clazz->GetAttributeAsJSVal(wrapper, desc, vp);
default:
NS_ASSERTION(0,"bad category");
return JS_FALSE;
}
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if(!wrapper)
return JS_FALSE;
nsXPCWrappedNativeClass* clazz = wrapper->GetClass();
NS_ASSERTION(clazz,"wrapper without class");
const XPCNativeMemberDescriptor* desc = clazz->LookupMemberByID(id);
if(!desc)
return JS_FALSE;
switch(desc->category)
{
case XPCNativeMemberDescriptor::CONSTANT:
case XPCNativeMemberDescriptor::METHOD:
case XPCNativeMemberDescriptor::ATTRIB_RO:
// fail silently
return JS_TRUE;
case XPCNativeMemberDescriptor::ATTRIB_RW:
return clazz->SetAttributeFromJSVal(wrapper, desc, vp);
default:
NS_ASSERTION(0,"bad category");
return JS_FALSE;
}
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
)
{
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if(wrapper)
{
nsXPCWrappedNativeClass* clazz = wrapper->GetClass();
NS_ASSERTION(clazz,"wrapper without class");
if(clazz->LookupMemberByID(id))
{
*objp = obj;
*propp = (JSProperty*)1;
return JS_TRUE;
}
}
*objp = NULL;
*propp = NULL;
return JS_TRUE;
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp)
{
// XXX dynamic properties not supported
JS_ReportError(cx, "Cannot define a new property in a WrappedNative");
return JS_FALSE;
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_getAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
// XXX dynamic properties not supported
/* We don't maintain JS property attributes for Java class members */
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
return JS_FALSE;
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_setAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
// XXX dynamic properties not supported
/* Silently ignore all setAttribute attempts */
return JS_TRUE;
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
// XXX dynamic properties not supported
/* Silently ignore */
return JS_TRUE;
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
return WrappedNative_convert(cx, obj, type, vp);
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if (!wrapper) {
*statep = JSVAL_NULL;
if (idp)
*idp = INT_TO_JSVAL(0);
return JS_TRUE;
}
nsXPCWrappedNativeClass* clazz = wrapper->GetClass();
NS_ASSERTION(clazz,"wrapper without class");
switch(enum_op) {
case JSENUMERATE_INIT:
*statep = INT_TO_JSVAL(0);
if (idp)
*idp = INT_TO_JSVAL(clazz->GetMemberCount());
return JS_TRUE;
case JSENUMERATE_NEXT:
{
int index = JSVAL_TO_INT(*statep);
int count = clazz->GetMemberCount();
if (index < count) {
*idp = INT_TO_JSVAL(clazz->GetMemberDescriptor(index++)->id);
*statep = INT_TO_JSVAL(index < count ? index : 0);
return JS_TRUE;
}
}
/* Fall through ... */
case JSENUMERATE_DESTROY:
*statep = JSVAL_NULL;
return JS_TRUE;
default:
NS_ASSERTION(0,"bad enum_op");
return JS_FALSE;
}
}
JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
switch (mode) {
case JSACC_WATCH:
JS_ReportError(cx, "Cannot place watchpoints on WrappedNative object properties");
return JS_FALSE;
case JSACC_IMPORT:
JS_ReportError(cx, "Cannot export a WrappedNative object's properties");
return JS_FALSE;
default:
return JS_TRUE;
}
}
JS_STATIC_DLL_CALLBACK(void)
WrappedNative_finalize(JSContext *cx, JSObject *obj)
{
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx,obj);
if(!wrapper)
return;
NS_ASSERTION(obj == wrapper->GetJSObject(),"bad obj");
NS_ASSERTION(cx == wrapper->GetClass()->GetXPCContext()->GetJSContext(),"bad obj");
wrapper->JSObjectFinalized();
}
JSObjectOps WrappedNative_ops = {
/* Mandatory non-null function pointer members. */
NULL, /* newObjectMap */
NULL, /* destroyObjectMap */
WrappedNative_lookupProperty,
WrappedNative_defineProperty,
WrappedNative_getPropertyById, /* getProperty */
WrappedNative_setPropertyById, /* setProperty */
WrappedNative_getAttributes,
WrappedNative_setAttributes,
WrappedNative_deleteProperty,
WrappedNative_defaultValue,
WrappedNative_newEnumerate,
WrappedNative_checkAccess,
/* Optionally non-null members start here. */
NULL, /* thisObject */
NULL, /* dropProperty */
NULL, /* call */
NULL, /* construct */
NULL, /* xdrObject */
NULL, /* hasInstance */
};
static JSObjectOps *
WrappedNative_getObjectOps(JSContext *cx, JSClass *clazz)
{
return &WrappedNative_ops;
}
JSClass WrappedNative_class = {
"XPCWrappedNative", JSCLASS_HAS_PRIVATE,
NULL, NULL, NULL, NULL,
NULL, NULL, WrappedNative_convert, WrappedNative_finalize,
WrappedNative_getObjectOps,
};
extern "C" JS_IMPORT_DATA(JSObjectOps) js_ObjectOps;
// static
JSBool
nsXPCWrappedNativeClass::InitForContext(XPCContext* xpcc)
{
WrappedNative_ops.newObjectMap = js_ObjectOps.newObjectMap;
WrappedNative_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
// XXX do we really want this class init'd this way? access to ctor?
if (!JS_InitClass(xpcc->GetJSContext(), xpcc->GetGlobalObject(),
0, &WrappedNative_class, 0, 0,
0, 0,
0, 0))
return JS_FALSE;
return JS_TRUE;
}
JSObject*
nsXPCWrappedNativeClass::NewInstanceJSObject(nsXPCWrappedNative* self)
{
JSContext* cx = GetXPCContext()->GetJSContext();
JSObject* jsobj = JS_NewObject(cx, &WrappedNative_class, NULL, NULL);
if(!jsobj || !JS_SetPrivate(cx, jsobj, self))
return NULL;
return jsobj;
}