зеркало из https://github.com/mozilla/pjs.git
OJI MozClassic to raptor merge
This commit is contained in:
Родитель
932229f590
Коммит
6624efe2b9
|
@ -586,10 +586,18 @@ nsCCapsManager::IsAllowed(void *annotation, char* targetName, PRBool *ret_val)
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCCapsManager:
|
||||
|
||||
nsCCapsManager::nsCCapsManager(nsISupports *aOuter)
|
||||
nsCCapsManager::nsCCapsManager(nsISupports *aOuter):m_pNSPrivilegeManager(NULL)
|
||||
{
|
||||
NS_INIT_AGGREGATED(aOuter);
|
||||
m_pNSPrivilegeManager = new nsPrivilegeManager();
|
||||
PRBool result;
|
||||
if (Initialize(&result) == NS_OK)
|
||||
{
|
||||
m_pNSPrivilegeManager = new nsPrivilegeManager();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pNSPrivilegeManager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nsCCapsManager::~nsCCapsManager()
|
||||
|
|
|
@ -27,9 +27,43 @@
|
|||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
static NS_DEFINE_IID(kCCapsManagerCID, NS_CCAPSMANAGER_CID);
|
||||
|
||||
nsIFactory *nsCCapsManagerFactory::m_pNSIFactory = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* NSGetFactory:
|
||||
* Provides entry point to liveconnect dll.
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
{
|
||||
|
||||
if (!aClass.Equals(kCCapsManagerCID)) {
|
||||
return NS_ERROR_FACTORY_NOT_LOADED; // XXX right error?
|
||||
}
|
||||
nsCCapsManagerFactory* pCCapsManagerFactory = new nsCCapsManagerFactory();
|
||||
if (pCCapsManagerFactory == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
pCCapsManagerFactory->AddRef();
|
||||
*aFactory = pCCapsManagerFactory;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT PRBool
|
||||
NSCanUnload(void)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISupports
|
||||
|
||||
|
|
|
@ -84,11 +84,13 @@ nsCapsInitialize()
|
|||
// as the factory object in the repository. All other modules should
|
||||
// FindFactory and use createInstance to create a instance of nsCCapsManager
|
||||
// and ask for nsICapsManager interface.
|
||||
/*
|
||||
nsCCapsManagerFactory *pNSCCapsManagerFactory = new nsCCapsManagerFactory();
|
||||
if ( pNSCCapsManagerFactory == NULL )
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
*/
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -666,9 +666,9 @@ nsresult nsDOMFactory::LockFactory(PRBool aLock)
|
|||
|
||||
// return the proper factory to the caller
|
||||
#if defined(XP_MAC) && defined(MAC_STATIC)
|
||||
extern "C" NS_DOM nsresult NSGetFactory_DOM_DLL(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_DOM nsresult NSGetFactory_DOM_DLL(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#else
|
||||
extern "C" NS_DOM nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_DOM nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory )
|
||||
#endif
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
|
|
|
@ -163,7 +163,7 @@ nsresult nsGfxFactoryGTK::LockFactory(PRBool aLock)
|
|||
}
|
||||
|
||||
// return the proper factory to the caller
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -175,9 +175,9 @@ nsresult nsGfxFactoryMac::LockFactory(PRBool aLock)
|
|||
|
||||
// return the proper factory to the caller
|
||||
#if defined(XP_MAC) && defined(MAC_STATIC)
|
||||
extern "C" NS_GFX nsresult NSGetFactory_GFXWIN_DLL(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_GFX nsresult NSGetFactory_GFXWIN_DLL(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#else
|
||||
extern "C" NS_GFX nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_GFX nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#endif
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
|
|
|
@ -161,7 +161,7 @@ nsresult nsGfxFactoryMotif::LockFactory(PRBool aLock)
|
|||
}
|
||||
|
||||
// return the proper factory to the caller
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -191,7 +191,7 @@ nsresult nsGfxFactoryWin::LockFactory(PRBool aLock)
|
|||
}
|
||||
|
||||
// return the proper factory to the caller
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_GFXNONXP nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -167,9 +167,9 @@ nsresult nsParserFactory::LockFactory(PRBool aLock)
|
|||
|
||||
// return the proper factory to the caller
|
||||
#if defined(XP_MAC) && defined(MAC_STATIC)
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory_PARSER_DLL(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory_PARSER_DLL(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#else
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#endif
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
|
|
|
@ -37,7 +37,7 @@ extern "C" NS_EXPORT PRBool NSCanUnload()
|
|||
return PRBool(g_InstanceCount == 0 && g_LockCount == 0);
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID,
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID, nsISupports* serviceMgr,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
if (aFactory == NULL) return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -38,7 +38,7 @@ extern "C" NS_EXPORT PRBool NSCanUnload()
|
|||
return PRBool(g_InstanceCount == 0 && g_LockCount == 0);
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID,
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID, nsISupports* serviceMgr,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
if (aFactory == NULL) return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -38,7 +38,7 @@ extern "C" NS_EXPORT PRBool NSCanUnload()
|
|||
return PRBool(g_InstanceCount == 0 && g_LockCount == 0);
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID,
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID, nsISupports* serviceMgr,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
if (aFactory == NULL) return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -47,7 +47,7 @@ extern "C" NS_EXPORT PRBool NSCanUnload()
|
|||
return PRBool(g_InstanceCount == 0 && g_LockCount == 0);
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID,
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID, nsISupports* serviceMgr,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
if (aFactory == NULL) return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
# Microsoft Developer Studio Project File - Name="LiveConnect" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 5.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=LiveConnect - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "LiveConnect.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "LiveConnect.mak" CFG="LiveConnect - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "LiveConnect - Win32 Release" (based on\
|
||||
"Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "LiveConnect - Win32 Debug" (based on\
|
||||
"Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "LiveConnect - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I ".." /I "$(JDK)\include" /I "$(JDK)\include\win32" /D "NDEBUG" /D "XP_PC" /D "JSFILE" /D "WIN32" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\Release\js32.lib $(JDK)\lib\javai.lib /nologo /subsystem:windows /dll /debug /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "LiveConnect - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I ".." /I "$(JDK)\include" /I "$(JDK)\include\win32" /D "_DEBUG" /D "_CONSOLE" /D "DEBUG" /D "XP_PC" /D "JSFILE" /D "WIN32" /D "_WINDOWS" /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\Debug\js32.lib $(JDK)\lib\javai_g.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Debug/LiveConnect_g.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "LiveConnect - Win32 Release"
|
||||
# Name "LiveConnect - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\liveconnect\jsj.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\liveconnect\jsj_array.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\liveconnect\jsj_class.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\liveconnect\jsj_convert.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\liveconnect\jsj_field.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jsj_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jsj_JavaArray.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jsj_JavaClass.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jsj_JavaMember.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jsj_JavaObject.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jsj_JavaPackage.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jsj_JSObject.c
|
||||
|
||||
!IF "$(CFG)" == "LiveConnect - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "LiveConnect - Win32 Debug"
|
||||
|
||||
# ADD CPP /I ".\_jni"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\liveconnect\jsj_method.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\liveconnect\jsj_utils.c
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
|
@ -0,0 +1,106 @@
|
|||
# Microsoft Developer Studio Project File - Name="LiveConnectShell" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 5.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=LiveConnectShell - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "LiveConnectShell.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "LiveConnectShell.mak" CFG="LiveConnectShell - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "LiveConnectShell - Win32 Release" (based on\
|
||||
"Win32 (x86) Console Application")
|
||||
!MESSAGE "LiveConnectShell - Win32 Debug" (based on\
|
||||
"Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "LiveConnectShell - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "LiveConnectShell_"
|
||||
# PROP BASE Intermediate_Dir "LiveConnectShell_"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "$(JDK)\include" /I "$(JDK)\include\win32" /I "." /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "XP_PC" /D "_WINDOWS" /D "JSFILE" /D "LIVECONNECT" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/lcshell.exe"
|
||||
# Begin Special Build Tool
|
||||
SOURCE=$(InputPath)
|
||||
PostBuild_Desc=Copy DLL(s) to build directory
|
||||
PostBuild_Cmds=COPY ..\Release\js32.dll .\Release
|
||||
# End Special Build Tool
|
||||
|
||||
!ELSEIF "$(CFG)" == "LiveConnectShell - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "LiveConnectShell0"
|
||||
# PROP BASE Intermediate_Dir "LiveConnectShell0"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "$(JDK)\include" /I "$(JDK)\include\win32" /I "." /D "LIVECONNECT" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "DEBUG" /D "XP_PC" /D "_WINDOWS" /D "JSFILE" /FR /YX /FD /c
|
||||
# SUBTRACT CPP /u
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/lcshell.exe" /pdbtype:sept
|
||||
# Begin Special Build Tool
|
||||
SOURCE=$(InputPath)
|
||||
PostBuild_Desc=Copy DLL(s) to build directory
|
||||
PostBuild_Cmds=COPY ..\Debug\js32.dll .\Debug
|
||||
# End Special Build Tool
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "LiveConnectShell - Win32 Release"
|
||||
# Name "LiveConnectShell - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\js.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Debug\js32.lib
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
|
@ -0,0 +1,44 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 5.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "LiveConnect"=.\LiveConnect.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "LiveConnectShell"=.\LiveConnectShell.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name LiveConnect
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
#
|
||||
# JSRef GNUmake makefile.
|
||||
#
|
||||
|
||||
DEPTH = ..
|
||||
|
||||
#
|
||||
# XCFLAGS may be set in the environment or on the gmake command line
|
||||
#
|
||||
CFLAGS += $(OPTIMIZER) $(OS_CFLAGS) $(DEFINES) $(INCLUDES) \
|
||||
-DJSFILE $(XCFLAGS)
|
||||
LDFLAGS += -lm $(XLDFLAGS)
|
||||
|
||||
# For purify
|
||||
PURE_CFLAGS = -DXP_UNIX $(OPTIMIZER) $(PURE_OS_CFLAGS) $(DEFINES) \
|
||||
$(INCLUDES) $(XCFLAGS)
|
||||
|
||||
#
|
||||
# LC file lists
|
||||
#
|
||||
LC_HFILES = \
|
||||
jsj_hash.h \
|
||||
jsj_private.h \
|
||||
jsjava.h \
|
||||
netscape_javascript_JSObject.h \
|
||||
$(NULL)
|
||||
|
||||
HFILES = $(LC_HFILES)
|
||||
|
||||
LC_CFILES = \
|
||||
jsj.c \
|
||||
jsj_JSObject.c \
|
||||
jsj_JavaArray.c \
|
||||
jsj_JavaClass.c \
|
||||
jsj_JavaMember.c \
|
||||
jsj_JavaObject.c \
|
||||
jsj_JavaPackage.c \
|
||||
jsj_array.c \
|
||||
jsj_class.c \
|
||||
jsj_convert.c \
|
||||
jsj_field.c \
|
||||
jsj_hash.c \
|
||||
jsj_method.c \
|
||||
jsj_utils.c \
|
||||
$(NULL)
|
||||
|
||||
LIB_CFILES = $(LC_CFILES)
|
||||
|
||||
PROG_FILE = js
|
||||
|
||||
include $(DEPTH)/config.mk
|
||||
include config/$(OS_CONFIG).mk
|
||||
|
||||
INCLUDES += -I. -I.. -I../$(OBJDIR)
|
||||
|
||||
ifdef USE_MSVC
|
||||
OTHER_LIBS += $(DEPTH)/fdlibm/$(OBJDIR)/fdlibm.lib
|
||||
else
|
||||
OTHER_LIBS += -L$(DEPTH)/fdlibm/$(OBJDIR) -lfdm
|
||||
endif
|
||||
|
||||
ifdef JS_THREADSAFE
|
||||
ifdef USE_MSVC
|
||||
OTHER_LIBS += $(DEPTH)/../../dist/$(OBJDIR)/lib/libnspr21.lib
|
||||
else
|
||||
OTHER_LIBS += -L$(DEPTH)/../../dist/$(OBJDIR)/lib -lnspr21
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_MSVC
|
||||
LIBRARY = $(OBJDIR)/jsj.lib
|
||||
SHARED_LIBRARY = $(OBJDIR)/jsj.dll
|
||||
PROGRAM = $(OBJDIR)/jsj.exe
|
||||
else
|
||||
LIBRARY = $(OBJDIR)/jsj.a
|
||||
SHARED_LIBRARY = $(OBJDIR)/jsj.so
|
||||
PROGRAM = $(OBJDIR)/jsj
|
||||
endif
|
||||
|
||||
include $(DEPTH)/rules.mk
|
||||
|
||||
ifdef USE_MSVC
|
||||
$(OBJDIR)/$(PROG_FILE)_lc.obj: ../$(PROG_FILE).c
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -Fo$@ -c $(CFLAGS) -DLIVECONNECT ../$(PROG_FILE).c
|
||||
|
||||
$(PROGRAM): $(OBJDIR)/$(PROG_FILE)_lc.obj $(LIBRARY)
|
||||
link.exe -out:"$@" /pdb:"$(OBJDIR)/$(@F:.exe=.pdb)" $(EXE_LINK_FLAGS) ../$(OBJDIR)/js32.lib $?
|
||||
else
|
||||
$(OBJDIR)/$(PROG_FILE).o: ../$(PROG_FILE).c
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ -c $(CFLAGS) -DLIVECONNECT ../$(PROG_FILE).c
|
||||
|
||||
$(PROGRAM): $(OBJDIR)/$(PROG_FILE).o
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ $(CFLAGS) $+ $(LIBRARY) ../$(OBJDIR)/libjs.a $(LDFLAGS) $(OTHER_LIBS)
|
||||
endif
|
|
@ -0,0 +1,684 @@
|
|||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Scott Furman">
|
||||
<meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
|
||||
<title>README for LiveConnect</title>
|
||||
</head>
|
||||
<body>
|
||||
This is the README file for the JavaScript LiveConnect
|
||||
Version 3 ("LC3") implementation.
|
||||
<h2>
|
||||
Table of Contents</h2>
|
||||
|
||||
<blockquote><a href="#Introduction">Introduction</a>
|
||||
<br><a href="#New_Features">New features</a>
|
||||
<br><a href="#Compatibility">Compatibility</a>
|
||||
<br><a href="#Limitations">Limitations/Bugs/To-Do</a>
|
||||
<br><a href="#Build_conventions">Build conventions</a>
|
||||
<br><a href="#coding_conventions">Naming and coding conventions</a>
|
||||
<br><a href="#API">The LiveConnect API</a>
|
||||
<br><a href="#sample_shell_interaction">Sample LiveConnect shell interactions</a></blockquote>
|
||||
|
||||
<h2>
|
||||
<a NAME="Introduction"></a>Introduction</h2>
|
||||
LiveConnect allows JavaScript and Java virtual machines to interoperate.
|
||||
Specifically, it enables JavaScript to access Java fields, invoke Java
|
||||
methods and makes it possible for Java to access JavaScript object properties
|
||||
and evaluate arbitrary JavaScript. More information on LiveConnect
|
||||
can be found by <a href="http://developer.netscape.com/find/find.cgi?scope=LiveConnect&browse-category=&ui=sr&chunk-size=&page=1&taxonomy=DevEdge+Online">searching
|
||||
the index on Netscape's DevEdge site</a>. This README assumes basic
|
||||
familiarity with <a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/js/src/README.html">JSRef</a>,
|
||||
the reference implementation of JavaScript, and with the LiveConnect technology.
|
||||
<p>JSRef project/makefiles build a library or DLL containing the JavaScript
|
||||
runtime (compiler, interpreter, decompiler, garbage collector, atom manager,
|
||||
standard classes). The LiveConnect project/makefiles build a library
|
||||
that links both with JSRef and with any Java Virtual Machine (JVM) that
|
||||
implements the Java Native Interface (JNI), as specified by JavaSoft.
|
||||
It then compiles a small "shell" example program and links that with the
|
||||
library to make an interpreter that can be used interactively and with
|
||||
test scripts. See the <a href="#sample_shell_interaction">sample
|
||||
shell interactions</a>.
|
||||
<p><i>Scott Furman, 10/31/98</i>
|
||||
<h2>
|
||||
<a NAME="New_Features"></a>New features</h2>
|
||||
The following features were not available in the versions of LiveConnect
|
||||
that were integrated with Netscape Navigator versions 4.x and earlier.
|
||||
For information on LiveConnect version 1, which was used in Navigator 3
|
||||
and 4 and Enterprise Server 3, see <a href="http://developer.netscape.com/find/find.cgi?scope=LiveConnect&browse-category=&ui=sr&chunk-size=&page=1&taxonomy=DevEdge+Online">Netscape's
|
||||
DevEdge site</a> or any number of 3rd-party publications.)
|
||||
<h4>
|
||||
LiveConnect version 3 (10/31/98)</h4>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
In previous versions of LiveConnect, when more than one overloaded Java
|
||||
method was compatible with the types of arguments in an invocation from
|
||||
JS, the choice of Java method was made arbitrarily, by using the first
|
||||
one enumerated by the Java reflection APIs. Unfortunately, the ordering
|
||||
of methods when enumerating is not governed by any specification, so differences
|
||||
between JVM vendors could lead to inconsistencies in LiveConnect behavior.
|
||||
Now, a <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">JVM-independent
|
||||
set of rules</a> is used to choose among a set of overloaded methods.
|
||||
Informally, the method with Java parameter types that most closely
|
||||
match the JavaScript types is chosen.</li>
|
||||
|
||||
<li>
|
||||
The weak correspondence between the JS language typing system and Java's
|
||||
may result in ambiguity and/or shadowing when resolving among overloaded
|
||||
Java methods, even when using LC3's improved method overload resolution
|
||||
algorithm. For example, JS's number type can map to any of Java's
|
||||
floating-point or integral types: byte, char, short, int, long, float,
|
||||
double.
|
||||
If necessary, it is possible to bypass the method overload resolution process
|
||||
and explicitly specify the method to be invoked:</li>
|
||||
|
||||
<br>
|
||||
<ul><tt>myPrintMethod = java.io.PrintStream["print(double)"];</tt>
|
||||
<br><tt>myPrintMethod(13);</tt></ul>
|
||||
<br>
|
||||
<li>
|
||||
Static methods can now be invoked using either the class name or a reference
|
||||
to an instance of the class. (Older versions of LiveConnect allow
|
||||
only the former.)</li>
|
||||
|
||||
<li>
|
||||
It is no longer necessary to convert Java Strings to JS strings before
|
||||
using them as the receivers of JS string methods, which is typically done
|
||||
by appending an empty string to the Java string, e.g.</li>
|
||||
|
||||
<p><br><tt> s = new java.lang.String("foo")</tt>
|
||||
<br><tt> s = s + "";
|
||||
|
||||
</tt>// s is now a JS string
|
||||
<br><tt> m = s.match(/o?/)</tt>
|
||||
<p>The explicit conversion to a JS string is no longer required because
|
||||
<i>java.lang.String</i>
|
||||
objects are treated as a special case that "inherit" all the methods of
|
||||
JS strings, i.e. so that the second statement in the example above is now
|
||||
superfluous.
|
||||
<li>
|
||||
Similarly, JavaArray objects "inherit" the methods of JS's <tt>Array.prototype</tt>,
|
||||
so it is possible to appy many of the JS array utility methods such as
|
||||
<tt>reverse()</tt>
|
||||
and <tt>join()</tt> to JavaArray objects.</li>
|
||||
|
||||
<li>
|
||||
There is now support for the <tt>instanceof</tt> and <tt>in</tt> operators.
|
||||
These operators are currently proposed for inclusion in the ECMA-2 standard.</li>
|
||||
|
||||
<li>
|
||||
LiveConnect has been extended to take advantage of JavaScript exceptions,
|
||||
a language feature that debuted in JavaScript 1.4. Now, when JavaScript
|
||||
calls into Java, any Java exceptions are converted to JS exceptions which
|
||||
can be caught using JS try-catch statements. Similarly, JS exceptions
|
||||
are propagated to Java wrapped in an instance of <i>netscape.javascript.JSException</i>.</li>
|
||||
</ul>
|
||||
|
||||
<h4>
|
||||
LiveConnect version 2 (7/31/98)</h4>
|
||||
|
||||
<blockquote>
|
||||
<li>
|
||||
The Java methods of <i>java.lang.Object</i> are now invokeable methods
|
||||
of <tt><font size=+1>JavaArray</font></tt> objects, matching the behavior
|
||||
of arrays when accessed from Java<i>.</i> (Java arrays are a subclass
|
||||
of <i>java.lang.Object</i>.) For example, Java's <tt><font size=+1>getClass()</font></tt>
|
||||
and <tt><font size=+1>hashCode()</font></tt> methods can now be called
|
||||
on <tt><font size=+1>JavaArray</font></tt> objects. (In prior versions
|
||||
of LiveConnect, the methods of <i>java.lang.Object</i> were only inherited
|
||||
by non-array Java objects.)</li>
|
||||
|
||||
<p>Note that this change has caused the string representation of JavaArray
|
||||
objects to change. Previously, the JavaArray toString() method always
|
||||
printed "<tt><font size=+1>[object JavaArray]"</font></tt> for all <tt><font size=+1>JavaArray</font></tt>'s.
|
||||
Now, the Java <tt><font size=+1>java.lang.Object.toString()</font></tt>
|
||||
method is called to convert JavaArray objects to strings, just as with
|
||||
other, non-array Java objects that are accessible via LiveConnect. <tt><font size=+1>java.lang.Object.toString()</font></tt>is
|
||||
defined in the <i>Java Language Specification</i> to return the value of
|
||||
the following expression:
|
||||
<p><tt><font size=-1>getClass().getName() + '@' + Integer.toHexString(hashCode())</font></tt>
|
||||
<br>
|
||||
<li>
|
||||
A one-character string is now an acceptable match for an argument to a
|
||||
Java method of type <tt><font size=+1>char</font></tt>. (In earlier
|
||||
versions of LiveConnect, the only acceptable match for a <tt><font size=+1>char</font></tt>
|
||||
had to be a JavaScript value that was convertible to a number.) For
|
||||
example, the following is now possible:</li>
|
||||
|
||||
<p><tt><font size=-1>c = new java.lang.Character("F")</font></tt>
|
||||
<br>
|
||||
<li>
|
||||
A JavaClass object is now an acceptable match for an argument to a Java
|
||||
method of type <i>java.lang.Class</i>. For example, you can now write:</li>
|
||||
|
||||
<p><tt><font size=-1>java.lang.reflect.Array.newInstance(java.lang.String,
|
||||
3)</font></tt>
|
||||
<p>instead of the more verbose:
|
||||
<p><tt><font size=-1>jls = java.lang.Class.forName("java.lang.String")</font></tt>
|
||||
<br><tt><font size=-1>java.lang.reflect.Array.newInstance(jls, 3)</font></tt>
|
||||
<br> </blockquote>
|
||||
|
||||
<h2>
|
||||
<a NAME="Compatibility"></a>Compatibility</h2>
|
||||
Unlike this standalone/component release, all previous versions of LiveConnect
|
||||
appeared only as an integrated feature of Netscape Navigator. The
|
||||
variants of LiveConnect that appeared in Navigator versions 3.x and 4.x
|
||||
all behave much the same, modulo bugs. For brevity we refer to this
|
||||
classic version of LiveConnect as "LC1" (LiveConnect version 1) and this
|
||||
most recent release as "LC3". (There was an intermediate LiveConnect
|
||||
release known as "LC2" in 7/98, but it was not used in any products.
|
||||
"LC3" provides a superset of LC2 features.)
|
||||
<ul>
|
||||
<li>
|
||||
As in LC1, JavaScript objects appear to Java as instances of <i>netscape.javascript.JSObject</i>.
|
||||
In LC1, two <i>JSObject</i>'s could be tested for equality, i.e. to see
|
||||
if they refer to the same instance, by using the `==' operator. Instead,
|
||||
developers must now use the <tt>equals()</tt>method of <i>netscape.javascript.JSObject</i>
|
||||
for comparison, a method that overrides <tt>java.lang.Object.equals()</tt>.
|
||||
Using <tt>equals()</tt> instead of `==' should work the same in all versions
|
||||
of LiveConnect.</li>
|
||||
|
||||
<p>It is not possible to replicate the identity behavior of the `==' operator
|
||||
that LC1 provides without the use of "weak" references, i.e. references
|
||||
that do not contribute to making a Java object reachable for purposes of
|
||||
garbage collection, but which nonetheless allow reference to an object
|
||||
as long as it is reachable by other means. The use of weak references
|
||||
is not portable, however. It is not part of the JNI or the JDK and
|
||||
it is not provided on all JVMs. The JDK1.2 release will include standard
|
||||
support for weak references.
|
||||
<br>
|
||||
<li>
|
||||
It's possible that, in a set of overloaded Java methods, more than one
|
||||
method is compatible with the types of the actual arguments in a call from
|
||||
JavaScript via LiveConnect. LC1 and LC2 resolved these ambiguities
|
||||
in a simplistic manner, by simply invoking whatever method was enumerated
|
||||
first by the JVM. The enumeration order of reflected methods using
|
||||
<i>java.lang.reflect</i>
|
||||
is not specified by Sun and may differ among vendor's JVMs, i.e. enumeration
|
||||
could be in order of classfile appearance, hashtable order, etc.
|
||||
Hence, the Java method chosen when there is more than one compatible method
|
||||
may vary depending on the JVM. With the Netscape and Sun JVMs, it
|
||||
is possible to change the behavior of an LC1/LC2 program by changing the
|
||||
order that Java methods appear in a source file, thus changing the method
|
||||
enumeration order.</li>
|
||||
|
||||
<p>In LC3, a new method overload resolution algorithm is used. Informally,
|
||||
the method with Java parameter types that most closely match the
|
||||
JavaScript types is chosen. You can read all the gorey details in
|
||||
the <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">spec</a>.
|
||||
<br>
|
||||
<li>
|
||||
There are several minor changes in error handling to make LiveConnect more
|
||||
conformant to ECMAScript. These include, for example, making any
|
||||
attempt to delete JavaObject, JavaClass or JavaPackage properties fail
|
||||
silently, rather than causing an error. Also, some error messages
|
||||
have been changed to be more informative. These changes should generally
|
||||
be backward-compatible with LC1 because few programs that use LiveConnect
|
||||
will depend on the exact behavior of LiveConnect when handling errors.</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="Limitations"></a>Limitations/Bugs/To-Do</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
There is no way to explicitly resolve overloaded constructors, i.e. in
|
||||
the same way that can be done with instance and static methods.</li>
|
||||
|
||||
<li>
|
||||
The efficiency of calling Java methods leaves something to be desired,
|
||||
due to the convoluted nature of implementing native methods for JS.
|
||||
JS_CloneFunctionObject() is called for every Java method invocation and
|
||||
the inability to store private data in a JSFunction object requires that
|
||||
the method table be searched twice instead of once.</li>
|
||||
|
||||
<li>
|
||||
When Java objects are referenced from JS, they are entered into a hash
|
||||
table, so as to ensure that the same JS Object wrapper is used every time
|
||||
a particular Java object is reflected into JS. In this way, the behavior of
|
||||
the JS '==' and '===' operators are preserved. Unfortunately, the
|
||||
hash table may grow quite large (objects are only removed from the hash
|
||||
table when finalized). One solution would be to make it possible
|
||||
to overload JS's equality-test operators, so that the hash table would
|
||||
no longer be required.</li>
|
||||
|
||||
<li>
|
||||
Initially, JavaClassDescriptors were reference-counted to permit free'ing
|
||||
of unused descriptors. However, it's relatively common to develop
|
||||
cycles in the graph of JavaClassDescriptors, which leads to unused JavaClassDescriptors
|
||||
that are not free'ed until JSJ_Shutdown(). Luckily, the amount of
|
||||
memory used by JavaClassDescriptors tends to be relatively small.</li>
|
||||
|
||||
<li>
|
||||
The LiveConnect API is designed to allow multiple JVMs to be used simultaneously
|
||||
in the same executable (although each JSContext is limited to interaction
|
||||
with at most one JVM). However, the API is not fully implemented.
|
||||
For example, many global variables will need to become members of the JSJavaVM
|
||||
struct so that they are stored on a per-JVM basis.</li>
|
||||
|
||||
<li>
|
||||
Java and JavaScript use independent garbage collection systems. A reference between the two worlds must, therefore, take the form of a GC root. It's possible to create uncollectable objects when cyclic graphs cross the boundary between JS and Java, e.g. a JS object that refers to a Java object that refers back to the original JS object. There is no simple solution to this dual-GC problem. Luckily, such cyclic object graphs are extremely rare.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="Build_conventions"></a>Build conventions</h2>
|
||||
Update your JVM's <tt><font size=+1>CLASSPATH</font></tt> to point to the
|
||||
<tt>js/src/liveconnect/classes</tt>
|
||||
subdirectory. If you do not, LiveConnect will still operate but with
|
||||
the limitation that JS objects may not be passed as arguments of Java methods
|
||||
and it will not be possible to call from Java into JavaScript, i.e. the
|
||||
<i>netscape.javascript.JSObject</i> class will be inaccessible. Another
|
||||
downside of operating without these classes is that Java error messages
|
||||
will not include a Java stack trace, when one is available. If your
|
||||
<tt><font size=+1>CLASSPATH</font></tt>
|
||||
is set improperly, you will see a message like, "<tt>initialization error:
|
||||
Can't load class netscape/javascript/JSObject</tt>" when starting a LiveConnect
|
||||
debug build.
|
||||
<p>By default, all platforms build a version of LiveConnect that is <i>not</i>
|
||||
threadsafe. If you require thread-safety, you must also populate
|
||||
the <tt>mozilla/dist</tt> directory with <a href="http://www.mozilla.org/docs/tplist/catCode/nsprdesc.htm">NSPR</a>
|
||||
headers and libraries. (NSPR implements a portable threading library,
|
||||
among other things. The source is downloadable via <a href="http://www.mozilla.org/cvs.html">CVS</a>
|
||||
from <tt><a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/nsprpub">mozilla/nsprpub</a></tt>.)
|
||||
Next, you must define <tt>JS_THREADSAFE</tt> when building LiveConnect,
|
||||
either on the command-line (gmake/nmake) or in a universal header file.
|
||||
Note that JSRef must also be built with <tt><font size=+1>JS_THREADSAFE</font></tt>.
|
||||
<ul><b>Windows</b>
|
||||
<ul>
|
||||
<li>
|
||||
Build the JS runtime and interpreter, <tt>js32.dll</tt>, by using the <a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/js/src/README.html#Build">normal
|
||||
JSRef build procedure</a>.</li>
|
||||
|
||||
<li>
|
||||
Set the <tt><font size=+1>JDK</font></tt> environment variable to point
|
||||
to the top-level JDK directory, e.g. <tt>D:\jdk1.1.5</tt>. This is
|
||||
used to establish paths for header file inclusion, linking and execution.
|
||||
If you are not using Sun's JVM, the project files may require manual tweaking
|
||||
to set these paths correctly.</li>
|
||||
|
||||
<li>
|
||||
Use MSDEV5.0 with the <tt>LiveConnectShell.dsw</tt> project file.
|
||||
<font color="#993300">NOTE: makefile.win is an nmake file used only for
|
||||
building the JS-engine in the Mozilla browser. Don't attempt to use
|
||||
it to build the standalone JS-engine.</font></li>
|
||||
|
||||
<li>
|
||||
The output files (DLLs and executables) are placed in either the <tt>js\src\liveconnect\Debug</tt>
|
||||
or the <tt>js\src\liveconnect\Release</tt> directory.</li>
|
||||
|
||||
<li>
|
||||
The LiveConnect-enabled shell is named <tt>lcshell.exe</tt> and appears
|
||||
in the output directory.</li>
|
||||
|
||||
<li>
|
||||
You must have the JVM DLL in your <tt><font size=+1>PATH</font></tt> environment
|
||||
variable in order to run. If you are using the Sun JDK, the DLL appears
|
||||
in the JDK's bin directory, e.g. <tt>D:\jdk1.1.5\bin\javai_g.dll</tt>.</li>
|
||||
|
||||
<li>
|
||||
Use any Java compiler to compile the java source files in the <tt>js\src\liveconnect\classes\netscape\javascript</tt>
|
||||
directory.</li>
|
||||
|
||||
<li>
|
||||
Update your JVM's <tt><font size=+1>CLASSPATH</font></tt> to point to the
|
||||
<tt>js\src\liveconnect\classes</tt>
|
||||
subdirectory. (See above)<br>
|
||||
<BR></li>
|
||||
</ul>
|
||||
<b>Mac OS</b>
|
||||
<ul>
|
||||
<li>
|
||||
Using CodeWarrior Pro 3 is recommended, though the project files will probably
|
||||
also work with CodeWarrior Pro 4.</li>
|
||||
|
||||
<li>
|
||||
Install Apple's JVM, MRJ 2.0 (or later), and the <a href="ftp://dev.apple.com/devworld/Java/MRJSDK2.0.1EarlyAccess4.hqx">MRJ
|
||||
SDK v2.0.1ea4</a>. Note: You do not need to install MRJ if you are
|
||||
running a recent version of MacOS 8, since it is shipped with the OS.</li>
|
||||
|
||||
<li>
|
||||
Copy the folders <tt>CIncludes</tt> & <tt>Libraries</tt> from the SDK's
|
||||
<tt>Interfaces&Libraries</tt> directory to <tt>js:src:liveconnect:macbuild:JavaSession</tt>.</li>
|
||||
|
||||
<li>
|
||||
Build the LiveConnect test application, <tt>LiveConnectShell</tt>, with
|
||||
<tt>js:src:liveconnect:macbuild:LiveConnectShell.mcp</tt>.</li>
|
||||
|
||||
<li>
|
||||
Build <tt>liveconnect.jar</tt> with <tt>js:src:liveconnect:macbuild:LiveConnect.mcp</tt>.</li>
|
||||
|
||||
<li>
|
||||
Make an alias to <tt>liveconnect.jar</tt> and place it in "<tt>{SystemFolder}Extensions:MRJ
|
||||
Libraries:MRJClasses</tt>".<br>
|
||||
<BR></li>
|
||||
</ul>
|
||||
<b>Unix</b>
|
||||
<ul>
|
||||
<li>
|
||||
<font color="#000000">Use '<tt>gmake -f Makefile.ref</tt>' to build. To
|
||||
compile optimized code, pass <tt>BUILD_OPT=1</tt> on the gmake command
|
||||
line or preset it in the environment or <tt>Makefile.ref</tt>. </font><font color="#990000">NOTE:
|
||||
Do not attempt to use <tt>Makefile</tt> to build. This file is used
|
||||
only for building LiveConnect in the Mozilla browser.</font></li>
|
||||
|
||||
<li>
|
||||
<font color="#000000">Each platform on which LiveConnect is built must
|
||||
have a *.mk configuration file in the <tt>js/src/liveconnect/config</tt>
|
||||
directory. The configuration file specifies the JVM headers/libraries
|
||||
used and allows for customization of command-line options. To date,
|
||||
the build system has been tested on Solaris, AIX, HP/UX, OSF, IRIX, x86
|
||||
Linux and Windows NT. Most platforms will work with either the vendor compiler
|
||||
or gcc.</font></li>
|
||||
|
||||
<li>
|
||||
Use any Java compiler to compile the java source files in the <tt>js/src/liveconnect/classes/netscape/javascript</tt>
|
||||
directory.</li>
|
||||
|
||||
<li>
|
||||
Update your JVM's <tt><font size=+1>CLASSPATH</font></tt> to point to the
|
||||
<tt>js/src/liveconnect/classes</tt>
|
||||
subdirectory. (See above)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="coding_conventions"></a>Naming and coding conventions:</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Public function names begin with JSJ_ followed by capitalized "intercaps",
|
||||
e.g. JSJ_ConnectToJavaVM.</li>
|
||||
|
||||
<li>
|
||||
Extern but library-private function names use a jsj_ prefix and mixed case,
|
||||
e.g. jsj_LookupSymbol.</li>
|
||||
|
||||
<li>
|
||||
Most static function names have unprefixed, underscore-separated names:
|
||||
get_char.</li>
|
||||
|
||||
<li>
|
||||
But static native methods of JS objects have intercaps names, e.g., JavaObject_getProperty().</li>
|
||||
|
||||
<li>
|
||||
And library-private and static data use underscores, not intercaps (but
|
||||
library-private data do use a js_ prefix).</li>
|
||||
|
||||
<li>
|
||||
Scalar type names are lowercase and js-prefixed: jsdouble.</li>
|
||||
|
||||
<li>
|
||||
Aggregate type names are JS-prefixed and mixed-case: JSObject.</li>
|
||||
|
||||
<li>
|
||||
Macros are generally ALL_CAPS and underscored, to call out potential side
|
||||
effects, multiple uses of a formal argument, etc.</li>
|
||||
|
||||
<li>
|
||||
Four spaces of indentation per statement nesting level. The files
|
||||
are space-filled, so adjusting of your tab setting should be unnecessary.</li>
|
||||
|
||||
<li>
|
||||
I don't bow down to the ancient "80 columns per line" gods, since most
|
||||
of us are not using vt100's to read source code. My rule of thumb
|
||||
is to use no more than 95 columns per line, but exceptions are made to
|
||||
format tables or table-like code.</li>
|
||||
|
||||
<li>
|
||||
DLL entry points have their return type expanded within a JS_EXPORT_API()
|
||||
macro call, to get the right Windows secret type qualifiers in the right
|
||||
places for both 16- and 32-bit builds.</li>
|
||||
|
||||
<li>
|
||||
Callback functions that might be called from a DLL are similarly macroized
|
||||
with JS_STATIC_DLL_CALLBACK (if the function otherwise would be static
|
||||
to hide its name) or JS_DLL_CALLBACK (this macro takes no type argument;
|
||||
it should be used after the return type and before the function name).</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="API"></a>The LiveConnect API</h2>
|
||||
All public LiveConnect entry points and callbacks are documented in <A HREF=http://cvs-mirror.mozilla.org/webtools/lxr/source/js/src/liveconnect/jsjava.h>jsjava.h</A>,
|
||||
the header file that exports those functions.
|
||||
<br>
|
||||
<h2>
|
||||
<a NAME="File_walkthrough"></a>File walk-through</h2>
|
||||
|
||||
<table BORDER=3 CELLSPACING=0 CELLPADDING=4 >
|
||||
<tr>
|
||||
<td>jsjava.h</td>
|
||||
|
||||
<td>LiveConnect's only public header file. Defines all public API
|
||||
entry points, callbacks and types. </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_private.h</td>
|
||||
|
||||
<td>LiveConnect internal header file for intra-module sharing of functions
|
||||
and types.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj.c</td>
|
||||
|
||||
<td>Public LiveConnect API entry points and initialization code. Handling
|
||||
of multiple threads and multiple JVMs.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_array.c</td>
|
||||
|
||||
<td>Read and write elements of a Java array, performing needed conversions
|
||||
to/from JS types.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_class.c</td>
|
||||
|
||||
<td>Construct and manipulate JavaClassDescriptor structs, which are the
|
||||
native representation for Java classes. JavaClassDescriptors are
|
||||
used to describe the methods and fields of a class, including their type
|
||||
signatures, and include a reference to the peer <i>java.lang.Class</i>
|
||||
object. Since each Java object has a class, there is a JavaClassDescriptor
|
||||
associated with the JavaScript reflection of each Java Object.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_convert.c</td>
|
||||
|
||||
<td>Convert between Java and JavaScript values of all types, which may
|
||||
require calling routines in other files to wrap JS objects as Java objects
|
||||
and vice-versa.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_field.c</td>
|
||||
|
||||
<td>Reflect Java fields as properties of JavaObject objects and implement
|
||||
getter/setter access to those fields.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_JavaArray.c</td>
|
||||
|
||||
<td>Implementation of the JavaScript JavaArray class. Instances of
|
||||
JavaArray are used to reflect Java arrays.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_JavaClass.c</td>
|
||||
|
||||
<td>Implementation of the JavaScript JavaClass class. Instances
|
||||
of JavaClass are used to reflect Java classes.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_JavaObject.c</td>
|
||||
|
||||
<td>Implementation of the JavaScript JavaObject class. Instances
|
||||
of JavaObject are used to reflect Java objects, except for Java arrays,
|
||||
although some of the code in this file is used by the JavaArray code.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_JavaMember.c</td>
|
||||
|
||||
<td>Implementation of the JavaScript JavaMember class. JavaMember's
|
||||
are a strange beast required only to handle the special case of a public
|
||||
field and a public method that appear in the same Java class and which
|
||||
have the same name.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_JavaPackage.c</td>
|
||||
|
||||
<td>Implementation of the JavaScript JavaPackage class. Instances
|
||||
of JavaPackage are used to reflect Java packages. The JS properties
|
||||
of a JavaPackage are either nested JavaPackage objects or a JavaClass object.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_JSObject.c</td>
|
||||
|
||||
<td>Implementation of the native methods for the <i>netscape.javascript.JSObject</i>
|
||||
Java class, which are used for calling into JavaScript from Java.
|
||||
It also contains the code that wraps JS objects as instances of <i>netscape.javascript.JSObject
|
||||
</i>and
|
||||
the code that handles propagation of exceptions both into and out of Java.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_method.c</td>
|
||||
|
||||
<td>Reflect Java methods as properties of JavaObject objects and make it
|
||||
possible to invoke those methods. Includes overloaded method resolution
|
||||
and argument/return-value conversion code.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jsj_utils.c</td>
|
||||
|
||||
<td>Low-level utility code for reporting errors, etc.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>
|
||||
<a NAME="sample_shell_interaction"></a>Sample LiveConnect shell interactions</h2>
|
||||
|
||||
<h4>
|
||||
Java packages, classes and constructors</h4>
|
||||
<tt>js> java</tt>
|
||||
<br><tt>[JavaPackage java]</tt>
|
||||
<br><tt>js> awt = java.awt</tt>
|
||||
<br><tt>[JavaPackage java.awt]</tt>
|
||||
<br><tt>js> Rectangle = awt.Rectangle</tt>
|
||||
<br><tt>[JavaClass java.awt.Rectangle]</tt>
|
||||
<h4>
|
||||
Java instance fields and methods</h4>
|
||||
<tt>js> r = new java.awt.Rectangle(34, 23)</tt>
|
||||
<br><tt>java.awt.Rectangle[x=0,y=0,width=34,height=23]</tt>
|
||||
<br><tt>js> r.width - r.height</tt>
|
||||
<br><tt>11</tt>
|
||||
<br><tt>js> r.x = 7; r.y = 4</tt>
|
||||
<br><tt>4</tt>
|
||||
<br><tt>js> r</tt>
|
||||
<br><tt>java.awt.Rectangle[x=7,y=4,width=34,height=23]</tt>
|
||||
<br><tt>js> r.grow(3)</tt>
|
||||
<br><tt>There is no Java method java.awt.Rectangle.grow that matches JavaScript
|
||||
argument types (number).</tt>
|
||||
<br><tt>Candidate methods with the same name are:</tt>
|
||||
<br><tt> void grow(int, int)</tt>
|
||||
<p><tt>js> r.grow(3, 3)</tt>
|
||||
<br><tt>js> r</tt>
|
||||
<br><tt>java.awt.Rectangle[x=4,y=1,width=40,height=29]</tt>
|
||||
<h4>
|
||||
Java arrays</h4>
|
||||
<tt>js> s = new java.lang.String("mastiff")</tt>
|
||||
<br><tt>mastiff</tt>
|
||||
<br><tt>js> c = s.toCharArray()</tt>
|
||||
<br><tt>[C@298e9b</tt>
|
||||
<br><tt>js> c[0] = "b"; c[4] = "a"; c[5] = "r"; c[6] = "d"</tt>
|
||||
<br><tt>d</tt>
|
||||
<br><tt>js> s2 = new java.lang.String(c)</tt>
|
||||
<br><tt>bastard</tt>
|
||||
<h4>
|
||||
Java static fields and methods</h4>
|
||||
<tt>js> java.lang.reflect.Modifier.ABSTRACT</tt>
|
||||
<br><tt>1024</tt>
|
||||
<br><tt>js> java.lang.Math.sin(3) + 2</tt>
|
||||
<br><tt>2.1411200080598674</tt>
|
||||
<h4>
|
||||
Explicit resolution of overloaded Java methods</h4>
|
||||
<tt>js> x = "23"</tt>
|
||||
<br><tt>23</tt>
|
||||
<br><tt>js> java.lang.Math.abs(x)</tt>
|
||||
<br><tt>The choice of static Java method java.lang.Math.abs matching JavaScript
|
||||
argument types (string) is ambiguous.</tt>
|
||||
<br><tt>Candidate methods are:</tt>
|
||||
<br><tt> long abs(long)</tt>
|
||||
<br><tt> float abs(float)</tt>
|
||||
<br><tt> double abs(double)</tt>
|
||||
<br><tt> int abs(int)</tt>
|
||||
<br><tt>js> abs = java.lang.Math["abs(int)"]</tt>
|
||||
<p><tt>function abs(int)() {</tt>
|
||||
<br><tt> [native code]</tt>
|
||||
<br><tt>}</tt>
|
||||
<p><tt>js> abs(x)</tt>
|
||||
<br><tt>23</tt>
|
||||
<h4>
|
||||
Public Method/field enumeration</h4>
|
||||
<tt>js> out = java.lang.System.out</tt>
|
||||
<br><tt>java.io.PrintStream@2980f5</tt>
|
||||
<br><tt>js> for (m in out) print(m)</tt>
|
||||
<br><tt>println</tt>
|
||||
<br><tt>print</tt>
|
||||
<br><tt>checkError</tt>
|
||||
<br><tt>close</tt>
|
||||
<br><tt>flush</tt>
|
||||
<br><tt>write</tt>
|
||||
<br><tt>wait</tt>
|
||||
<br><tt>notifyAll</tt>
|
||||
<br><tt>notify</tt>
|
||||
<br><tt>toString</tt>
|
||||
<br><tt>equals</tt>
|
||||
<br><tt>hashCode</tt>
|
||||
<br><tt>getClass</tt>
|
||||
<br><tt>js> for (m in java.lang.String) print(m)</tt>
|
||||
<br><tt>copyValueOf</tt>
|
||||
<br><tt>valueOf</tt>
|
||||
<h4>
|
||||
'instanceof' and 'in' operators</h4>
|
||||
<tt>js> s = new java.lang.String("foop")</tt>
|
||||
<br><tt>foop</tt>
|
||||
<br><tt>js> s instanceof java.lang.Class</tt>
|
||||
<br><tt>false</tt>
|
||||
<br><tt>js> s instanceof java.lang.Object</tt>
|
||||
<br><tt>true</tt>
|
||||
<br><tt>js> "valueOf" in s</tt>
|
||||
<br><tt>true</tt>
|
||||
<br><tt>js> "NoSuchThing" in s</tt>
|
||||
<br><tt>false</tt>
|
||||
<h4>
|
||||
Applying JavaScript string methods to Java strings</h4>
|
||||
<tt>js> s = new java.lang.String("The rain in Spain falls mainly on my
|
||||
head.")</tt>
|
||||
<br><tt>The rain in Spain falls mainly on my head.</tt>
|
||||
<br><tt>js> s.match(/Spain.*my/)</tt>
|
||||
<br><tt>Spain falls mainly on my</tt>
|
||||
<h4>
|
||||
Applying JavaScript array methods to Java arrays</h4>
|
||||
<tt>js> s = new java.lang.String("JavaScript")</tt>
|
||||
<br><tt>JavaScript</tt>
|
||||
<br><tt>js> c = s.toCharArray()</tt>
|
||||
<br><tt>[C@298aef</tt>
|
||||
<br><tt>js> c.reverse()</tt>
|
||||
<br><tt>[C@298aef</tt>
|
||||
<br><tt>js> new java.lang.String(c)</tt>
|
||||
<br><tt>tpircSavaJ</tt>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,31 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include "jni.h"
|
||||
/* -*- 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 "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* Declarations of private (internal) functions/data/types for
|
||||
* JavaScript <==> Java communication.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
/* Header for class netscape_javascript_JSObject */
|
||||
|
||||
#ifndef _Included_netscape_javascript_JSObject
|
||||
|
@ -96,6 +121,14 @@ JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getWindow
|
|||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: equals
|
||||
* Signature: (Ljava/lang/Object;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_netscape_javascript_JSObject_equals
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
/* Insert copyright and license here 19** */
|
||||
/* -*- Mode: Java; tab-width: 8; 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.
|
||||
*/
|
||||
|
||||
package netscape.javascript;
|
||||
|
||||
|
@ -8,15 +24,28 @@ package netscape.javascript;
|
|||
*/
|
||||
|
||||
public
|
||||
class JSException extends Exception {
|
||||
class JSException extends RuntimeException {
|
||||
public static final int EXCEPTION_TYPE_EMPTY = -1;
|
||||
public static final int EXCEPTION_TYPE_VOID = 0;
|
||||
public static final int EXCEPTION_TYPE_OBJECT = 1;
|
||||
public static final int EXCEPTION_TYPE_FUNCTION = 2;
|
||||
public static final int EXCEPTION_TYPE_STRING = 3;
|
||||
public static final int EXCEPTION_TYPE_NUMBER = 4;
|
||||
public static final int EXCEPTION_TYPE_BOOLEAN = 5;
|
||||
public static final int EXCEPTION_TYPE_ERROR = 6;
|
||||
|
||||
String filename;
|
||||
int lineno;
|
||||
String source;
|
||||
int tokenIndex;
|
||||
private int wrappedExceptionType;
|
||||
private Object wrappedException;
|
||||
|
||||
/**
|
||||
* Constructs a JSException without a detail message.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
*
|
||||
* @deprecated Not for public use in future versions.
|
||||
*/
|
||||
public JSException() {
|
||||
super();
|
||||
|
@ -24,12 +53,15 @@ class JSException extends Exception {
|
|||
lineno = 0;
|
||||
source = "";
|
||||
tokenIndex = 0;
|
||||
wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JSException with a detail message.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
* @param s the detail message
|
||||
*
|
||||
* @deprecated Not for public use in future versions.
|
||||
*/
|
||||
public JSException(String s) {
|
||||
super(s);
|
||||
|
@ -37,12 +69,26 @@ class JSException extends Exception {
|
|||
lineno = 0;
|
||||
source = "";
|
||||
tokenIndex = 0;
|
||||
wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JSException with a wrapped JavaScript exception object.
|
||||
* This constructor needs to be public so that Java users can throw
|
||||
* exceptions to JS cleanly.
|
||||
*/
|
||||
private JSException(int wrappedExceptionType, Object wrappedException) {
|
||||
super();
|
||||
this.wrappedExceptionType = wrappedExceptionType;
|
||||
this.wrappedException = wrappedException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JSException with a detail message and all the
|
||||
* other info that usually comes with a JavaScript error.
|
||||
* @param s the detail message
|
||||
*
|
||||
* @deprecated Not for public use in future versions.
|
||||
*/
|
||||
public JSException(String s, String filename, int lineno,
|
||||
String source, int tokenIndex) {
|
||||
|
@ -51,6 +97,23 @@ class JSException extends Exception {
|
|||
this.lineno = lineno;
|
||||
this.source = source;
|
||||
this.tokenIndex = tokenIndex;
|
||||
wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance method getWrappedExceptionType returns the int mapping of the
|
||||
* type of the wrappedException Object.
|
||||
*/
|
||||
public int getWrappedExceptionType() {
|
||||
return wrappedExceptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance method getWrappedException.
|
||||
*/
|
||||
public Object getWrappedException() {
|
||||
return wrappedException;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
|
||||
/* Insert copyright and license here 19** */
|
||||
/* -*- Mode: Java; tab-width: 8; 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.
|
||||
*/
|
||||
|
||||
/* more doc todo:
|
||||
* threads
|
||||
|
@ -23,7 +37,7 @@ import java.applet.Applet;
|
|||
* which can be used to access methods and fields of the java object.
|
||||
* Converting this wrapper to a string will call the toString method
|
||||
* on the original object, converting to a number will call the
|
||||
* floatValue method if possible and fail otherwise. Converting
|
||||
* doubleValue method if possible and fail otherwise. Converting
|
||||
* to a boolean will try to call the booleanValue method in the
|
||||
* same way.
|
||||
* <li>Java arrays are wrapped with a JavaScript object that understands
|
||||
|
@ -35,7 +49,7 @@ import java.applet.Applet;
|
|||
* Values passed from JavaScript to Java are converted as follows:<ul>
|
||||
* <li>objects which are wrappers around java objects are unwrapped
|
||||
* <li>other objects are wrapped with a JSObject
|
||||
* <li>strings, numbers and booleans are converted to String, Float,
|
||||
* <li>strings, numbers and booleans are converted to String, Double,
|
||||
* and Boolean objects respectively
|
||||
* </ul>
|
||||
* This means that all JavaScript values show up as some kind
|
||||
|
@ -139,12 +153,5 @@ public final class JSObject {
|
|||
* Override java.lang.Object.equals() because identity is not preserved
|
||||
* with instances of JSObject.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
JSObject jsobj;
|
||||
|
||||
if (!(obj instanceof JSObject))
|
||||
return false;
|
||||
jsobj = (JSObject)obj;
|
||||
return (internal == jsobj.internal);
|
||||
}
|
||||
public native boolean equals(Object obj);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/* ** */
|
||||
|
||||
/**
|
||||
* The JSProxy interface allows applets and plugins to
|
||||
* share javascript contexts.
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/* -*- Mode: Java; tab-width: 8; 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.
|
||||
*/
|
||||
|
||||
package netscape.javascript;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: Java; tab-width: 8; 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
|
||||
|
@ -25,14 +25,26 @@ public class JSUtil {
|
|||
/* Return the stack trace of an exception or error as a String */
|
||||
public static String getStackTrace(Throwable t) {
|
||||
ByteArrayOutputStream captureStream;
|
||||
PrintStream p;
|
||||
PrintWriter p;
|
||||
|
||||
captureStream = new ByteArrayOutputStream();
|
||||
p = new PrintStream(captureStream);
|
||||
p = new PrintWriter(captureStream);
|
||||
|
||||
t.printStackTrace(p);
|
||||
p.flush();
|
||||
|
||||
return captureStream.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to work around a bug in AIX JDK1.1.6, in which
|
||||
* static initializers are not run when a static field is referenced from
|
||||
* native code. The problem does not manifest itself if the field is
|
||||
* accessed from Java code.
|
||||
*/
|
||||
private static void workAroundAIXJavaBug() {
|
||||
if (java.lang.Void.TYPE == null)
|
||||
java.lang.System.out.println("JDK bug: " +
|
||||
"java.lang.Void.TYPE uninitialized");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
# Change these to the current platform settings!!!
|
||||
|
||||
JDK = /tools/ns
|
||||
|
||||
INCLUDES += -I$(JDK)/include/java -I$(JDK)/include/java/aix
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/aix/native_threads -ljava
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
# Change these to the current platform settings!!!
|
||||
|
||||
JDK = /tools/ns
|
||||
|
||||
INCLUDES += -I$(JDK)/include/java -I$(JDK)/include/java/aix
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/aix/native_threads -ljava
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
JDK = /share/builds/components/jdk/1.1.5/HP-UX10
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/hp-ux
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/PA_RISC/green_threads -ljava
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
JDK = /share/builds/components/jdk/1.1.5/HP-UX10
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/hp-ux
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/PA_RISC/green_threads -ljava
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
JDK = /share/builds/components/jdk/1.1.5/HP-UX
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/hp-ux
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/PA_RISC/native_threads -ljava
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
JDK = /share/builds/components/jdk/1.1.6/IRIX
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/irix
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/sgi/native_threads -ljava
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
JDK = /share/builds/components/jdk/1.1.6/IRIX
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/irix
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/sgi/native_threads -ljava
|
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
# JDK_DIR should be the directory you put the JDK in, and should have
|
||||
# the appropriate lib/ and include/ dirs on it.
|
||||
# If you're not using the `Blackdown' JDK, try changing the following line:
|
||||
JDK_DIR=/usr/lib/jdk-1.1.5
|
||||
|
||||
INCLUDES += -I$(JDK_DIR)/include -I$(JDK_DIR)/include/md \
|
||||
-I$(JDK_DIR)/include/genunix
|
||||
|
||||
OTHER_LIBS += -L$(JDK_DIR)/lib/i386/green_threads -ljava
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
JDK = /share/builds/components/jdk/1.1.6/OSF1
|
||||
|
||||
INCLUDES += -I$(JDK)/include/java -I$(JDK)/include/java/alpha
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/alpha -ljava
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
# Change these to the current platform settings!!!
|
||||
|
||||
JDK = /u/rchinta/util/java/jdk1.1.5
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/solaris
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/sparc/native_threads -ljava
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
# Change these to the current platform settings!!!
|
||||
|
||||
JDK = /u/rchinta/util/java/jdk1.1.5
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/solaris
|
||||
|
||||
OTHER_LIBS += -L$(JDK)/lib/sparc/native_threads -ljava
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# 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.
|
||||
|
||||
JDK = c:/jdk1.1.6
|
||||
|
||||
INCLUDES += -I$(JDK)/include -I$(JDK)/include/win32
|
||||
|
||||
OTHER_LIBS += $(JDK)/lib/javai.lib ../$(OBJDIR)/js32.lib
|
||||
|
||||
JSDLL_CFLAGS =
|
|
@ -43,24 +43,23 @@ report_java_initialization_error(JNIEnv *jEnv, const char *js_error_msg)
|
|||
const char *error_msg, *java_error_msg;
|
||||
|
||||
java_error_msg = NULL;
|
||||
#if 0 /* This can never work here, because jsj_GetJavaErrorMessage relies on
|
||||
jlThrowable_toString which is set up by the initialization that calls
|
||||
this function. */
|
||||
|
||||
if (jEnv) {
|
||||
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (java_error_msg) {
|
||||
error_msg = PR_smprintf("initialization error: %s (%s)\n",
|
||||
error_msg = JS_smprintf("initialization error: %s (%s)\n",
|
||||
js_error_msg, java_error_msg);
|
||||
free((void*)java_error_msg);
|
||||
} else {
|
||||
error_msg = PR_smprintf("initialization error: %s\n",
|
||||
error_msg = JS_smprintf("initialization error: %s\n",
|
||||
js_error_msg);
|
||||
}
|
||||
|
||||
jsj_LogError(error_msg);
|
||||
free((void*)error_msg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -115,14 +114,18 @@ jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() *
|
|||
|
||||
jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
|
||||
|
||||
jmethodID njJSException_JSException; /* netscape.javascript.JSexception constructor */
|
||||
jmethodID njJSException_JSException; /* netscape.javascript.JSException constructor */
|
||||
jmethodID njJSException_JSException_wrap;/*netscape.javascript.JSException alternate constructor */
|
||||
jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
|
||||
jmethodID njJSUtil_workAroundAIXJavaBug;/* netscape.javascript.JSUtil.workAroundAIXJavaBug() */
|
||||
jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
|
||||
jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
|
||||
jfieldID njJSException_lineno; /* netscape.javascript.JSException.lineno */
|
||||
jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
|
||||
jfieldID njJSException_source; /* netscape.javascript.JSException.source */
|
||||
jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
|
||||
jfieldID njJSException_wrappedExceptionType; /* netscape.javascript.JSException.wrappedExceptionType */
|
||||
jfieldID njJSException_wrappedException; /* netscape.javascript.JSException.wrappedException */
|
||||
|
||||
/* Obtain a reference to a Java class */
|
||||
#define LOAD_CLASS(qualified_name, class) \
|
||||
|
@ -147,6 +150,7 @@ jfieldID njJSException_filename; /* netscape.javascript.JSException.filen
|
|||
(*jEnv)->GetMethodID(jEnv, class, #method, signature); \
|
||||
} \
|
||||
if (class##_##mvar == 0) { \
|
||||
(*jEnv)->ExceptionClear(jEnv); \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't get mid for " #qualified_class "." #method "()"); \
|
||||
return JS_FALSE; \
|
||||
|
@ -172,6 +176,7 @@ jfieldID njJSException_filename; /* netscape.javascript.JSException.filen
|
|||
class##_##field = (*jEnv)->GetFieldID(jEnv, class, #field, signature);\
|
||||
} \
|
||||
if (class##_##field == 0) { \
|
||||
(*jEnv)->ExceptionClear(jEnv); \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't get fid for " #qualified_class "." #field); \
|
||||
return JS_FALSE; \
|
||||
|
@ -194,6 +199,7 @@ jfieldID njJSException_filename; /* netscape.javascript.JSException.filen
|
|||
class##_##field = \
|
||||
(*jEnv)->GetStatic##type##Field(jEnv, class, field_id); \
|
||||
if (class##_##field == 0) { \
|
||||
(*jEnv)->ExceptionClear(jEnv); \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't read static field " #qualified_class "." #field); \
|
||||
return JS_FALSE; \
|
||||
|
@ -263,7 +269,7 @@ init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#if XP_MAC
|
||||
#if defined(XP_MAC) || !defined(OJI)
|
||||
|
||||
/**
|
||||
* Workaround for the fact that MRJ loads a different instance of the shared library.
|
||||
|
@ -271,37 +277,39 @@ init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
|
|||
|
||||
#include "netscape_javascript_JSObject.h"
|
||||
|
||||
static JSObject_RegisterNativeMethods(JNIEnv* jEnv)
|
||||
/* Manually load the required native methods. */
|
||||
static JSBool
|
||||
JSObject_RegisterNativeMethods(JNIEnv* jEnv)
|
||||
{
|
||||
// Manually load the required native methods.
|
||||
|
||||
static JNINativeMethod nativeMethods[] = {
|
||||
"initClass", "()V", (void*)&Java_netscape_javascript_JSObject_initClass,
|
||||
{"initClass", "()V", (void*)&Java_netscape_javascript_JSObject_initClass},
|
||||
|
||||
#if 0
|
||||
"getMember", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getMember,
|
||||
"getSlot", "(I)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getSlot,
|
||||
"setMember", "(Ljava/lang/String;Ljava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setMember,
|
||||
"setSlot", "(ILjava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setSlot,
|
||||
"removeMember", "(Ljava/lang/String;)V", (void*)&Java_netscape_javascript_JSObject_removeMember,
|
||||
"call", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_call,
|
||||
"eval", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_eval,
|
||||
#endif
|
||||
#ifndef OJI
|
||||
{"getMember", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getMember},
|
||||
{"getSlot", "(I)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getSlot},
|
||||
{"setMember", "(Ljava/lang/String;Ljava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setMember},
|
||||
{"setSlot", "(ILjava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setSlot},
|
||||
{"removeMember", "(Ljava/lang/String;)V", (void*)&Java_netscape_javascript_JSObject_removeMember},
|
||||
{"call", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_call},
|
||||
{"eval", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_eval},
|
||||
|
||||
{"toString", "()Ljava/lang/String;", (void*)&Java_netscape_javascript_JSObject_toString},
|
||||
{"getWindow", "(Ljava/applet/Applet;)Lnetscape/javascript/JSObject;", (void*)&Java_netscape_javascript_JSObject_getWindow},
|
||||
{"finalize", "()V", (void*)&Java_netscape_javascript_JSObject_finalize},
|
||||
{"equals", "(Ljava/lang/Object;)Z", (void*)&Java_netscape_javascript_JSObject_equals}
|
||||
#endif /* !OJI */
|
||||
|
||||
"toString", "()Ljava/lang/String;", (void*)&Java_netscape_javascript_JSObject_toString,
|
||||
|
||||
#if 0
|
||||
"getWindow", "(Ljava/applet/Applet;)Lnetscape/javascript/JSObject;", (void*)&Java_netscape_javascript_JSObject_getWindow,
|
||||
"finalize", "()V", (void*)&Java_netscape_javascript_JSObject_finalize,
|
||||
/* "equals", "(Ljava/lang/Object;)Z", (void*)&Java_netscape_javascript_JSObject_equals */
|
||||
#endif
|
||||
};
|
||||
(*jEnv)->RegisterNatives(jEnv, njJSObject, nativeMethods, sizeof(nativeMethods) / sizeof(JNINativeMethod));
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
report_java_initialization_error(jEnv, "Couldn't initialize JSObject native methods.");
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
return JS_FALSE;
|
||||
}
|
||||
/* call the initClass method, since we nailed the static initializer for testing. */
|
||||
/* Call the initClass method */
|
||||
Java_netscape_javascript_JSObject_initClass(jEnv, njJSObject);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -314,17 +322,27 @@ init_netscape_java_classes(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
|
|||
LOAD_CLASS(netscape/javascript/JSException, njJSException);
|
||||
LOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
|
||||
|
||||
#if XP_MAC
|
||||
#if defined(XP_MAC) || !defined(OJI)
|
||||
JSObject_RegisterNativeMethods(jEnv);
|
||||
#endif
|
||||
|
||||
#ifndef OJI
|
||||
LOAD_CONSTRUCTOR(netscape.javascript.JSObject,
|
||||
JSObject, "(I)V", njJSObject);
|
||||
#endif
|
||||
LOAD_CONSTRUCTOR(netscape.javascript.JSException,
|
||||
JSException, "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V",
|
||||
njJSException);
|
||||
/* Load second constructor for wrapping JS exception objects inside JSExceptions */
|
||||
_LOAD_METHOD(netscape.javascript.JSException,<init>,
|
||||
JSException_wrap, "(ILjava/lang/Object;)V",
|
||||
njJSException, JS_FALSE);
|
||||
|
||||
|
||||
#ifndef OJI
|
||||
LOAD_FIELDID(netscape.javascript.JSObject,
|
||||
internal, "I", njJSObject);
|
||||
#endif
|
||||
LOAD_FIELDID(netscape.javascript.JSException,
|
||||
lineno, "I", njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSException,
|
||||
|
@ -333,11 +351,32 @@ init_netscape_java_classes(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
|
|||
source, "Ljava/lang/String;", njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSException,
|
||||
filename, "Ljava/lang/String;", njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSException, wrappedExceptionType, "I",
|
||||
njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSException, wrappedException,
|
||||
"Ljava/lang/Object;", njJSException);
|
||||
|
||||
LOAD_STATIC_METHOD(netscape.javascript.JSUtil,
|
||||
getStackTrace, "(Ljava/lang/Throwable;)Ljava/lang/String;",
|
||||
njJSUtil);
|
||||
|
||||
#ifdef AIX
|
||||
# define JAVA_STATIC_INITIALIZER_BUG
|
||||
#endif
|
||||
|
||||
#ifdef JAVA_STATIC_INITIALIZER_BUG
|
||||
/* The following is used to work around a bug in AIX JDK1.1.6 (See
|
||||
* #331620), in which static initializers are not run when a
|
||||
* static field is referenced from native code. The problem does
|
||||
* not manifest itself if the field is accessed from Java code, so
|
||||
* we first call some Java code to access the fields of interest
|
||||
* before attempting to read them from native code.
|
||||
*/
|
||||
LOAD_STATIC_METHOD(netscape.javascript.JSUtil,
|
||||
workAroundAIXJavaBug,"()V", njJSUtil);
|
||||
(*jEnv)->CallStaticObjectMethod(jEnv, njJSUtil, njJSUtil_workAroundAIXJavaBug);
|
||||
#endif /* JAVA_STATIC_INITIALIZER_BUG */
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -356,10 +395,10 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
|||
JSJavaVM *jsjava_vm;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
PR_ASSERT(JSJ_callbacks);
|
||||
PR_ASSERT(JSJ_callbacks->attach_current_thread);
|
||||
PR_ASSERT(JSJ_callbacks->detach_current_thread);
|
||||
PR_ASSERT(JSJ_callbacks->get_java_vm);
|
||||
JS_ASSERT(JSJ_callbacks);
|
||||
JS_ASSERT(JSJ_callbacks->attach_current_thread);
|
||||
JS_ASSERT(JSJ_callbacks->detach_current_thread);
|
||||
JS_ASSERT(JSJ_callbacks->get_java_vm);
|
||||
|
||||
jsjava_vm = (JSJavaVM*)malloc(sizeof(JSJavaVM));
|
||||
if (!jsjava_vm)
|
||||
|
@ -376,11 +415,10 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
|||
free(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PRBool ok;
|
||||
PR_ASSERT(JSJ_callbacks->create_java_vm);
|
||||
PR_ASSERT(JSJ_callbacks->destroy_java_vm);
|
||||
} else {
|
||||
JSBool ok;
|
||||
JS_ASSERT(JSJ_callbacks->create_java_vm);
|
||||
JS_ASSERT(JSJ_callbacks->destroy_java_vm);
|
||||
|
||||
ok = JSJ_callbacks->create_java_vm(&java_vm, &jEnv, initargs);
|
||||
if (!ok || java_vm == NULL) {
|
||||
|
@ -396,13 +434,6 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
|||
jsjava_vm->java_vm = java_vm;
|
||||
jsjava_vm->main_thread_env = jEnv;
|
||||
|
||||
/* Load the Java classes, and the method and field descriptors required for
|
||||
Java reflection. */
|
||||
if (!init_java_VM_reflection(jsjava_vm, jEnv)) {
|
||||
JSJ_DisconnectFromJavaVM(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* JVM initialization for netscape.javascript.JSObject is performed
|
||||
* independently of the other classes that are initialized in
|
||||
|
@ -412,6 +443,21 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
|||
*/
|
||||
init_netscape_java_classes(jsjava_vm, jEnv);
|
||||
|
||||
/* Load the Java classes, and the method and field descriptors required for
|
||||
Java reflection. */
|
||||
if (!init_java_VM_reflection(jsjava_vm, jEnv) ||
|
||||
!jsj_InitJavaObjReflectionsTable()) {
|
||||
JSJ_DisconnectFromJavaVM(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
if (jsjava_vm_list == NULL) {
|
||||
thread_list_monitor =
|
||||
(struct PRMonitor *) PR_NewNamedMonitor("thread_list_monitor");
|
||||
}
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
/* Put this VM on the list of all created VMs */
|
||||
jsjava_vm->next = jsjava_vm_list;
|
||||
jsjava_vm_list = jsjava_vm;
|
||||
|
@ -425,7 +471,7 @@ JSJCallbacks *JSJ_callbacks = NULL;
|
|||
void
|
||||
JSJ_Init(JSJCallbacks *callbacks)
|
||||
{
|
||||
PR_ASSERT(callbacks);
|
||||
JS_ASSERT(callbacks);
|
||||
JSJ_callbacks = callbacks;
|
||||
}
|
||||
|
||||
|
@ -510,7 +556,6 @@ JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
|
|||
UNLOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
|
||||
}
|
||||
|
||||
|
||||
/* Remove this VM from the list of all JSJavaVM objects. */
|
||||
for (jp = &jsjava_vm_list; (j = *jp) != NULL; jp = &j->next) {
|
||||
if (j == jsjava_vm) {
|
||||
|
@ -518,13 +563,24 @@ JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
|
|||
break;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(j);
|
||||
JS_ASSERT(j);
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
if (jsjava_vm_list == NULL) {
|
||||
PR_DestroyMonitor(thread_list_monitor);
|
||||
thread_list_monitor = NULL;
|
||||
}
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
free(jsjava_vm);
|
||||
}
|
||||
|
||||
static JSJavaThreadState *thread_list = NULL;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
static PRMonitor *thread_list_monitor = NULL;
|
||||
#endif
|
||||
|
||||
static JSJavaThreadState *
|
||||
new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jEnv)
|
||||
{
|
||||
|
@ -540,10 +596,17 @@ new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jE
|
|||
if (thread_name)
|
||||
jsj_env->name = strdup(thread_name);
|
||||
|
||||
/* THREADSAFETY - need to protect against races */
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
jsj_env->next = thread_list;
|
||||
thread_list = jsj_env;
|
||||
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
|
@ -553,26 +616,34 @@ find_jsjava_thread(JNIEnv *jEnv)
|
|||
JSJavaThreadState *e, **p, *jsj_env;
|
||||
jsj_env = NULL;
|
||||
|
||||
/* THREADSAFETY - need to protect against races in manipulating the thread list */
|
||||
|
||||
/* Search for the thread state among the list of all created
|
||||
LiveConnect threads */
|
||||
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
|
||||
if (e->jEnv == jEnv) {
|
||||
jsj_env = e;
|
||||
*p = jsj_env->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move a found thread to head of list for faster search next time. */
|
||||
if (jsj_env)
|
||||
thread_list = jsj_env;
|
||||
if (jsj_env && p != &thread_list) {
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif
|
||||
/* First, check to make sure list hasn't mutated since we searched */
|
||||
if (*p == jsj_env) {
|
||||
*p = jsj_env->next;
|
||||
thread_list = jsj_env;
|
||||
}
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif
|
||||
}
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJavaThreadState *)
|
||||
JS_EXPORT_API(JSJavaThreadState *)
|
||||
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *name, JNIEnv **java_envp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
@ -636,13 +707,13 @@ jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp)
|
|||
|
||||
/* First, figure out which Java VM is calling us */
|
||||
java_vm = JSJ_callbacks->get_java_vm(jEnv);
|
||||
if (jsjava_vm == NULL)
|
||||
if (java_vm == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Get our private JavaVM data */
|
||||
jsjava_vm = map_java_vm_to_jsjava_vm(java_vm);
|
||||
if (!jsjava_vm) {
|
||||
*errp = PR_smprintf("Total weirdness: No JSJavaVM wrapper ever created "
|
||||
*errp = JS_smprintf("Total weirdness: No JSJavaVM wrapper ever created "
|
||||
"for JavaVM 0x%08x", java_vm);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -663,7 +734,7 @@ jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp)
|
|||
* before Java is invoked on that thread.) The return value is the previous
|
||||
* context associated with the given Java thread.
|
||||
*/
|
||||
PR_IMPLEMENT(JSContext *)
|
||||
JS_EXPORT_API(JSContext *)
|
||||
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env)
|
||||
{
|
||||
JSContext *old_context;
|
||||
|
@ -672,7 +743,7 @@ JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env)
|
|||
return old_context;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JS_EXPORT_API(JSBool)
|
||||
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
|
||||
{
|
||||
SystemJavaVM *java_vm;
|
||||
|
@ -688,7 +759,10 @@ JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
|
|||
/* Destroy the LiveConnect execution environment passed in */
|
||||
jsj_ClearPendingJSErrors(jsj_env);
|
||||
|
||||
/* THREADSAFETY - need to protect against races */
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(thread_list_monitor);
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
|
||||
if (e == jsj_env) {
|
||||
*p = jsj_env->next;
|
||||
|
@ -696,10 +770,16 @@ JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(thread_list_monitor);
|
||||
#endif JSJ_THREADSAFE
|
||||
|
||||
free(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Utility routine to wrap a Java object inside a JS object, having a
|
||||
a result type of either JavaObject or JavaArray. */
|
||||
JSBool
|
||||
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp)
|
||||
{
|
||||
|
@ -744,12 +824,12 @@ default_map_jsj_thread_to_js_context(JSJavaThreadState *jsj_env, JNIEnv *jEnv, c
|
|||
|
||||
/* Trivial implementation of callback function */
|
||||
static JSObject *
|
||||
default_map_java_object_to_js_object(JNIEnv *jEnv, jobject hint, char **errp)
|
||||
default_map_java_object_to_js_object(JNIEnv *jEnv, void *hint, char **errp)
|
||||
{
|
||||
return the_global_js_obj;
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
static JSBool JS_DLL_CALLBACK
|
||||
default_create_java_vm(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs)
|
||||
{
|
||||
jint err;
|
||||
|
@ -765,12 +845,12 @@ default_create_java_vm(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs)
|
|||
/* Prepend the classpath argument to the default JVM classpath */
|
||||
if (user_classpath) {
|
||||
#ifdef XP_UNIX
|
||||
const char *full_classpath = PR_smprintf("%s:%s", user_classpath, vm_args.classpath);
|
||||
const char *full_classpath = JS_smprintf("%s:%s", user_classpath, vm_args.classpath);
|
||||
#else
|
||||
const char *full_classpath = PR_smprintf("%s;%s", user_classpath, vm_args.classpath);
|
||||
const char *full_classpath = JS_smprintf("%s;%s", user_classpath, vm_args.classpath);
|
||||
#endif
|
||||
if (!full_classpath) {
|
||||
return PR_FALSE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
vm_args.classpath = (char*)full_classpath;
|
||||
}
|
||||
|
@ -779,7 +859,7 @@ default_create_java_vm(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs)
|
|||
return err == 0;
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
static JSBool JS_DLL_CALLBACK
|
||||
default_destroy_java_vm(SystemJavaVM* jvm, JNIEnv* initialEnv)
|
||||
{
|
||||
JavaVM* java_vm = (JavaVM*)jvm;
|
||||
|
@ -787,16 +867,16 @@ default_destroy_java_vm(SystemJavaVM* jvm, JNIEnv* initialEnv)
|
|||
return err == 0;
|
||||
}
|
||||
|
||||
static JNIEnv* PR_CALLBACK
|
||||
static JNIEnv* JS_DLL_CALLBACK
|
||||
default_attach_current_thread(SystemJavaVM* jvm)
|
||||
{
|
||||
JavaVM* java_vm = (JavaVM*)jvm;
|
||||
JNIEnv* env = NULL;
|
||||
jint err = (*java_vm)->AttachCurrentThread(java_vm, &env, NULL);
|
||||
(*java_vm)->AttachCurrentThread(java_vm, &env, NULL);
|
||||
return env;
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
static JSBool JS_DLL_CALLBACK
|
||||
default_detach_current_thread(SystemJavaVM* jvm, JNIEnv* env)
|
||||
{
|
||||
JavaVM* java_vm = (JavaVM*)jvm;
|
||||
|
@ -805,11 +885,11 @@ default_detach_current_thread(SystemJavaVM* jvm, JNIEnv* env)
|
|||
return err == 0;
|
||||
}
|
||||
|
||||
static SystemJavaVM* PR_CALLBACK
|
||||
static SystemJavaVM* JS_DLL_CALLBACK
|
||||
default_get_java_vm(JNIEnv* env)
|
||||
{
|
||||
JavaVM* java_vm = NULL;
|
||||
jint err = (*env)->GetJavaVM(env, &java_vm);
|
||||
(*env)->GetJavaVM(env, &java_vm);
|
||||
return (SystemJavaVM*)java_vm;
|
||||
}
|
||||
|
||||
|
@ -822,6 +902,7 @@ JSJCallbacks jsj_default_callbacks = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
default_create_java_vm,
|
||||
default_destroy_java_vm,
|
||||
default_attach_current_thread,
|
||||
|
@ -841,13 +922,13 @@ JSJ_SimpleInit(JSContext *cx, JSObject *global_obj, SystemJavaVM *java_vm, const
|
|||
{
|
||||
JNIEnv *jEnv;
|
||||
|
||||
PR_ASSERT(!the_jsj_vm);
|
||||
JSJ_Init(&jsj_default_callbacks);
|
||||
|
||||
JS_ASSERT(!the_jsj_vm);
|
||||
the_jsj_vm = JSJ_ConnectToJavaVM(java_vm, (void*)classpath);
|
||||
if (!the_jsj_vm)
|
||||
return JS_FALSE;
|
||||
|
||||
JSJ_Init(&jsj_default_callbacks);
|
||||
|
||||
if (!JSJ_InitJSContext(cx, global_obj, NULL))
|
||||
goto error;
|
||||
the_cx = cx;
|
||||
|
@ -868,10 +949,10 @@ error:
|
|||
* Free up all LiveConnect resources. Destroy the Java VM if it was
|
||||
* created by LiveConnect.
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
JS_EXPORT_API(void)
|
||||
JSJ_SimpleShutdown()
|
||||
{
|
||||
PR_ASSERT(the_jsj_vm);
|
||||
JS_ASSERT(the_jsj_vm);
|
||||
JSJ_DisconnectFromJavaVM(the_jsj_vm);
|
||||
the_jsj_vm = NULL;
|
||||
the_cx = NULL;
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- Mode: C; tab-width: 8 -*-
|
||||
* Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
Error messages for LiveConnect. See JSJMSG.def for format.
|
||||
|
||||
*/
|
||||
|
||||
MSG_DEF(JSJMSG_NOT_AN_ERROR, 0, 0, "<Error #0 is reserved>")
|
||||
MSG_DEF(JSJMSG_CANT_LOAD_JSOBJECT, 1, 0, "Couldn't convert JavaScript object to an "
|
||||
"instance of netscape.javascript.JSObject "
|
||||
"because that class could not be loaded.")
|
||||
MSG_DEF(JSJMSG_CANT_CONVERT_JS, 2, 2, "Unable to convert JavaScript value {0} to "
|
||||
"Java value of type {1}")
|
||||
MSG_DEF(JSJMSG_BAD_OP_JARRAY, 3, 0, "illegal operation on JavaArray prototype object")
|
||||
MSG_DEF(JSJMSG_CANT_WRITE_JARRAY, 4, 1, "Attempt to write to invalid Java array element \"{0}\"")
|
||||
MSG_DEF(JSJMSG_BAD_INDEX_EXPR, 5, 0, "invalid Java array index expression")
|
||||
MSG_DEF(JSJMSG_BAD_JARRAY_INDEX, 6, 1, "Java array index {0} out of range")
|
||||
MSG_DEF(JSJMSG_JARRAY_PROP_DEFINE, 7, 0, "Cannot define a new property in a JavaArray")
|
||||
MSG_DEF(JSJMSG_JARRAY_PROP_DELETE, 8, 0, "Properties of JavaArray objects may not be deleted")
|
||||
MSG_DEF(JSJMSG_JARRAY_PROP_WATCH, 9, 0, "Cannot place watchpoints on JavaArray object properties")
|
||||
MSG_DEF(JSJMSG_JARRAY_PROP_EXPORT, 10, 0, "Cannot export a JavaArray object's properties")
|
||||
MSG_DEF(JSJMSG_BAD_JCLASS_EXPR, 11, 0, "invalid JavaClass property expression. "
|
||||
"(methods and fields of a JavaClass object can only be identified by their name)")
|
||||
MSG_DEF(JSJMSG_MISSING_NAME, 12, 2, "Java class {0} has no public static field or method named \"{1}\"")
|
||||
MSG_DEF(JSJMSG_MISSING_STATIC, 13, 2, "No static field named \"{0}\" in Java class {1}")
|
||||
MSG_DEF(JSJMSG_JCLASS_PROP_DEFINE, 14, 0, "Cannot define a new property in a JavaClass")
|
||||
MSG_DEF(JSJMSG_JCLASS_PROP_DELETE, 15, 0, "Properties of JavaClass objects may not be deleted")
|
||||
MSG_DEF(JSJMSG_JCLASS_PROP_WATCH, 16, 0, "Cannot place watchpoints on JavaClass object properties")
|
||||
MSG_DEF(JSJMSG_JCLASS_PROP_EXPORT, 17, 0, "Cannot export a JavaClass object's properties")
|
||||
MSG_DEF(JSJMSG_BAD_OP_JCLASS, 18, 0, "illegal operation on JavaClass prototype object")
|
||||
MSG_DEF(JSJMSG_BAD_OP_PROTO, 19, 0, "illegal operation on prototype object")
|
||||
MSG_DEF(JSJMSG_NEED_JOBJECT_ARG, 20, 0, "getClass expects a Java object argument")
|
||||
MSG_DEF(JSJMSG_PROTO_GETCLASS, 21, 0, "getClass called on prototype object")
|
||||
MSG_DEF(JSJMSG_BAD_OP_JOBJECT, 22, 0, "illegal operation on JavaObject prototype object")
|
||||
MSG_DEF(JSJMSG_BAD_JOBJECT_EXPR, 23, 0, "invalid JavaObject property expression. "
|
||||
"(methods and field properties of a JavaObject object can only be strings)")
|
||||
MSG_DEF(JSJMSG_NO_INSTANCE_NAME, 24, 2, "Java class {0} has no public field or method named \"{1}\"")
|
||||
MSG_DEF(JSJMSG_NO_NAME_IN_CLASS, 25, 2, "No instance field named \"{0}\" in Java class {1}")
|
||||
MSG_DEF(JSJMSG_JOBJECT_PROP_DEFINE, 26, 0, "Cannot define a new property in a JavaObject")
|
||||
MSG_DEF(JSJMSG_JOBJECT_PROP_DELETE, 27, 0, "Properties of JavaObject objects may not be deleted")
|
||||
MSG_DEF(JSJMSG_JOBJECT_PROP_WATCH, 28, 0, "Cannot place watchpoints on JavaObject object properties")
|
||||
MSG_DEF(JSJMSG_JOBJECT_PROP_EXPORT, 29, 0, "Cannot export a JavaObject object's properties")
|
||||
MSG_DEF(JSJMSG_CONVERT_TO_FUNC, 30, 0, "can't convert Java object to function")
|
||||
MSG_DEF(JSJMSG_BAD_ADD_TO_PACKAGE, 31, 0, "illegal attempt to add property to JavaPackage prototype object")
|
||||
MSG_DEF(JSJMSG_DONT_ADD_TO_PACKAGE, 32, 0, "You may not add properties to a JavaPackage object")
|
||||
MSG_DEF(JSJMSG_MISSING_PACKAGE, 33, 1, "No Java system package with name \"{0}\" was identified "
|
||||
"and no Java class with that name exists either")
|
||||
MSG_DEF(JSJMSG_DOUBLE_SHIPPING, 34, 1, "Package {0} defined twice ?")
|
||||
MSG_DEF(JSJMSG_BAD_PACKAGE_PREDEF, 35, 1, "Illegal predefined package definition for {0}")
|
||||
MSG_DEF(JSJMSG_NULL_MEMBER_NAME, 36, 0, "illegal null member name")
|
||||
MSG_DEF(JSJMSG_NULL_FUNCTION_NAME, 37, 0, "illegal null JavaScript function name")
|
||||
MSG_DEF(JSJMSG_NULL_EVAL_ARG, 38, 0, "illegal null string eval argument")
|
||||
MSG_DEF(JSJMSG_MULTIPLE_JTHREADS, 39, 0, "Java thread in simultaneous use by more than one JSContext ?")
|
||||
MSG_DEF(JSJMSG_ABSTRACT_JCLASS, 40, 1, "Java class {0} is abstract and therefore may not be instantiated")
|
||||
MSG_DEF(JSJMSG_IS_INTERFACE, 41, 1, "{0} is a Java interface and therefore may not be instantiated")
|
||||
MSG_DEF(JSJMSG_NOT_PUBLIC, 42, 1, "Java class {0} is not public and therefore may not be instantiated")
|
||||
MSG_DEF(JSJMSG_NO_CONSTRUCTORS, 43, 1, "No public constructors defined for Java class {0}")
|
||||
MSG_DEF(JSJMSG_BAD_PROTO_ASSIGNMENT,44, 0, "Only objects can be assigned as the value of the __proto__ property")
|
||||
MSG_DEF(JSJMSG_NEED_JCLASS_ARG, 45, 0, "The JavaClass constructor expects an instance of java.lang.Class as an argument")
|
|
@ -44,7 +44,7 @@ struct CapturedJSError {
|
|||
char * message;
|
||||
JSErrorReport report; /* Line # of error, etc. */
|
||||
jthrowable java_exception; /* Java exception, error, or null */
|
||||
CapturedJSError * next; /* Next oldest captured JS error */
|
||||
CapturedJSError * next; /* Next oldest captured JS error */
|
||||
};
|
||||
|
||||
|
||||
|
@ -61,16 +61,20 @@ struct CapturedJSError {
|
|||
* (of type jobject). When the corresponding Java instance is finalized,
|
||||
* the entry is removed from the table, and a JavaScript GC root for the JS
|
||||
* object is removed.
|
||||
*
|
||||
* This code is disabled because cycles in GC roots between the two systems
|
||||
* cause every reflected JS object to become uncollectable. This can only
|
||||
* be solved by using weak links, a feature not available in JDK1.1.
|
||||
*/
|
||||
static PRHashTable *js_obj_reflections = NULL;
|
||||
static JSHashTable *js_obj_reflections = NULL;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
/*
|
||||
* Used to protect the js_obj_reflections hashtable from simultaneous
|
||||
* read/write or * write/write access.
|
||||
*/
|
||||
static PRMonitor *js_obj_reflections_monitor = NULL;
|
||||
#endif /* JS_THREADSAFE */
|
||||
#endif /* JSJ_THREADSAFE */
|
||||
#endif /* PRESERVE_JSOBJECT_IDENTITY */
|
||||
|
||||
JSBool
|
||||
|
@ -81,18 +85,18 @@ jsj_init_js_obj_reflections_table()
|
|||
{
|
||||
return JS_TRUE;
|
||||
}
|
||||
js_obj_reflections = PR_NewHashTable(128, NULL, PR_CompareValues,
|
||||
PR_CompareValues, NULL, NULL);
|
||||
js_obj_reflections = JS_NewHashTable(128, NULL, JS_CompareValues,
|
||||
JS_CompareValues, NULL, NULL);
|
||||
if (!js_obj_reflections)
|
||||
return JS_FALSE;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
js_obj_reflections_monitor = PR_NewNamedMonitor("js_obj_reflections");
|
||||
if (!js_obj_reflections_monitor) {
|
||||
PR_HashTableDestroy(js_obj_reflections);
|
||||
JS_HashTableDestroy(js_obj_reflections);
|
||||
return JS_FALSE;
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
#endif /* JSJ_THREADSAFE */
|
||||
#endif /* PRESERVE_JSOBJECT_IDENTITY */
|
||||
|
||||
return JS_TRUE;
|
||||
|
@ -113,17 +117,17 @@ jobject
|
|||
jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj)
|
||||
{
|
||||
jobject java_wrapper_obj;
|
||||
PRHashEntry *he, **hep;
|
||||
JSHashEntry *he, **hep;
|
||||
|
||||
java_wrapper_obj = NULL;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(js_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
/* First, look in the hash table for an existing reflection of the same
|
||||
JavaScript object. If one is found, return it. */
|
||||
hep = PR_HashTableRawLookup(js_obj_reflections, (PRHashNumber)js_obj, js_obj);
|
||||
hep = JS_HashTableRawLookup(js_obj_reflections, (JSHashNumber)js_obj, js_obj);
|
||||
|
||||
/* If the same JSObject is reflected into Java more than once then we should
|
||||
return the same Java object, both for efficiency and so that the '=='
|
||||
|
@ -135,21 +139,22 @@ jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj)
|
|||
he = *hep;
|
||||
if (he) {
|
||||
java_wrapper_obj = (jobject)he->value;
|
||||
PR_ASSERT(java_wrapper_obj);
|
||||
JS_ASSERT(java_wrapper_obj);
|
||||
if (java_wrapper_obj)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* No existing reflection found, so create a new Java object that wraps
|
||||
the JavaScript object by storing its address in a private integer field. */
|
||||
#if 0
|
||||
#ifndef OJI
|
||||
java_wrapper_obj =
|
||||
(*jEnv)->NewObject(jEnv, njJSObject, njJSObject_JSObject, (jint)js_obj);
|
||||
#else
|
||||
if (JSJ_callbacks->get_java_wrapper != NULL) {
|
||||
java_wrapper_obj = JSJ_callbacks->get_java_wrapper(jEnv, (jint)js_obj);
|
||||
java_wrapper_obj = JSJ_callbacks->get_java_wrapper(jEnv, (jint)handle);
|
||||
}
|
||||
#endif /*! OJI */
|
||||
|
||||
if (!java_wrapper_obj) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't create new instance of "
|
||||
"netscape.javascript.JSObject");
|
||||
|
@ -157,7 +162,7 @@ jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj)
|
|||
}
|
||||
|
||||
/* Add the new reflection to the hash table. */
|
||||
he = PR_HashTableRawAdd(js_obj_reflections, hep, (PRHashNumber)js_obj,
|
||||
he = JS_HashTableRawAdd(js_obj_reflections, hep, (JSHashNumber)js_obj,
|
||||
js_obj, java_wrapper_obj);
|
||||
if (he) {
|
||||
/* Tell the JavaScript GC about this object since the only reference
|
||||
|
@ -178,7 +183,7 @@ jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj)
|
|||
/* (*jEnv)->DeleteLocalRef(jEnv, java_wrapper_obj); */
|
||||
|
||||
done:
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(js_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
|
@ -193,27 +198,27 @@ done:
|
|||
JSBool
|
||||
jsj_remove_js_obj_reflection_from_hashtable(JSContext *cx, JSObject *js_obj)
|
||||
{
|
||||
PRHashEntry *he, **hep;
|
||||
JSHashEntry *he, **hep;
|
||||
JSBool success = JS_FALSE;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(js_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
/* Get the hash-table entry for this wrapper object */
|
||||
hep = PR_HashTableRawLookup(js_obj_reflections, (PRHashNumber)js_obj, js_obj);
|
||||
hep = JS_HashTableRawLookup(js_obj_reflections, (JSHashNumber)js_obj, js_obj);
|
||||
he = *hep;
|
||||
|
||||
PR_ASSERT(he);
|
||||
JS_ASSERT(he);
|
||||
if (he) {
|
||||
/* Tell the JS GC that Java no longer keeps a reference to this
|
||||
JS object. */
|
||||
success = JS_RemoveRoot(cx, (void *)&he->key);
|
||||
|
||||
PR_HashTableRawRemove(js_obj_reflections, hep, he);
|
||||
JS_HashTableRawRemove(js_obj_reflections, hep, he);
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(js_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
|
@ -241,9 +246,9 @@ jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj)
|
|||
handle->js_obj = js_obj;
|
||||
handle->cx = cx;
|
||||
|
||||
/* No existing reflection found, so create a new Java object that wraps
|
||||
the JavaScript object by storing its address in a private integer field. */
|
||||
#if 0
|
||||
/* Create a new Java object that wraps the JavaScript object by storing its
|
||||
address in a private integer field. */
|
||||
#ifndef OJI
|
||||
java_wrapper_obj =
|
||||
(*jEnv)->NewObject(jEnv, njJSObject, njJSObject_JSObject, (jint)handle);
|
||||
#else
|
||||
|
@ -270,7 +275,7 @@ jsj_UnwrapJSObjectWrapper(JNIEnv *jEnv, jobject java_wrapper_obj)
|
|||
JSObjectHandle *handle;
|
||||
|
||||
handle = (JSObjectHandle*)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal));
|
||||
PR_ASSERT(handle);
|
||||
JS_ASSERT(handle);
|
||||
if (!handle)
|
||||
return NULL;
|
||||
return handle->js_obj;
|
||||
|
@ -315,15 +320,21 @@ destroy_saved_js_error(JNIEnv *jEnv, CapturedJSError *error)
|
|||
* into JavaScript, in which case the error will be re-reported as a JavaScript
|
||||
* error.
|
||||
*/
|
||||
PR_STATIC_CALLBACK(void)
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
capture_js_error_reports_for_java(JSContext *cx, const char *message,
|
||||
JSErrorReport *report)
|
||||
{
|
||||
CapturedJSError *new_error;
|
||||
JSJavaThreadState *jsj_env;
|
||||
jthrowable java_exception;
|
||||
jthrowable java_exception, tmp_exception;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* Warnings are not propagated as Java exceptions - they are simply
|
||||
ignored. Ditto for exceptions that are duplicated in the form
|
||||
of error reports. */
|
||||
if (report && (report->flags & (JSREPORT_WARNING | JSREPORT_EXCEPTION)))
|
||||
return;
|
||||
|
||||
/* Create an empty struct to hold the saved JS error state */
|
||||
new_error = malloc(sizeof(CapturedJSError));
|
||||
if (!new_error)
|
||||
|
@ -363,8 +374,10 @@ capture_js_error_reports_for_java(JSContext *cx, const char *message,
|
|||
java_exception = (*jEnv)->ExceptionOccurred(jEnv);
|
||||
if (java_exception) {
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
tmp_exception = java_exception; /* Make a copy */
|
||||
java_exception = (*jEnv)->NewGlobalRef(jEnv, java_exception);
|
||||
new_error->java_exception = java_exception;
|
||||
(*jEnv)->DeleteLocalRef(jEnv, tmp_exception);
|
||||
}
|
||||
|
||||
/* Push this error onto the list of pending JS errors */
|
||||
|
@ -375,7 +388,7 @@ capture_js_error_reports_for_java(JSContext *cx, const char *message,
|
|||
abort:
|
||||
out_of_memory:
|
||||
/* No recovery action possible */
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
destroy_saved_js_error(jEnv, new_error);
|
||||
return;
|
||||
}
|
||||
|
@ -401,18 +414,61 @@ throw_any_pending_js_error_as_a_java_exception(JSJavaThreadState *jsj_env)
|
|||
jstring message_jstr, linebuf_jstr, filename_jstr;
|
||||
jint index, lineno;
|
||||
JSErrorReport *report;
|
||||
JSContext *cx;
|
||||
jsval pending_exception;
|
||||
jobject java_obj;
|
||||
int dummy_cost;
|
||||
JSBool is_local_refp;
|
||||
JSType primitive_type;
|
||||
jthrowable java_exception;
|
||||
|
||||
message_jstr = linebuf_jstr = filename_jstr = java_exception = NULL;
|
||||
|
||||
/* Get the Java JNI environment */
|
||||
jEnv = jsj_env->jEnv;
|
||||
|
||||
cx = jsj_env->cx;
|
||||
/* Get the pending JS exception if it exists */
|
||||
if (JS_IsExceptionPending(cx)) {
|
||||
if (!JS_GetPendingException(cx, &pending_exception))
|
||||
goto out_of_memory;
|
||||
|
||||
/* Find out the JSTYPE of this jsval. */
|
||||
primitive_type = JS_TypeOfValue(cx, pending_exception);
|
||||
|
||||
/* Convert jsval exception to a java object and then use it to
|
||||
create an instance of JSException. */
|
||||
if (!jsj_ConvertJSValueToJavaObject(cx, jEnv,
|
||||
pending_exception,
|
||||
jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &java_obj,
|
||||
&is_local_refp))
|
||||
goto done;
|
||||
|
||||
java_exception = (*jEnv)->NewObject(jEnv, njJSException,
|
||||
njJSException_JSException_wrap,
|
||||
primitive_type, java_obj);
|
||||
if (is_local_refp)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_obj);
|
||||
if (!java_exception)
|
||||
goto out_of_memory;
|
||||
|
||||
/* Throw the newly-created JSException */
|
||||
if ((*jEnv)->Throw(jEnv, java_exception) < 0) {
|
||||
JS_ASSERT(0);
|
||||
jsj_LogError("Couldn't throw JSException\n");
|
||||
goto done;
|
||||
}
|
||||
JS_ClearPendingException(cx);
|
||||
return;
|
||||
}
|
||||
if (!jsj_env->pending_js_errors) {
|
||||
#ifdef DEBUG
|
||||
/* Any exception should be cleared as soon as it's detected, so there
|
||||
shouldn't be any pending. */
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
/* A Java exception occurred, but nobody in JS-land noticed. */
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
}
|
||||
#endif
|
||||
|
@ -473,29 +529,30 @@ throw_any_pending_js_error_as_a_java_exception(JSJavaThreadState *jsj_env)
|
|||
|
||||
/* Throw the newly-created JSException */
|
||||
if ((*jEnv)->Throw(jEnv, java_exception) < 0) {
|
||||
PR_ASSERT(0);
|
||||
jsj_LogError("Couldn't throw JSException\n");
|
||||
goto done;
|
||||
JS_ASSERT(0);
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't throw JSException\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Release local references to Java objects, since some JVMs seem reticent
|
||||
* about collecting them otherwise.
|
||||
*/
|
||||
(*jEnv)->DeleteLocalRef(jEnv, message_jstr);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, filename_jstr);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, linebuf_jstr);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_exception);
|
||||
|
||||
goto done;
|
||||
|
||||
out_of_memory:
|
||||
/* No recovery possible */
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
jsj_LogError("Out of memory while attempting to throw JSException\n");
|
||||
|
||||
done:
|
||||
jsj_ClearPendingJSErrors(jsj_env);
|
||||
/*
|
||||
* Release local references to Java objects, since some JVMs seem reticent
|
||||
* about collecting them otherwise.
|
||||
*/
|
||||
if (message_jstr)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, message_jstr);
|
||||
if (filename_jstr)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, filename_jstr);
|
||||
if (linebuf_jstr)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, linebuf_jstr);
|
||||
if (java_exception)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_exception);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -518,7 +575,7 @@ jsj_ReportUncaughtJSException(JSContext *cx, JNIEnv *jEnv, jthrowable java_excep
|
|||
/* Initialize everything to NULL */
|
||||
memset(&report, 0, sizeof(JSErrorReport));
|
||||
success = JS_FALSE;
|
||||
filename_jstr = linebuf_jstr = NULL;
|
||||
filename_jstr = linebuf_jstr = message_jstr = NULL;
|
||||
filename = message = linebuf = tokenptr = NULL;
|
||||
|
||||
lineno = (*jEnv)->GetIntField(jEnv, java_exception, njJSException_lineno);
|
||||
|
@ -584,8 +641,8 @@ done:
|
|||
|
||||
JSJavaThreadState *
|
||||
jsj_enter_js(JNIEnv *jEnv, jobject java_wrapper_obj,
|
||||
JSContext **cxp, JSObject **js_objp, JavaToJSSavedState* saved_state,
|
||||
void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext)
|
||||
JSContext **cxp, JSObject **js_objp, JSErrorReporter *old_error_reporterp,
|
||||
void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext)
|
||||
{
|
||||
JSContext *cx;
|
||||
char *err_msg;
|
||||
|
@ -614,7 +671,7 @@ jsj_enter_js(JNIEnv *jEnv, jobject java_wrapper_obj,
|
|||
js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_wrapper_obj);
|
||||
#endif /* PRESERVE_JSOBJECT_IDENTITY */
|
||||
|
||||
PR_ASSERT(js_obj);
|
||||
JS_ASSERT(js_obj);
|
||||
if (!js_obj)
|
||||
goto error;
|
||||
*js_objp = js_obj;
|
||||
|
@ -636,19 +693,21 @@ jsj_enter_js(JNIEnv *jEnv, jobject java_wrapper_obj,
|
|||
if (!cx)
|
||||
goto error;
|
||||
} else {
|
||||
err_msg = PR_smprintf("Unable to find/create JavaScript execution "
|
||||
err_msg = JS_smprintf("Unable to find/create JavaScript execution "
|
||||
"context for JNI thread 0x%08x", jEnv);
|
||||
goto error;
|
||||
}
|
||||
jsj_env->cx = cx;
|
||||
}
|
||||
*cxp = cx;
|
||||
jsj_env->recursion_depth++;
|
||||
|
||||
/*
|
||||
* Capture all JS error reports so that they can be thrown into the Java
|
||||
* caller as an instance of netscape.javascript.JSException.
|
||||
*/
|
||||
saved_state->error_reporter = JS_SetErrorReporter(cx, capture_js_error_reports_for_java);
|
||||
saved_state->java_jsj_env = jsj_SetJavaJSJEnv(jsj_env);
|
||||
*old_error_reporterp =
|
||||
JS_SetErrorReporter(cx, capture_js_error_reports_for_java);
|
||||
|
||||
return jsj_env;
|
||||
|
||||
|
@ -673,20 +732,19 @@ entry_failure:
|
|||
* This utility function is called just prior to returning into Java from JS.
|
||||
*/
|
||||
JSBool
|
||||
jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JavaToJSSavedState* original_state)
|
||||
jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JSErrorReporter original_reporter)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* Restore the JS error reporter */
|
||||
JS_SetErrorReporter(cx, original_state->error_reporter);
|
||||
jsj_SetJavaJSJEnv(original_state->java_jsj_env);
|
||||
JS_SetErrorReporter(cx, original_reporter);
|
||||
|
||||
jEnv = jsj_env->jEnv;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Any Java exceptions should have been noticed and reported already */
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
jsj_LogError("Unhandled Java exception detected");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -703,6 +761,9 @@ jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JavaToJSSavedState* origi
|
|||
if (JSJ_callbacks->exit_js)
|
||||
JSJ_callbacks->exit_js(jEnv);
|
||||
|
||||
jsj_env->recursion_depth--;
|
||||
if (!jsj_env->recursion_depth)
|
||||
jsj_env->cx = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -753,18 +814,19 @@ Java_netscape_javascript_JSObject_getMember(JNIEnv *jEnv,
|
|||
JSBool dummy_bool;
|
||||
const jchar *property_name_ucs2;
|
||||
jsize property_name_len;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
jobject member;
|
||||
jboolean is_copy;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
property_name_ucs2 = NULL;
|
||||
if (!property_name_jstr) {
|
||||
JS_ReportError(cx, "illegal null member name");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NULL_MEMBER_NAME);
|
||||
member = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
@ -772,7 +834,7 @@ Java_netscape_javascript_JSObject_getMember(JNIEnv *jEnv,
|
|||
/* Get the Unicode string for the JS property name */
|
||||
property_name_ucs2 = (*jEnv)->GetStringChars(jEnv, property_name_jstr, &is_copy);
|
||||
if (!property_name_ucs2) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
goto done;
|
||||
}
|
||||
property_name_len = (*jEnv)->GetStringLength(jEnv, property_name_jstr);
|
||||
|
@ -780,13 +842,14 @@ Java_netscape_javascript_JSObject_getMember(JNIEnv *jEnv,
|
|||
if (!JS_GetUCProperty(cx, js_obj, property_name_ucs2, property_name_len, &js_val))
|
||||
goto done;
|
||||
|
||||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val,
|
||||
jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &member, &dummy_bool);
|
||||
|
||||
done:
|
||||
if (property_name_ucs2)
|
||||
(*jEnv)->ReleaseStringChars(jEnv, property_name_jstr, property_name_ucs2);
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_reporter))
|
||||
return NULL;
|
||||
|
||||
return member;
|
||||
|
@ -807,11 +870,11 @@ Java_netscape_javascript_JSObject_getSlot(JNIEnv *jEnv,
|
|||
jsval js_val;
|
||||
int dummy_cost;
|
||||
JSBool dummy_bool;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
jobject member;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
|
@ -823,7 +886,7 @@ Java_netscape_javascript_JSObject_getSlot(JNIEnv *jEnv,
|
|||
goto done;
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_reporter))
|
||||
return NULL;
|
||||
|
||||
return member;
|
||||
|
@ -845,24 +908,25 @@ Java_netscape_javascript_JSObject_setMember(JNIEnv *jEnv,
|
|||
jsval js_val;
|
||||
const jchar *property_name_ucs2;
|
||||
jsize property_name_len;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
jboolean is_copy;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return;
|
||||
|
||||
property_name_ucs2 = NULL;
|
||||
if (!property_name_jstr) {
|
||||
JS_ReportError(cx, "illegal null member name");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NULL_MEMBER_NAME);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Get the Unicode string for the JS property name */
|
||||
property_name_ucs2 = (*jEnv)->GetStringChars(jEnv, property_name_jstr, &is_copy);
|
||||
if (!property_name_ucs2) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
goto done;
|
||||
}
|
||||
property_name_len = (*jEnv)->GetStringLength(jEnv, property_name_jstr);
|
||||
|
@ -875,7 +939,7 @@ Java_netscape_javascript_JSObject_setMember(JNIEnv *jEnv,
|
|||
done:
|
||||
if (property_name_ucs2)
|
||||
(*jEnv)->ReleaseStringChars(jEnv, property_name_jstr, property_name_ucs2);
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
jsj_exit_js(cx, jsj_env, saved_reporter);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -892,10 +956,10 @@ Java_netscape_javascript_JSObject_setSlot(JNIEnv *jEnv,
|
|||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
jsval js_val;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return;
|
||||
|
||||
|
@ -904,7 +968,7 @@ Java_netscape_javascript_JSObject_setSlot(JNIEnv *jEnv,
|
|||
JS_SetElement(cx, js_obj, slot, &js_val);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
jsj_exit_js(cx, jsj_env, saved_reporter);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -922,22 +986,23 @@ Java_netscape_javascript_JSObject_removeMember(JNIEnv *jEnv,
|
|||
jsval js_val;
|
||||
const jchar *property_name_ucs2;
|
||||
jsize property_name_len;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
jboolean is_copy;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return;
|
||||
|
||||
if (!property_name_jstr) {
|
||||
JS_ReportError(cx, "illegal null member name");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NULL_MEMBER_NAME);
|
||||
goto done;
|
||||
}
|
||||
/* Get the Unicode string for the JS property name */
|
||||
property_name_ucs2 = (*jEnv)->GetStringChars(jEnv, property_name_jstr, &is_copy);
|
||||
if (!property_name_ucs2) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
goto done;
|
||||
}
|
||||
property_name_len = (*jEnv)->GetStringLength(jEnv, property_name_jstr);
|
||||
|
@ -947,7 +1012,7 @@ Java_netscape_javascript_JSObject_removeMember(JNIEnv *jEnv,
|
|||
(*jEnv)->ReleaseStringChars(jEnv, property_name_jstr, property_name_ucs2);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
jsj_exit_js(cx, jsj_env, saved_reporter);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -969,32 +1034,31 @@ Java_netscape_javascript_JSObject_call(JNIEnv *jEnv, jobject java_wrapper_obj,
|
|||
JSBool dummy_bool;
|
||||
const jchar *function_name_ucs2;
|
||||
jsize function_name_len;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
jboolean is_copy;
|
||||
jobject result;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
function_name_ucs2 = NULL;
|
||||
result = NULL;
|
||||
if (!function_name_jstr) {
|
||||
JS_ReportError(cx, "illegal null JavaScript function name");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NULL_FUNCTION_NAME);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Get the function name to eval as raw Unicode characters */
|
||||
function_name_ucs2 = (*jEnv)->GetStringChars(jEnv, function_name_jstr, &is_copy);
|
||||
if (!function_name_ucs2) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
goto done;
|
||||
}
|
||||
function_name_len = (*jEnv)->GetStringLength(jEnv, function_name_jstr);
|
||||
|
||||
/* FIXME: What about security stuff ? Don't principals need to be set here ? */
|
||||
|
||||
/* Allocate space for JS arguments */
|
||||
if (java_args) {
|
||||
argc = (*jEnv)->GetArrayLength(jEnv, java_args);
|
||||
|
@ -1033,7 +1097,7 @@ cleanup_argv:
|
|||
done:
|
||||
if (function_name_ucs2)
|
||||
(*jEnv)->ReleaseStringChars(jEnv, function_name_jstr, function_name_ucs2);
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_reporter))
|
||||
return NULL;
|
||||
|
||||
return result;
|
||||
|
@ -1059,26 +1123,27 @@ Java_netscape_javascript_JSObject_eval(JNIEnv *jEnv,
|
|||
JSBool dummy_bool;
|
||||
const jchar *eval_ucs2;
|
||||
jsize eval_len;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
jboolean is_copy;
|
||||
jobject result;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
result = NULL;
|
||||
eval_ucs2 = NULL;
|
||||
if (!eval_jstr) {
|
||||
JS_ReportError(cx, "illegal null string eval argument");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NULL_EVAL_ARG);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Get the string to eval as raw Unicode characters */
|
||||
eval_ucs2 = (*jEnv)->GetStringChars(jEnv, eval_jstr, &is_copy);
|
||||
if (!eval_ucs2) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
goto done;
|
||||
}
|
||||
eval_len = (*jEnv)->GetStringLength(jEnv, eval_jstr);
|
||||
|
@ -1103,7 +1168,7 @@ Java_netscape_javascript_JSObject_eval(JNIEnv *jEnv,
|
|||
done:
|
||||
if (eval_ucs2)
|
||||
(*jEnv)->ReleaseStringChars(jEnv, eval_jstr, eval_ucs2);
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_reporter))
|
||||
return NULL;
|
||||
|
||||
return result;
|
||||
|
@ -1122,10 +1187,10 @@ Java_netscape_javascript_JSObject_toString(JNIEnv *jEnv,
|
|||
JSContext *cx;
|
||||
JSObject *js_obj;
|
||||
JSString *jsstr;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
|
@ -1136,7 +1201,7 @@ Java_netscape_javascript_JSObject_toString(JNIEnv *jEnv,
|
|||
if (!result)
|
||||
result = (*jEnv)->NewStringUTF(jEnv, "*JavaObject*");
|
||||
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_reporter))
|
||||
return NULL;
|
||||
|
||||
return result;
|
||||
|
@ -1158,11 +1223,11 @@ Java_netscape_javascript_JSObject_getWindow(JNIEnv *jEnv,
|
|||
jsval js_val;
|
||||
int dummy_cost;
|
||||
JSBool dummy_bool;
|
||||
JavaToJSSavedState saved_state;
|
||||
JSErrorReporter saved_reporter;
|
||||
jobject java_obj;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state, NULL, 0, NULL);
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_reporter, NULL, 0, NULL);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
|
@ -1180,7 +1245,7 @@ Java_netscape_javascript_JSObject_getWindow(JNIEnv *jEnv,
|
|||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &java_obj, &dummy_bool);
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_reporter))
|
||||
return NULL;
|
||||
|
||||
return java_obj;
|
||||
|
@ -1201,7 +1266,7 @@ Java_netscape_javascript_JSObject_finalize(JNIEnv *jEnv, jobject java_wrapper_ob
|
|||
success = JS_FALSE;
|
||||
|
||||
handle = (JSObjectHandle *)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal));
|
||||
PR_ASSERT(handle);
|
||||
JS_ASSERT(handle);
|
||||
if (!handle)
|
||||
return;
|
||||
cx = handle->cx;
|
||||
|
@ -1209,7 +1274,7 @@ Java_netscape_javascript_JSObject_finalize(JNIEnv *jEnv, jobject java_wrapper_ob
|
|||
success = JS_RemoveRoot(cx, &handle->js_obj);
|
||||
JS_free(cx, handle);
|
||||
|
||||
PR_ASSERT(success);
|
||||
JS_ASSERT(success);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1240,3 +1305,4 @@ Java_netscape_javascript_JSObject_equals(JNIEnv *jEnv,
|
|||
return (js_obj1 == js_obj2);
|
||||
#endif /* PRESERVE_JSOBJECT_IDENTITY */
|
||||
}
|
||||
|
||||
|
|
|
@ -98,13 +98,14 @@ access_java_array_element(JSContext *cx,
|
|||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
JS_ReportError(cx, "illegal operation on JavaArray prototype object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_OP_JARRAY);
|
||||
return JS_FALSE;
|
||||
}
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
java_array = java_wrapper->java_obj;
|
||||
|
||||
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_ARRAY);
|
||||
JS_ASSERT(class_descriptor->type == JAVA_SIGNATURE_ARRAY);
|
||||
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
|
||||
|
@ -127,8 +128,8 @@ access_java_array_element(JSContext *cx,
|
|||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
|
||||
JS_ReportError(cx, "Attempt to write to invalid Java array "
|
||||
"element \"%s\"", member_name);
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_CANT_WRITE_JARRAY, member_name);
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
*vp = JSVAL_VOID;
|
||||
|
@ -149,7 +150,8 @@ access_java_array_element(JSContext *cx,
|
|||
}
|
||||
}
|
||||
|
||||
JS_ReportError(cx, "invalid Java array index expression");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_INDEX_EXPR);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -162,7 +164,10 @@ access_java_array_element(JSContext *cx,
|
|||
|
||||
/* Just let Java throw an exception instead of checking array bounds here */
|
||||
if (index < 0 || index >= array_length) {
|
||||
JS_ReportError(cx, "Java array index %d out of range", index);
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%d", index);
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_JARRAY_INDEX, numBuf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
@ -181,7 +186,7 @@ access_java_array_element(JSContext *cx,
|
|||
}
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
JavaArray_getPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
@ -191,7 +196,7 @@ JavaArray_getPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
return access_java_array_element(cx, jEnv, obj, id, vp, JS_FALSE);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
JavaArray_setPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
@ -210,11 +215,16 @@ JavaArray_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
JSBool result;
|
||||
JSErrorReporter old_reporter;
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
return access_java_array_element(cx, jEnv, obj, id, NULL, JS_FALSE);
|
||||
old_reporter = JS_SetErrorReporter(cx, NULL);
|
||||
result = access_java_array_element(cx, jEnv, obj, id, NULL, JS_FALSE);
|
||||
JS_SetErrorReporter(cx, old_reporter);
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -222,7 +232,8 @@ JavaArray_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
|||
JSPropertyOp getter, JSPropertyOp setter,
|
||||
uintN attrs, JSProperty **propp)
|
||||
{
|
||||
JS_ReportError(cx, "Cannot define a new property in a JavaArray");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JARRAY_PROP_DEFINE);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -241,7 +252,7 @@ JavaArray_setAttributes(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -257,7 +268,8 @@ JavaArray_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
*vp = JSVAL_FALSE;
|
||||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
JS_ReportError(cx, "Properties of JavaArray objects may not be deleted");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JARRAY_PROP_DELETE);
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
/* Attempts to delete permanent properties are silently ignored
|
||||
|
@ -323,7 +335,7 @@ JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -334,11 +346,13 @@ JavaArray_checkAccess(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
switch (mode) {
|
||||
case JSACC_WATCH:
|
||||
JS_ReportError(cx, "Cannot place watchpoints on JavaArray object properties");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JARRAY_PROP_WATCH);
|
||||
return JS_FALSE;
|
||||
|
||||
case JSACC_IMPORT:
|
||||
JS_ReportError(cx, "Cannot export a JavaArray object's properties");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JARRAY_PROP_EXPORT);
|
||||
return JS_FALSE;
|
||||
|
||||
default:
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
#include "jscntxt.h" /* for error reporting */
|
||||
|
||||
static JSBool
|
||||
JavaClass_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
|
@ -57,7 +58,7 @@ JavaClass_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
/* Convert '/' to '.' so that it looks like Java language syntax. */
|
||||
if (!class_descriptor->name)
|
||||
break;
|
||||
name = PR_smprintf("[JavaClass %s]", class_descriptor->name);
|
||||
name = JS_smprintf("[JavaClass %s]", class_descriptor->name);
|
||||
if (!name) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
|
@ -104,12 +105,21 @@ lookup_static_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
|
|||
if (!member_descriptor) {
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
if (!JSVAL_IS_STRING(idval)) {
|
||||
JS_ReportError(cx, "invalid JavaClass property expression. "
|
||||
"(methods and fields of a JavaClass object can only be identified by their name)");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_JCLASS_EXPR);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
|
||||
/*
|
||||
* See if the property looks like the explicit resolution of an
|
||||
* overloaded method, e.g. "max(double,double)".
|
||||
*/
|
||||
member_descriptor =
|
||||
jsj_ResolveExplicitMethod(cx, jEnv, class_descriptor, id, JS_TRUE);
|
||||
if (member_descriptor)
|
||||
goto done;
|
||||
|
||||
/* Why do we have to do this ? */
|
||||
if (!strcmp(member_name, "prototype")) {
|
||||
|
@ -117,16 +127,19 @@ lookup_static_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_ReportError(cx, "Java class %s has no public static field or method named \"%s\"",
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_MISSING_NAME,
|
||||
class_descriptor->name, member_name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
done:
|
||||
if (memberp)
|
||||
*memberp = member_descriptor;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jsval idval;
|
||||
|
@ -156,14 +169,24 @@ JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
if (!member_descriptor->methods) {
|
||||
return jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, vp);
|
||||
} else {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
}
|
||||
} else {
|
||||
JSFunction *function;
|
||||
|
||||
/* TODO - eliminate JSFUN_BOUND_METHOD */
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
if (member_descriptor->methods->is_alias) {
|
||||
/* If this is an explicit resolution of an overloaded method,
|
||||
use the fully-qualified method name as the name of the
|
||||
resulting JS function, i.e. "myMethod(int,long)" */
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
} else {
|
||||
/* Either not explicit resolution of overloaded method or
|
||||
explicit resolution was unnecessary because method was
|
||||
not overloaded. */
|
||||
member_name = member_descriptor->name;
|
||||
}
|
||||
function = JS_NewFunction(cx, jsj_JavaStaticMethodWrapper, 0,
|
||||
JSFUN_BOUND_METHOD, obj, member_name);
|
||||
if (!function)
|
||||
|
@ -174,7 +197,7 @@ JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jclass java_class;
|
||||
|
@ -209,7 +232,8 @@ JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
no_such_field:
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
JS_ReportError(cx, "No static field named \"%s\" in Java class %s",
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_MISSING_STATIC,
|
||||
member_name, class_descriptor->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -217,7 +241,7 @@ no_such_field:
|
|||
/*
|
||||
* Free the private native data associated with the JavaPackage object.
|
||||
*/
|
||||
PR_STATIC_CALLBACK(void)
|
||||
JS_STATIC_DLL_CALLBACK(void)
|
||||
JavaClass_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
@ -272,7 +296,16 @@ JavaClass_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
|||
JSPropertyOp getter, JSPropertyOp setter,
|
||||
uintN attrs, JSProperty **propp)
|
||||
{
|
||||
JS_ReportError(cx, "Cannot define a new property in a JavaClass");
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
|
||||
/* Check for prototype JavaClass object */
|
||||
if (!class_descriptor)
|
||||
return JS_TRUE;
|
||||
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JCLASS_PROP_DEFINE);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -291,7 +324,7 @@ JavaClass_setAttributes(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -307,7 +340,8 @@ JavaClass_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
*vp = JSVAL_FALSE;
|
||||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
JS_ReportError(cx, "Properties of JavaClass objects may not be deleted");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JCLASS_PROP_DELETE);
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
/* Attempts to delete permanent properties are silently ignored
|
||||
|
@ -356,6 +390,17 @@ JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
case JSENUMERATE_NEXT:
|
||||
member_descriptor = JSVAL_TO_PRIVATE(*statep);
|
||||
if (member_descriptor) {
|
||||
|
||||
/* Don't enumerate explicit-signature methods, i.e. enumerate toValue,
|
||||
but not toValue(int), toValue(double), etc. */
|
||||
while (member_descriptor->methods && member_descriptor->methods->is_alias) {
|
||||
member_descriptor = member_descriptor->next;
|
||||
if (!member_descriptor) {
|
||||
*statep = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
*idp = member_descriptor->id;
|
||||
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
|
||||
return JS_TRUE;
|
||||
|
@ -367,7 +412,7 @@ JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -378,11 +423,13 @@ JavaClass_checkAccess(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
switch (mode) {
|
||||
case JSACC_WATCH:
|
||||
JS_ReportError(cx, "Cannot place watchpoints on JavaClass object properties");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JCLASS_PROP_WATCH);
|
||||
return JS_FALSE;
|
||||
|
||||
case JSACC_IMPORT:
|
||||
JS_ReportError(cx, "Cannot export a JavaClass object's properties");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JCLASS_PROP_EXPORT);
|
||||
return JS_FALSE;
|
||||
|
||||
default:
|
||||
|
@ -410,7 +457,8 @@ JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval,
|
|||
has_instance = JS_FALSE;
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
if (!class_descriptor) {
|
||||
JS_ReportError(cx, "illegal operation on JavaClass prototype object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_OP_JCLASS);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -432,7 +480,8 @@ JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval,
|
|||
java_class = class_descriptor->java_class;
|
||||
java_wrapper = JS_GetPrivate(cx, candidate_obj);
|
||||
if (!java_wrapper) {
|
||||
JS_ReportError(cx, "illegal operation on prototype object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_OP_PROTO);
|
||||
return JS_FALSE;
|
||||
}
|
||||
java_obj = java_wrapper->java_obj;
|
||||
|
@ -479,7 +528,7 @@ JSClass JavaClass_class = {
|
|||
"JavaClass", JSCLASS_HAS_PRIVATE,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JavaClass_convert, JavaClass_finalize,
|
||||
JavaClass_getObjectOps,
|
||||
JavaClass_getObjectOps
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
|
@ -550,13 +599,15 @@ getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
!(obj_arg = JSVAL_TO_OBJECT(argv[0])) ||
|
||||
(!JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) &&
|
||||
!JS_InstanceOf(cx, obj_arg, &JavaArray_class, 0))) {
|
||||
JS_ReportError(cx, "getClass expects a Java object argument");
|
||||
return JS_FALSE;
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NEED_JOBJECT_ARG);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj_arg);
|
||||
if (!java_wrapper) {
|
||||
JS_ReportError(cx, "getClass called on prototype object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_PROTO_GETCLASS);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -569,6 +620,43 @@ getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSObject *obj_arg, *JavaClass_obj;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (argc != 1 ||
|
||||
!JSVAL_IS_OBJECT(argv[0]) ||
|
||||
!(obj_arg = JSVAL_TO_OBJECT(argv[0])) ||
|
||||
!JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) ||
|
||||
((java_wrapper = JS_GetPrivate(cx, obj_arg)) == NULL)) {
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NEED_JCLASS_ARG);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
if (!(*jEnv)->IsSameObject(jEnv, class_descriptor->java_class, jlClass)) {
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NEED_JCLASS_ARG);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_wrapper->java_obj);
|
||||
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor);
|
||||
if (!JavaClass_obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(JavaClass_obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
extern JS_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
JSBool
|
||||
|
@ -578,7 +666,7 @@ jsj_init_JavaClass(JSContext *cx, JSObject *global_obj)
|
|||
JavaClass_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
|
||||
|
||||
/* Define JavaClass class */
|
||||
if (!JS_InitClass(cx, global_obj, 0, &JavaClass_class, 0, 0, 0, 0, 0, 0))
|
||||
if (!JS_InitClass(cx, global_obj, 0, &JavaClass_class, JavaClass_construct, 0, 0, 0, 0, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JS_DefineFunction(cx, global_obj, "getClass", getClass, 0,
|
||||
|
|
|
@ -64,13 +64,14 @@ JavaMember_finalize(JSContext *cx, JSObject *obj)
|
|||
JavaMethodOrFieldValue *member_val;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
member_val = JS_GetPrivate(cx, obj);
|
||||
if (!member_val)
|
||||
return;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
member_val = JS_GetPrivate(cx, obj);
|
||||
if (!member_val)
|
||||
return;
|
||||
JS_RemoveRoot(cx, &member_val->method_val);
|
||||
if (JSVAL_IS_GCTHING(member_val->method_val))
|
||||
JS_RemoveRoot(cx, &member_val->method_val);
|
||||
|
@ -107,20 +108,33 @@ JavaMember_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function exists only to make JavaMember's Call'able. The way the JS
|
||||
* engine is written now, it's never actually called because when a JavaMember
|
||||
* is invoked, it's converted to a JS function via JavaMember_convert().
|
||||
*/
|
||||
JSBool
|
||||
JavaMember_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JS_ASSERT(0);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSClass JavaMember_class = {
|
||||
"JavaMember", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JavaMember_convert, JavaMember_finalize
|
||||
JavaMember_convert, JavaMember_finalize,
|
||||
NULL, /* getObjectOps */
|
||||
NULL, /* checkAccess */
|
||||
JavaMember_Call
|
||||
};
|
||||
|
||||
extern JS_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
JSBool
|
||||
jsj_init_JavaMember(JSContext *cx, JSObject *global_obj)
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
#include "jsj_hash.h" /* Hash table with Java object as key */
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
#include "prmon.h"
|
||||
#endif
|
||||
|
||||
|
@ -52,24 +52,26 @@
|
|||
*/
|
||||
static JSJHashTable *java_obj_reflections = NULL;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
static PRMonitor *java_obj_reflections_monitor = NULL;
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
init_java_obj_reflections_table()
|
||||
JSBool
|
||||
jsj_InitJavaObjReflectionsTable(void)
|
||||
{
|
||||
JS_ASSERT(!java_obj_reflections);
|
||||
|
||||
java_obj_reflections =
|
||||
JSJ_NewHashTable(512, jsj_HashJavaObject, jsj_JavaObjectComparator,
|
||||
NULL, NULL, NULL);
|
||||
if (!java_obj_reflections)
|
||||
return JS_FALSE;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
java_obj_reflections_monitor =
|
||||
(struct PRMonitor *) PR_NewNamedMonitor("java_obj_reflections");
|
||||
if (!java_obj_reflections_monitor) {
|
||||
PR_HashTableDestroy((struct PRHashTable *) java_obj_reflections);
|
||||
JS_HashTableDestroy(java_obj_reflections);
|
||||
return JS_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
@ -94,7 +96,7 @@ jsj_WrapJavaObject(JSContext *cx,
|
|||
|
||||
hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
|
@ -114,7 +116,7 @@ jsj_WrapJavaObject(JSContext *cx,
|
|||
if (class_descriptor->type == JAVA_SIGNATURE_ARRAY) {
|
||||
js_class = &JavaArray_class;
|
||||
} else {
|
||||
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS);
|
||||
JS_ASSERT(IS_OBJECT_TYPE(class_descriptor->type));
|
||||
js_class = &JavaObject_class;
|
||||
}
|
||||
|
||||
|
@ -147,7 +149,7 @@ jsj_WrapJavaObject(JSContext *cx,
|
|||
}
|
||||
|
||||
done:
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
|
@ -168,7 +170,7 @@ remove_java_obj_reflection_from_hashtable(jobject java_obj, JNIEnv *jEnv)
|
|||
|
||||
hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_EnterMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
|
@ -176,11 +178,11 @@ remove_java_obj_reflection_from_hashtable(jobject java_obj, JNIEnv *jEnv)
|
|||
java_obj, (void*)jEnv);
|
||||
he = *hep;
|
||||
|
||||
PR_ASSERT(he);
|
||||
JS_ASSERT(he);
|
||||
if (he)
|
||||
JSJ_HashTableRawRemove(java_obj_reflections, hep, he, (void*)jEnv);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#ifdef JSJ_THREADSAFE
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
}
|
||||
|
@ -192,15 +194,15 @@ JavaObject_finalize(JSContext *cx, JSObject *obj)
|
|||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper)
|
||||
return;
|
||||
java_obj = java_wrapper->java_obj;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
if (java_obj) {
|
||||
remove_java_obj_reflection_from_hashtable(java_obj, jEnv);
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
|
||||
|
@ -210,8 +212,8 @@ JavaObject_finalize(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
/* Trivial helper for jsj_DiscardJavaObjReflections(), below */
|
||||
static PRIntn
|
||||
enumerate_remove_java_obj(JSJHashEntry *he, PRIntn i, void *arg)
|
||||
static JSIntn
|
||||
enumerate_remove_java_obj(JSJHashEntry *he, JSIntn i, void *arg)
|
||||
{
|
||||
JNIEnv *jEnv = (JNIEnv*)arg;
|
||||
jobject java_obj;
|
||||
|
@ -241,7 +243,7 @@ jsj_DiscardJavaObjReflections(JNIEnv *jEnv)
|
|||
}
|
||||
}
|
||||
|
||||
PR_CALLBACK JSBool
|
||||
JS_DLL_CALLBACK JSBool
|
||||
JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
|
@ -261,7 +263,8 @@ JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_OP_JOBJECT);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -274,7 +277,8 @@ JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
return JS_TRUE;
|
||||
|
||||
case JSTYPE_FUNCTION:
|
||||
JS_ReportError(cx, "can't convert Java object to function");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_CONVERT_TO_FUNC);
|
||||
return JS_FALSE;
|
||||
|
||||
case JSTYPE_VOID:
|
||||
|
@ -292,58 +296,147 @@ JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
return jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a property from the prototype object of a native ECMA object, i.e.
|
||||
* return <js_constructor_name>.prototype.<member_name>
|
||||
* This is used to allow Java objects to inherit methods from Array.prototype
|
||||
* and String.prototype.
|
||||
*/
|
||||
static JSBool
|
||||
inherit_props_from_JS_natives(JSContext *cx, const char *js_constructor_name,
|
||||
const char *member_name, jsval *vp)
|
||||
{
|
||||
JSObject *global_obj, *constructor_obj, *prototype_obj;
|
||||
jsval constructor_val, prototype_val;
|
||||
|
||||
global_obj = JS_GetGlobalObject(cx);
|
||||
JS_ASSERT(global_obj);
|
||||
if (!global_obj)
|
||||
return JS_FALSE;
|
||||
|
||||
JS_GetProperty(cx, global_obj, js_constructor_name, &constructor_val);
|
||||
JS_ASSERT(JSVAL_IS_OBJECT(constructor_val));
|
||||
constructor_obj = JSVAL_TO_OBJECT(constructor_val);
|
||||
|
||||
JS_GetProperty(cx, constructor_obj, "prototype", &prototype_val);
|
||||
JS_ASSERT(JSVAL_IS_OBJECT(prototype_val));
|
||||
prototype_obj = JSVAL_TO_OBJECT(prototype_val);
|
||||
|
||||
return JS_GetProperty(cx, prototype_obj, member_name, vp) && *vp != JSVAL_VOID;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
lookup_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
|
||||
JavaObjectWrapper **java_wrapperp,
|
||||
jsid id,
|
||||
JavaMemberDescriptor **member_descriptorp)
|
||||
JavaMemberDescriptor **member_descriptorp,
|
||||
jsval *vp)
|
||||
{
|
||||
jsval idval;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
const char *member_name, *property_name;
|
||||
const char *member_name;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
JSObject *proto_chain;
|
||||
|
||||
member_descriptor = NULL;
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
|
||||
/* Handle accesses to prototype object */
|
||||
if (!java_wrapper) {
|
||||
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
|
||||
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
|
||||
if (!strcmp(property_name, "constructor")) {
|
||||
*java_wrapperp = NULL;
|
||||
*member_descriptorp = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
(member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
|
||||
if (!strcmp(member_name, "constructor"))
|
||||
goto done;
|
||||
}
|
||||
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_OP_JOBJECT);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS ||
|
||||
class_descriptor->type == JAVA_SIGNATURE_ARRAY);
|
||||
|
||||
JS_ASSERT(IS_REFERENCE_TYPE(class_descriptor->type));
|
||||
|
||||
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
|
||||
if (!member_descriptor) {
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
if (!JSVAL_IS_STRING(idval)) {
|
||||
JS_ReportError(cx, "invalid JavaObject property expression. "
|
||||
"(methods and field properties of a JavaObject object can only be strings)");
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (member_descriptor)
|
||||
goto done;
|
||||
|
||||
/* Instances can reference static methods and fields */
|
||||
member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);
|
||||
if (member_descriptor)
|
||||
goto done;
|
||||
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
|
||||
JS_ReportError(cx, "Java class %s has no public instance field or "
|
||||
"method named \"%s\"",
|
||||
class_descriptor->name, member_name);
|
||||
/* Ensure that the property we're searching for is string-valued. */
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
if (!JSVAL_IS_STRING(idval)) {
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_JOBJECT_EXPR);
|
||||
return JS_FALSE;
|
||||
}
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
|
||||
/*
|
||||
* A little LC3 feature magic:
|
||||
* + Instances of java.lang.String "inherit" the standard ECMA string methods
|
||||
* of String.prototype. All of the ECMA string methods convert the Java
|
||||
* string to a JS string before performing the string operation. For example,
|
||||
* s = new java.lang.String("foobar");
|
||||
* return s.slice(2);
|
||||
* + Similarly, instances of Java arrays "inherit" the standard ECMA array
|
||||
* methods of Array.prototype. (Not all of these methods work properly
|
||||
* on JavaArray objects, however, since the 'length' property is read-only.)
|
||||
*/
|
||||
if (vp) {
|
||||
if ((class_descriptor->type == JAVA_SIGNATURE_JAVA_LANG_STRING) &&
|
||||
inherit_props_from_JS_natives(cx, "String", member_name, vp))
|
||||
goto done;
|
||||
if ((class_descriptor->type == JAVA_SIGNATURE_ARRAY) &&
|
||||
inherit_props_from_JS_natives(cx, "Array", member_name, vp))
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check for access to magic prototype chain property */
|
||||
if (!strcmp(member_name, "__proto__")) {
|
||||
proto_chain = JS_GetPrototype(cx, obj);
|
||||
if (vp)
|
||||
*vp = OBJECT_TO_JSVAL(proto_chain);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the property looks like the explicit resolution of an
|
||||
* overloaded method, e.g. "max(double,double)", first as an instance method,
|
||||
* then as a static method. If we find such a method, it will be cached
|
||||
* so future accesses won't run this code.
|
||||
*/
|
||||
member_descriptor = jsj_ResolveExplicitMethod(cx, jEnv, class_descriptor, id, JS_FALSE);
|
||||
if (member_descriptor)
|
||||
goto done;
|
||||
member_descriptor = jsj_ResolveExplicitMethod(cx, jEnv, class_descriptor, id, JS_TRUE);
|
||||
if (member_descriptor)
|
||||
goto done;
|
||||
|
||||
/* Is this lookup on behalf of a GetProperty or a LookupProperty ? */
|
||||
if (vp) {
|
||||
/* If so, follow __proto__ link to search prototype chain */
|
||||
proto_chain = JS_GetPrototype(cx, obj);
|
||||
|
||||
/* TODO: No way to tell if the property doesn't exist in proto_chain
|
||||
or if it exists, but has an undefined value. We assume the former. */
|
||||
if (proto_chain && JS_LookupProperty(cx, proto_chain, member_name, vp) &&
|
||||
(*vp != JSVAL_VOID))
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Report lack of Java member with the given property name */
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_NO_INSTANCE_NAME,
|
||||
class_descriptor->name, member_name);
|
||||
return JS_FALSE;
|
||||
|
||||
done:
|
||||
/* Success. Handle the multiple return values */
|
||||
if (java_wrapperp)
|
||||
*java_wrapperp = java_wrapper;
|
||||
|
@ -352,7 +445,7 @@ lookup_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_CALLBACK JSBool
|
||||
JS_DLL_CALLBACK JSBool
|
||||
JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jobject java_obj;
|
||||
|
@ -370,15 +463,15 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor))
|
||||
if (vp)
|
||||
*vp = JSVAL_VOID;
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor, vp))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Handle access to "constructor" property of prototype object with
|
||||
silent failure. */
|
||||
if (!member_descriptor) {
|
||||
*vp = JSVAL_VOID;
|
||||
/* Handle access to special, non-Java properties of JavaObjects, e.g. the
|
||||
"constructor" property of the prototype object */
|
||||
if (!member_descriptor)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
java_obj = java_wrapper->java_obj;
|
||||
field_val = method_val = JSVAL_VOID;
|
||||
|
@ -433,7 +526,7 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jobject java_obj;
|
||||
|
@ -451,10 +544,27 @@ JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor))
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Check for the case where there is a method with the give name, but no field
|
||||
/* Could be assignment to magic JS __proto__ property rather than a Java field */
|
||||
if (!member_descriptor) {
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
if (!JSVAL_IS_STRING(idval))
|
||||
goto no_such_field;
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
if (strcmp(member_name, "__proto__"))
|
||||
goto no_such_field;
|
||||
if (!JSVAL_IS_OBJECT(*vp)) {
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_PROTO_ASSIGNMENT);
|
||||
return JS_FALSE;
|
||||
}
|
||||
JS_SetPrototype(cx, obj, JSVAL_TO_OBJECT(*vp));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Check for the case where there is a method with the given name, but no field
|
||||
with that name */
|
||||
if (!member_descriptor->field)
|
||||
goto no_such_field;
|
||||
|
@ -470,7 +580,8 @@ no_such_field:
|
|||
JS_IdToValue(cx, id, &idval);
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
JS_ReportError(cx, "No instance field named \"%s\" in Java class %s",
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_NO_NAME_IN_CLASS,
|
||||
member_name, class_descriptor->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -485,6 +596,7 @@ JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
JNIEnv *jEnv;
|
||||
JSErrorReporter old_reporter;
|
||||
jsval dummy_val;
|
||||
|
||||
/* printf("In JavaObject_lookupProperty()\n"); */
|
||||
|
||||
|
@ -494,7 +606,11 @@ JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
return JS_FALSE;
|
||||
|
||||
old_reporter = JS_SetErrorReporter(cx, NULL);
|
||||
if (lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL)) {
|
||||
if (lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL, &dummy_val)) {
|
||||
/* TODO - objp may not be set correctly if a property is found, not in
|
||||
obj, but somewhere in obj's proto chain. However, there is
|
||||
no exported JS API to discover which object a property is defined
|
||||
in. */
|
||||
*objp = obj;
|
||||
*propp = (JSProperty*)1;
|
||||
} else {
|
||||
|
@ -511,7 +627,8 @@ JavaObject_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
|||
JSPropertyOp getter, JSPropertyOp setter,
|
||||
uintN attrs, JSProperty **propp)
|
||||
{
|
||||
JS_ReportError(cx, "Cannot define a new property in a JavaObject");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JOBJECT_PROP_DEFINE);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -530,7 +647,7 @@ JavaObject_setAttributes(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -546,7 +663,8 @@ JavaObject_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
*vp = JSVAL_FALSE;
|
||||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
JS_ReportError(cx, "Properties of JavaObject objects may not be deleted");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JOBJECT_PROP_DELETE);
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
/* Attempts to delete permanent properties are silently ignored
|
||||
|
@ -599,6 +717,17 @@ JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
case JSENUMERATE_NEXT:
|
||||
member_descriptor = JSVAL_TO_PRIVATE(*statep);
|
||||
if (member_descriptor) {
|
||||
|
||||
/* Don't enumerate explicit-signature methods, i.e. enumerate toValue,
|
||||
but not toValue(int), toValue(double), etc. */
|
||||
while (member_descriptor->methods && member_descriptor->methods->is_alias) {
|
||||
member_descriptor = member_descriptor->next;
|
||||
if (!member_descriptor) {
|
||||
*statep = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
*idp = member_descriptor->id;
|
||||
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
|
||||
return JS_TRUE;
|
||||
|
@ -611,7 +740,7 @@ JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -622,11 +751,13 @@ JavaObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
|
|||
{
|
||||
switch (mode) {
|
||||
case JSACC_WATCH:
|
||||
JS_ReportError(cx, "Cannot place watchpoints on JavaObject object properties");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JOBJECT_PROP_WATCH);
|
||||
return JS_FALSE;
|
||||
|
||||
case JSACC_IMPORT:
|
||||
JS_ReportError(cx, "Cannot export a JavaObject object's properties");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_JOBJECT_PROP_EXPORT);
|
||||
return JS_FALSE;
|
||||
|
||||
default:
|
||||
|
@ -686,5 +817,5 @@ jsj_init_JavaObject(JSContext *cx, JSObject *global_obj)
|
|||
0, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
return init_java_obj_reflections_table();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -95,11 +95,12 @@ JavaPackage_setProperty(JSContext *cx, JSObject *obj, jsval slot, jsval *vp)
|
|||
{
|
||||
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
|
||||
if (!package) {
|
||||
JS_ReportError(cx, "illegal attempt to add property to "
|
||||
"JavaPackage prototype object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_ADD_TO_PACKAGE);
|
||||
return JS_FALSE;
|
||||
}
|
||||
JS_ReportError(cx, "You may not add properties to a JavaPackage object");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_DONT_ADD_TO_PACKAGE);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -118,6 +119,10 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
const char *path;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* Painful hack for pre_define_java_packages() */
|
||||
if (quiet_resolve_failure)
|
||||
return JS_FALSE;
|
||||
|
||||
package = (JavaPackage_Private *)JS_GetPrivate(cx, obj);
|
||||
if (!package)
|
||||
return JS_TRUE;
|
||||
|
@ -137,7 +142,7 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
return JS_FALSE;
|
||||
|
||||
path = package->path;
|
||||
newPath = PR_smprintf("%s%s%s", path, (path[0] ? "/" : ""), subPath);
|
||||
newPath = JS_smprintf("%s%s%s", path, (path[0] ? "/" : ""), subPath);
|
||||
if (!newPath) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
|
@ -176,6 +181,7 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
JSObject *newClass;
|
||||
|
||||
newClass = jsj_define_JavaClass(cx, jEnv, obj, subPath, jclazz);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, jclazz);
|
||||
if (!newClass) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
@ -187,13 +193,6 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
the exception type and make sure that it's NoClassDefFoundError */
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
|
||||
/* beard: this has to be done here, so built-in classes will be defined. */
|
||||
/* Painful hack for pre_define_java_packages() */
|
||||
if (quiet_resolve_failure) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's no class of the given name, then we must be referring to
|
||||
* a package. However, don't allow bogus sub-packages of pre-defined
|
||||
|
@ -205,10 +204,7 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
package = JS_GetPrivate(cx, obj);
|
||||
if (package->flags & PKG_SYSTEM) {
|
||||
char *msg, *cp;
|
||||
|
||||
msg = PR_smprintf("No Java system package with name \"%s\" was identified "
|
||||
"and no Java class with that name exists either",
|
||||
newPath);
|
||||
msg = JS_strdup(cx, newPath);
|
||||
|
||||
/* Check for OOM */
|
||||
if (msg) {
|
||||
|
@ -216,7 +212,8 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
|||
for (cp = msg; *cp != '\0'; cp++)
|
||||
if (*cp == '/')
|
||||
*cp = '.';
|
||||
JS_ReportError(cx, msg);
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_MISSING_PACKAGE, msg);
|
||||
free((char*)msg);
|
||||
}
|
||||
|
||||
|
@ -262,7 +259,7 @@ JavaPackage_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
/* Convert '/' to '.' so that it looks like Java language syntax. */
|
||||
if (!package->path)
|
||||
break;
|
||||
name = PR_smprintf("[JavaPackage %s]", package->path);
|
||||
name = JS_smprintf("[JavaPackage %s]", package->path);
|
||||
if (!name) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
|
@ -401,7 +398,8 @@ pre_define_java_packages(JSContext *cx, JSObject *global_obj,
|
|||
jsval v;
|
||||
|
||||
if (!simple_name) {
|
||||
JS_ReportError(cx, "Package %s defined twice ?", package_name);
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_DOUBLE_SHIPPING, package_name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -417,7 +415,8 @@ pre_define_java_packages(JSContext *cx, JSObject *global_obj,
|
|||
/* New package objects should only be created at the terminal
|
||||
sub-package in a fully-qualified package-name */
|
||||
if (strtok(NULL, ".")) {
|
||||
JS_ReportError(cx, "Illegal predefined package definition for %s",
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_BAD_PACKAGE_PREDEF,
|
||||
package_def->name);
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize in
|
|||
{
|
||||
jvalue java_value;
|
||||
JavaSignatureChar component_type;
|
||||
JSBool success;
|
||||
|
||||
#define GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \
|
||||
(*jEnv)->Get##Type##ArrayRegion(jEnv, java_array, index, 1, \
|
||||
|
@ -83,18 +84,22 @@ jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize in
|
|||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
/* Non-primitive (reference) type */
|
||||
default:
|
||||
JS_ASSERT(component_type >= JAVA_SIGNATURE_ARRAY);
|
||||
java_value.l = (*jEnv)->GetObjectArrayElement(jEnv, java_array, index);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jsj_ReportJavaError(cx, jEnv, "Error reading Java object array");
|
||||
return JS_FALSE;
|
||||
}
|
||||
break;
|
||||
success = jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value.l, vp);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
|
||||
return success;
|
||||
|
||||
#undef GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
case JAVA_SIGNATURE_UNKNOWN:
|
||||
case JAVA_SIGNATURE_VOID:
|
||||
JS_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -158,8 +163,9 @@ jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize in
|
|||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
/* Non-primitive (reference) type */
|
||||
default:
|
||||
JS_ASSERT(IS_REFERENCE_TYPE(component_type));
|
||||
(*jEnv)->SetObjectArrayElement(jEnv, java_array, index, java_value.l);
|
||||
if (is_local_ref) \
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
|
||||
|
@ -170,8 +176,9 @@ jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize in
|
|||
break;
|
||||
|
||||
#undef SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
case JAVA_SIGNATURE_UNKNOWN:
|
||||
case JAVA_SIGNATURE_VOID:
|
||||
JS_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,15 +54,13 @@ jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class)
|
|||
java_class_name_jstr =
|
||||
(*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getName);
|
||||
|
||||
|
||||
if (!java_class_name_jstr)
|
||||
goto error;
|
||||
|
||||
/* Convert to UTF8 encoding and copy */
|
||||
java_class_name = jsj_DupJavaStringUTF(cx, jEnv, java_class_name_jstr);
|
||||
if (!java_class_name)
|
||||
return NULL;
|
||||
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_class_name_jstr);
|
||||
return java_class_name;
|
||||
|
||||
error:
|
||||
|
@ -99,7 +97,7 @@ get_signature_type(JSContext *cx, JavaClassDescriptor *class_descriptor)
|
|||
|
||||
/* Get UTF8 encoding of class name */
|
||||
java_class_name = class_descriptor->name;
|
||||
PR_ASSERT(java_class_name);
|
||||
JS_ASSERT(java_class_name);
|
||||
if (!java_class_name)
|
||||
return JAVA_SIGNATURE_UNKNOWN;
|
||||
|
||||
|
@ -121,10 +119,20 @@ get_signature_type(JSContext *cx, JavaClassDescriptor *class_descriptor)
|
|||
type = JAVA_SIGNATURE_BOOLEAN;
|
||||
else if (!strcmp(java_class_name, "void"))
|
||||
type = JAVA_SIGNATURE_VOID;
|
||||
else if (!strcmp(java_class_name, "java.lang.Boolean"))
|
||||
type = JAVA_SIGNATURE_JAVA_LANG_BOOLEAN;
|
||||
else if (!strcmp(java_class_name, "java.lang.Double"))
|
||||
type = JAVA_SIGNATURE_JAVA_LANG_DOUBLE;
|
||||
else if (!strcmp(java_class_name, "java.lang.String"))
|
||||
type = JAVA_SIGNATURE_JAVA_LANG_STRING;
|
||||
else if (!strcmp(java_class_name, "java.lang.Object"))
|
||||
type = JAVA_SIGNATURE_JAVA_LANG_OBJECT;
|
||||
else if (!strcmp(java_class_name, "java.lang.Class"))
|
||||
type = JAVA_SIGNATURE_JAVA_LANG_CLASS;
|
||||
else if (!strcmp(java_class_name, "netscape.javascript.JSObject"))
|
||||
type = JAVA_SIGNATURE_NETSCAPE_JAVASCRIPT_JSOBJECT;
|
||||
else
|
||||
/* Well, I guess it's a Java class, then. */
|
||||
type = JAVA_SIGNATURE_CLASS;
|
||||
|
||||
type = JAVA_SIGNATURE_OBJECT;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -175,14 +183,26 @@ compute_java_class_signature(JSContext *cx, JNIEnv *jEnv, JavaSignature *signatu
|
|||
|
||||
signature->array_component_signature =
|
||||
jsj_GetJavaClassDescriptor(cx, jEnv, component_class);
|
||||
if (!signature->array_component_signature)
|
||||
if (!signature->array_component_signature) {
|
||||
(*jEnv)->DeleteLocalRef(jEnv, component_class);
|
||||
return JS_FALSE;
|
||||
}
|
||||
} else {
|
||||
signature->type = get_signature_type(cx, signature);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from JavaSignatureChar enumeration to single-character
|
||||
* signature used by the JDK and JNI methods.
|
||||
*/
|
||||
static char
|
||||
get_jdk_signature_char(JavaSignatureChar type)
|
||||
{
|
||||
return "XVZCBSIJFD[LLLLLL"[(int)type];
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a JavaSignature object into a string format as used by
|
||||
* the JNI functions, e.g. java.lang.Object ==> "Ljava/lang/Object;"
|
||||
|
@ -195,9 +215,9 @@ jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature)
|
|||
{
|
||||
char *sig;
|
||||
|
||||
if (signature->type == JAVA_SIGNATURE_CLASS) {
|
||||
if (IS_OBJECT_TYPE(signature->type)) {
|
||||
/* A non-array object class */
|
||||
sig = PR_smprintf("L%s;", signature->name);
|
||||
sig = JS_smprintf("L%s;", signature->name);
|
||||
if (sig)
|
||||
jsj_MakeJNIClassname(sig);
|
||||
|
||||
|
@ -209,12 +229,12 @@ jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature)
|
|||
jsj_ConvertJavaSignatureToString(cx, signature->array_component_signature);
|
||||
if (!component_signature_string)
|
||||
return NULL;
|
||||
sig = PR_smprintf("[%s", component_signature_string);
|
||||
sig = JS_smprintf("[%s", component_signature_string);
|
||||
JS_free(cx, (char*)component_signature_string);
|
||||
|
||||
} else {
|
||||
/* A primitive class */
|
||||
sig = PR_smprintf("%c", (char)signature->type);
|
||||
sig = JS_smprintf("%c", get_jdk_signature_char(signature->type));
|
||||
}
|
||||
|
||||
if (!sig) {
|
||||
|
@ -246,7 +266,7 @@ jsj_ConvertJavaSignatureToHRString(JSContext *cx,
|
|||
jsj_ConvertJavaSignatureToHRString(cx, acs);
|
||||
if (!component_signature_string)
|
||||
return NULL;
|
||||
sig = PR_smprintf("%s[]", component_signature_string);
|
||||
sig = JS_smprintf("%s[]", component_signature_string);
|
||||
JS_free(cx, (char*)component_signature_string);
|
||||
|
||||
} else {
|
||||
|
@ -295,11 +315,8 @@ static void
|
|||
destroy_class_descriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
JS_FREE_IF(cx, (char *)class_descriptor->name);
|
||||
if (class_descriptor->java_class) {
|
||||
JSJ_HashTableRemove(java_class_reflections,
|
||||
class_descriptor->java_class, (void*)jEnv);
|
||||
if (class_descriptor->java_class)
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, class_descriptor->java_class);
|
||||
}
|
||||
|
||||
if (class_descriptor->array_component_signature)
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor->array_component_signature);
|
||||
|
@ -350,18 +367,15 @@ error:
|
|||
}
|
||||
|
||||
/* Trivial helper for jsj_DiscardJavaClassReflections(), below */
|
||||
static PRIntn
|
||||
enumerate_remove_java_class(JSJHashEntry *he, PRIntn i, void *arg)
|
||||
static JSIntn
|
||||
enumerate_remove_java_class(JSJHashEntry *he, JSIntn i, void *arg)
|
||||
{
|
||||
JNIEnv *jEnv = (JNIEnv*)arg;
|
||||
jclass java_class;
|
||||
JSJavaThreadState *jsj_env = (JSJavaThreadState *)arg;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
class_descriptor = (JavaClassDescriptor*)he->value;
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, java_class);
|
||||
class_descriptor->java_class = NULL;
|
||||
destroy_class_descriptor(jsj_env->cx, jsj_env->jEnv, class_descriptor);
|
||||
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
@ -372,10 +386,17 @@ enumerate_remove_java_class(JSJHashEntry *he, PRIntn i, void *arg)
|
|||
void
|
||||
jsj_DiscardJavaClassReflections(JNIEnv *jEnv)
|
||||
{
|
||||
JSJavaThreadState *jsj_env;
|
||||
char *err_msg;
|
||||
|
||||
/* Get the per-thread state corresponding to the current Java thread */
|
||||
jsj_env = jsj_MapJavaThreadToJSJavaThreadState(jEnv, &err_msg);
|
||||
JS_ASSERT(jsj_env);
|
||||
|
||||
if (java_class_reflections) {
|
||||
JSJ_HashTableEnumerateEntries(java_class_reflections,
|
||||
enumerate_remove_java_class,
|
||||
(void*)jEnv);
|
||||
(void*)jsj_env);
|
||||
JSJ_HashTableDestroy(java_class_reflections);
|
||||
java_class_reflections = NULL;
|
||||
}
|
||||
|
@ -391,7 +412,7 @@ jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
|
|||
if (!class_descriptor)
|
||||
return new_class_descriptor(cx, jEnv, java_class);
|
||||
|
||||
PR_ASSERT(class_descriptor->ref_count > 0);
|
||||
JS_ASSERT(class_descriptor->ref_count > 0);
|
||||
class_descriptor->ref_count++;
|
||||
return class_descriptor;
|
||||
}
|
||||
|
@ -399,10 +420,22 @@ jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
|
|||
void
|
||||
jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (!--class_descriptor->ref_count)
|
||||
#if 0
|
||||
/* The ref-counting code doesn't work very well because cycles in the data
|
||||
structures routinely lead to uncollectible JavaClassDescriptor's. Skip it. */
|
||||
JS_ASSERT(class_descriptor->ref_count >= 1);
|
||||
if (!--class_descriptor->ref_count) {
|
||||
JSJ_HashTableRemove(java_class_reflections,
|
||||
class_descriptor->java_class, (void*)jEnv);
|
||||
destroy_class_descriptor(cx, jEnv, class_descriptor);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
static PRMonitor *java_reflect_monitor = NULL;
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
reflect_java_methods_and_fields(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
|
@ -410,16 +443,29 @@ reflect_java_methods_and_fields(JSContext *cx,
|
|||
JSBool reflect_statics_only)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
JSBool success;
|
||||
|
||||
if (reflect_statics_only)
|
||||
success = JS_TRUE; /* optimism */
|
||||
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_EnterMonitor(java_reflect_monitor);
|
||||
#endif
|
||||
|
||||
/* See if we raced with another thread to reflect members of this class */
|
||||
if (reflect_statics_only) {
|
||||
if (class_descriptor->static_members_reflected)
|
||||
goto done;
|
||||
class_descriptor->static_members_reflected = JS_TRUE;
|
||||
else
|
||||
} else {
|
||||
if (class_descriptor->instance_members_reflected)
|
||||
goto done;
|
||||
class_descriptor->instance_members_reflected = JS_TRUE;
|
||||
}
|
||||
|
||||
if (!jsj_ReflectJavaMethods(cx, jEnv, class_descriptor, reflect_statics_only))
|
||||
return JS_FALSE;
|
||||
goto error;
|
||||
if (!jsj_ReflectJavaFields(cx, jEnv, class_descriptor, reflect_statics_only))
|
||||
return JS_FALSE;
|
||||
goto error;
|
||||
|
||||
if (reflect_statics_only) {
|
||||
member_descriptor = class_descriptor->static_members;
|
||||
|
@ -434,7 +480,16 @@ reflect_java_methods_and_fields(JSContext *cx,
|
|||
member_descriptor = member_descriptor->next;
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
|
||||
done:
|
||||
#ifdef JSJ_THREAD_SAFE
|
||||
PR_ExitMonitor(java_reflect_monitor);
|
||||
#endif
|
||||
return success;
|
||||
|
||||
error:
|
||||
success = JS_FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
|
@ -601,5 +656,11 @@ jsj_InitJavaClassReflectionsTable()
|
|||
|
||||
if (!java_class_reflections)
|
||||
return JS_FALSE;
|
||||
|
||||
#ifdef JSJ_THREADSAFE
|
||||
java_reflect_monitor =
|
||||
(struct PRMonitor *) PR_NewNamedMonitor("java_reflect_monitor");
|
||||
#endif
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef OJI
|
||||
#include "prtypes.h" /* Need platform-dependent definition of HAVE_LONG_LONG
|
||||
for non-standard jri_md.h file */
|
||||
#endif
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
|
||||
/* Floating-point double utilities, stolen from jsnum.h */
|
||||
|
@ -55,9 +60,8 @@ convert_js_obj_to_JSObject_wrapper(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj
|
|||
{
|
||||
if (!njJSObject) {
|
||||
if (java_value)
|
||||
JS_ReportError(cx, "Couldn't convert JavaScript object to an "
|
||||
"instance of netscape.javascript.JSObject "
|
||||
"because that class could not be loaded.");
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_CANT_LOAD_JSOBJECT);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -100,8 +104,7 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
JSString *jsstr;
|
||||
jclass target_java_class;
|
||||
|
||||
PR_ASSERT(signature->type == JAVA_SIGNATURE_CLASS ||
|
||||
signature->type == JAVA_SIGNATURE_ARRAY);
|
||||
JS_ASSERT(IS_REFERENCE_TYPE(signature->type));
|
||||
|
||||
/* Initialize to default case, in which no new Java object is
|
||||
synthesized to perform the conversion and, therefore, no JNI local
|
||||
|
@ -137,12 +140,7 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
/* Don't allow wrapped Java objects to be converted to strings */
|
||||
goto conversion_error;
|
||||
#else
|
||||
/* Fall through, to attempt conversion to a Java string */
|
||||
#endif
|
||||
|
||||
} else if (JS_InstanceOf(cx, js_obj, &JavaClass_class, 0)) {
|
||||
/* We're dealing with the reflection of a Java class */
|
||||
|
@ -157,7 +155,7 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
|
||||
/* Check if target type is netscape.javascript.JSObject wrapper class */
|
||||
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) {
|
||||
if (*java_value)
|
||||
if (java_value && *java_value)
|
||||
*is_local_refp = JS_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -177,6 +175,8 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
reference is passed to the original JS object by wrapping it
|
||||
inside an instance of netscape.javascript.JSObject */
|
||||
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) {
|
||||
if (java_value && *java_value)
|
||||
*is_local_refp = JS_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -199,9 +199,7 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
(*cost)++;
|
||||
#endif
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
/* Fall through, to attempt conversion to a java.lang.String ... */
|
||||
|
@ -223,9 +221,7 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
(*cost)++;
|
||||
#endif
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
/* Fall through, to attempt conversion to a java.lang.String ... */
|
||||
|
@ -233,9 +229,6 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
|
||||
/* If no other conversion is possible, see if the target type is java.lang.String */
|
||||
if ((*jEnv)->IsAssignableFrom(jEnv, jlString, target_java_class)) {
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
JSBool is_string = JSVAL_IS_STRING(v);
|
||||
#endif
|
||||
|
||||
/* Convert to JS string, if necessary, and then to a Java Unicode string */
|
||||
jsstr = JS_ValueToString(cx, v);
|
||||
|
@ -248,10 +241,7 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
|
|||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
if (!is_string)
|
||||
(*cost)++;
|
||||
#endif
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -295,12 +285,12 @@ conversion_error:
|
|||
\
|
||||
/* NaN becomes zero when converted to integral value */ \
|
||||
if (JSDOUBLE_IS_NaN(dval)) \
|
||||
member_name = 0; \
|
||||
goto numeric_conversion_error; \
|
||||
\
|
||||
/* Unrepresentably large numbers, including infinities, */ \
|
||||
/* cause an error. */ \
|
||||
else if ((dval > member_type ## _MAX_VALUE) || \
|
||||
(dval < member_type ## _MIN_VALUE)) { \
|
||||
else if ((dval >= member_type ## _MAX_VALUE + 1) || \
|
||||
(dval <= member_type ## _MIN_VALUE - 1)) { \
|
||||
goto numeric_conversion_error; \
|
||||
} else \
|
||||
member_name = (member_type) dval; \
|
||||
|
@ -365,12 +355,12 @@ if (!JSVAL_IS_NUMBER(jsvalue)) { \
|
|||
\
|
||||
/* NaN becomes zero when converted to integral value */ \
|
||||
if (JSDOUBLE_IS_NaN(dval)) \
|
||||
member_name = jsint_to_jlong(0); \
|
||||
goto numeric_conversion_error; \
|
||||
\
|
||||
/* Unrepresentably large numbers, including infinities, */ \
|
||||
/* cause an error. */ \
|
||||
else if ((dval > member_type ## _MAX_VALUE) || \
|
||||
(dval < member_type ## _MIN_VALUE)) { \
|
||||
else if ((dval >= member_type ## _MAX_VALUE + 1) || \
|
||||
(dval <= member_type ## _MIN_VALUE - 1)) { \
|
||||
goto numeric_conversion_error; \
|
||||
} else \
|
||||
member_name = jdouble_to_jlong(dval); \
|
||||
|
@ -404,11 +394,12 @@ if (!JSVAL_IS_NUMBER(jsvalue)) { \
|
|||
* reporter is called with an appropriate message.
|
||||
*/
|
||||
JSBool
|
||||
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v,
|
||||
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v_arg,
|
||||
JavaSignature *signature,
|
||||
int *cost, jvalue *java_value, JSBool *is_local_refp)
|
||||
{
|
||||
JavaSignatureChar type;
|
||||
jsval v;
|
||||
JSBool success = JS_FALSE;
|
||||
|
||||
/* Initialize to default case, in which no new Java object is
|
||||
|
@ -417,11 +408,14 @@ jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v,
|
|||
*is_local_refp = JS_FALSE;
|
||||
|
||||
type = signature->type;
|
||||
v = v_arg;
|
||||
switch (type) {
|
||||
case JAVA_SIGNATURE_BOOLEAN:
|
||||
if (!JSVAL_IS_BOOLEAN(v)) {
|
||||
if (!JS_ConvertValue(cx, v, JSTYPE_BOOLEAN, &v))
|
||||
goto conversion_error;
|
||||
if (JSVAL_IS_VOID(v))
|
||||
goto conversion_error;
|
||||
(*cost)++;
|
||||
}
|
||||
if (java_value)
|
||||
|
@ -484,15 +478,17 @@ jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v,
|
|||
}
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
/* Non-primitive (reference) type */
|
||||
default:
|
||||
JS_ASSERT(IS_REFERENCE_TYPE(type));
|
||||
if (!jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
|
||||
&java_value->l, is_local_refp))
|
||||
goto conversion_error;
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
case JAVA_SIGNATURE_UNKNOWN:
|
||||
case JAVA_SIGNATURE_VOID:
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -510,15 +506,14 @@ conversion_error:
|
|||
JSString *jsstr;
|
||||
|
||||
jsval_string = NULL;
|
||||
jsstr = JS_ValueToString(cx, v);
|
||||
jsstr = JS_ValueToString(cx, v_arg);
|
||||
if (jsstr)
|
||||
jsval_string = JS_GetStringBytes(jsstr);
|
||||
if (!jsval_string)
|
||||
jsval_string = "";
|
||||
|
||||
JS_ReportError(cx, "Unable to convert JavaScript value %s to "
|
||||
"Java value of type %s",
|
||||
jsval_string, signature->name);
|
||||
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
|
||||
JSJMSG_CANT_CONVERT_JS, jsval_string, signature->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
return success;
|
||||
|
@ -578,35 +573,43 @@ jsj_ConvertJavaObjectToJSString(JSContext *cx,
|
|||
JSString *js_str;
|
||||
jstring java_str;
|
||||
jmethodID toString;
|
||||
jclass java_class;
|
||||
|
||||
/* Create a Java string, unless java_obj is already a java.lang.String */
|
||||
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, jlString)) {
|
||||
java_str = java_obj;
|
||||
} else {
|
||||
jclass java_class;
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
toString = (*jEnv)->GetMethodID(jEnv, java_class, "toString",
|
||||
"()Ljava/lang/String;");
|
||||
if (!toString) {
|
||||
/* All Java objects have a toString method */
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "No toString() method for class %s!",
|
||||
class_descriptor->name);
|
||||
/* Extract Unicode from java.lang.String instance and convert to JS string */
|
||||
js_str = jsj_ConvertJavaStringToJSString(cx, jEnv, java_obj);
|
||||
if (!js_str)
|
||||
return JS_FALSE;
|
||||
}
|
||||
java_str = (*jEnv)->CallObjectMethod(jEnv, java_obj, toString);
|
||||
if (!java_str) {
|
||||
jsj_ReportJavaError(cx, jEnv, "toString() method failed");
|
||||
return JS_FALSE;
|
||||
}
|
||||
*vp = STRING_TO_JSVAL(js_str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
toString = (*jEnv)->GetMethodID(jEnv, java_class, "toString",
|
||||
"()Ljava/lang/String;");
|
||||
if (!toString) {
|
||||
/* All Java objects have a toString method */
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "No toString() method for class %s!",
|
||||
class_descriptor->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
java_str = (*jEnv)->CallObjectMethod(jEnv, java_obj, toString);
|
||||
if (!java_str) {
|
||||
jsj_ReportJavaError(cx, jEnv, "toString() method failed");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Extract Unicode from java.lang.String instance and convert to JS string */
|
||||
js_str = jsj_ConvertJavaStringToJSString(cx, jEnv, java_str);
|
||||
if (!js_str)
|
||||
if (!js_str) {
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_str);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*vp = STRING_TO_JSVAL(js_str);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -671,7 +674,7 @@ jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
|
|||
return JS_TRUE;
|
||||
}
|
||||
java_class = class_descriptor->java_class;
|
||||
booleanValue = (*jEnv)->GetMethodID(jEnv, java_obj, "booleanValue", "()Z");
|
||||
booleanValue = (*jEnv)->GetMethodID(jEnv, java_class, "booleanValue", "()Z");
|
||||
|
||||
/* Non-null Java object does not have a booleanValue() method, so
|
||||
it converts to true. */
|
||||
|
@ -720,25 +723,26 @@ jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
|
|||
#else
|
||||
js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_obj);
|
||||
#endif
|
||||
PR_ASSERT(js_obj);
|
||||
JS_ASSERT(js_obj);
|
||||
if (!js_obj)
|
||||
return JS_FALSE;
|
||||
goto error;
|
||||
*vp = OBJECT_TO_JSVAL(js_obj);
|
||||
return JS_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Instances of java.lang.String are wrapped so we can call methods on
|
||||
* them, but they convert to a JS string if used in a string context.
|
||||
*/
|
||||
/* TODO - let's get rid of this annoying "feature" */
|
||||
|
||||
/* otherwise, wrap it inside a JavaObject */
|
||||
js_obj = jsj_WrapJavaObject(cx, jEnv, java_obj, java_class);
|
||||
if (!js_obj)
|
||||
return JS_FALSE;
|
||||
goto error;
|
||||
*vp = OBJECT_TO_JSVAL(js_obj);
|
||||
|
||||
done:
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_class);
|
||||
return JS_TRUE;
|
||||
|
||||
error:
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_class);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -794,13 +798,15 @@ jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv,
|
|||
case JAVA_SIGNATURE_DOUBLE:
|
||||
return JS_NewDoubleValue(cx, java_value->d, vp);
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
case JAVA_SIGNATURE_UNKNOWN:
|
||||
JS_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
|
||||
/* Non-primitive (reference) type */
|
||||
default:
|
||||
JS_ASSERT(IS_REFERENCE_TYPE(signature->type));
|
||||
return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value->l, vp);
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ add_java_field_to_class_descriptor(JSContext *cx,
|
|||
}
|
||||
|
||||
signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, fieldType);
|
||||
if (!signature)
|
||||
goto error;
|
||||
field_spec->signature = signature;
|
||||
|
@ -192,11 +193,11 @@ jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_de
|
|||
|
||||
/* Don't allow access to private or protected Java fields. */
|
||||
if (!(modifiers & ACC_PUBLIC))
|
||||
continue;
|
||||
goto no_reflect;
|
||||
|
||||
/* Reflect all instance fields or all static fields, but not both */
|
||||
if (reflect_only_static_fields != ((modifiers & ACC_STATIC) != 0))
|
||||
continue;
|
||||
goto no_reflect;
|
||||
|
||||
/* Determine the unqualified name of the field */
|
||||
field_name_jstr = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getName);
|
||||
|
@ -212,8 +213,17 @@ jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_de
|
|||
java_field, modifiers);
|
||||
if (!ok)
|
||||
return JS_FALSE;
|
||||
|
||||
(*jEnv)->DeleteLocalRef(jEnv, field_name_jstr);
|
||||
field_name_jstr = NULL;
|
||||
|
||||
no_reflect:
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_field);
|
||||
java_field = NULL;
|
||||
}
|
||||
|
||||
(*jEnv)->DeleteLocalRef(jEnv, joFieldArray);
|
||||
|
||||
/* Success */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -229,7 +239,7 @@ JSBool
|
|||
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
||||
jobject java_obj, jsval *vp)
|
||||
{
|
||||
JSBool is_static_field;
|
||||
JSBool is_static_field, success;
|
||||
jvalue java_value;
|
||||
JavaSignature *signature;
|
||||
JavaSignatureChar field_type;
|
||||
|
@ -238,7 +248,7 @@ jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
|||
is_static_field = field_spec->modifiers & ACC_STATIC;
|
||||
|
||||
#define GET_JAVA_FIELD(Type,member) \
|
||||
PR_BEGIN_MACRO \
|
||||
JS_BEGIN_MACRO \
|
||||
if (is_static_field) \
|
||||
java_value.member = \
|
||||
(*jEnv)->GetStatic##Type##Field(jEnv, java_obj, fieldID); \
|
||||
|
@ -249,7 +259,7 @@ jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
|||
jsj_UnexpectedJavaError(cx, jEnv, "Error reading Java field"); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
JS_END_MACRO
|
||||
|
||||
signature = field_spec->signature;
|
||||
field_type = signature->type;
|
||||
|
@ -285,17 +295,22 @@ jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
|||
case JAVA_SIGNATURE_DOUBLE:
|
||||
GET_JAVA_FIELD(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
GET_JAVA_FIELD(Object,l);
|
||||
break;
|
||||
|
||||
#undef GET_JAVA_FIELD
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
|
||||
case JAVA_SIGNATURE_UNKNOWN:
|
||||
case JAVA_SIGNATURE_VOID:
|
||||
JS_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
|
||||
/* Non-primitive (reference) type */
|
||||
default:
|
||||
JS_ASSERT(IS_REFERENCE_TYPE(field_type));
|
||||
GET_JAVA_FIELD(Object,l);
|
||||
success = jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value.l, vp);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
|
||||
return success;
|
||||
}
|
||||
|
||||
#undef GET_JAVA_FIELD
|
||||
|
||||
return jsj_ConvertJavaValueToJSValue(cx, jEnv, signature, &java_value, vp);
|
||||
}
|
||||
|
@ -314,7 +329,7 @@ jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
|||
is_static_field = field_spec->modifiers & ACC_STATIC;
|
||||
|
||||
#define SET_JAVA_FIELD(Type,member) \
|
||||
PR_BEGIN_MACRO \
|
||||
JS_BEGIN_MACRO \
|
||||
if (is_static_field) { \
|
||||
(*jEnv)->SetStatic##Type##Field(jEnv, java_obj, fieldID, \
|
||||
java_value.member); \
|
||||
|
@ -325,7 +340,7 @@ jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
|||
jsj_UnexpectedJavaError(cx, jEnv, "Error assigning to Java field"); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
JS_END_MACRO
|
||||
|
||||
signature = field_spec->signature;
|
||||
if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, signature, &dummy_cost,
|
||||
|
@ -365,19 +380,22 @@ jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
|||
case JAVA_SIGNATURE_DOUBLE:
|
||||
SET_JAVA_FIELD(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
|
||||
/* Non-primitive (reference) type */
|
||||
default:
|
||||
JS_ASSERT(IS_REFERENCE_TYPE(field_type));
|
||||
SET_JAVA_FIELD(Object,l);
|
||||
if (is_local_ref)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
|
||||
break;
|
||||
|
||||
#undef SET_JAVA_FIELD
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
case JAVA_SIGNATURE_UNKNOWN:
|
||||
case JAVA_SIGNATURE_VOID:
|
||||
JS_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#undef SET_JAVA_FIELD
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "jsj_hash.h"
|
||||
#include "prtypes.h"
|
||||
# include "prlog.h"
|
||||
# include "prbit.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsbit.h"
|
||||
|
||||
|
||||
/* Compute the number of buckets in ht */
|
||||
#define NBUCKETS(ht) (1 << (JSJ_HASH_BITS - (ht)->shift))
|
||||
|
@ -81,7 +82,7 @@ DefaultAllocEntry(void *pool, const void *key)
|
|||
}
|
||||
|
||||
static void
|
||||
DefaultFreeEntry(void *pool, JSJHashEntry *he, PRUintn flag)
|
||||
DefaultFreeEntry(void *pool, JSJHashEntry *he, JSUintn flag)
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
#pragma unused (pool)
|
||||
|
@ -96,19 +97,19 @@ static JSJHashAllocOps defaultHashAllocOps = {
|
|||
DefaultAllocEntry, DefaultFreeEntry
|
||||
};
|
||||
|
||||
PR_IMPLEMENT(JSJHashTable *)
|
||||
JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash,
|
||||
JS_EXPORT_API(JSJHashTable *)
|
||||
JSJ_NewHashTable(JSUint32 n, JSJHashFunction keyHash,
|
||||
JSJHashComparator keyCompare, JSJHashComparator valueCompare,
|
||||
JSJHashAllocOps *allocOps, void *allocPriv)
|
||||
{
|
||||
JSJHashTable *ht;
|
||||
PRUint32 nb;
|
||||
JSUint32 nb;
|
||||
|
||||
if (n <= MINBUCKETS) {
|
||||
n = MINBUCKETSLOG2;
|
||||
} else {
|
||||
n = PR_CeilingLog2(n);
|
||||
if ((PRInt32)n < 0)
|
||||
n = JS_CeilingLog2(n);
|
||||
if ((JSInt32)n < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -142,10 +143,10 @@ JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash,
|
|||
return ht;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
JS_EXPORT_API(void)
|
||||
JSJ_HashTableDestroy(JSJHashTable *ht)
|
||||
{
|
||||
PRUint32 i, n;
|
||||
JSUint32 i, n;
|
||||
JSJHashEntry *he, *next;
|
||||
JSJHashAllocOps *allocOps = ht->allocOps;
|
||||
void *allocPriv = ht->allocPriv;
|
||||
|
@ -172,7 +173,7 @@ JSJ_HashTableDestroy(JSJHashTable *ht)
|
|||
*/
|
||||
#define GOLDEN_RATIO 0x9E3779B9U
|
||||
|
||||
PR_IMPLEMENT(JSJHashEntry **)
|
||||
JS_EXPORT_API(JSJHashEntry **)
|
||||
JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg)
|
||||
{
|
||||
JSJHashEntry *he, **hep, **hep0;
|
||||
|
@ -202,14 +203,14 @@ JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key,
|
|||
return hep;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJHashEntry *)
|
||||
JS_EXPORT_API(JSJHashEntry *)
|
||||
JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep,
|
||||
JSJHashNumber keyHash, const void *key, void *value,
|
||||
void *arg)
|
||||
{
|
||||
PRUint32 i, n;
|
||||
JSUint32 i, n;
|
||||
JSJHashEntry *he, *next, **oldbuckets;
|
||||
PRUint32 nb;
|
||||
JSUint32 nb;
|
||||
|
||||
/* Grow the table if it is overloaded */
|
||||
n = NBUCKETS(ht);
|
||||
|
@ -235,7 +236,7 @@ JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep,
|
|||
for (he = oldbuckets[i]; he; he = next) {
|
||||
next = he->next;
|
||||
hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg);
|
||||
PR_ASSERT(*hep == 0);
|
||||
JS_ASSERT(*hep == 0);
|
||||
he->next = 0;
|
||||
*hep = he;
|
||||
}
|
||||
|
@ -260,7 +261,7 @@ JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep,
|
|||
return he;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJHashEntry *)
|
||||
JS_EXPORT_API(JSJHashEntry *)
|
||||
JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg)
|
||||
{
|
||||
JSJHashNumber keyHash;
|
||||
|
@ -282,12 +283,12 @@ JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg)
|
|||
return JSJ_HashTableRawAdd(ht, hep, keyHash, key, value, arg);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
JS_EXPORT_API(void)
|
||||
JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg)
|
||||
{
|
||||
PRUint32 i, n;
|
||||
JSUint32 i, n;
|
||||
JSJHashEntry *next, **oldbuckets;
|
||||
PRUint32 nb;
|
||||
JSUint32 nb;
|
||||
|
||||
*hep = he->next;
|
||||
(*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
|
||||
|
@ -312,7 +313,7 @@ JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, v
|
|||
for (he = oldbuckets[i]; he; he = next) {
|
||||
next = he->next;
|
||||
hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg);
|
||||
PR_ASSERT(*hep == 0);
|
||||
JS_ASSERT(*hep == 0);
|
||||
he->next = 0;
|
||||
*hep = he;
|
||||
}
|
||||
|
@ -324,7 +325,7 @@ JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, v
|
|||
}
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRBool)
|
||||
JS_EXPORT_API(JSBool)
|
||||
JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg)
|
||||
{
|
||||
JSJHashNumber keyHash;
|
||||
|
@ -333,14 +334,14 @@ JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg)
|
|||
keyHash = (*ht->keyHash)(key, arg);
|
||||
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
|
||||
if ((he = *hep) == 0)
|
||||
return PR_FALSE;
|
||||
return JS_FALSE;
|
||||
|
||||
/* Hit; remove element */
|
||||
JSJ_HashTableRawRemove(ht, hep, he, arg);
|
||||
return PR_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void *)
|
||||
JS_EXPORT_API(void *)
|
||||
JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg)
|
||||
{
|
||||
JSJHashNumber keyHash;
|
||||
|
@ -356,14 +357,14 @@ JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg)
|
|||
|
||||
/*
|
||||
** Iterate over the entries in the hash table calling func for each
|
||||
** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP).
|
||||
** entry found. Stop if "f" says to (return value & JS_ENUMERATE_STOP).
|
||||
** Return a count of the number of elements scanned.
|
||||
*/
|
||||
PR_IMPLEMENT(int)
|
||||
JS_EXPORT_API(int)
|
||||
JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg)
|
||||
{
|
||||
JSJHashEntry *he, **hep;
|
||||
PRUint32 i, nbuckets;
|
||||
JSUint32 i, nbuckets;
|
||||
int rv, n = 0;
|
||||
JSJHashEntry *todo = 0;
|
||||
|
||||
|
@ -400,12 +401,12 @@ out:
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
JS_EXPORT_API(void)
|
||||
JSJ_HashTableDumpMeter(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
|
||||
{
|
||||
double mean, variance;
|
||||
PRUint32 nchains, nbuckets;
|
||||
PRUint32 i, n, maxChain, maxChainLen;
|
||||
JSUint32 nchains, nbuckets;
|
||||
JSUint32 i, n, maxChain, maxChainLen;
|
||||
JSJHashEntry *he;
|
||||
|
||||
variance = 0;
|
||||
|
@ -446,7 +447,7 @@ JSJ_HashTableDumpMeter(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
|
|||
}
|
||||
#endif /* HASHMETER */
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
JS_EXPORT_API(int)
|
||||
JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
|
||||
{
|
||||
int count;
|
||||
|
@ -458,7 +459,7 @@ JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
|
|||
return count;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJHashNumber)
|
||||
JS_EXPORT_API(JSJHashNumber)
|
||||
JSJ_HashString(const void *key)
|
||||
{
|
||||
JSJHashNumber h;
|
||||
|
@ -470,13 +471,13 @@ JSJ_HashString(const void *key)
|
|||
return h;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
JS_EXPORT_API(int)
|
||||
JSJ_CompareStrings(const void *v1, const void *v2)
|
||||
{
|
||||
return strcmp(v1, v2) == 0;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
JS_EXPORT_API(int)
|
||||
JSJ_CompareValues(const void *v1, const void *v2)
|
||||
{
|
||||
return v1 == v2;
|
||||
|
|
|
@ -33,17 +33,17 @@
|
|||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "prtypes.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct JSJHashEntry JSJHashEntry;
|
||||
typedef struct JSJHashTable JSJHashTable;
|
||||
typedef PRUint32 JSJHashNumber;
|
||||
typedef JSUint32 JSJHashNumber;
|
||||
#define JSJ_HASH_BITS 32
|
||||
typedef JSJHashNumber (*JSJHashFunction)(const void *key, void *arg);
|
||||
typedef PRIntn (*JSJHashComparator)(const void *v1, const void *v2, void *arg);
|
||||
typedef PRIntn (*JSJHashEnumerator)(JSJHashEntry *he, PRIntn i, void *arg);
|
||||
typedef JSIntn (*JSJHashComparator)(const void *v1, const void *v2, void *arg);
|
||||
typedef JSIntn (*JSJHashEnumerator)(JSJHashEntry *he, JSIntn i, void *arg);
|
||||
|
||||
/* Flag bits in JSJHashEnumerator's return value */
|
||||
#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */
|
||||
|
@ -55,7 +55,7 @@ typedef struct JSJHashAllocOps {
|
|||
void * (*allocTable)(void *pool, size_t size);
|
||||
void (*freeTable)(void *pool, void *item);
|
||||
JSJHashEntry * (*allocEntry)(void *pool, const void *key);
|
||||
void (*freeEntry)(void *pool, JSJHashEntry *he, PRUintn flag);
|
||||
void (*freeEntry)(void *pool, JSJHashEntry *he, JSUintn flag);
|
||||
} JSJHashAllocOps;
|
||||
|
||||
#define HT_FREE_VALUE 0 /* just free the entry's value */
|
||||
|
@ -70,18 +70,18 @@ struct JSJHashEntry {
|
|||
|
||||
struct JSJHashTable {
|
||||
JSJHashEntry **buckets; /* vector of hash buckets */
|
||||
PRUint32 nentries; /* number of entries in table */
|
||||
PRUint32 shift; /* multiplicative hash shift */
|
||||
JSUint32 nentries; /* number of entries in table */
|
||||
JSUint32 shift; /* multiplicative hash shift */
|
||||
JSJHashFunction keyHash; /* key hash function */
|
||||
JSJHashComparator keyCompare; /* key comparison function */
|
||||
JSJHashComparator valueCompare; /* value comparison function */
|
||||
JSJHashAllocOps *allocOps; /* allocation operations */
|
||||
void *allocPriv; /* allocation private data */
|
||||
#ifdef HASHMETER
|
||||
PRUint32 nlookups; /* total number of lookups */
|
||||
PRUint32 nsteps; /* number of hash chains traversed */
|
||||
PRUint32 ngrows; /* number of table expansions */
|
||||
PRUint32 nshrinks; /* number of table contractions */
|
||||
JSUint32 nlookups; /* total number of lookups */
|
||||
JSUint32 nsteps; /* number of hash chains traversed */
|
||||
JSUint32 ngrows; /* number of table expansions */
|
||||
JSUint32 nshrinks; /* number of table contractions */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -89,53 +89,53 @@ struct JSJHashTable {
|
|||
* Create a new hash table.
|
||||
* If allocOps is null, use default allocator ops built on top of malloc().
|
||||
*/
|
||||
PR_EXTERN(JSJHashTable *)
|
||||
JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash,
|
||||
JS_EXTERN_API(JSJHashTable *)
|
||||
JSJ_NewHashTable(JSUint32 n, JSJHashFunction keyHash,
|
||||
JSJHashComparator keyCompare, JSJHashComparator valueCompare,
|
||||
JSJHashAllocOps *allocOps, void *allocPriv);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JS_EXTERN_API(void)
|
||||
JSJ_HashTableDestroy(JSJHashTable *ht);
|
||||
|
||||
/* Low level access methods */
|
||||
PR_EXTERN(JSJHashEntry **)
|
||||
JS_EXTERN_API(JSJHashEntry **)
|
||||
JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg);
|
||||
|
||||
PR_EXTERN(JSJHashEntry *)
|
||||
JS_EXTERN_API(JSJHashEntry *)
|
||||
JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep, JSJHashNumber keyHash,
|
||||
const void *key, void *value, void *arg);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JS_EXTERN_API(void)
|
||||
JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg);
|
||||
|
||||
/* Higher level access methods */
|
||||
PR_EXTERN(JSJHashEntry *)
|
||||
JS_EXTERN_API(JSJHashEntry *)
|
||||
JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg);
|
||||
|
||||
PR_EXTERN(PRBool)
|
||||
JS_EXTERN_API(JSBool)
|
||||
JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg);
|
||||
|
||||
PR_EXTERN(PRIntn)
|
||||
JS_EXTERN_API(JSIntn)
|
||||
JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg);
|
||||
|
||||
PR_EXTERN(void *)
|
||||
JS_EXTERN_API(void *)
|
||||
JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg);
|
||||
|
||||
PR_EXTERN(PRIntn)
|
||||
JS_EXTERN_API(JSIntn)
|
||||
JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp);
|
||||
|
||||
/* General-purpose C string hash function. */
|
||||
PR_EXTERN(JSJHashNumber)
|
||||
JS_EXTERN_API(JSJHashNumber)
|
||||
JSJ_HashString(const void *key);
|
||||
|
||||
/* Compare strings using strcmp(), return true if equal. */
|
||||
PR_EXTERN(int)
|
||||
JS_EXTERN_API(int)
|
||||
JSJ_CompareStrings(const void *v1, const void *v2);
|
||||
|
||||
/* Stub function just returns v1 == v2 */
|
||||
PR_EXTERN(PRIntn)
|
||||
JS_EXTERN_API(JSIntn)
|
||||
JSJ_CompareValues(const void *v1, const void *v2);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsj_hash_h___ */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -29,11 +29,11 @@
|
|||
#ifndef _JSJAVA_PVT_H
|
||||
#define _JSJAVA_PVT_H
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
# include "prprf.h"
|
||||
# include "prlog.h"
|
||||
# include "plhash.h" /* NSPR hash-tables */
|
||||
# include "jsprf.h"
|
||||
# include "jsutil.h"
|
||||
# include "jshash.h"
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include "macstdlibextras.h" /* for strdup() */
|
||||
|
@ -44,6 +44,20 @@
|
|||
#include "jsapi.h" /* JavaScript engine API */
|
||||
#include "jsjava.h" /* LiveConnect public API */
|
||||
|
||||
/*
|
||||
* OJI provides its own reentrancy-inhibiting monitors in the enter_js()
|
||||
* and exit_js() callbacks, so it does not need redundant thread-safety code.
|
||||
*/
|
||||
#if defined(OJI) && !defined(JSJ_INHIBIT_THREADSAFE)
|
||||
# define JSJ_INHIBIT_THREADSAFE
|
||||
#endif
|
||||
|
||||
/* If JS is thread-safe, so is LiveConnect, unless overridden */
|
||||
#ifndef JSJ_THREADSAFE
|
||||
# if defined(JS_THREADSAFE) && !defined(JSJ_INHIBIT_THREADSAFE)
|
||||
# define JSJ_THREADSAFE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*************************** Type Declarations ******************************/
|
||||
|
||||
|
@ -53,27 +67,48 @@ typedef struct JavaMethodSpec JavaMethodSpec;
|
|||
typedef struct JavaClassDescriptor JavaClassDescriptor;
|
||||
typedef struct JavaClassDescriptor JavaSignature;
|
||||
typedef struct CapturedJSError CapturedJSError;
|
||||
typedef struct JavaMemberVal JavaMemberVal;
|
||||
|
||||
/*
|
||||
* This enum uses the same character encoding used by the JDK to encode
|
||||
* Java type signatures, but the enum is easier to debug/compile with.
|
||||
* This enum uses a method similar to the JDK to specify
|
||||
* Java type signatures, but the classification of Java
|
||||
* object types is more fine-grained.
|
||||
*/
|
||||
typedef enum {
|
||||
JAVA_SIGNATURE_ARRAY = '[',
|
||||
JAVA_SIGNATURE_BYTE = 'B',
|
||||
JAVA_SIGNATURE_CHAR = 'C',
|
||||
JAVA_SIGNATURE_CLASS = 'L',
|
||||
JAVA_SIGNATURE_FLOAT = 'F',
|
||||
JAVA_SIGNATURE_DOUBLE = 'D',
|
||||
JAVA_SIGNATURE_INT = 'I',
|
||||
JAVA_SIGNATURE_LONG = 'J',
|
||||
JAVA_SIGNATURE_SHORT = 'S',
|
||||
JAVA_SIGNATURE_VOID = 'V',
|
||||
JAVA_SIGNATURE_BOOLEAN = 'Z',
|
||||
JAVA_SIGNATURE_UNKNOWN = 0
|
||||
JAVA_SIGNATURE_UNKNOWN,
|
||||
JAVA_SIGNATURE_VOID,
|
||||
|
||||
/* Primitive types */
|
||||
JAVA_SIGNATURE_BOOLEAN,
|
||||
JAVA_SIGNATURE_CHAR,
|
||||
JAVA_SIGNATURE_BYTE,
|
||||
JAVA_SIGNATURE_SHORT,
|
||||
JAVA_SIGNATURE_INT,
|
||||
JAVA_SIGNATURE_LONG,
|
||||
JAVA_SIGNATURE_FLOAT,
|
||||
JAVA_SIGNATURE_DOUBLE,
|
||||
|
||||
/* Reference types */
|
||||
JAVA_SIGNATURE_ARRAY, /* Any array class */
|
||||
JAVA_SIGNATURE_OBJECT, /* non-array object, but not one of the
|
||||
more specific types below */
|
||||
JAVA_SIGNATURE_JAVA_LANG_BOOLEAN, /* java.lang.Boolean */
|
||||
JAVA_SIGNATURE_JAVA_LANG_CLASS, /* java.lang.Class */
|
||||
JAVA_SIGNATURE_JAVA_LANG_DOUBLE, /* java.lang.Double */
|
||||
JAVA_SIGNATURE_NETSCAPE_JAVASCRIPT_JSOBJECT, /* nestcape.javascript.JSObject */
|
||||
JAVA_SIGNATURE_JAVA_LANG_OBJECT, /* java.lang.Object */
|
||||
JAVA_SIGNATURE_JAVA_LANG_STRING, /* java.lang.String */
|
||||
|
||||
JAVA_SIGNATURE_LIMIT
|
||||
} JavaSignatureChar;
|
||||
|
||||
#define IS_REFERENCE_TYPE(sig) ((int)(sig) >= (int)JAVA_SIGNATURE_ARRAY)
|
||||
#define IS_OBJECT_TYPE(sig) ((int)(sig) >= (int)JAVA_SIGNATURE_OBJECT)
|
||||
#define IS_PRIMITIVE_TYPE(sig) \
|
||||
(((int)(sig) >= (int)JAVA_SIGNATURE_BOOLEAN) && !IS_REFERENCE_TYPE(sig)) \
|
||||
|
||||
/* This is used for checking whether an exception is wrapped or not. */
|
||||
#define JSTYPE_EMPTY -1
|
||||
|
||||
/* The signature of a Java method consists of the signatures of all its
|
||||
arguments and its return type signature. */
|
||||
typedef struct JavaMethodSignature {
|
||||
|
@ -97,6 +132,7 @@ struct JavaMethodSpec {
|
|||
JavaMethodSignature signature;
|
||||
const char * name; /* UTF8; TODO - Should support Unicode method names */
|
||||
JavaMethodSpec * next; /* next method in chain of overloaded methods */
|
||||
JSBool is_alias; /* An aliased name for a Java method ? */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -117,7 +153,7 @@ struct JavaMemberDescriptor {
|
|||
|
||||
/* This is the native portion of a reflected Java class */
|
||||
struct JavaClassDescriptor {
|
||||
const char * name; /* Name of class, e.g. "java/lang/Byte" */
|
||||
const char * name; /* Name of class, e.g. "java.lang.Byte" */
|
||||
JavaSignatureChar type; /* class category: primitive type, object, array */
|
||||
jclass java_class; /* Opaque JVM handle to corresponding java.lang.Class */
|
||||
int num_instance_members;
|
||||
|
@ -133,14 +169,6 @@ struct JavaClassDescriptor {
|
|||
JavaSignature * array_component_signature; /* Only non-NULL for array classes */
|
||||
};
|
||||
|
||||
/* This is the native portion of a reflected Java method or field */
|
||||
struct JavaMemberVal {
|
||||
jsval field_val; /* Captured value of Java field */
|
||||
jsval invoke_method_func_val; /* JSFunction wrapper around Java method invoker */
|
||||
JavaMemberDescriptor * descriptor;
|
||||
JavaMemberVal * next;
|
||||
};
|
||||
|
||||
/* This is the native portion of a reflected Java object */
|
||||
typedef struct JavaObjectWrapper {
|
||||
jobject java_obj; /* Opaque JVM ref to Java object */
|
||||
|
@ -176,6 +204,7 @@ struct JSJavaThreadState {
|
|||
JNIEnv * jEnv; /* Per-thread opaque handle to Java VM */
|
||||
CapturedJSError * pending_js_errors; /* JS errors to be thrown as Java exceptions */
|
||||
JSContext * cx; /* current JS context for thread */
|
||||
int recursion_depth;/* # transitions into JS from Java */
|
||||
JSJavaThreadState * next; /* next thread state among all created threads */
|
||||
};
|
||||
|
||||
|
@ -254,7 +283,8 @@ extern jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashC
|
|||
|
||||
extern jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
|
||||
|
||||
extern jmethodID njJSException_JSException; /* netscape.javascipt.JSexception constructor */
|
||||
extern jmethodID njJSException_JSException; /* netscape.javascipt.JSException constructor */
|
||||
extern jmethodID njJSException_JSException_wrap;/*netscape.javascipt.JSException alternate constructor */
|
||||
extern jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
|
||||
extern jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
|
||||
extern jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
|
||||
|
@ -262,7 +292,8 @@ extern jfieldID njJSException_lineno; /* netscape.javascript.JSExceptio
|
|||
extern jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
|
||||
extern jfieldID njJSException_source; /* netscape.javascript.JSException.source */
|
||||
extern jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
|
||||
|
||||
extern jfieldID njJSException_wrappedExceptionType; /* netscape.javascript.JSException.wrappedExceptionType */
|
||||
extern jfieldID njJSException_wrappedException; /* netscape.javascript.JSException.wrappedException */
|
||||
|
||||
/**************** Java <==> JS conversions and Java types *******************/
|
||||
extern JSBool
|
||||
|
@ -322,10 +353,11 @@ jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
|
|||
jobject java_obj, jsval *vp);
|
||||
extern JSJavaThreadState *
|
||||
jsj_enter_js(JNIEnv *jEnv, jobject java_wrapper_obj,
|
||||
JSContext **cxp, JSObject **js_objp, JavaToJSSavedState* saved_state,
|
||||
JSContext **cxp, JSObject **js_objp, JSErrorReporter *old_error_reporterp,
|
||||
void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext);
|
||||
|
||||
extern JSBool
|
||||
jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JavaToJSSavedState* original_state);
|
||||
jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JSErrorReporter old_error_reporterp);
|
||||
|
||||
extern JavaClassDescriptor *
|
||||
jsj_get_jlObject_descriptor(JSContext *cx, JNIEnv *jEnv);
|
||||
|
@ -334,7 +366,7 @@ extern JSBool
|
|||
jsj_remove_js_obj_reflection_from_hashtable(JSContext *cx, JSObject *js_obj);
|
||||
|
||||
extern JSBool
|
||||
jsj_init_js_obj_reflections_table();
|
||||
jsj_init_js_obj_reflections_table(void);
|
||||
|
||||
/************************ Java package reflection **************************/
|
||||
extern JSBool
|
||||
|
@ -400,7 +432,7 @@ jsj_GetClassStaticMembers(JSContext *cx, JNIEnv *jEnv,
|
|||
JavaClassDescriptor *class_descriptor);
|
||||
|
||||
extern JSBool
|
||||
jsj_InitJavaClassReflectionsTable();
|
||||
jsj_InitJavaClassReflectionsTable(void);
|
||||
|
||||
/************************* Java field reflection ***************************/
|
||||
|
||||
|
@ -431,6 +463,12 @@ extern JSBool
|
|||
jsj_ReflectJavaMethods(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
JSBool reflect_only_static_methods);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_ResolveExplicitMethod(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jsid method_name_id,
|
||||
JSBool is_static);
|
||||
extern void
|
||||
jsj_DestroyMethodSpec(JSContext *cx, JNIEnv *jEnv, JavaMethodSpec *method_spec);
|
||||
|
||||
|
@ -449,6 +487,9 @@ jsj_CreateJavaMember(JSContext *cx, jsval method_val, jsval field_val);
|
|||
extern JSBool
|
||||
jsj_init_JavaObject(JSContext *, JSObject *);
|
||||
|
||||
extern JSBool
|
||||
jsj_InitJavaObjReflectionsTable(void);
|
||||
|
||||
extern JSObject *
|
||||
jsj_WrapJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_obj, jclass java_class);
|
||||
|
||||
|
@ -510,10 +551,13 @@ jsj_GetJavaErrorMessage(JNIEnv *env);
|
|||
extern void
|
||||
jsj_LogError(const char *error_msg);
|
||||
|
||||
PR_CALLBACK JSJHashNumber
|
||||
extern const JSErrorFormatString *
|
||||
jsj_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
|
||||
|
||||
JS_DLL_CALLBACK JSJHashNumber
|
||||
jsj_HashJavaObject(const void *key, void* env);
|
||||
|
||||
PR_CALLBACK intN
|
||||
JS_DLL_CALLBACK intN
|
||||
jsj_JavaObjectComparator(const void *v1, const void *v2, void *arg);
|
||||
|
||||
extern JSJavaThreadState *
|
||||
|
@ -537,17 +581,24 @@ jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr);
|
|||
JSJavaThreadState *
|
||||
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp);
|
||||
|
||||
JSJavaThreadState *
|
||||
jsj_SetJavaJSJEnv(JSJavaThreadState* java_jsj_env);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_LOG(args) printf args
|
||||
#endif
|
||||
|
||||
#define JS_FREE_IF(cx, x) \
|
||||
PR_BEGIN_MACRO \
|
||||
JS_BEGIN_MACRO \
|
||||
if (x) \
|
||||
JS_free(cx, x); \
|
||||
PR_END_MACRO
|
||||
JS_END_MACRO
|
||||
|
||||
|
||||
enum JSJErrNum {
|
||||
#define MSG_DEF(name, number, format, count) \
|
||||
name = number,
|
||||
#include "jsj.msg"
|
||||
#undef MSG_DEF
|
||||
JSJ_Err_Limit
|
||||
#undef MSGDEF
|
||||
};
|
||||
|
||||
#endif /* _JSJAVA_PVT_H */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- 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 "License"); you may not use this file except in
|
||||
|
@ -35,18 +35,26 @@
|
|||
* This is a hash-table utility routine that computes the hash code of a Java
|
||||
* object by calling java.lang.System.identityHashCode()
|
||||
*/
|
||||
PR_CALLBACK JSJHashNumber
|
||||
JS_DLL_CALLBACK JSJHashNumber
|
||||
jsj_HashJavaObject(const void *key, void* env)
|
||||
{
|
||||
PRHashNumber hash_code;
|
||||
JSHashNumber hash_code;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
java_obj = (jobject)key;
|
||||
jEnv = (JNIEnv*) env;
|
||||
JS_ASSERT(!(*jEnv)->ExceptionOccurred(jEnv));
|
||||
hash_code = (*jEnv)->CallStaticIntMethod(jEnv, jlSystem,
|
||||
jlSystem_identityHashCode, java_obj);
|
||||
PR_ASSERT(!(*jEnv)->ExceptionOccurred(jEnv));
|
||||
|
||||
#ifdef DEBUG
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
(*jEnv)->ExceptionDescribe(jEnv);
|
||||
JS_ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return hash_code;
|
||||
}
|
||||
|
||||
|
@ -57,7 +65,7 @@ jsj_HashJavaObject(const void *key, void* env)
|
|||
* or handles (though they may be in some JVM implementations). Instead,
|
||||
* use the JNI routine for comparing the two objects.
|
||||
*/
|
||||
PR_CALLBACK intN
|
||||
JS_DLL_CALLBACK intN
|
||||
jsj_JavaObjectComparator(const void *v1, const void *v2, void *arg)
|
||||
{
|
||||
jobject java_obj1, java_obj2;
|
||||
|
@ -120,23 +128,6 @@ JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Not used ?
|
||||
const char *
|
||||
jsj_ClassNameOfJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_object)
|
||||
{
|
||||
jobject java_class;
|
||||
|
||||
java_class = (*jEnv)->GetObjectClass(jEnv, java_object);
|
||||
|
||||
if (!java_class) {
|
||||
PR_ASSERT(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return jsj_GetJavaClassName(cx, jEnv, java_class);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return, as a C string, the error message associated with a Java exception
|
||||
* that occurred as a result of a JNI call, preceded by the class name of
|
||||
|
@ -159,14 +150,22 @@ jsj_GetJavaErrorMessage(JNIEnv *jEnv)
|
|||
if (exception && jlThrowable_toString) {
|
||||
java_exception_jstring =
|
||||
(*jEnv)->CallObjectMethod(jEnv, exception, jlThrowable_toString);
|
||||
if (!java_exception_jstring)
|
||||
goto done;
|
||||
java_error_msg = (*jEnv)->GetStringUTFChars(jEnv, java_exception_jstring, NULL);
|
||||
error_msg = strdup((char*)java_error_msg);
|
||||
(*jEnv)->ReleaseStringUTFChars(jEnv, java_exception_jstring, java_error_msg);
|
||||
if (java_error_msg) {
|
||||
error_msg = strdup((char*)java_error_msg);
|
||||
(*jEnv)->ReleaseStringUTFChars(jEnv, java_exception_jstring, java_error_msg);
|
||||
}
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_exception_jstring);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* (*jEnv)->ExceptionDescribe(jEnv); */
|
||||
#endif
|
||||
}
|
||||
done:
|
||||
if (exception)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, exception);
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
|
@ -193,6 +192,7 @@ get_java_stack_trace(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception)
|
|||
return NULL;
|
||||
}
|
||||
backtrace = jsj_DupJavaStringUTF(cx, jEnv, backtrace_jstr);
|
||||
(*jEnv)->DeleteLocalRef(jEnv, backtrace_jstr);
|
||||
}
|
||||
return backtrace;
|
||||
}
|
||||
|
@ -209,58 +209,111 @@ get_java_stack_trace(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception)
|
|||
static void
|
||||
vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
|
||||
{
|
||||
char *error_msg, *js_error_msg;
|
||||
const char *java_stack_trace;
|
||||
const char *java_error_msg;
|
||||
jobject java_obj;
|
||||
jclass java_class;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
jthrowable java_exception;
|
||||
|
||||
java_error_msg = NULL;
|
||||
JSType wrapped_exception_type;
|
||||
jsval js_exception;
|
||||
|
||||
java_obj = NULL;
|
||||
class_descriptor = NULL;
|
||||
|
||||
/* Get the exception out of the java environment. */
|
||||
java_exception = (*jEnv)->ExceptionOccurred(jEnv);
|
||||
if (java_exception && njJSException &&
|
||||
(*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
|
||||
|
||||
if (java_exception) {
|
||||
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
jsj_ReportUncaughtJSException(cx, jEnv, java_exception);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for JSException */
|
||||
if (njJSException &&
|
||||
(*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
|
||||
|
||||
js_error_msg = PR_vsmprintf(format, ap);
|
||||
wrapped_exception_type =
|
||||
(*jEnv)->GetIntField(jEnv, java_exception,
|
||||
njJSException_wrappedExceptionType);
|
||||
|
||||
if (wrapped_exception_type != JSTYPE_EMPTY) {
|
||||
java_obj =
|
||||
(*jEnv)->GetObjectField(jEnv, java_exception,
|
||||
njJSException_wrappedException);
|
||||
|
||||
if (!js_error_msg) {
|
||||
PR_ASSERT(0); /* Out-of-memory */
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef REPORT_JAVA_EXCEPTION_STACK_TRACE
|
||||
|
||||
java_stack_trace = get_java_stack_trace(cx, jEnv, java_exception);
|
||||
if (java_stack_trace) {
|
||||
error_msg = PR_smprintf("%s\n%s", js_error_msg, java_stack_trace);
|
||||
free((char*)java_stack_trace);
|
||||
if (!error_msg) {
|
||||
PR_ASSERT(0); /* Out-of-memory */
|
||||
return;
|
||||
}
|
||||
} else
|
||||
|
||||
#endif
|
||||
{
|
||||
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
|
||||
if (java_error_msg) {
|
||||
error_msg = PR_smprintf("%s (%s)\n", js_error_msg, java_error_msg);
|
||||
free((char*)java_error_msg);
|
||||
free(js_error_msg);
|
||||
if ((java_obj == NULL) &&
|
||||
(wrapped_exception_type == JSTYPE_OBJECT)) {
|
||||
js_exception = JSVAL_NULL;
|
||||
} else {
|
||||
java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
|
||||
/* OK to delete ref, since above call adds global ref */
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_class);
|
||||
|
||||
/* Convert native JS values back to native types. */
|
||||
switch(wrapped_exception_type) {
|
||||
case JSTYPE_NUMBER:
|
||||
if (!jsj_ConvertJavaObjectToJSNumber(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
break;
|
||||
case JSTYPE_BOOLEAN:
|
||||
if (!jsj_ConvertJavaObjectToJSBoolean(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
break;
|
||||
case JSTYPE_STRING:
|
||||
if (!jsj_ConvertJavaObjectToJSString(cx, jEnv,
|
||||
class_descriptor,
|
||||
java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
break;
|
||||
case JSTYPE_VOID:
|
||||
js_exception = JSVAL_VOID;
|
||||
break;
|
||||
case JSTYPE_OBJECT:
|
||||
case JSTYPE_FUNCTION:
|
||||
default:
|
||||
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
|
||||
js_exception = OBJECT_TO_JSVAL(jsj_UnwrapJSObjectWrapper(jEnv, java_obj));
|
||||
if (!js_exception)
|
||||
goto do_report;
|
||||
} else {
|
||||
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj,
|
||||
&js_exception))
|
||||
goto do_report;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check for internal exception */
|
||||
} else {
|
||||
error_msg = js_error_msg;
|
||||
if (!JSJ_ConvertJavaObjectToJSValue(cx, java_exception,
|
||||
&js_exception)) {
|
||||
goto do_report;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set pending JS exception and clear the java exception. */
|
||||
JS_SetPendingException(cx, js_exception);
|
||||
goto done;
|
||||
}
|
||||
|
||||
do_report:
|
||||
|
||||
JS_ReportError(cx, error_msg);
|
||||
JS_ASSERT(0);
|
||||
jsj_LogError("Out of memory while attempting to throw JSException\n");
|
||||
|
||||
/* Important: the Java exception must not be cleared until the reporter
|
||||
has been called, because the capture_js_error_reports_for_java(),
|
||||
called from JS_ReportError(), needs to read the exception from the JVM */
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
free(error_msg);
|
||||
done:
|
||||
if (class_descriptor)
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
|
||||
if (java_obj)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_obj);
|
||||
if (java_exception)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_exception);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -284,7 +337,7 @@ jsj_UnexpectedJavaError(JSContext *cx, JNIEnv *env, const char *format, ...)
|
|||
const char *format2;
|
||||
|
||||
va_start(ap, format);
|
||||
format2 = PR_smprintf("internal error: %s", format);
|
||||
format2 = JS_smprintf("internal error: %s", format);
|
||||
if (format2) {
|
||||
vreport_java_error(cx, env, format2, ap);
|
||||
free((void*)format2);
|
||||
|
@ -307,12 +360,49 @@ jsj_LogError(const char *error_msg)
|
|||
fputs(error_msg, stderr);
|
||||
}
|
||||
|
||||
/*
|
||||
Error number handling.
|
||||
|
||||
jsj_ErrorFormatString is an array of format strings mapped
|
||||
by error number. It is initialized by the contents of jsj.msg
|
||||
|
||||
jsj_GetErrorMessage is invoked by the engine whenever it wants
|
||||
to convert an error number into an error format string.
|
||||
*/
|
||||
/*
|
||||
this define needs to go somewhere sensible
|
||||
*/
|
||||
#define JSJ_HAS_DFLT_MSG_STRINGS 1
|
||||
|
||||
JSErrorFormatString jsj_ErrorFormatString[JSJ_Err_Limit] = {
|
||||
#if JSJ_HAS_DFLT_MSG_STRINGS
|
||||
#define MSG_DEF(name, number, count, format) \
|
||||
{ format, count } ,
|
||||
#else
|
||||
#define MSG_DEF(name, number, count, format) \
|
||||
{ NULL, count } ,
|
||||
#endif
|
||||
#include "jsj.msg"
|
||||
#undef MSG_DEF
|
||||
};
|
||||
|
||||
const JSErrorFormatString *
|
||||
jsj_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
|
||||
{
|
||||
if ((errorNumber > 0) && (errorNumber < JSJ_Err_Limit))
|
||||
return &jsj_ErrorFormatString[errorNumber];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsize
|
||||
jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array)
|
||||
{
|
||||
jsize array_length = (*jEnv)->GetArrayLength(jEnv, java_array);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jthrowable java_exception = (*jEnv)->ExceptionOccurred(jEnv);
|
||||
if (java_exception) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain array length");
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_exception);
|
||||
return -1;
|
||||
}
|
||||
return array_length;
|
||||
|
@ -331,7 +421,7 @@ jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp)
|
|||
|
||||
jsj_env = the_java_jsj_env;
|
||||
if (jsj_env == NULL)
|
||||
jsj_env = JSJ_callbacks->map_js_context_to_jsj_thread(cx, &err_msg);
|
||||
jsj_env = JSJ_callbacks->map_js_context_to_jsj_thread(cx, &err_msg);
|
||||
if (!jsj_env) {
|
||||
if (err_msg) {
|
||||
JS_ReportError(cx, err_msg);
|
||||
|
@ -339,6 +429,8 @@ jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
/* need to assign the context field. */
|
||||
jsj_env->cx = cx;
|
||||
if (envp)
|
||||
*envp = jsj_env->jEnv;
|
||||
return jsj_env;
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
#ifndef _JSJAVA_H
|
||||
#define _JSJAVA_H
|
||||
|
||||
#ifndef prtypes_h___
|
||||
#include "prtypes.h"
|
||||
#ifndef jstypes_h___
|
||||
#include "jstypes.h"
|
||||
#endif
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
#include "jni.h" /* Java Native Interface */
|
||||
#include "jsapi.h" /* JavaScript engine API */
|
||||
|
@ -51,7 +51,11 @@ typedef struct JSJavaThreadState JSJavaThreadState;
|
|||
* it is a reference to a JVM plugin. A set of callbacks in the JSJCallbacks
|
||||
* struct allow it to be manipulated.
|
||||
*/
|
||||
#ifdef OJI
|
||||
typedef struct SystemJavaVM SystemJavaVM;
|
||||
#else
|
||||
typedef JavaVM SystemJavaVM;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This callback table provides hooks to external functions that implement
|
||||
|
@ -122,10 +126,10 @@ typedef struct JSJCallbacks {
|
|||
jobject (*get_java_wrapper)(JNIEnv *jEnv, jint jsobject);
|
||||
|
||||
/* The following set of methods abstract over the JavaVM object. */
|
||||
PRBool (*create_java_vm)(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs);
|
||||
PRBool (*destroy_java_vm)(SystemJavaVM* jvm, JNIEnv* initialEnv);
|
||||
JSBool (*create_java_vm)(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs);
|
||||
JSBool (*destroy_java_vm)(SystemJavaVM* jvm, JNIEnv* initialEnv);
|
||||
JNIEnv* (*attach_current_thread)(SystemJavaVM* jvm);
|
||||
PRBool (*detach_current_thread)(SystemJavaVM* jvm, JNIEnv* env);
|
||||
JSBool (*detach_current_thread)(SystemJavaVM* jvm, JNIEnv* env);
|
||||
SystemJavaVM* (*get_java_vm)(JNIEnv* env);
|
||||
|
||||
/* Reserved for future use */
|
||||
|
@ -170,13 +174,13 @@ typedef struct JavaPackageDef {
|
|||
as properties of global_obj. If java_vm is NULL, a new Java VM is
|
||||
created, using the provided classpath in addition to any default classpath.
|
||||
The classpath argument is ignored, however, if java_vm is non-NULL. */
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JS_EXPORT_API(JSBool)
|
||||
JSJ_SimpleInit(JSContext *cx, JSObject *global_obj,
|
||||
SystemJavaVM *java_vm, const char *classpath);
|
||||
|
||||
/* Free up all resources. Destroy the Java VM if it was created by LiveConnect */
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_SimpleShutdown();
|
||||
JS_EXPORT_API(void)
|
||||
JSJ_SimpleShutdown(void);
|
||||
|
||||
/*===========================================================================*/
|
||||
|
||||
|
@ -197,7 +201,7 @@ JSJ_SimpleShutdown();
|
|||
*/
|
||||
|
||||
/* Called once for all instances of LiveConnect to set up callbacks */
|
||||
PR_IMPLEMENT(void)
|
||||
JS_EXPORT_API(void)
|
||||
JSJ_Init(JSJCallbacks *callbacks);
|
||||
|
||||
/* Called once per Java VM, this function initializes the classes, fields, and
|
||||
|
@ -205,7 +209,7 @@ JSJ_Init(JSJCallbacks *callbacks);
|
|||
created according to the create_java_vm callback in the JSJCallbacks,
|
||||
using the provided classpath in addition to any default initargs.
|
||||
The initargs argument is ignored, however, if java_vm is non-NULL. */
|
||||
PR_IMPLEMENT(JSJavaVM *)
|
||||
JS_EXPORT_API(JSJavaVM *)
|
||||
JSJ_ConnectToJavaVM(SystemJavaVM *java_vm, void* initargs);
|
||||
|
||||
/* Initialize the provided JSContext by setting up the JS classes necessary for
|
||||
|
@ -215,7 +219,7 @@ JSJ_ConnectToJavaVM(SystemJavaVM *java_vm, void* initargs);
|
|||
initialization time is not necessary, but it will make package lookup faster
|
||||
and, more importantly, will avoid unnecessary network accesses if classes
|
||||
are being loaded over the network.) */
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JS_EXPORT_API(JSBool)
|
||||
JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
|
||||
JavaPackageDef *predefined_packages);
|
||||
|
||||
|
@ -226,12 +230,12 @@ JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
|
|||
used for debugging purposes and can be set to NULL. The Java JNI
|
||||
environment associated with this thread is returned through the java_envp
|
||||
argument if java_envp is non-NULL. */
|
||||
PR_IMPLEMENT(JSJavaThreadState *)
|
||||
JS_EXPORT_API(JSJavaThreadState *)
|
||||
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *thread_name,
|
||||
JNIEnv **java_envp);
|
||||
|
||||
/* Destructor routine for per-thread JSJavaThreadState structure */
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JS_EXPORT_API(JSBool)
|
||||
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env);
|
||||
|
||||
/* This function is used to specify a particular JSContext as *the* JavaScript
|
||||
|
@ -247,21 +251,23 @@ JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env);
|
|||
be invoked to determine the JSContext for the thread. The purpose of the
|
||||
function is to improve performance by avoiding the expense of the callback.
|
||||
*/
|
||||
PR_IMPLEMENT(JSContext *)
|
||||
JS_EXPORT_API(JSContext *)
|
||||
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env);
|
||||
|
||||
/* This routine severs the connection to a Java VM, freeing all related resources.
|
||||
It shouldn't be called until the global scope has been cleared in all related
|
||||
JSContexts (so that all LiveConnect objects are finalized) and a JavaScript
|
||||
GC is performed. Otherwise, accessed to free'ed memory could result. */
|
||||
PR_IMPLEMENT(void)
|
||||
JS_EXPORT_API(void)
|
||||
JSJ_DisconnectFromJavaVM(JSJavaVM *);
|
||||
|
||||
/*
|
||||
* Reflect a Java object into a JS value. The source object, java_obj, must
|
||||
* be of type java.lang.Object or a subclass and may, therefore, be an array.
|
||||
*/
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JS_EXPORT_API(JSBool)
|
||||
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp);
|
||||
PR_END_EXTERN_C
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* _JSJAVA_H */
|
||||
|
|
|
@ -45,7 +45,6 @@ DIRS = classes
|
|||
DLLNAME=jsj$(MOZ_BITS)$(VERSION_NUMBER)
|
||||
PDBFILE=$(DLLNAME).pdb
|
||||
MAPFILE = $(DLLNAME).map
|
||||
RESFILE = jsj1640.res
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
|
@ -124,7 +123,6 @@ JNI_GEN= \
|
|||
MODULE = java
|
||||
EXPORTS = \
|
||||
$(JNI_GEN_DIR)\netscape_javascript_JSObject.h \
|
||||
$(JNI_GEN_DIR)\netscape_javascript_JSException.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ nsCLiveconnect::GetMember(JNIEnv *jEnv, jsobject obj, const jchar *name, jsize l
|
|||
jsval js_val;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
|
@ -131,7 +131,7 @@ nsCLiveconnect::GetMember(JNIEnv *jEnv, jsobject obj, const jchar *name, jsize l
|
|||
&dummy_cost, &member, &dummy_bool);
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*pjobj = member;
|
||||
|
@ -161,7 +161,7 @@ nsCLiveconnect::GetSlot(JNIEnv *jEnv, jsobject obj, jint slot, void* principalsA
|
|||
jsval js_val;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
|
@ -180,7 +180,7 @@ nsCLiveconnect::GetSlot(JNIEnv *jEnv, jsobject obj, jint slot, void* principalsA
|
|||
goto done;
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*pjobj = member;
|
||||
|
@ -206,7 +206,7 @@ nsCLiveconnect::SetMember(JNIEnv *jEnv, jsobject obj, const jchar *name, jsize l
|
|||
JSObjectHandle *handle = (JSObjectHandle*)obj;
|
||||
JSObject *js_obj = handle->js_obj;
|
||||
jsval js_val;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
|
@ -228,7 +228,7 @@ nsCLiveconnect::SetMember(JNIEnv *jEnv, jsobject obj, const jchar *name, jsize l
|
|||
JS_SetUCProperty(cx, js_obj, name, length, &js_val);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
jsj_exit_js(cx, jsj_env, saved_state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ nsCLiveconnect::SetSlot(JNIEnv *jEnv, jsobject obj, jint slot, jobject java_obj,
|
|||
JSObjectHandle *handle = (JSObjectHandle*)obj;
|
||||
JSObject *js_obj = handle->js_obj;
|
||||
jsval js_val;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
|
@ -267,7 +267,7 @@ nsCLiveconnect::SetSlot(JNIEnv *jEnv, jsobject obj, jint slot, jobject java_obj,
|
|||
JS_SetElement(cx, js_obj, slot, &js_val);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
jsj_exit_js(cx, jsj_env, saved_state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -288,7 +288,7 @@ nsCLiveconnect::RemoveMember(JNIEnv *jEnv, jsobject obj, const jchar *name, jsiz
|
|||
JSObjectHandle *handle = (JSObjectHandle*)obj;
|
||||
JSObject *js_obj = handle->js_obj;
|
||||
jsval js_val;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
|
@ -305,7 +305,7 @@ nsCLiveconnect::RemoveMember(JNIEnv *jEnv, jsobject obj, const jchar *name, jsiz
|
|||
JS_DeleteUCProperty2(cx, js_obj, name, length, &js_val);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
jsj_exit_js(cx, jsj_env, saved_state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -335,7 +335,7 @@ nsCLiveconnect::Call(JNIEnv *jEnv, jsobject obj, const jchar *name, jsize length
|
|||
jsval function_val = 0;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
jobject result = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
|
@ -390,7 +390,7 @@ cleanup_argv:
|
|||
}
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*pjobj = result;
|
||||
|
@ -404,11 +404,12 @@ nsCLiveconnect::Eval(JNIEnv *jEnv, jsobject obj, const jchar *script, jsize leng
|
|||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
JSObjectHandle *handle = (JSObjectHandle*)obj;
|
||||
JSObject *js_obj = handle->js_obj;
|
||||
jsval js_val;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
jobject result = NULL;
|
||||
const char *codebase = NULL;
|
||||
JSPrincipals *principals = NULL;
|
||||
|
@ -446,7 +447,7 @@ nsCLiveconnect::Eval(JNIEnv *jEnv, jsobject obj, const jchar *script, jsize leng
|
|||
&dummy_cost, &result, &dummy_bool);
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*pjobj = result;
|
||||
|
@ -471,10 +472,12 @@ nsCLiveconnect::GetWindow(JNIEnv *jEnv, void *pJavaObject, void* principalsArra
|
|||
char *err_msg = NULL;
|
||||
JSContext *cx = NULL;
|
||||
JSObject *js_obj = NULL;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSErrorReporter saved_state = NULL;
|
||||
jobject java_obj = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JSObjectHandle *handle = NULL;
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -493,17 +496,28 @@ nsCLiveconnect::GetWindow(JNIEnv *jEnv, void *pJavaObject, void* principalsArra
|
|||
}
|
||||
goto done;
|
||||
}
|
||||
#if 0
|
||||
js_val = OBJECT_TO_JSVAL(js_obj);
|
||||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &java_obj, &dummy_bool);
|
||||
#endif
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
#ifdef PRESERVE_JSOBJECT_IDENTITY
|
||||
//*pjobj = java_obj;
|
||||
*pobj = (jint)js_obj;
|
||||
#else
|
||||
/* FIXME: to handle PRESERVE_JSOBJECT_IDENTITY case, this needs to
|
||||
just return a raw JSObject reference. FIXME !!! */
|
||||
/* Create a tiny stub object to act as the GC root that points to the
|
||||
JSObject from its netscape.javascript.JSObject counterpart. */
|
||||
handle = (JSObjectHandle*)JS_malloc(cx, sizeof(JSObjectHandle));
|
||||
if (handle != NULL)
|
||||
{
|
||||
handle->js_obj = js_obj;
|
||||
handle->cx = cx;
|
||||
}
|
||||
*pobj = (jsobject)handle;
|
||||
/* FIXME: what if the window is explicitly disposed of, how do we
|
||||
notify Java? */
|
||||
#endif
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -529,6 +543,40 @@ nsCLiveconnect::FinalizeJSObject(JNIEnv *jEnv, jsobject obj)
|
|||
}
|
||||
|
||||
|
||||
NS_METHOD
|
||||
nsCLiveconnect::ToString(JNIEnv *jEnv, jsobject obj, jstring *pjstring)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObjectHandle *handle = (JSObjectHandle*)obj;
|
||||
JSObject *js_obj = handle->js_obj;
|
||||
JSErrorReporter saved_state = NULL;
|
||||
jstring result = NULL;
|
||||
JSString *jsstr = NULL;
|
||||
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state, NULL, 0, NULL );
|
||||
if (!jsj_env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
result = NULL;
|
||||
jsstr = JS_ValueToString(cx, OBJECT_TO_JSVAL(js_obj));
|
||||
if (jsstr)
|
||||
result = jsj_ConvertJSStringToJavaString(cx, jEnv, jsstr);
|
||||
if (!result)
|
||||
result = jEnv->NewStringUTF("*JavaObject*");
|
||||
|
||||
if (!jsj_exit_js(cx, jsj_env, saved_state))
|
||||
return NULL;
|
||||
*pjstring = result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCLiveconnect:
|
||||
|
||||
|
|
|
@ -154,6 +154,15 @@ public:
|
|||
NS_IMETHOD
|
||||
FinalizeJSObject(JNIEnv *jEnv, jsobject obj);
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param jstring - Return value as a jstring representing a JS object.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
ToString(JNIEnv *jEnv, jsobject obj, jstring *pjstring);
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCLiveconnect:
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ nsCLiveconnect *nsCLiveconnectFactory::m_pNSCLiveconnect = NULL;
|
|||
+++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
{
|
||||
|
||||
if (!aClass.Equals(kCLiveconnectCID)) {
|
||||
|
|
|
@ -143,6 +143,15 @@ public:
|
|||
NS_IMETHOD
|
||||
FinalizeJSObject(JNIEnv *jEnv, jsobject jsobj) = 0;
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param jstring - Return value as a jstring representing a JS object.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
ToString(JNIEnv *jEnv, jsobject obj, jstring *pjstring) = 0;
|
||||
};
|
||||
|
||||
#define NS_ILIVECONNECT_IID \
|
||||
|
|
|
@ -85,6 +85,6 @@ public:
|
|||
0x4c41, \
|
||||
0x11d2, \
|
||||
{ 0xa1, 0xcb, 0x0, 0x80, 0x5f, 0x8f, 0x69, 0x4d } \
|
||||
};
|
||||
}
|
||||
|
||||
#endif // nsISecurityContext_h___
|
||||
|
|
|
@ -54,6 +54,8 @@ MISCDEP = \
|
|||
$(DIST)\lib\jsdom.lib \
|
||||
$(DIST)\lib\libplc21.lib \
|
||||
$(DIST)\lib\js3250.lib \
|
||||
$(DIST)\lib\oji.lib \
|
||||
$(DIST)\lib\jsj3250.lib \
|
||||
$(LIBNSPR)
|
||||
|
||||
LCFLAGS = \
|
||||
|
|
|
@ -362,9 +362,9 @@ static ScriptNameSetRegistryHolder gManager;
|
|||
|
||||
// return the proper factory to the caller
|
||||
#if defined(XP_MAC) && defined(MAC_STATIC)
|
||||
extern "C" NS_LAYOUT nsresult NSGetFactory_LAYOUT_DLL(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_LAYOUT nsresult NSGetFactory_LAYOUT_DLL(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory )
|
||||
#else
|
||||
extern "C" NS_LAYOUT nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_LAYOUT nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#endif
|
||||
{
|
||||
if (nsnull == ScriptNameSetRegistryHolder::gRegistry) {
|
||||
|
|
|
@ -583,7 +583,7 @@ nsresult nsPrefFactory::CreateInstance(nsISupports *aDelegate,
|
|||
return res;
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID, nsIFactory **aFactory)
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aCID, nsISupports* serviceMgr, nsIFactory **aFactory)
|
||||
{
|
||||
if (aFactory == NULL) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Makefile to build the MODULES\APPLET tree
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Specify the depth of the current directory relative to the
|
||||
#// root of NS
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DEPTH=..\..
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Specify any "command" targets. (ie. DIRS, INSTALL_FILES, ...)
|
||||
#// (these must come before the common makefiles are included)
|
||||
#//
|
||||
#// DIRS - There are subdirectories to process
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
!if !defined(NGLAYOUT_PLUGINS)
|
||||
DIRS= public src
|
||||
!else
|
||||
DIRS= public
|
||||
!endif
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Include the common makefile rules
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
include <$(DEPTH)\config\rules.mak>
|
|
@ -32,6 +32,8 @@ EXPORTS = \
|
|||
nsIJVMPlugin.h \
|
||||
nsIJVMPluginInstance.h \
|
||||
nsIJVMPluginTagInfo.h \
|
||||
nsIJVMPrefsWindow.h \
|
||||
nsIJVMWindow.h \
|
||||
nsISymantecDebugManager.h \
|
||||
nsISymantecDebugger.h \
|
||||
nsISecureJNI2.h \
|
||||
|
|
|
@ -29,6 +29,8 @@ EXPORTS = \
|
|||
nsIJVMPlugin.h \
|
||||
nsIJVMPluginInstance.h \
|
||||
nsIJVMPluginTagInfo.h \
|
||||
nsIJVMPrefsWindow.h \
|
||||
nsIJVMWindow.h \
|
||||
nsISymantecDebugManager.h \
|
||||
nsISymantecDebugger.h \
|
||||
nsISecureJNI2.h \
|
||||
|
|
|
@ -29,26 +29,15 @@
|
|||
#ifndef nsIJVMConsole_h___
|
||||
#define nsIJVMConsole_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIJVMWindow.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// JVM Console Interface
|
||||
// This interface defines the API the browser needs to show and hide the JVM's
|
||||
// Java console, and to send text to it.
|
||||
|
||||
class nsIJVMConsole : public nsISupports {
|
||||
class nsIJVMConsole : public nsIJVMWindow {
|
||||
public:
|
||||
|
||||
// QueryInterface on nsIJVMPlugin to get this.
|
||||
|
||||
NS_IMETHOD
|
||||
ShowConsole(void) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
HideConsole(void) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
IsConsoleVisible(PRBool *result) = 0;
|
||||
|
||||
// Prints a message to the Java console. The encodingName specifies the
|
||||
// encoding of the message, and if NULL, specifies the default platform
|
||||
|
@ -59,11 +48,11 @@ public:
|
|||
};
|
||||
|
||||
#define NS_IJVMCONSOLE_IID \
|
||||
{ /* 85344580-01c1-11d2-815b-006008119d7a */ \
|
||||
0x85344580, \
|
||||
0x01c1, \
|
||||
{ /* fefaf860-6220-11d2-8164-006008119d7a */ \
|
||||
0xfefaf860, \
|
||||
0x6220, \
|
||||
0x11d2, \
|
||||
{0x81, 0x5b, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
{0x81, 0x64, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -31,18 +31,6 @@
|
|||
|
||||
#include "nsISupports.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NPJVM_MIME_TYPE "application/x-java-vm" // XXX application/java
|
||||
|
||||
enum {
|
||||
NS_JVM_ERROR_BASE = NS_ERROR_BASE + 0x10000,
|
||||
NS_JVM_ERROR_NO_CLASSES,
|
||||
NS_JVM_ERROR_WRONG_CLASSES,
|
||||
NS_JVM_ERROR_JAVA_ERROR,
|
||||
NS_JVM_ERROR_NO_DEBUGGER
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Java VM Plugin Manager
|
||||
// This interface defines additional entry points that are available
|
||||
|
@ -54,10 +42,21 @@ class nsISecureJNI2;
|
|||
class nsIJVMManager : public nsISupports {
|
||||
public:
|
||||
/**
|
||||
* Creates a proxy JNI for a given secure environment.
|
||||
* Creates a proxy JNI with an optional secure environment (which can be NULL).
|
||||
* There is a one-to-one correspondence between proxy JNIs and threads, so
|
||||
* calling this method multiple times from the same thread will return
|
||||
* the same proxy JNI.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateProxyJNI(nsISecureJNI2* inSecureEnv, JNIEnv** outProxyEnv) = 0;
|
||||
NS_IMETHOD
|
||||
CreateProxyJNI(nsISecureJNI2* inSecureEnv, JNIEnv** outProxyEnv) = 0;
|
||||
|
||||
/**
|
||||
* Returns the proxy JNI associated with the current thread, or NULL if no
|
||||
* such association exists.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetProxyJNI(JNIEnv** outProxyEnv) = 0;
|
||||
|
||||
};
|
||||
|
||||
#define NS_IJVMMANAGER_IID \
|
||||
|
@ -68,6 +67,15 @@ public:
|
|||
{0x85, 0xb2, 0x00, 0x80, 0x5f, 0x0e, 0x4d, 0xfe} \
|
||||
}
|
||||
|
||||
#define NS_JVMMANAGER_CID \
|
||||
{ /* 38e7ef10-58df-11d2-8164-006008119d7a */ \
|
||||
0x38e7ef10, \
|
||||
0x58df, \
|
||||
0x11d2, \
|
||||
{0x81, 0x64, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* nsIJVMManager_h___ */
|
||||
|
|
|
@ -33,44 +33,21 @@
|
|||
#include "nsIPrincipal.h"
|
||||
#include "jni.h"
|
||||
|
||||
class nsISecureJNI2;
|
||||
|
||||
/**
|
||||
* This MIME type is what should be used to signify a Java VM plugin.
|
||||
*/
|
||||
#define NS_JVM_MIME_TYPE "application/x-java-vm" // XXX "application/java" ?
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Java VM Plugin Interface
|
||||
// This interface defines additional entry points that a plugin developer needs
|
||||
// to implement in order to implement a Java virtual machine plugin.
|
||||
|
||||
struct nsJVMInitArgs {
|
||||
PRUint32 version;
|
||||
const char* classpathAdditions; // appended to the JVM's classpath
|
||||
// other fields may be added here for version numbers beyond 0x00010000
|
||||
};
|
||||
|
||||
/**
|
||||
* nsJVMInitArgs_Version is the current version number for the nsJVMInitArgs
|
||||
* struct specified above. The nsVersionOk macro should be used when comparing
|
||||
* a supplied nsJVMInitArgs struct against this version.
|
||||
*/
|
||||
#define nsJVMInitArgs_Version 0x00010000L
|
||||
|
||||
class nsISecureJNI2;
|
||||
|
||||
class nsIJVMPlugin : public nsIPlugin {
|
||||
public:
|
||||
|
||||
// This method us used to start the Java virtual machine.
|
||||
// It sets up any global state necessary to host Java programs.
|
||||
// Note that calling this method is distinctly separate from
|
||||
// initializing the nsIJVMPlugin object (done by the Initialize
|
||||
// method).
|
||||
NS_IMETHOD
|
||||
StartupJVM(nsJVMInitArgs* initargs) = 0;
|
||||
|
||||
// This method us used to stop the Java virtual machine.
|
||||
// It tears down any global state necessary to host Java programs.
|
||||
// The fullShutdown flag specifies whether the browser is quitting
|
||||
// (PR_TRUE) or simply whether the JVM is being shut down (PR_FALSE).
|
||||
NS_IMETHOD
|
||||
ShutdownJVM(PRBool fullShutdown = PR_FALSE) = 0;
|
||||
|
||||
// Causes the JVM to append a new directory to its classpath.
|
||||
// If the JVM doesn't support this operation, an error is returned.
|
||||
NS_IMETHOD
|
||||
|
@ -88,13 +65,6 @@ public:
|
|||
NS_IMETHOD
|
||||
GetJavaWrapper(JNIEnv* jenv, jint obj, jobject *jobj) = 0;
|
||||
|
||||
#if 0 // still trying to decide on this
|
||||
// nsIPrincipals is a array of pointers to principals associated with this
|
||||
// java object trying to run a JS script.
|
||||
NS_IMETHOD
|
||||
GetPrincipalArray(JNIEnv *pJNIEnv, PRInt32 frameIndex, nsIPrincipal ***principalArray, PRInt32 *length) = 0;
|
||||
#endif
|
||||
|
||||
// Find or create a JNIEnv for the current thread.
|
||||
// Returns NULL if an error occurs.
|
||||
NS_IMETHOD_(nsrefcnt)
|
||||
|
@ -105,23 +75,23 @@ public:
|
|||
NS_IMETHOD_(nsrefcnt)
|
||||
ReleaseJNIEnv(JNIEnv* env) = 0;
|
||||
|
||||
/**
|
||||
* This creates a new secure communication channel with Java. The second parameter,
|
||||
* nativeEnv, if non-NULL, will be the actual thread for Java communication.
|
||||
* Otherwise, a new thread should be created.
|
||||
* @param proxyEnv the env to be used by all clients on the browser side
|
||||
* @return outSecureEnv the secure environment used by the proxyEnv
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateSecureEnv(JNIEnv* proxyEnv, nsISecureJNI2* *outSecureEnv) = 0;
|
||||
/**
|
||||
* This creates a new secure communication channel with Java. The second parameter,
|
||||
* nativeEnv, if non-NULL, will be the actual thread for Java communication.
|
||||
* Otherwise, a new thread should be created.
|
||||
* @param proxyEnv the env to be used by all clients on the browser side
|
||||
* @return outSecureEnv the secure environment used by the proxyEnv
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateSecureEnv(JNIEnv* proxyEnv, nsISecureJNI2* *outSecureEnv) = 0;
|
||||
|
||||
/**
|
||||
* Gives time to the JVM from the main event loop of the browser. This is
|
||||
* necessary when there aren't any plugin instances around, but Java threads exist.
|
||||
*/
|
||||
/**
|
||||
* Gives time to the JVM from the main event loop of the browser. This is
|
||||
* necessary when there aren't any plugin instances around, but Java threads exist.
|
||||
*/
|
||||
#ifdef XP_MAC
|
||||
NS_IMETHOD
|
||||
SpendTime(PRUint32 timeMillis) = 0;
|
||||
NS_IMETHOD
|
||||
SpendTime(PRUint32 timeMillis) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsISymantecDebugger.h"
|
||||
#include "nsICapsManager.h"
|
||||
#include "nsILiveconnect.h"
|
||||
#include "nsIThreadManager.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -19,16 +19,23 @@ ifdef MOZ_OJI
|
|||
LIBRARY_NAME = oji
|
||||
|
||||
CPPSRCS = jvmmgr.cpp \
|
||||
scd.cpp \
|
||||
ProxyJNI.cpp \
|
||||
nsCSecurityContext.cpp
|
||||
scd.cpp \
|
||||
nsJVMManager.cpp \
|
||||
nsJVMPluginTagInfo.cpp \
|
||||
ProxyJNI.cpp \
|
||||
nsCSecurityContext.cpp \
|
||||
nsCJVMManagerFactory.cpp \
|
||||
lcglue.cpp
|
||||
|
||||
|
||||
REQUIRES = img java js lay layer plugin plugimpl pref style util xpcom raptor oji caps
|
||||
CFLAGS += -DJSJDLL=\"$(JSJDLL)\"
|
||||
INCLUDES += -I$(DIST)/include/private
|
||||
endif # MOZ_OJI
|
||||
|
||||
EXPORTS = jvmmgr.h
|
||||
EXPORTS = jvmmgr.h \
|
||||
nsJVMManager.h \
|
||||
nsJVMPluginTagInfo.h
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
|
|
|
@ -410,7 +410,7 @@ private:
|
|||
ProxyJNIEnv& secureEnv = nsJNIEnvRef(env);
|
||||
jmethodID outMethodID = NULL;
|
||||
nsresult result = secureEnv->GetMethodID(clazz, name, sig, &outMethodID);
|
||||
if (result == NS_OK) {
|
||||
if (result == NS_OK && outMethodID != NULL) {
|
||||
JNIHashKey key(outMethodID);
|
||||
JNIMethod* method = (JNIMethod*) theIDTable->Get(&key);
|
||||
if (method == NULL) {
|
||||
|
@ -620,7 +620,7 @@ private:
|
|||
ProxyJNIEnv& secureEnv = nsJNIEnvRef(env);
|
||||
jfieldID outFieldID = NULL;
|
||||
nsresult result = secureEnv->GetFieldID(clazz, name, sig, &outFieldID);
|
||||
if (result == NS_OK) {
|
||||
if (result == NS_OK && outFieldID != NULL) {
|
||||
JNIHashKey key(outFieldID);
|
||||
JNIField* field = (JNIField*) theIDTable->Get(&key);
|
||||
if (field == NULL) {
|
||||
|
@ -695,7 +695,7 @@ private:
|
|||
ProxyJNIEnv& secureEnv = nsJNIEnvRef(env);
|
||||
jmethodID outMethodID = NULL;
|
||||
nsresult result = secureEnv->GetStaticMethodID(clazz, name, sig, &outMethodID);
|
||||
if (result == NS_OK) {
|
||||
if (result == NS_OK && outMethodID != NULL) {
|
||||
JNIHashKey key(outMethodID);
|
||||
JNIMethod* method = (JNIMethod*) theIDTable->Get(&key);
|
||||
if (method == NULL) {
|
||||
|
@ -799,7 +799,7 @@ private:
|
|||
ProxyJNIEnv& secureEnv = nsJNIEnvRef(env);
|
||||
jfieldID outFieldID = NULL;
|
||||
nsresult result = secureEnv->GetStaticFieldID(clazz, name, sig, &outFieldID);
|
||||
if (result == NS_OK) {
|
||||
if (result == NS_OK && outFieldID != NULL) {
|
||||
JNIHashKey key(outFieldID);
|
||||
JNIField* field = (JNIField*) theIDTable->Get(&key);
|
||||
if (field == NULL) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# This is a list of files to be copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
nsjvm.h
|
||||
nsscd.h
|
||||
jvmmgr.h
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -19,14 +19,12 @@
|
|||
#ifndef jvmmgr_h___
|
||||
#define jvmmgr_h___
|
||||
|
||||
#include "xp_core.h" /* include first because of Bool problem */
|
||||
#include "prtypes.h"
|
||||
#include "nsCom.h"
|
||||
#include "nsError.h" /* for nsresult */
|
||||
#include "jni.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "nsError.h"
|
||||
|
||||
struct nsJVMMgr;
|
||||
struct nsJVMManager;
|
||||
|
||||
typedef enum nsJVMStatus {
|
||||
nsJVMStatus_Enabled, /* but not Running */
|
||||
|
@ -35,231 +33,27 @@ typedef enum nsJVMStatus {
|
|||
nsJVMStatus_Failed /* enabled but failed to start */
|
||||
} nsJVMStatus;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "nsjvm.h"
|
||||
#include "nsAgg.h"
|
||||
#include "jsjava.h"
|
||||
#include "nsVector.h"
|
||||
#include "nsIThreadManager.h"
|
||||
#include "nsISecurityContext.h"
|
||||
|
||||
class nsIPluginTagInfo2;
|
||||
class nsSymantecDebugManager;
|
||||
|
||||
struct ThreadLocalStorageAtIndex0 {
|
||||
PRUint32 refcount;
|
||||
};
|
||||
typedef struct ThreadLocalStorageAtIndex0 ThreadLocalStorageAtIndex0;
|
||||
typedef struct ThreadLocalStorageAtIndex1 ThreadLocalStorageAtIndex1;
|
||||
struct ThreadLocalStorageAtIndex1 {
|
||||
void **pNSIPrincipaArray;
|
||||
int numPrincipals;
|
||||
void *pNSISecurityContext;
|
||||
JSStackFrame *pJavaToJSSFrame;
|
||||
ThreadLocalStorageAtIndex1 *next;
|
||||
ThreadLocalStorageAtIndex1 *prev;
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* JVMMgr is the interface to the JVM manager that the browser sees. All
|
||||
* files that want to include java services should include this header file.
|
||||
* nsIJVMManager is the more limited interface what the JVM plugin sees.
|
||||
******************************************************************************/
|
||||
|
||||
struct nsJVMMgr : public nsIJVMManager, public nsIThreadManager {
|
||||
public:
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
|
||||
/* from nsIJVMManager: */
|
||||
|
||||
/**
|
||||
* Creates a proxy JNI for a given secure environment.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateProxyJNI(nsISecureJNI2* inSecureEnv, JNIEnv** outProxyEnv);
|
||||
|
||||
/* from nsIThreadManager: */
|
||||
|
||||
/**
|
||||
* Returns a unique identifier for the "current" system thread.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetCurrentThread(PRUint32* threadID);
|
||||
|
||||
/**
|
||||
* Pauses the current thread for the specified number of milliseconds.
|
||||
* If milli is zero, then merely yields the CPU if another thread of
|
||||
* greater or equal priority.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Sleep(PRUint32 milli = 0);
|
||||
|
||||
/**
|
||||
* Creates a unique monitor for the specified address, and makes the
|
||||
* current system thread the owner of the monitor.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
EnterMonitor(void* address);
|
||||
|
||||
/**
|
||||
* Exits the monitor associated with the address.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
ExitMonitor(void* address);
|
||||
|
||||
/**
|
||||
* Waits on the monitor associated with the address (must be entered already).
|
||||
* If milli is 0, wait indefinitely.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Wait(void* address, PRUint32 milli = 0);
|
||||
|
||||
/**
|
||||
* Notifies a single thread waiting on the monitor associated with the address (must be entered already).
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Notify(void* address);
|
||||
|
||||
/**
|
||||
* Notifies all threads waiting on the monitor associated with the address (must be entered already).
|
||||
*/
|
||||
NS_IMETHOD
|
||||
NotifyAll(void* address);
|
||||
|
||||
/**
|
||||
* Thread creation primitives.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateThread(PRUint32* threadID, nsIRunnable* runnable);
|
||||
|
||||
/* JVMMgr specific methods: */
|
||||
|
||||
/* ====> From here on are things only called by the browser, not the plugin... */
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
|
||||
nsIJVMPlugin* GetJVMPlugin(void) { return fJVM; }
|
||||
|
||||
/* Unlike the nsIJVMPlugin::StartupJVM, this version handles putting
|
||||
* up any error dialog: */
|
||||
nsJVMStatus StartupJVM(void);
|
||||
nsJVMStatus ShutdownJVM(PRBool fullShutdown = PR_FALSE);
|
||||
nsJVMStatus GetJVMStatus(void);
|
||||
void SetJVMEnabled(PRBool enabled);
|
||||
|
||||
void ReportJVMError(nsresult err);
|
||||
const char* GetJavaErrorString(JNIEnv* env);
|
||||
|
||||
nsresult AddToClassPath(const char* dirPath);
|
||||
PRBool MaybeStartupLiveConnect(void);
|
||||
PRBool MaybeShutdownLiveConnect(void);
|
||||
PRBool IsLiveConnectEnabled(void);
|
||||
JSJavaVM* GetJSJavaVM() { return fJSJavaVM; }
|
||||
|
||||
|
||||
protected:
|
||||
nsJVMMgr(nsISupports* outer);
|
||||
virtual ~nsJVMMgr(void);
|
||||
|
||||
void EnsurePrefCallbackRegistered(void);
|
||||
const char* GetJavaErrorString(JRIEnv* env);
|
||||
|
||||
nsIJVMPlugin* fJVM;
|
||||
nsJVMStatus fStatus;
|
||||
PRBool fRegisteredJavaPrefChanged;
|
||||
nsISupports* fDebugManager;
|
||||
JSJavaVM * fJSJavaVM;
|
||||
nsVector* fClassPathAdditions;
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Symantec Debugger Stuff
|
||||
******************************************************************************/
|
||||
|
||||
class nsSymantecDebugManager : public nsISymantecDebugManager {
|
||||
public:
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
|
||||
NS_IMETHOD
|
||||
SetDebugAgentPassword(PRInt32 pwd);
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr,
|
||||
nsJVMMgr* jvmMgr);
|
||||
|
||||
protected:
|
||||
nsSymantecDebugManager(nsISupports* outer, nsJVMMgr* jvmMgr);
|
||||
virtual ~nsSymantecDebugManager(void);
|
||||
|
||||
nsJVMMgr* fJVMMgr;
|
||||
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* nsJVMPluginTagInfo: The browser makes one of these when it sees an APPLET or
|
||||
* appropriate OBJECT tag.
|
||||
******************************************************************************/
|
||||
|
||||
class nsJVMPluginTagInfo : public nsIJVMPluginTagInfo {
|
||||
public:
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
|
||||
/* from nsIJVMPluginTagInfo: */
|
||||
|
||||
/* ====> These are usually only called by the plugin, not the browser... */
|
||||
|
||||
NS_IMETHOD
|
||||
GetCode(const char* *result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetCodeBase(const char* *result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetArchive(const char* *result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetName(const char* *result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetMayScript(PRBool *result);
|
||||
|
||||
/* Methods specific to nsJVMPluginInstancePeer: */
|
||||
|
||||
/* ====> From here on are things only called by the browser, not the plugin... */
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr,
|
||||
nsIPluginTagInfo2* info);
|
||||
|
||||
protected:
|
||||
|
||||
nsJVMPluginTagInfo(nsISupports* outer, nsIPluginTagInfo2* info);
|
||||
virtual ~nsJVMPluginTagInfo(void);
|
||||
|
||||
/* Instance Variables: */
|
||||
nsIPluginTagInfo2* fPluginTagInfo;
|
||||
char* fSimulatedCodebase;
|
||||
char* fSimulatedCode;
|
||||
};
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*******************************************************************************
|
||||
* Convenience Routines
|
||||
* Interface for C Clients
|
||||
******************************************************************************/
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
/* Returns the JVM manager. You must do a Release on the pointer returned when
|
||||
you're done with it. */
|
||||
PR_EXTERN(struct nsJVMMgr*)
|
||||
PR_EXTERN(struct nsJVMManager*)
|
||||
JVM_GetJVMMgr(void);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JVM_ReleaseJVMMgr(struct nsJVMManager* mgr);
|
||||
|
||||
PR_EXTERN(nsJVMStatus)
|
||||
JVM_StartupJVM(void);
|
||||
|
||||
PR_EXTERN(nsJVMStatus)
|
||||
JVM_ShutdownJVM(void);
|
||||
|
||||
PR_EXTERN(nsJVMStatus)
|
||||
JVM_GetJVMStatus(void);
|
||||
|
||||
|
@ -276,10 +70,16 @@ PR_EXTERN(PRBool)
|
|||
JVM_IsConsoleVisible(void);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JVM_ToggleConsole(void);
|
||||
JVM_PrintToConsole(const char* msg);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JVM_PrintToConsole(const char* msg);
|
||||
JVM_ShowPrefsWindow(void);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JVM_HidePrefsWindow(void);
|
||||
|
||||
PR_EXTERN(PRBool)
|
||||
JVM_IsPrefsWindowVisible(void);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JVM_StartDebugger(void);
|
||||
|
@ -311,8 +111,11 @@ JVM_NSISecurityContextImplies(JSStackFrame *pCurrentFrame, const char* target,
|
|||
PR_EXTERN(JSPrincipals*)
|
||||
JVM_GetJavaPrincipalsFromStack(JSStackFrame *pCurrentFrame);
|
||||
|
||||
PR_EXTERN(JSStackFrame*)
|
||||
JVM_GetStartJSFrameFromParallelStack();
|
||||
PR_EXTERN(void *)
|
||||
JVM_GetJavaPrincipalsFromStackAsNSVector(JSStackFrame *pCurrentFrame);
|
||||
|
||||
PR_EXTERN(JSStackFrame**)
|
||||
JVM_GetStartJSFrameFromParallelStack(void);
|
||||
|
||||
PR_EXTERN(JSStackFrame*)
|
||||
JVM_GetEndJSFrameFromParallelStack(JSStackFrame *pCurrentFrame);
|
||||
|
|
|
@ -18,21 +18,36 @@
|
|||
|
||||
#include "prthread.h"
|
||||
#include "pprthred.h"
|
||||
#include "plstr.h"
|
||||
#include "jni.h"
|
||||
#include "jsjava.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "libmocha.h"
|
||||
#include "libevent.h"
|
||||
#include "jvmmgr.h"
|
||||
#include "npglue.h"
|
||||
#include "nsJVMManager.h"
|
||||
#include "nsIPluginInstancePeer.h"
|
||||
//#include "npglue.h"
|
||||
#include "nsCCapsManager.h"
|
||||
#include "prinrval.h"
|
||||
#include "ProxyJNI.h"
|
||||
#include "prcmon.h"
|
||||
#include "nsCSecurityContext.h"
|
||||
#include "nsISecurityContext.h"
|
||||
#include "xpgetstr.h"
|
||||
#include "lcglue.h"
|
||||
#include "nsIServiceManager.h"
|
||||
extern nsIServiceManager *g_pNSIServiceManager;
|
||||
extern "C" int XP_PROGRESS_STARTING_JAVA;
|
||||
extern "C" int XP_PROGRESS_STARTING_JAVA_DONE;
|
||||
extern "C" int XP_JAVA_NO_CLASSES;
|
||||
extern "C" int XP_JAVA_GENERAL_FAILURE;
|
||||
extern "C" int XP_JAVA_STARTUP_FAILED;
|
||||
extern "C" int XP_JAVA_DEBUGGER_FAILED;
|
||||
|
||||
static NS_DEFINE_IID(kIJVMPluginInstanceIID, NS_IJVMPLUGININSTANCE_IID);
|
||||
static NS_DEFINE_IID(kIJVMPluginTagInfoIID, NS_IJVMPLUGINTAGINFO_IID);
|
||||
|
||||
static PRUintn tlsIndex_g = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// LiveConnect callbacks
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Template based Thread Local Storage.
|
||||
*/
|
||||
template <class T>
|
||||
class ThreadLocalStorage {
|
||||
public:
|
||||
|
@ -56,55 +71,74 @@ private:
|
|||
PRBool mValid;
|
||||
};
|
||||
|
||||
|
||||
static void PR_CALLBACK detach_JVMContext(void* storage)
|
||||
{
|
||||
JVMContext* context = (JVMContext*)storage;
|
||||
|
||||
JNIEnv* proxyEnv = context->proxyEnv;
|
||||
if (proxyEnv != NULL) {
|
||||
DeleteProxyJNI(proxyEnv);
|
||||
context->proxyEnv = NULL;
|
||||
}
|
||||
|
||||
delete storage;
|
||||
}
|
||||
|
||||
JVMContext* GetJVMContext()
|
||||
{
|
||||
/* Use NSPR thread private data to manage the per-thread JNIEnv* association. */
|
||||
static ThreadLocalStorage<JVMContext*> localContext(&detach_JVMContext);
|
||||
JVMContext* context = localContext.get();
|
||||
if (context == NULL) {
|
||||
context = new JVMContext;
|
||||
context->proxyEnv = NULL;
|
||||
context->securityStack = NULL;
|
||||
context->jsj_env = NULL;
|
||||
context->js_context = NULL;
|
||||
context->js_startframe = NULL;
|
||||
localContext.set(context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIJVMManagerIID, NS_IJVMMANAGER_IID);
|
||||
static NS_DEFINE_IID(kCJVMManagerCID, NS_JVMMANAGER_CID);
|
||||
static NS_DEFINE_IID(kIThreadManagerIID, NS_ITHREADMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIJVMPluginIID, NS_IJVMPLUGIN_IID);
|
||||
static NS_DEFINE_IID(kISymantecDebugManagerIID, NS_ISYMANTECDEBUGMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIJVMPluginInstanceIID, NS_IJVMPLUGININSTANCE_IID);
|
||||
static NS_DEFINE_IID(kIJVMPluginTagInfoIID, NS_IJVMPLUGINTAGINFO_IID);
|
||||
static NS_DEFINE_IID(kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
|
||||
static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIJVMConsoleIID, NS_IJVMCONSOLE_IID);
|
||||
static NS_DEFINE_IID(kISymantecDebuggerIID, NS_ISYMANTECDEBUGGER_IID);
|
||||
static NS_DEFINE_IID(kISecurityContextIID, NS_ISECURITYCONTEXT_IID);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// LiveConnect callbacks
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
#include "jscntxt.h"
|
||||
|
||||
|
||||
static JSContext* PR_CALLBACK
|
||||
map_jsj_thread_to_js_context_impl(JSJavaThreadState *jsj_env, JNIEnv *env, char **errp)
|
||||
{
|
||||
JSContext *cx = LM_GetCrippledContext();
|
||||
PRBool jvmMochaPrefsEnabled = PR_FALSE;
|
||||
/*
|
||||
** This callback is called for spontaneous calls only. Either create a new JSContext
|
||||
** or return the crippled context.
|
||||
** TODO: Get to some kind of script manager via service manager and then get to script context
|
||||
** and then to get to the native context.
|
||||
*/
|
||||
//JSContext *cx = LM_GetCrippledContext();
|
||||
JSContext *cx = NULL;
|
||||
|
||||
*errp = NULL;
|
||||
#if 0
|
||||
nsJVMMgr* pJVMMgr = JVM_GetJVMMgr();
|
||||
if (pJVMMgr != NULL) {
|
||||
nsIJVMPlugin* pJVMPI = pJVMMgr->GetJVMPlugin();
|
||||
jvmMochaPrefsEnabled = LM_GetMochaEnabled();
|
||||
if (pJVMPI != NULL) {
|
||||
nsIPluginInstance* pPIT;
|
||||
nsresult err = pJVMPI->GetPluginInstance(env, &pPIT);
|
||||
if ( (err == NS_OK) && (pPIT != NULL) ) {
|
||||
nsIJVMPluginInstance* pJVMPIT;
|
||||
if (pPIT->QueryInterface(kIJVMPluginInstanceIID,
|
||||
(void**)&pJVMPIT) == NS_OK) {
|
||||
nsPluginInstancePeer* pPITP;
|
||||
err = pJVMPIT->GetPeer((nsIPluginInstancePeer**)&pPITP);
|
||||
if ( (err == NS_OK) &&(pPITP != NULL) ) {
|
||||
cx = pPITP->GetJSContext();
|
||||
pPITP->Release();
|
||||
}
|
||||
pJVMPIT->Release();
|
||||
}
|
||||
pPIT->Release();
|
||||
}
|
||||
// pJVMPI->Release(); // GetJVMPlugin no longer calls AddRef
|
||||
}
|
||||
pJVMMgr->Release();
|
||||
}
|
||||
if (jvmMochaPrefsEnabled == PR_FALSE)
|
||||
{
|
||||
*errp = strdup("Java preference is disabled");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( cx == NULL )
|
||||
{
|
||||
*errp = strdup("Java thread could not be associated with a JSContext");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return cx;
|
||||
}
|
||||
|
||||
|
@ -125,18 +159,18 @@ map_js_context_to_jsj_thread_impl(JSContext *cx, char **errp)
|
|||
{
|
||||
*errp = NULL;
|
||||
|
||||
static ThreadLocalStorage<JSJavaThreadState*> localThreadState(&detach_jsjava_thread_state);
|
||||
JSJavaThreadState* jsj_env = localThreadState.get();
|
||||
JVMContext* context = GetJVMContext();
|
||||
JSJavaThreadState* jsj_env = context->jsj_env;
|
||||
if (jsj_env != NULL)
|
||||
return jsj_env;
|
||||
|
||||
/*/TODO: Figure out if moja intiailzation went ok.
|
||||
if (ET_InitMoja(0) != LM_MOJA_OK) {
|
||||
*errp = strdup("LiveConnect initialization failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*/
|
||||
JSJavaVM* js_jvm = NULL;
|
||||
nsJVMMgr* pJVMMgr = JVM_GetJVMMgr();
|
||||
nsJVMManager* pJVMMgr = JVM_GetJVMMgr();
|
||||
if (pJVMMgr != NULL) {
|
||||
js_jvm = pJVMMgr->GetJSJavaVM();
|
||||
pJVMMgr->Release();
|
||||
|
@ -147,24 +181,23 @@ map_js_context_to_jsj_thread_impl(JSContext *cx, char **errp)
|
|||
}
|
||||
|
||||
jsj_env = JSJ_AttachCurrentThreadToJava(js_jvm, NULL, NULL);
|
||||
localThreadState.set(jsj_env);
|
||||
context->jsj_env = jsj_env;
|
||||
context->js_context = cx;
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
/*
|
||||
** This callback is called to map a applet,bean to its corresponding JSObject
|
||||
** created on javascript side and then map that to a java wrapper JSObject class.
|
||||
** This callback is called in JSObject.getWindow implementation to get
|
||||
** a java wrapper JSObject class for a applet only once.
|
||||
** Note that once a mapping between applet -> javascript JSObject -> Java wrapper JSObject
|
||||
** is made, all subsequent method calls via JSObject use the internal field
|
||||
** to get to the javascript JSObject.
|
||||
*/
|
||||
|
||||
static JSObject* PR_CALLBACK
|
||||
map_java_object_to_js_object_impl(JNIEnv *env, void *pNSIPluginInstanceIn, char **errp)
|
||||
{
|
||||
MWContext *cx;
|
||||
JSObject *window;
|
||||
MochaDecoder *decoder;
|
||||
PRBool mayscript = PR_FALSE;
|
||||
|
@ -172,116 +205,70 @@ map_java_object_to_js_object_impl(JNIEnv *env, void *pNSIPluginInstanceIn, char
|
|||
nsresult err = NS_OK;
|
||||
|
||||
*errp = NULL;
|
||||
/* XXX assert JS is locked */
|
||||
|
||||
if (!pNSIPluginInstanceIn) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"),0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsJVMMgr* pJVMMgr = JVM_GetJVMMgr();
|
||||
if (pJVMMgr != NULL) {
|
||||
nsIJVMPlugin* pJVMPI = pJVMMgr->GetJVMPlugin();
|
||||
jvmMochaPrefsEnabled = LM_GetMochaEnabled();
|
||||
if (pJVMPI != NULL) {
|
||||
//jobject javaObject = applet;
|
||||
nsIPluginInstance* pPIT;
|
||||
//nsresult err = pJVMPI->GetPluginInstance(javaObject, &pPIT);
|
||||
pPIT = (nsIPluginInstance*)pNSIPluginInstanceIn;
|
||||
if ( (err == NS_OK) && (pPIT != NULL) ) {
|
||||
nsIJVMPluginInstance* pJVMPIT;
|
||||
if (pPIT->QueryInterface(kIJVMPluginInstanceIID,
|
||||
(void**)&pJVMPIT) == NS_OK) {
|
||||
nsPluginInstancePeer* pPITP;
|
||||
err = pJVMPIT->GetPeer((nsIPluginInstancePeer**)&pPITP);
|
||||
if ( (err == NS_OK) &&(pPITP != NULL) ) {
|
||||
nsIJVMPluginTagInfo* pJVMTagInfo;
|
||||
if (pPITP->QueryInterface(kIJVMPluginTagInfoIID,
|
||||
(void**)&pJVMTagInfo) == NS_OK) {
|
||||
err = pJVMTagInfo->GetMayScript(&mayscript);
|
||||
PR_ASSERT(err != NS_OK ? mayscript == PR_FALSE : PR_TRUE);
|
||||
pJVMTagInfo->Release();
|
||||
}
|
||||
cx = pPITP->GetMWContext();
|
||||
pPITP->Release();
|
||||
}
|
||||
pJVMPIT->Release();
|
||||
//TODO: Check if Mocha is enabled. To get to any mocha api, we should use service
|
||||
// manager and get to the appropriate service.
|
||||
// jvmMochaPrefsEnabled = LM_GetMochaEnabled();
|
||||
if(jvmMochaPrefsEnabled == PR_FALSE)
|
||||
{
|
||||
*errp = strdup("JSObject.getWindow() failed: java preference is disabled");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check for the mayscript tag.
|
||||
*/
|
||||
nsIPluginInstance* pPIT;
|
||||
pPIT = (nsIPluginInstance*)pNSIPluginInstanceIn;
|
||||
if ( (err == NS_OK) && (pPIT != NULL) ) {
|
||||
nsIJVMPluginInstance* pJVMPIT;
|
||||
if (pPIT->QueryInterface(kIJVMPluginInstanceIID,
|
||||
(void**)&pJVMPIT) == NS_OK) {
|
||||
nsIPluginInstancePeer* pPITP;
|
||||
err = pJVMPIT->GetPeer((nsIPluginInstancePeer**)&pPITP);
|
||||
if ( (err == NS_OK) &&(pPITP != NULL) ) {
|
||||
nsIJVMPluginTagInfo* pJVMTagInfo;
|
||||
if (pPITP->QueryInterface(kIJVMPluginTagInfoIID,
|
||||
(void**)&pJVMTagInfo) == NS_OK) {
|
||||
err = pJVMTagInfo->GetMayScript(&mayscript);
|
||||
PR_ASSERT(err != NS_OK ? mayscript == PR_FALSE : PR_TRUE);
|
||||
pJVMTagInfo->Release();
|
||||
}
|
||||
pPIT->Release();
|
||||
pPITP->Release();
|
||||
}
|
||||
// pJVMPI->Release(); // GetJVMPlugin no longer calls AddRef
|
||||
pJVMPIT->Release();
|
||||
}
|
||||
pJVMMgr->Release();
|
||||
}
|
||||
|
||||
if ( (mayscript == PR_FALSE)
|
||||
||(jvmMochaPrefsEnabled == PR_FALSE)
|
||||
)
|
||||
if (mayscript == PR_FALSE)
|
||||
{
|
||||
*errp = strdup("JSObject.getWindow() requires mayscript attribute on this Applet or java preference is disabled");
|
||||
goto except;
|
||||
*errp = strdup("JSObject.getWindow() requires mayscript attribute on this Applet");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
if (!cx || (cx->type != MWContextBrowser && cx->type != MWContextPane))
|
||||
{
|
||||
*errp = strdup("JSObject.getWindow() can only be called in MWContextBrowser or MWContextPane");
|
||||
return 0;
|
||||
}
|
||||
|
||||
decoder = LM_GetMochaDecoder(cx);
|
||||
|
||||
/* if there is a decoder now, reflect the window */
|
||||
if (decoder && (jvmMochaPrefsEnabled == PR_TRUE)) {
|
||||
window = decoder->window_object;
|
||||
}
|
||||
|
||||
LM_PutMochaDecoder(decoder);
|
||||
|
||||
//TODO: Get to the window object using DOM.
|
||||
// window = getDOMWindow().getScriptOwner().getJSObject().
|
||||
return window;
|
||||
except:
|
||||
failed:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static JavaVM* PR_CALLBACK
|
||||
get_java_vm_impl(char **errp)
|
||||
{
|
||||
*errp = NULL;
|
||||
JavaVM *pJavaVM = NULL;
|
||||
|
||||
nsJVMMgr* pJVMMgr = JVM_GetJVMMgr();
|
||||
if (pJVMMgr != NULL) {
|
||||
nsIJVMPlugin* pJVMPI = pJVMMgr->GetJVMPlugin();
|
||||
if (pJVMPI != NULL) {
|
||||
nsresult err = pJVMPI->GetJavaVM(&pJavaVM);
|
||||
PR_ASSERT(err != NS_OK ? pJavaVM == NULL : PR_TRUE);
|
||||
// pJVMPI->Release(); // GetJVMPlugin no longer calls AddRef
|
||||
}
|
||||
pJVMMgr->Release();
|
||||
}
|
||||
if ( pJavaVM == NULL )
|
||||
{
|
||||
*errp = strdup("Could not find a JavaVM to attach to.");
|
||||
}
|
||||
return pJavaVM;
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSPrincipals* PR_CALLBACK
|
||||
get_JSPrincipals_from_java_caller_impl(JNIEnv *pJNIEnv, JSContext *pJSContext)
|
||||
#if 0
|
||||
// TODO: Need raman's help. This needs to convert between C++ [] array data type to a nsVector object.
|
||||
void*
|
||||
ConvertNSIPrincipalArrayToObject(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext)
|
||||
{
|
||||
nsIPrincipal **ppNSIPrincipalArray = NULL;
|
||||
PRInt32 length = 0;
|
||||
nsIPrincipal **ppNSIPrincipalArray = (nsIPrincipal **)ppNSIPrincipalArrayIN;
|
||||
PRInt32 length = numPrincipals;
|
||||
nsresult err = NS_OK;
|
||||
nsJVMManager* pJVMMgr = JVM_GetJVMMgr();
|
||||
void *pNSPrincipalArray = NULL;
|
||||
#if 0 // TODO: =-= sudu: fix it.
|
||||
nsJVMMgr* pJVMMgr = JVM_GetJVMMgr();
|
||||
if (pJVMMgr != NULL) {
|
||||
nsIJVMPlugin* pJVMPI = pJVMMgr->GetJVMPlugin();
|
||||
if (pJVMPI != NULL) {
|
||||
err = pJVMPI->GetPrincipalArray(pJNIEnv, 0, &ppNSIPrincipalArray, &length);
|
||||
if ((err == NS_OK) && (ppNSIPrincipalArray != NULL)) {
|
||||
if (ppNSIPrincipalArray != NULL) {
|
||||
nsIPluginManager *pNSIPluginManager = NULL;
|
||||
NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
|
||||
err = pJVMMgr->QueryInterface(kIPluginManagerIID,
|
||||
|
@ -315,27 +302,41 @@ get_JSPrincipals_from_java_caller_impl(JNIEnv *pJNIEnv, JSContext *pJSContext)
|
|||
pNSIPluginManager->Release();
|
||||
}
|
||||
}
|
||||
//pJVMPI->Release();
|
||||
}
|
||||
pJVMMgr->Release();
|
||||
}
|
||||
#endif
|
||||
if ( (pNSPrincipalArray != NULL)
|
||||
&&(length != 0)
|
||||
)
|
||||
{
|
||||
return LM_GetJSPrincipalsFromJavaCaller(pJSContext, pNSPrincipalArray);
|
||||
return pNSPrincipalArray;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif //0
|
||||
|
||||
|
||||
static JSPrincipals* PR_CALLBACK
|
||||
get_JSPrincipals_from_java_caller_impl(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext)
|
||||
{
|
||||
#if 0
|
||||
// TODO: FIX lm_taint.c to receive nsIPrincipals. Get help from Tom Pixley.
|
||||
void *pNSIPrincipalArrayObject = ConvertNSIPrincipalArrayToObject(pJNIEnv, pJSContext, ppNSIPrincipalArrayIN, numPrincipals, pNSISecurityContext);
|
||||
if (pNSIPrincipalArrayObject != NULL)
|
||||
{
|
||||
return LM_GetJSPrincipalsFromJavaCaller(pJSContext, pNSIPrincipalArrayObject, pNSISecurityContext);
|
||||
}
|
||||
|
||||
#endif
|
||||
PR_ASSERT(PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
static jobject PR_CALLBACK
|
||||
get_java_wrapper_impl(JNIEnv *pJNIEnv, jint jsobject)
|
||||
{
|
||||
nsresult err = NS_OK;
|
||||
jobject pJSObjectWrapper = NULL;
|
||||
nsJVMMgr* pJVMMgr = JVM_GetJVMMgr();
|
||||
nsJVMManager* pJVMMgr = JVM_GetJVMMgr();
|
||||
if (pJVMMgr != NULL) {
|
||||
nsIJVMPlugin* pJVMPI = pJVMMgr->GetJVMPlugin();
|
||||
if (pJVMPI != NULL) {
|
||||
|
@ -352,51 +353,74 @@ get_java_wrapper_impl(JNIEnv *pJNIEnv, jint jsobject)
|
|||
}
|
||||
|
||||
static JSBool PR_CALLBACK
|
||||
enter_js_from_java_impl(JNIEnv *jEnv, char **errp)
|
||||
enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
|
||||
void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext)
|
||||
{
|
||||
#ifdef OJI
|
||||
ThreadLocalStorageAtIndex0 *priv = NULL;
|
||||
if ( PR_GetCurrentThread() == NULL )
|
||||
{
|
||||
PR_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL);
|
||||
priv = (ThreadLocalStorageAtIndex0 *)malloc(sizeof(ThreadLocalStorageAtIndex0));
|
||||
priv->refcount=1;
|
||||
PR_SetThreadPrivate(tlsIndex_g, (void *)priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv = (ThreadLocalStorageAtIndex0 *)PR_GetThreadPrivate(tlsIndex_g);
|
||||
if(priv != NULL)
|
||||
{
|
||||
priv->refcount++;
|
||||
}
|
||||
}
|
||||
JVMContext* context = GetJVMContext();
|
||||
JSContext *pJSCX = context->js_context;
|
||||
|
||||
return LM_LockJS(errp);
|
||||
#else
|
||||
return JS_TRUE;
|
||||
#endif
|
||||
/* TODO: Get to the mocha lock.
|
||||
** LM_LockJS(cx, errp);
|
||||
*/
|
||||
if (pJSCX == NULL) {
|
||||
// TODO: get to the new LM api.
|
||||
// pJSCX = LM_GetCrippledContext();
|
||||
}
|
||||
|
||||
// Setup tls to maintain a stack of security contexts.
|
||||
if ((pNSIPrincipaArray != NULL) && (pNSISecurityContext != NULL)) {
|
||||
JVMSecurityStack *pSecInfoNew = new JVMSecurityStack;
|
||||
pSecInfoNew->pNSIPrincipaArray = pNSIPrincipaArray;
|
||||
pSecInfoNew->numPrincipals = numPrincipals;
|
||||
pSecInfoNew->pNSISecurityContext = pNSISecurityContext;
|
||||
pSecInfoNew->prev = pSecInfoNew;
|
||||
pSecInfoNew->next = pSecInfoNew;
|
||||
JSStackFrame *fp = NULL;
|
||||
pSecInfoNew->pJavaToJSFrame = JS_FrameIterator(pJSCX, &fp);
|
||||
pSecInfoNew->pJSToJavaFrame = NULL;
|
||||
|
||||
JVMSecurityStack *pSecInfoBottom = context->securityStack;
|
||||
if (pSecInfoBottom == NULL) {
|
||||
context->securityStack = pSecInfoNew;
|
||||
} else {
|
||||
pSecInfoBottom->prev->next = pSecInfoNew;
|
||||
pSecInfoNew->prev = pSecInfoBottom->prev;
|
||||
pSecInfoNew->next = pSecInfoBottom;
|
||||
pSecInfoBottom->prev = pSecInfoNew;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static void PR_CALLBACK
|
||||
exit_js_impl(JNIEnv *jEnv)
|
||||
{
|
||||
ThreadLocalStorageAtIndex0 *priv = NULL;
|
||||
//TODO:
|
||||
//LM_UnlockJS();
|
||||
|
||||
LM_UnlockJS();
|
||||
|
||||
if ( (PR_GetCurrentThread() != NULL )
|
||||
&& ((priv = (ThreadLocalStorageAtIndex0 *)PR_GetThreadPrivate(tlsIndex_g)) != NULL)
|
||||
)
|
||||
// Pop the security context stack
|
||||
JVMContext* context = GetJVMContext();
|
||||
JVMSecurityStack *pSecInfoBottom = context->securityStack;
|
||||
if (pSecInfoBottom != NULL)
|
||||
{
|
||||
priv->refcount--;
|
||||
if(priv->refcount == 0)
|
||||
{
|
||||
PR_SetThreadPrivate(tlsIndex_g, NULL);
|
||||
PR_DetachThread();
|
||||
free(priv);
|
||||
}
|
||||
if(pSecInfoBottom->next == pSecInfoBottom)
|
||||
{
|
||||
context->securityStack = NULL;
|
||||
pSecInfoBottom->next = NULL;
|
||||
pSecInfoBottom->prev = NULL;
|
||||
delete pSecInfoBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
JVMSecurityStack *top = pSecInfoBottom->prev;
|
||||
top->next = NULL;
|
||||
pSecInfoBottom->prev = top->prev;
|
||||
top->prev->next = pSecInfoBottom;
|
||||
top->prev = NULL;
|
||||
delete top;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -437,14 +461,13 @@ get_java_vm_impl(JNIEnv* env)
|
|||
return (SystemJavaVM*)JVM_GetJVMMgr();
|
||||
}
|
||||
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
|
||||
/*
|
||||
* Callbacks for client-specific jsjava glue
|
||||
*/
|
||||
JSJCallbacks jsj_callbacks = {
|
||||
static JSJCallbacks jsj_callbacks = {
|
||||
map_jsj_thread_to_js_context_impl,
|
||||
map_js_context_to_jsj_thread_impl,
|
||||
map_java_object_to_js_object_impl,
|
||||
|
@ -460,4 +483,29 @@ JSJCallbacks jsj_callbacks = {
|
|||
get_java_vm_impl
|
||||
};
|
||||
|
||||
void
|
||||
JVM_InitLCGlue(void)
|
||||
{
|
||||
JSJ_Init(&jsj_callbacks);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
TODO:Tom Pixley.
|
||||
APIs required from Tom Pixley.
|
||||
o LM_LockJS(errp); Grab the mocha lock before doing any liveconect stuff.
|
||||
This is because layers above JS engine including liveconnect
|
||||
DLL itself are not thread safe.
|
||||
o LM_UnlockJS()
|
||||
o LM_GetMochaEnabled() Check to see if Mocha is enabled.
|
||||
o LM_GetCrippledContext(). Get to a pre-created crippled context. All spontaneous
|
||||
Java calls map into one crippled context.
|
||||
o ET_InitMoja(0) != LM_MOJA_OK: This tells if moja initialization went ok.
|
||||
o LM_GetJSPrincipalsFromJavaCaller : Wrap a nsIPrincipal array object to get back a JSPrincipals data struct.
|
||||
o LM_CanAccessTargetStr This code is used to figure out if access is allowed. It is used during security
|
||||
stack walking. The tricky thing is that we need to set the start frame into
|
||||
TLS before calling this code.
|
||||
Look into nsCSecurityContext::Implies
|
||||
*/
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: C++; tab-width: 4; 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.
|
||||
*/
|
||||
|
||||
#ifndef lcglue_h___
|
||||
#define lcglue_h___
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "jni.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#include "nsIThreadManager.h"
|
||||
#include "nsISecurityContext.h"
|
||||
|
||||
struct JVMSecurityStack {
|
||||
void **pNSIPrincipaArray;
|
||||
int numPrincipals;
|
||||
void *pNSISecurityContext;
|
||||
JSStackFrame *pJavaToJSFrame;
|
||||
JSStackFrame *pJSToJavaFrame;
|
||||
JVMSecurityStack *next;
|
||||
JVMSecurityStack *prev;
|
||||
};
|
||||
typedef struct JVMSecurityStack JVMSecurityStack;
|
||||
|
||||
/**
|
||||
* JVMContext is maintained as thread local storage. The current thread's
|
||||
* context is accessed by calling GetJVMContext().
|
||||
*/
|
||||
struct JVMContext {
|
||||
JNIEnv *proxyEnv; /* thread local proxy JNI */
|
||||
JVMSecurityStack *securityStack; /* thread local security stack. */
|
||||
JSJavaThreadState *jsj_env; /* thread local JavaScript execution env. */
|
||||
JSContext *js_context; /* thread local JavaScript context. */
|
||||
JSStackFrame *js_startframe; /* thread local JavaScript stack frame. */
|
||||
};
|
||||
|
||||
JVMContext* GetJVMContext();
|
||||
void JVM_InitLCGlue(void); // in lcglue.cpp
|
||||
extern "C" void*
|
||||
ConvertNSIPrincipalToNSPrincipalArray(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext);
|
||||
|
||||
#endif /* lcglue_h___ */
|
|
@ -21,14 +21,18 @@ include <$(DEPTH)/config/config.mak>
|
|||
!ifndef MAKE_OBJ_TYPE
|
||||
MAKE_OBJ_TYPE=EXE
|
||||
!endif
|
||||
MAKE_OBJ_TYPE=DLL
|
||||
|
||||
DLLNAME=oji
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBNAME=oji$(MOZ_BITS)
|
||||
PDBFILE=$(LIBNAME).pdb
|
||||
#LIBNAME=oji$(MOZ_BITS)
|
||||
#PDBFILE=$(LIBNAME).pdb
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
|
@ -37,9 +41,13 @@ PDBFILE=$(LIBNAME).pdb
|
|||
#//------------------------------------------------------------------------
|
||||
|
||||
OBJS = .\$(OBJDIR)\jvmmgr.obj \
|
||||
.\$(OBJDIR)\scd.obj \
|
||||
.\$(OBJDIR)\nsJVMManager.obj \
|
||||
.\$(OBJDIR)\nsJVMPluginTagInfo.obj \
|
||||
.\$(OBJDIR)\ProxyJNI.obj \
|
||||
.\$(OBJDIR)\nsCSecurityContext.obj
|
||||
.\$(OBJDIR)\lcglue.obj \
|
||||
.\$(OBJDIR)\nsCSecurityContext.obj \
|
||||
.\$(OBJDIR)\nsCJVMManagerFactory.obj \
|
||||
.\$(OBJDIR)\scd.obj
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
|
@ -48,7 +56,7 @@ OBJS = .\$(OBJDIR)\jvmmgr.obj \
|
|||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
LIBRARY= .\$(OBJDIR)\$(LIBNAME).lib
|
||||
#LIBRARY= .\$(OBJDIR)\$(LIBNAME).lib
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
|
@ -76,6 +84,7 @@ LINCS= $(LINCS) -I_jri \
|
|||
-I$(PUBLIC)/plugin \
|
||||
-I$(PUBLIC)/oji \
|
||||
-I$(PUBLIC)/plugimpl \
|
||||
-I$(PUBLIC)/netlib \
|
||||
!endif
|
||||
-I$(DIST)/include/private \
|
||||
-I$(DEPTH)/lib/layout \
|
||||
|
@ -83,14 +92,24 @@ LINCS= $(LINCS) -I_jri \
|
|||
-I$(DEPTH)/lib/libjar \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = jvmmgr.cpp \
|
||||
scd.cpp
|
||||
|
||||
!endif # MOZ_OJI
|
||||
|
||||
MODULE = ojiimpl
|
||||
|
||||
EXPORTS = jvmmgr.h
|
||||
EXPORTS = jvmmgr.h \
|
||||
nsJVMManager.h \
|
||||
nsJVMPluginTagInfo.h
|
||||
|
||||
LLIBS = \
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\libplc21.lib \
|
||||
$(DIST)\lib\xpcom32.lib \
|
||||
$(DIST)\lib\xplib.lib \
|
||||
$(DIST)\lib\js3250.lib \
|
||||
$(DIST)\lib\jsj3250.lib \
|
||||
$(NULL)
|
||||
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
|
@ -108,12 +127,13 @@ PUBLIC_HEADER_DIR=$(PUBLIC)\ojiimpl
|
|||
PUBLIC_HEADER_DIR=$(PUBLIC)\win16
|
||||
!endif
|
||||
|
||||
export::
|
||||
$(MAKE_INSTALL) jvmmgr.h $(PUBLIC_HEADER_DIR)
|
||||
#export::
|
||||
# $(MAKE_INSTALL) $(EXPORTS) $(PUBLIC_HEADER_DIR)
|
||||
|
||||
!ifdef MOZ_OJI
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
$(RM_R) _jri
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/* -*- Mode: C++; tab-width: 4; 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.
|
||||
*/
|
||||
#include "prtypes.h"
|
||||
#include "nspr.h"
|
||||
#include "prmem.h"
|
||||
#include "prmon.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#include "nsJVMManager.h"
|
||||
#include "nsCJVMManagerFactory.h"
|
||||
#include "nsRepository.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIServiceManagerIID, NS_ISERVICEMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
static NS_DEFINE_IID(kCJVMManagerCID, NS_JVMMANAGER_CID);
|
||||
|
||||
nsIFactory *nsCJVMManagerFactory::m_pNSIFactory = NULL;
|
||||
nsIServiceManager *g_pNSIServiceManager = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* NSGetFactory:
|
||||
* Provides entry point to liveconnect dll.
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
if (!aClass.Equals(kCJVMManagerCID)) {
|
||||
return NS_ERROR_FACTORY_NOT_LOADED; // XXX right error?
|
||||
}
|
||||
nsCJVMManagerFactory* pCJVMManagerFactory = new nsCJVMManagerFactory();
|
||||
if (pCJVMManagerFactory == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
pCJVMManagerFactory->AddRef();
|
||||
*aFactory = pCJVMManagerFactory;
|
||||
res = servMgr->QueryInterface(kIServiceManagerIID, (void**)&g_pNSIServiceManager);
|
||||
if ((NS_OK == res) && (nsnull != g_pNSIServiceManager))
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT PRBool
|
||||
NSCanUnload(void)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISupports
|
||||
|
||||
NS_METHOD
|
||||
nsCJVMManagerFactory::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
PR_ASSERT(NULL != aInstancePtr);
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(kIFactoryIID) ||
|
||||
aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*) this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsCJVMManagerFactory)
|
||||
NS_IMPL_RELEASE(nsCJVMManagerFactory)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsIFactory:
|
||||
|
||||
NS_METHOD
|
||||
nsCJVMManagerFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
nsJVMManager *pNSJVMManager = NULL;
|
||||
*aResult = NULL;
|
||||
|
||||
if (aOuter && !aIID.Equals(kISupportsIID))
|
||||
return NS_NOINTERFACE; // XXX right error?
|
||||
pNSJVMManager = new nsJVMManager(aOuter);
|
||||
if (pNSJVMManager->QueryInterface(aIID,
|
||||
(void**)aResult) != NS_OK) {
|
||||
// then we're trying get a interface other than nsISupports and
|
||||
// nsICapsManager
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsCJVMManagerFactory::LockFactory(PRBool aLock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCJVMManagerFactory:
|
||||
|
||||
nsCJVMManagerFactory::nsCJVMManagerFactory(void)
|
||||
{
|
||||
if( m_pNSIFactory != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NS_INIT_REFCNT();
|
||||
nsresult err = NS_OK;
|
||||
NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
|
||||
err = this->QueryInterface(kIFactoryIID, (void**)&m_pNSIFactory);
|
||||
if ( (err == NS_OK) && (m_pNSIFactory != NULL) )
|
||||
{
|
||||
NS_DEFINE_CID(kCJVMManagerCID, NS_CCAPSMANAGER_CID);
|
||||
nsRepository::RegisterFactory(kCJVMManagerCID, m_pNSIFactory,
|
||||
PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
nsCJVMManagerFactory::~nsCJVMManagerFactory()
|
||||
{
|
||||
if(mRefCnt == 0)
|
||||
{
|
||||
NS_DEFINE_CID(kCJVMManagerCID, NS_CCAPSMANAGER_CID);
|
||||
nsRepository::UnregisterFactory(kCJVMManagerCID, (nsIFactory *)m_pNSIFactory);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- Mode: C++; tab-width: 4; 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.
|
||||
*/
|
||||
|
||||
#ifndef nsCJVMManagerFactory_h___
|
||||
#define nsCJVMManagerFactory_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
class nsCJVMManagerFactory : public nsIFactory {
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISupports and AggregatedQueryInterface:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsIFactory:
|
||||
|
||||
NS_IMETHOD
|
||||
CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD
|
||||
LockFactory(PRBool aLock);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCJVMManagerFactory:
|
||||
|
||||
nsCJVMManagerFactory(void);
|
||||
virtual ~nsCJVMManagerFactory(void);
|
||||
|
||||
protected:
|
||||
static nsIFactory *m_pNSIFactory;
|
||||
};
|
||||
|
||||
#endif // nsCJVMManagerFactory_h___
|
|
@ -30,6 +30,7 @@
|
|||
#include "jsdbgapi.h"
|
||||
#include "libmocha.h"
|
||||
#include "nsCSecurityContext.h"
|
||||
#include "jvmmgr.h"
|
||||
|
||||
static NS_DEFINE_IID(kISecurityContextIID, NS_ISECURITYCONTEXT_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
@ -59,29 +60,30 @@ nsCSecurityContext::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
extern PRUintn tlsIndex2_g;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISecurityContext:
|
||||
|
||||
NS_METHOD
|
||||
nsCSecurityContext::Implies(const char* target, const char* action, PRBool *bAllowedAccess)
|
||||
{
|
||||
//TODO: for test purpose only. Remove this stuff.
|
||||
//NOTE: Test purpose only. Turn this on if you do not want security stack walking code.
|
||||
//*bAllowedAccess = PR_TRUE;
|
||||
//if(1)
|
||||
// return NS_OK;
|
||||
//return NS_OK;
|
||||
|
||||
if(m_pJStoJavaFrame == NULL)
|
||||
{
|
||||
*bAllowedAccess = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
JSContext *pJSContext = LM_GetCrippledContext();
|
||||
PR_SetThreadPrivate(tlsIndex2_g, (void *)m_pJStoJavaFrame);
|
||||
*bAllowedAccess = LM_CanAccessTargetStr(pJSContext, target);
|
||||
PR_SetThreadPrivate(tlsIndex2_g, (void *)NULL);
|
||||
JSStackFrame** startFrame = JVM_GetStartJSFrameFromParallelStack();
|
||||
*startFrame = m_pJStoJavaFrame; // This updates the TLS start frame for a brief period
|
||||
// until the following code runs.
|
||||
/*
|
||||
** TODO: Get a new API from Tom.
|
||||
** bAllowedAccess = LM_CanAccessTargetStr(m_pJSCX, target);
|
||||
*/
|
||||
*startFrame = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -89,17 +91,13 @@ nsCSecurityContext::Implies(const char* target, const char* action, PRBool *bAll
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCSecurityContext:
|
||||
extern PRUintn tlsIndex3_g;
|
||||
nsCSecurityContext::nsCSecurityContext()
|
||||
: m_pJStoJavaFrame(NULL)
|
||||
nsCSecurityContext::nsCSecurityContext(JSContext* cx)
|
||||
: m_pJStoJavaFrame(NULL), m_pJSCX(NULL)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
JSContext *pJSCX = (JSContext *)PR_GetThreadPrivate(tlsIndex3_g);
|
||||
if (pJSCX == NULL)
|
||||
{
|
||||
pJSCX = LM_GetCrippledContext();
|
||||
}
|
||||
JSStackFrame *fp = NULL;
|
||||
m_pJStoJavaFrame = JS_FrameIterator(pJSCX, &fp);
|
||||
m_pJStoJavaFrame = JS_FrameIterator(cx, &fp);
|
||||
m_pJSCX = cx;
|
||||
}
|
||||
|
||||
nsCSecurityContext::~nsCSecurityContext()
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
#ifndef nsCSecurityContext_h___
|
||||
#define nsCSecurityContext_h___
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "nsISecurityContext.h"
|
||||
|
||||
struct JSContext;
|
||||
|
||||
/**
|
||||
* nsCSecurityContext implements nsISecurityContext interface for navigator.
|
||||
|
@ -58,11 +60,12 @@ public:
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCSecurityContext:
|
||||
|
||||
nsCSecurityContext(void);
|
||||
nsCSecurityContext(JSContext* cx);
|
||||
virtual ~nsCSecurityContext(void);
|
||||
|
||||
protected:
|
||||
JSStackFrame *m_pJStoJavaFrame;
|
||||
JSContext *m_pJSCX;
|
||||
};
|
||||
|
||||
#endif // nsCSecurityContext_h___
|
||||
|
|
|
@ -21,19 +21,30 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nsJVMManager.h"
|
||||
#include "npglue.h"
|
||||
//#include "npglue.h"
|
||||
#include "prefapi.h"
|
||||
#include "np.h"
|
||||
#include "primpl.h"
|
||||
#include "prio.h"
|
||||
#include "prmem.h"
|
||||
#include "prthread.h"
|
||||
#include "pprthred.h"
|
||||
#include "plstr.h"
|
||||
#include "jni.h"
|
||||
#include "jsjava.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "libmocha.h"
|
||||
|
||||
extern "C" void jvm_InitLCGlue(void); // in lcglue.cpp
|
||||
|
||||
#include "libevent.h"
|
||||
#include "nsCCapsManager.h"
|
||||
#include "prinrval.h"
|
||||
#include "ProxyJNI.h"
|
||||
#include "prcmon.h"
|
||||
#include "nsCSecurityContext.h"
|
||||
#include "nsISecurityContext.h"
|
||||
#include "nsIPluginHost.h"
|
||||
#include "nsIPluginManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "lcglue.h"
|
||||
#include "xpgetstr.h"
|
||||
extern "C" int XP_PROGRESS_STARTING_JAVA;
|
||||
extern "C" int XP_PROGRESS_STARTING_JAVA_DONE;
|
||||
|
@ -41,6 +52,9 @@ extern "C" int XP_JAVA_NO_CLASSES;
|
|||
extern "C" int XP_JAVA_GENERAL_FAILURE;
|
||||
extern "C" int XP_JAVA_STARTUP_FAILED;
|
||||
extern "C" int XP_JAVA_DEBUGGER_FAILED;
|
||||
extern nsIServiceManager *g_pNSIServiceManager;
|
||||
static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
|
||||
static NS_DEFINE_CID(kPluginHostIID, NS_IPLUGINHOST_IID);
|
||||
|
||||
// FIXME -- need prototypes for these functions!!! XXX
|
||||
#ifdef XP_MAC
|
||||
|
@ -53,6 +67,7 @@ void stopAsyncCursors(void);
|
|||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIJVMManagerIID, NS_IJVMMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIThreadManagerIID, NS_ITHREADMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIJVMPluginIID, NS_IJVMPLUGIN_IID);
|
||||
static NS_DEFINE_IID(kISymantecDebugManagerIID, NS_ISYMANTECDEBUGMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
|
||||
|
@ -61,6 +76,114 @@ static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
|
|||
|
||||
NS_IMPL_AGGREGATED(nsJVMManager);
|
||||
|
||||
extern "C" {
|
||||
static nsIJVMPlugin* GetRunningJVM(void);
|
||||
static nsIJVMPlugin*
|
||||
GetRunningJVM()
|
||||
{
|
||||
nsIJVMPlugin* jvm = NULL;
|
||||
nsJVMManager* jvmMgr = JVM_GetJVMMgr();
|
||||
if (jvmMgr) {
|
||||
nsJVMStatus status = jvmMgr->GetJVMStatus();
|
||||
if (status == nsJVMStatus_Enabled)
|
||||
status = jvmMgr->StartupJVM();
|
||||
if (status == nsJVMStatus_Running) {
|
||||
jvm = jvmMgr->GetJVMPlugin();
|
||||
}
|
||||
jvmMgr->Release();
|
||||
}
|
||||
return jvm;
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::CreateProxyJNI(nsISecureJNI2* inSecureEnv, JNIEnv** outProxyEnv)
|
||||
{
|
||||
JVMContext* context = GetJVMContext();
|
||||
if (context->proxyEnv != NULL) {
|
||||
*outProxyEnv = context->proxyEnv;
|
||||
return NS_OK;
|
||||
}
|
||||
nsIJVMPlugin* jvmPlugin = GetRunningJVM();
|
||||
if (jvmPlugin != NULL) {
|
||||
*outProxyEnv = context->proxyEnv = ::CreateProxyJNI(jvmPlugin, inSecureEnv);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::GetProxyJNI(JNIEnv** outProxyEnv)
|
||||
{
|
||||
JVMContext* context = GetJVMContext();
|
||||
*outProxyEnv = context->proxyEnv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIThreadManager:
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::GetCurrentThread(PRUint32* threadID)
|
||||
{
|
||||
*threadID = PRUint32(PR_GetCurrentThread());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::Sleep(PRUint32 milli)
|
||||
{
|
||||
PRIntervalTime ticks = (milli > 0 ? PR_MillisecondsToInterval(milli) : PR_INTERVAL_NO_WAIT);
|
||||
return (PR_Sleep(ticks) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::EnterMonitor(void* address)
|
||||
{
|
||||
return (PR_CEnterMonitor(address) != NULL ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::ExitMonitor(void* address)
|
||||
{
|
||||
return (PR_CExitMonitor(address) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::Wait(void* address, PRUint32 milli)
|
||||
{
|
||||
PRIntervalTime timeout = (milli > 0 ? PR_MillisecondsToInterval(milli) : PR_INTERVAL_NO_TIMEOUT);
|
||||
return (PR_CWait(address, timeout) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::Notify(void* address)
|
||||
{
|
||||
return (PR_CNotify(address) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::NotifyAll(void* address)
|
||||
{
|
||||
return (PR_CNotifyAll(address) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
static void thread_starter(void* arg)
|
||||
{
|
||||
nsIRunnable* runnable = (nsIRunnable*) arg;
|
||||
if (runnable != NULL) {
|
||||
runnable->Run();
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::CreateThread(PRUint32* outThreadID, nsIRunnable* runnable)
|
||||
{
|
||||
PRThread* thread = PR_CreateThread(PR_USER_THREAD, &thread_starter, (void*) runnable,
|
||||
PR_PRIORITY_LOW, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
*outThreadID = (PRUint32) thread;
|
||||
return (thread != NULL ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
|
@ -70,14 +193,14 @@ nsJVMManager::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
|||
if (jvmmgr == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
jvmmgr->AddRef();
|
||||
*aInstancePtr = outer ? (void*)jvmmgr->GetInner() : (void*)jvmmgr;
|
||||
*aInstancePtr = (outer != NULL ? (void*) jvmmgr->GetInner() : (void*) jvmmgr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsJVMManager::nsJVMManager(nsISupports* outer)
|
||||
: fJVM(NULL), fStatus(nsJVMStatus_Enabled),
|
||||
fRegisteredJavaPrefChanged(PR_FALSE), fDebugManager(NULL), fJSJavaVM(NULL),
|
||||
fClassPathAdditions(new nsVector())
|
||||
fClassPathAdditions(new nsVector()), fClassPathAdditionsString(NULL)
|
||||
{
|
||||
NS_INIT_AGGREGATED(outer);
|
||||
}
|
||||
|
@ -89,6 +212,8 @@ nsJVMManager::~nsJVMManager()
|
|||
PR_Free((*fClassPathAdditions)[i]);
|
||||
}
|
||||
delete fClassPathAdditions;
|
||||
if (fClassPathAdditionsString)
|
||||
PR_Free(fClassPathAdditionsString);
|
||||
if (fJVM) {
|
||||
/*nsrefcnt c =*/ fJVM->Release(); // Release for QueryInterface in GetJVM
|
||||
// XXX unload plugin if c == 1 ? (should this be done inside Release?)
|
||||
|
@ -103,11 +228,16 @@ nsJVMManager::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kIThreadManagerIID)) {
|
||||
*aInstancePtr = (void*) (nsIThreadManager*) this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
#ifdef XP_PC
|
||||
// Aggregates...
|
||||
if (fDebugManager == NULL) {
|
||||
nsresult rslt =
|
||||
nsSymantecDebugManager::Create(this, kISupportsIID,
|
||||
nsSymantecDebugManager::Create((nsIJVMManager *)this, kISupportsIID,
|
||||
(void**)&fDebugManager, this);
|
||||
if (rslt != NS_OK) return rslt;
|
||||
}
|
||||
|
@ -119,6 +249,30 @@ nsJVMManager::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_METHOD
|
||||
nsJVMManager::GetClasspathAdditions(const char* *result)
|
||||
{
|
||||
if (fClassPathAdditionsString != NULL)
|
||||
PR_Free(fClassPathAdditionsString);
|
||||
int count = fClassPathAdditions->GetSize();
|
||||
char* classpathAdditions = NULL;
|
||||
for (int i = 0; i < count; i++) {
|
||||
const char* path = (const char*)(*fClassPathAdditions)[i];
|
||||
char* oldPath = classpathAdditions;
|
||||
if (oldPath) {
|
||||
classpathAdditions = PR_smprintf("%s%c%s", oldPath, PR_PATH_SEPARATOR, path);
|
||||
PR_Free(oldPath);
|
||||
}
|
||||
else
|
||||
classpathAdditions = PL_strdup(path);
|
||||
}
|
||||
fClassPathAdditionsString = classpathAdditions;
|
||||
*result = classpathAdditions; // XXX need to convert to PRUnichar*
|
||||
return classpathAdditions ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
static const char*
|
||||
ConvertToPlatformPathList(const char* cp)
|
||||
|
@ -130,30 +284,26 @@ ConvertToPlatformPathList(const char* cp)
|
|||
{
|
||||
const char* path;
|
||||
const char* strtok_path;
|
||||
|
||||
|
||||
char* result = (char*) malloc(1);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
result[0] = '\0';
|
||||
path = c;
|
||||
strtok_path = path;
|
||||
#ifndef NSPR20
|
||||
while ((path = XP_STRTOK(strtok_path, PATH_SEPARATOR_STR)))
|
||||
#else
|
||||
while ((path = XP_STRTOK(strtok_path, PR_PATH_SEPARATOR_STR)))
|
||||
#endif
|
||||
{
|
||||
const char* macPath;
|
||||
OSErr err = ConvertUnixPathToMacPath(path, &macPath);
|
||||
char* r = PR_smprintf("%s\r%s", result, macPath);
|
||||
while ((path = XP_STRTOK(strtok_path, PR_PATH_SEPARATOR_STR)))
|
||||
{
|
||||
const char* macPath;
|
||||
OSErr err = ConvertUnixPathToMacPath(path, &macPath);
|
||||
char* r = PR_smprintf("%s\r%s", result, macPath);
|
||||
|
||||
strtok_path = NULL;
|
||||
strtok_path = NULL;
|
||||
|
||||
if (r == NULL)
|
||||
return result; /* return what we could come up with */
|
||||
free(result);
|
||||
result = r;
|
||||
}
|
||||
if (r == NULL)
|
||||
return result; /* return what we could come up with */
|
||||
free(result);
|
||||
result = r;
|
||||
}
|
||||
free(c);
|
||||
return result;
|
||||
}
|
||||
|
@ -161,7 +311,6 @@ ConvertToPlatformPathList(const char* cp)
|
|||
return c;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsJVMManager::ReportJVMError(nsresult err)
|
||||
|
@ -183,7 +332,7 @@ nsJVMManager::ReportJVMError(nsresult err)
|
|||
const char* msg = GetJavaErrorString(env);
|
||||
plugin->ReleaseJNIEnv(env);
|
||||
#ifdef DEBUG
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionDescribe();
|
||||
#endif
|
||||
s = PR_smprintf(XP_GetString(XP_JAVA_STARTUP_FAILED),
|
||||
(msg ? msg : ""));
|
||||
|
@ -206,7 +355,6 @@ nsJVMManager::ReportJVMError(nsresult err)
|
|||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
/* stolen from java_lang_Object.h (jri version) */
|
||||
#define classname_java_lang_Object "java/lang/Object"
|
||||
#define name_java_lang_Object_toString "toString"
|
||||
|
@ -230,15 +378,16 @@ nsJVMManager::GetJavaErrorString(JNIEnv* env)
|
|||
jmethodID toString = env->GetMethodID(classObject, name_java_lang_Object_toString, sig_java_lang_Object_toString);
|
||||
jstring excString = (jstring) env->CallObjectMethod(exc, toString);
|
||||
|
||||
jboolean isCopy;
|
||||
jboolean isCopy;
|
||||
const char* msg = env->GetStringUTFChars(excString, &isCopy);
|
||||
if (msg != NULL) {
|
||||
const char* dupmsg = (msg == NULL ? NULL : strdup(msg));
|
||||
const char* dupmsg = (msg == NULL ? (const char*)NULL : strdup(msg));
|
||||
env->ReleaseStringUTFChars(excString, msg);
|
||||
msg = dupmsg;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -264,13 +413,32 @@ nsJVMManager::StartupJVM(void)
|
|||
PR_LOG(NSJAVA, PR_LOG_ALWAYS, ("Starting java..."));
|
||||
#endif
|
||||
|
||||
MWContext* someRandomContext = XP_FindSomeContext();
|
||||
if (someRandomContext) {
|
||||
FE_Progress(someRandomContext, XP_GetString(XP_PROGRESS_STARTING_JAVA));
|
||||
}
|
||||
/* TODO: Show the progress bar.
|
||||
MWContext* someRandomContext = XP_FindSomeContext();
|
||||
if (someRandomContext) {
|
||||
FE_Progress(someRandomContext, XP_GetString(XP_PROGRESS_STARTING_JAVA));
|
||||
}
|
||||
*/
|
||||
|
||||
PR_ASSERT(fJVM == NULL);
|
||||
nsIPlugin* plugin = NPL_LoadPluginByType(NPJVM_MIME_TYPE);
|
||||
nsIPlugin* plugin = NULL;
|
||||
/*
|
||||
**TODO: amusil. Load the plugin by getting into Service manager.
|
||||
** Right now there is no API to do this stuff. We need to
|
||||
** add this to nsIPluginHost. We need a case where we just
|
||||
** load the plugin but do not instantiate any instance.
|
||||
** The code in there right now always creates a new instance.
|
||||
** But for Java we may not create any instances and may need to
|
||||
** do JNI calls via liveconnect.
|
||||
** nsIPlugin* plugin = NPL_LoadPluginByType(NS_JVM_MIME_TYPE);
|
||||
*/
|
||||
nsIPluginHost* pNSIPluginHost = NULL;
|
||||
nsresult err = g_pNSIServiceManager->GetService(kPluginManagerCID, kPluginHostIID, (nsISupports**)&pNSIPluginHost);
|
||||
if (err != NS_OK) {
|
||||
fStatus = nsJVMStatus_Failed;
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
if (plugin == NULL) {
|
||||
fStatus = nsJVMStatus_Failed;
|
||||
return fStatus;
|
||||
|
@ -282,31 +450,16 @@ nsJVMManager::StartupJVM(void)
|
|||
fStatus = nsJVMStatus_Failed;
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
nsJVMInitArgs initargs;
|
||||
int count = fClassPathAdditions->GetSize();
|
||||
char* classpathAdditions = NULL;
|
||||
for (int i = 0; i < count; i++) {
|
||||
const char* path = (const char*)(*fClassPathAdditions)[i];
|
||||
char* oldPath = classpathAdditions;
|
||||
if (oldPath) {
|
||||
classpathAdditions = PR_smprintf("%s%c%s", oldPath, PR_PATH_SEPARATOR, path);
|
||||
PR_Free(oldPath);
|
||||
}
|
||||
else
|
||||
classpathAdditions = PL_strdup(path);
|
||||
}
|
||||
initargs.version = nsJVMInitArgs_Version;
|
||||
initargs.classpathAdditions = classpathAdditions;
|
||||
|
||||
nsresult err = fJVM->StartupJVM(&initargs);
|
||||
if (err == NS_OK) {
|
||||
/* assume the JVM is running. */
|
||||
fStatus = nsJVMStatus_Running;
|
||||
// Get an execution environment -- that will cause the VM to start up
|
||||
JNIEnv* env = NULL;
|
||||
rslt = fJVM->GetJNIEnv(&env);
|
||||
if (rslt != NS_OK || env == NULL) {
|
||||
fStatus = nsJVMStatus_Failed;
|
||||
}
|
||||
else {
|
||||
ReportJVMError(err);
|
||||
fStatus = nsJVMStatus_Failed;
|
||||
/* else the JVM is running. */
|
||||
fStatus = nsJVMStatus_Running;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -323,10 +476,12 @@ nsJVMManager::StartupJVM(void)
|
|||
("Starting java...%s (%ld ms)",
|
||||
(fStatus == nsJVMStatus_Running ? "done" : "failed"), d));
|
||||
#endif
|
||||
/* TODO:
|
||||
|
||||
if (someRandomContext) {
|
||||
FE_Progress(someRandomContext, XP_GetString(XP_PROGRESS_STARTING_JAVA_DONE));
|
||||
}
|
||||
if (someRandomContext) {
|
||||
FE_Progress(someRandomContext, XP_GetString(XP_PROGRESS_STARTING_JAVA_DONE));
|
||||
}
|
||||
*/
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
@ -336,13 +491,14 @@ nsJVMManager::ShutdownJVM(PRBool fullShutdown)
|
|||
if (fStatus == nsJVMStatus_Running) {
|
||||
PR_ASSERT(fJVM != NULL);
|
||||
(void)MaybeShutdownLiveConnect();
|
||||
nsresult err = fJVM->ShutdownJVM(fullShutdown);
|
||||
if (err == NS_OK)
|
||||
// XXX need to shutdown JVM via ServiceManager
|
||||
// nsresult err = fJVM->ShutdownJVM(fullShutdown);
|
||||
// if (err == NS_OK)
|
||||
fStatus = nsJVMStatus_Enabled;
|
||||
else {
|
||||
ReportJVMError(err);
|
||||
fStatus = nsJVMStatus_Disabled;
|
||||
}
|
||||
// else {
|
||||
// ReportJVMError(err);
|
||||
// fStatus = nsJVMStatus_Disabled;
|
||||
// }
|
||||
fJVM = NULL;
|
||||
}
|
||||
PR_ASSERT(fJVM == NULL);
|
||||
|
@ -355,12 +511,14 @@ static int PR_CALLBACK
|
|||
JavaPrefChanged(const char *prefStr, void* data)
|
||||
{
|
||||
nsJVMManager* mgr = (nsJVMManager*)data;
|
||||
XP_Bool prefBool;
|
||||
PRBool prefBool;
|
||||
#if defined(XP_MAC)
|
||||
// beard: under Mozilla, no way to enable this right now.
|
||||
prefBool = TRUE;
|
||||
// beard: under Mozilla, no way to enable this right now.
|
||||
prefBool = TRUE;
|
||||
#else
|
||||
/*TODO: hshaw: Use the new prefs api. Get to it from service manager and use nsIPref.
|
||||
PREF_GetBoolPref(prefStr, &prefBool);
|
||||
*/
|
||||
#endif
|
||||
mgr->SetJVMEnabled(prefBool);
|
||||
return 0;
|
||||
|
@ -386,7 +544,9 @@ nsJVMManager::EnsurePrefCallbackRegistered(void)
|
|||
{
|
||||
if (fRegisteredJavaPrefChanged != PR_TRUE) {
|
||||
fRegisteredJavaPrefChanged = PR_TRUE;
|
||||
/*TODO: hshaw: Use the new prefs api. Get to it from service manager.
|
||||
PREF_RegisterCallback("security.enable_java", JavaPrefChanged, this);
|
||||
*/
|
||||
JavaPrefChanged("security.enable_java", this);
|
||||
}
|
||||
}
|
||||
|
@ -408,34 +568,34 @@ nsJVMManager::MaybeStartupLiveConnect(void)
|
|||
if (fJSJavaVM)
|
||||
return PR_TRUE;
|
||||
|
||||
do {
|
||||
static PRBool registeredLiveConnectFactory = PR_FALSE;
|
||||
if (!registeredLiveConnectFactory) {
|
||||
do {
|
||||
static PRBool registeredLiveConnectFactory = PR_FALSE;
|
||||
if (!registeredLiveConnectFactory) {
|
||||
NS_DEFINE_CID(kCLiveconnectCID, NS_CLIVECONNECT_CID);
|
||||
registeredLiveConnectFactory =
|
||||
(nsRepository::RegisterFactory(kCLiveconnectCID, (const char *)JSJDLL,
|
||||
PR_FALSE, PR_FALSE) == NS_OK);
|
||||
}
|
||||
if (IsLiveConnectEnabled() && StartupJVM() == nsJVMStatus_Running) {
|
||||
jvm_InitLCGlue();
|
||||
JVM_InitLCGlue();
|
||||
nsIJVMPlugin* plugin = GetJVMPlugin();
|
||||
if (plugin) {
|
||||
#if 0
|
||||
const char* classpath = NULL;
|
||||
nsresult err = plugin->GetClassPath(&classpath);
|
||||
if (err != NS_OK) break;
|
||||
const char* classpath = NULL;
|
||||
nsresult err = plugin->GetClassPath(&classpath);
|
||||
if (err != NS_OK) break;
|
||||
|
||||
JavaVM* javaVM = NULL;
|
||||
err = plugin->GetJavaVM(&javaVM);
|
||||
if (err != NS_OK) break;
|
||||
JavaVM* javaVM = NULL;
|
||||
err = plugin->GetJavaVM(&javaVM);
|
||||
if (err != NS_OK) break;
|
||||
#endif
|
||||
fJSJavaVM = JSJ_ConnectToJavaVM(NULL, NULL);
|
||||
if (fJSJavaVM != NULL)
|
||||
return PR_TRUE;
|
||||
// plugin->Release(); // GetJVMPlugin no longer calls AddRef
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
fJSJavaVM = JSJ_ConnectToJavaVM(NULL, NULL);
|
||||
if (fJSJavaVM != NULL)
|
||||
return PR_TRUE;
|
||||
// plugin->Release(); // GetJVMPlugin no longer calls AddRef
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -453,11 +613,14 @@ nsJVMManager::MaybeShutdownLiveConnect(void)
|
|||
PRBool
|
||||
nsJVMManager::IsLiveConnectEnabled(void)
|
||||
{
|
||||
if (LM_GetMochaEnabled()) {
|
||||
nsJVMStatus status = GetJVMStatus();
|
||||
return (status == nsJVMStatus_Enabled || status == nsJVMStatus_Running);
|
||||
}
|
||||
return PR_FALSE;
|
||||
#if 0
|
||||
TODO: Get a replacement for LM_GetMochaEnabled. This is on Ton's list.
|
||||
if (LM_GetMochaEnabled()) {
|
||||
nsJVMStatus status = GetJVMStatus();
|
||||
return (status == nsJVMStatus_Enabled || status == nsJVMStatus_Running);
|
||||
}
|
||||
#endif
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -474,29 +637,29 @@ nsJVMManager::AddToClassPath(const char* dirPath)
|
|||
while ((dirent = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
|
||||
PRFileInfo info;
|
||||
char* path = PR_smprintf("%s%c%s", dirPath, PR_DIRECTORY_SEPARATOR, PR_DirName(dirent));
|
||||
if (path != NULL) {
|
||||
PRBool freePath = PR_TRUE;
|
||||
if ((PR_GetFileInfo(path, &info) == PR_SUCCESS)
|
||||
&& (info.type == PR_FILE_FILE)) {
|
||||
int len = PL_strlen(path);
|
||||
if (path != NULL) {
|
||||
PRBool freePath = PR_TRUE;
|
||||
if ((PR_GetFileInfo(path, &info) == PR_SUCCESS)
|
||||
&& (info.type == PR_FILE_FILE)) {
|
||||
int len = PL_strlen(path);
|
||||
|
||||
/* Is it a zip or jar file? */
|
||||
if ((len > 4) &&
|
||||
((PL_strcasecmp(path+len-4, ".zip") == 0) ||
|
||||
(PL_strcasecmp(path+len-4, ".jar") == 0))) {
|
||||
fClassPathAdditions->Add((void*)path);
|
||||
if (jvm) {
|
||||
/* Add this path to the classpath: */
|
||||
jvm->AddToClassPath(path);
|
||||
}
|
||||
freePath = PR_FALSE;
|
||||
}
|
||||
}
|
||||
/* Is it a zip or jar file? */
|
||||
if ((len > 4) &&
|
||||
((PL_strcasecmp(path+len-4, ".zip") == 0) ||
|
||||
(PL_strcasecmp(path+len-4, ".jar") == 0))) {
|
||||
fClassPathAdditions->Add((void*)path);
|
||||
if (jvm) {
|
||||
/* Add this path to the classpath: */
|
||||
jvm->AddToClassPath(path);
|
||||
}
|
||||
freePath = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't leak the path!
|
||||
if (freePath)
|
||||
PR_smprintf_free(path);
|
||||
}
|
||||
// Don't leak the path!
|
||||
if (freePath)
|
||||
PR_smprintf_free(path);
|
||||
}
|
||||
}
|
||||
PR_CloseDir(dir);
|
||||
}
|
||||
|
@ -553,19 +716,4 @@ nsJVMFactory::LockFactory(PRBool aLock)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Bogus stuff that will go away when
|
||||
// a) we have a persistent registry for CLSID -> Factory mappings, and
|
||||
// b) when we ship a browser where all this JVM management code is in a DLL.
|
||||
|
||||
static NS_DEFINE_CID(kJVMManagerCID, NS_JVMMANAGER_CID);
|
||||
|
||||
extern "C" void
|
||||
jvm_RegisterJVMMgr(void)
|
||||
{
|
||||
nsRepository::RegisterFactory(kJVMManagerCID,
|
||||
new nsJVMFactory(),
|
||||
PR_TRUE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "xp_core.h" /* include first because of Bool problem */
|
||||
#include "prtypes.h"
|
||||
#include "nsCom.h"
|
||||
#include "jni.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "nsError.h"
|
||||
|
||||
|
||||
#include "nsjvm.h"
|
||||
#include "nsAgg.h"
|
||||
|
@ -31,10 +35,6 @@
|
|||
|
||||
class nsSymantecDebugManager;
|
||||
|
||||
struct ThreadLocalStorageAtIndex0 {
|
||||
PRUint32 refcount;
|
||||
};
|
||||
typedef struct ThreadLocalStorageAtIndex0 ThreadLocalStorageAtIndex0;
|
||||
|
||||
/*******************************************************************************
|
||||
* NsJVMManager is the interface to the JVM manager that the browser sees. All
|
||||
|
@ -42,16 +42,88 @@ typedef struct ThreadLocalStorageAtIndex0 ThreadLocalStorageAtIndex0;
|
|||
* nsIJVMManager is the more limited interface what the JVM plugin sees.
|
||||
******************************************************************************/
|
||||
|
||||
struct nsJVMManager : public nsIJVMManager {
|
||||
struct nsJVMManager : public nsIJVMManager, public nsIThreadManager {
|
||||
public:
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
|
||||
/* from nsIJVMManager: */
|
||||
|
||||
/**
|
||||
* Creates a proxy JNI with an optional secure environment (which can be NULL).
|
||||
* There is a one-to-one correspondence between proxy JNIs and threads, so
|
||||
* calling this method multiple times from the same thread will return
|
||||
* the same proxy JNI.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateProxyJNI(nsISecureJNI2* inSecureEnv, JNIEnv** outProxyEnv);
|
||||
|
||||
/**
|
||||
* Returns the proxy JNI associated with the current thread, or NULL if no
|
||||
* such association exists.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetProxyJNI(JNIEnv** outProxyEnv);
|
||||
|
||||
/* from nsIThreadManager: */
|
||||
|
||||
/**
|
||||
* Returns a unique identifier for the "current" system thread.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetCurrentThread(PRUint32* threadID);
|
||||
|
||||
/* NsJVMManager specific methods: */
|
||||
/**
|
||||
* Pauses the current thread for the specified number of milliseconds.
|
||||
* If milli is zero, then merely yields the CPU if another thread of
|
||||
* greater or equal priority.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Sleep(PRUint32 milli = 0);
|
||||
|
||||
/**
|
||||
* Creates a unique monitor for the specified address, and makes the
|
||||
* current system thread the owner of the monitor.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
EnterMonitor(void* address);
|
||||
|
||||
/**
|
||||
* Exits the monitor associated with the address.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
ExitMonitor(void* address);
|
||||
|
||||
/**
|
||||
* Waits on the monitor associated with the address (must be entered already).
|
||||
* If milli is 0, wait indefinitely.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Wait(void* address, PRUint32 milli = 0);
|
||||
|
||||
/**
|
||||
* Notifies a single thread waiting on the monitor associated with the address (must be entered already).
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Notify(void* address);
|
||||
|
||||
/**
|
||||
* Notifies all threads waiting on the monitor associated with the address (must be entered already).
|
||||
*/
|
||||
NS_IMETHOD
|
||||
NotifyAll(void* address);
|
||||
|
||||
/**
|
||||
* Thread creation primitives.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
CreateThread(PRUint32* threadID, nsIRunnable* runnable);
|
||||
|
||||
/* JVMMgr specific methods: */
|
||||
|
||||
/* ====> From here on are things only called by the browser, not the plugin... */
|
||||
NS_IMETHOD
|
||||
GetClasspathAdditions(const char* *result);
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
|
@ -64,9 +136,11 @@ public:
|
|||
nsJVMStatus ShutdownJVM(PRBool fullShutdown = PR_FALSE);
|
||||
nsJVMStatus GetJVMStatus(void);
|
||||
void SetJVMEnabled(PRBool enabled);
|
||||
|
||||
|
||||
#if 0
|
||||
void ReportJVMError(nsresult err);
|
||||
const char* GetJavaErrorString(JNIEnv* env);
|
||||
#endif
|
||||
|
||||
nsresult AddToClassPath(const char* dirPath);
|
||||
PRBool MaybeStartupLiveConnect(void);
|
||||
|
@ -75,8 +149,8 @@ public:
|
|||
JSJavaVM* GetJSJavaVM(void) { return fJSJavaVM; }
|
||||
|
||||
|
||||
protected:
|
||||
nsJVMManager(nsISupports* outer);
|
||||
protected:
|
||||
virtual ~nsJVMManager(void);
|
||||
|
||||
void EnsurePrefCallbackRegistered(void);
|
||||
|
@ -88,6 +162,7 @@ protected:
|
|||
nsISupports* fDebugManager;
|
||||
JSJavaVM * fJSJavaVM;
|
||||
nsVector* fClassPathAdditions;
|
||||
char* fClassPathAdditionsString;
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -116,12 +191,4 @@ protected:
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NS_JVMMANAGER_CID \
|
||||
{ /* 38e7ef10-58df-11d2-8164-006008119d7a */ \
|
||||
0x38e7ef10, \
|
||||
0x58df, \
|
||||
0x11d2, \
|
||||
{0x81, 0x64, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
#endif // nsJVMManager_h___
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include "nsJVMPluginTagInfo.h"
|
||||
#include "nsIPluginTagInfo2.h"
|
||||
#include "plstr.h"
|
||||
#ifdef XP_UNIX
|
||||
#undef Bool
|
||||
#endif
|
||||
#include "xp.h"
|
||||
#include "xp_str.h"
|
||||
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
// Plugin Manager Methods to support the JVM Plugin API
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "jvmmgr.h"
|
||||
#include "nsJVMManager.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kISymantecDebugManagerIID, NS_ISYMANTECDEBUGMANAGER_IID);
|
||||
|
||||
NS_IMPL_AGGREGATED(nsSymantecDebugManager);
|
||||
|
||||
nsSymantecDebugManager::nsSymantecDebugManager(nsISupports* outer, nsJVMMgr* jvmMgr)
|
||||
nsSymantecDebugManager::nsSymantecDebugManager(nsISupports* outer, nsJVMManager* jvmMgr)
|
||||
: fJVMMgr(jvmMgr)
|
||||
{
|
||||
NS_INIT_AGGREGATED(outer);
|
||||
|
@ -50,7 +50,7 @@ nsSymantecDebugManager::AggregatedQueryInterface(const nsIID& aIID, void** aInst
|
|||
|
||||
NS_METHOD
|
||||
nsSymantecDebugManager::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr,
|
||||
nsJVMMgr* jvmMgr)
|
||||
nsJVMManager* jvmMgr)
|
||||
{
|
||||
if (outer && !aIID.Equals(kISupportsIID))
|
||||
return NS_NOINTERFACE; // XXX right error?
|
||||
|
@ -70,7 +70,11 @@ NS_METHOD
|
|||
nsSymantecDebugManager::SetDebugAgentPassword(PRInt32 pwd)
|
||||
{
|
||||
#if defined(XP_PC) && defined(_WIN32)
|
||||
HWND win = NULL;
|
||||
/*
|
||||
** TODO:amusil Get to a hidden window for symantec debugger to get its password from.
|
||||
HWND win = FindNavigatorHiddenWindow();
|
||||
*/
|
||||
HANDLE sem;
|
||||
long err;
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@ public:
|
|||
const char* url,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
nsPluginStreamType streamType = nsPluginStreamType_Normal,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE) = 0;
|
||||
|
@ -104,7 +103,6 @@ public:
|
|||
PRBool isFile = PR_FALSE,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
nsPluginStreamType streamType = nsPluginStreamType_Normal,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE,
|
||||
|
@ -186,6 +184,15 @@ public:
|
|||
{0x81, 0x64, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
// CLSID for the browser's global plugin manager object.
|
||||
#define NS_PLUGINMANAGER_CID \
|
||||
{ /* ce768990-5a4e-11d2-8164-006008119d7a */ \
|
||||
0xce768990, \
|
||||
0x5a4e, \
|
||||
0x11d2, \
|
||||
{0x81, 0x64, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* nsIPluginManager_h___ */
|
||||
|
|
|
@ -79,6 +79,8 @@
|
|||
#ifndef nsplugins_h___
|
||||
#define nsplugins_h___
|
||||
|
||||
#define NEW_PLUGIN_STREAM_API
|
||||
|
||||
#include "nsRepository.h" // for NSGetFactory
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,6 +98,7 @@
|
|||
*/
|
||||
// (Declared in nsRepository.h)
|
||||
//extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aClass,
|
||||
// nsISupports* serviceMgr,
|
||||
// nsIFactory **aFactory);
|
||||
|
||||
/**
|
||||
|
@ -134,7 +137,7 @@
|
|||
* Note that this interface is part of a new JNI-based LiveConnect
|
||||
* implementation and superceeds that provided prior to Communicator 5.0.
|
||||
*/
|
||||
#include "nsILiveConnectPlugin.h"
|
||||
//#include "nsILiveConnectPlugin.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
|
@ -229,7 +232,7 @@
|
|||
*
|
||||
* To obtain: QueryInterface on nsIPluginInstancePeer
|
||||
*/
|
||||
#include "nsILiveConnectPlugInstPeer.h"
|
||||
//#include "nsILiveConnectPlugInstPeer.h"
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
|
||||
|
|
|
@ -20,13 +20,17 @@
|
|||
#include "nsIFactory.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
#include "nsPluginsCID.h"
|
||||
//#include "nsPluginsCID.h"
|
||||
#include "nsPluginHostImpl.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPluginManager.h"
|
||||
|
||||
static NS_DEFINE_IID(kCPluginHost, NS_PLUGIN_HOST_CID);
|
||||
//static NS_DEFINE_IID(kCPluginHost, NS_PLUGIN_HOST_CID);
|
||||
static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
static NS_DEFINE_IID(kIServiceManagerIID, NS_ISERVICEMANAGER_IID);
|
||||
|
||||
class nsPluginFactory : public nsIFactory
|
||||
{
|
||||
|
@ -44,7 +48,7 @@ class nsPluginFactory : public nsIFactory
|
|||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
nsPluginFactory(const nsCID &aClass);
|
||||
nsPluginFactory(const nsCID &aClass, nsIServiceManager* serviceMgr);
|
||||
|
||||
protected:
|
||||
virtual ~nsPluginFactory();
|
||||
|
@ -52,12 +56,14 @@ class nsPluginFactory : public nsIFactory
|
|||
private:
|
||||
nsrefcnt mRefCnt;
|
||||
nsCID mClassID;
|
||||
nsIServiceManager *mserviceMgr;
|
||||
};
|
||||
|
||||
nsPluginFactory :: nsPluginFactory(const nsCID &aClass)
|
||||
nsPluginFactory :: nsPluginFactory(const nsCID &aClass, nsIServiceManager* serviceMgr)
|
||||
{
|
||||
mRefCnt = 0;
|
||||
mClassID = aClass;
|
||||
mserviceMgr = serviceMgr;
|
||||
}
|
||||
|
||||
nsPluginFactory :: ~nsPluginFactory()
|
||||
|
@ -115,8 +121,9 @@ nsresult nsPluginFactory :: CreateInstance(nsISupports *aOuter,
|
|||
|
||||
nsISupports *inst = nsnull;
|
||||
|
||||
if (mClassID.Equals(kCPluginHost)) {
|
||||
inst = (nsISupports *)(nsIPluginManager *)new nsPluginHostImpl();
|
||||
//if (mClassID.Equals(kCPluginHost) || mClassID.Equals(kCPluginManagerCID) ){
|
||||
if (mClassID.Equals(kCPluginManagerCID) ){
|
||||
inst = (nsISupports *)(nsIPluginManager *)new nsPluginHostImpl(mserviceMgr);
|
||||
}
|
||||
|
||||
if (inst == NULL) {
|
||||
|
@ -140,13 +147,18 @@ nsresult nsPluginFactory :: LockFactory(PRBool aLock)
|
|||
}
|
||||
|
||||
// return the proper factory to the caller
|
||||
extern "C" NS_PLUGIN nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_PLUGIN nsresult NSGetFactory(const nsCID &aClass, nsISupports* serviceMgr, nsIFactory **aFactory )
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aFactory = new nsPluginFactory(aClass);
|
||||
nsIServiceManager *pnsIServiceManager = NULL;
|
||||
if (NS_FAILED(serviceMgr->QueryInterface(kIServiceManagerIID, (void**) &pnsIServiceManager)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aFactory = new nsPluginFactory(aClass, pnsIServiceManager);
|
||||
serviceMgr->Release();
|
||||
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -26,6 +26,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "prlink.h"
|
||||
#include "nsIMalloc.h"
|
||||
#include "nsIFileUtilities.h"
|
||||
|
||||
class ns4xPlugin;
|
||||
|
||||
|
@ -54,10 +55,11 @@ public:
|
|||
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 //is this a pre-xpcom plugin?
|
||||
|
||||
class nsPluginHostImpl : public nsIPluginManager2,
|
||||
public nsIPluginHost
|
||||
public nsIPluginHost,
|
||||
public nsIFileUtilities
|
||||
{
|
||||
public:
|
||||
nsPluginHostImpl();
|
||||
nsPluginHostImpl(nsIServiceManager *serviceMgr);
|
||||
~nsPluginHostImpl();
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
|
@ -68,7 +70,7 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
//nsIPluginManager interface
|
||||
//nsIPluginManager interface - the main interface nsIPlugin communicates to
|
||||
|
||||
NS_IMETHOD
|
||||
GetValue(nsPluginManagerVariable variable, void *value);
|
||||
|
@ -79,6 +81,32 @@ public:
|
|||
NS_IMETHOD
|
||||
UserAgent(const char* *resultingAgentString);
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
|
||||
NS_IMETHOD
|
||||
GetURL(nsISupports* pluginInst,
|
||||
const char* url,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE);
|
||||
|
||||
NS_IMETHOD
|
||||
PostURL(nsISupports* pluginInst,
|
||||
const char* url,
|
||||
PRUint32 postDataLen,
|
||||
const char* postData,
|
||||
PRBool isFile = PR_FALSE,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE,
|
||||
PRUint32 postHeadersLength = 0,
|
||||
const char* postHeaders = NULL);
|
||||
#else
|
||||
|
||||
NS_IMETHOD
|
||||
GetURL(nsISupports* inst, const char* url, const char* target,
|
||||
void* notifyData = NULL, const char* altHost = NULL,
|
||||
|
@ -91,8 +119,9 @@ public:
|
|||
const char* altHost = NULL, const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE,
|
||||
PRUint32 postHeadersLength = 0, const char* postHeaders = NULL);
|
||||
#endif
|
||||
|
||||
//nsIPluginHost interface
|
||||
//nsIPluginHost interface - used to communicate to the nsPluginInstanceOwner
|
||||
|
||||
NS_IMETHOD
|
||||
Init(void);
|
||||
|
@ -104,25 +133,15 @@ public:
|
|||
LoadPlugins(void);
|
||||
|
||||
NS_IMETHOD
|
||||
InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner);
|
||||
InstantiateEmbededPlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
NS_IMETHOD
|
||||
InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner);
|
||||
InstantiateFullPagePlugin(const char *aMimeType, nsString& aURLSpec, nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
NS_IMETHOD
|
||||
InstantiatePlugin(const char *aMimeType, nsString& aURLSpec,
|
||||
nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner);
|
||||
SetUpPluginInstance(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
NS_IMETHOD
|
||||
NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData);
|
||||
|
||||
NS_IMETHOD
|
||||
NewPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, void *aNotifyData);
|
||||
|
||||
NS_IMETHOD
|
||||
NewPluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance, void *aNotifyData);
|
||||
|
||||
//nsIPluginManager2 interface
|
||||
//nsIPluginManager2 interface - secondary methods that nsIPlugin communicates to
|
||||
|
||||
NS_IMETHOD
|
||||
BeginWaitCursor(void);
|
||||
|
@ -157,7 +176,7 @@ public:
|
|||
NS_IMETHOD
|
||||
ProcessNextEvent(PRBool *bEventHandled);
|
||||
|
||||
//nsIFactory interface
|
||||
//nsIFactory interface - used to create new Plugin instances
|
||||
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
|
@ -165,11 +184,38 @@ public:
|
|||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
// nsIFileUtilities interface
|
||||
|
||||
NS_IMETHOD GetProgramPath(const char* *result);
|
||||
|
||||
NS_IMETHOD GetTempDirPath(const char* *result);
|
||||
|
||||
NS_IMETHOD NewTempFileName(const char* prefix, PRUint32 bufLen, char* resultBuf);
|
||||
|
||||
/* Called by GetURL and PostURL */
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
NS_IMETHOD
|
||||
NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
|
||||
#else
|
||||
NS_IMETHOD
|
||||
NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/* Called by InstantiatePlugin */
|
||||
|
||||
nsresult
|
||||
NewEmbededPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, nsIPluginInstance* aInstance);
|
||||
nsresult
|
||||
NewFullPagePluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance);
|
||||
|
||||
char *mPluginPath;
|
||||
nsPluginTag *mPlugins;
|
||||
nsIMalloc *mMalloc;
|
||||
PRBool mPluginsLoaded;
|
||||
nsIServiceManager *mserviceMgr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,13 +20,17 @@
|
|||
#include "nsIFactory.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
#include "nsPluginsCID.h"
|
||||
//#include "nsPluginsCID.h"
|
||||
#include "nsPluginHostImpl.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPluginManager.h"
|
||||
|
||||
static NS_DEFINE_IID(kCPluginHost, NS_PLUGIN_HOST_CID);
|
||||
//static NS_DEFINE_IID(kCPluginHost, NS_PLUGIN_HOST_CID);
|
||||
static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
static NS_DEFINE_IID(kIServiceManagerIID, NS_ISERVICEMANAGER_IID);
|
||||
|
||||
class nsPluginFactory : public nsIFactory
|
||||
{
|
||||
|
@ -44,7 +48,7 @@ class nsPluginFactory : public nsIFactory
|
|||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
nsPluginFactory(const nsCID &aClass);
|
||||
nsPluginFactory(const nsCID &aClass, nsIServiceManager* serviceMgr);
|
||||
|
||||
protected:
|
||||
virtual ~nsPluginFactory();
|
||||
|
@ -52,12 +56,14 @@ class nsPluginFactory : public nsIFactory
|
|||
private:
|
||||
nsrefcnt mRefCnt;
|
||||
nsCID mClassID;
|
||||
nsIServiceManager *mserviceMgr;
|
||||
};
|
||||
|
||||
nsPluginFactory :: nsPluginFactory(const nsCID &aClass)
|
||||
nsPluginFactory :: nsPluginFactory(const nsCID &aClass, nsIServiceManager* serviceMgr)
|
||||
{
|
||||
mRefCnt = 0;
|
||||
mClassID = aClass;
|
||||
mserviceMgr = serviceMgr;
|
||||
}
|
||||
|
||||
nsPluginFactory :: ~nsPluginFactory()
|
||||
|
@ -115,8 +121,9 @@ nsresult nsPluginFactory :: CreateInstance(nsISupports *aOuter,
|
|||
|
||||
nsISupports *inst = nsnull;
|
||||
|
||||
if (mClassID.Equals(kCPluginHost)) {
|
||||
inst = (nsISupports *)(nsIPluginManager *)new nsPluginHostImpl();
|
||||
//if (mClassID.Equals(kCPluginHost) || mClassID.Equals(kCPluginManagerCID) ){
|
||||
if (mClassID.Equals(kCPluginManagerCID) ){
|
||||
inst = (nsISupports *)(nsIPluginManager *)new nsPluginHostImpl(mserviceMgr);
|
||||
}
|
||||
|
||||
if (inst == NULL) {
|
||||
|
@ -140,13 +147,18 @@ nsresult nsPluginFactory :: LockFactory(PRBool aLock)
|
|||
}
|
||||
|
||||
// return the proper factory to the caller
|
||||
extern "C" NS_PLUGIN nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_PLUGIN nsresult NSGetFactory(const nsCID &aClass, nsISupports* serviceMgr, nsIFactory **aFactory )
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aFactory = new nsPluginFactory(aClass);
|
||||
nsIServiceManager *pnsIServiceManager = NULL;
|
||||
if (NS_FAILED(serviceMgr->QueryInterface(kIServiceManagerIID, (void**) &pnsIServiceManager)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aFactory = new nsPluginFactory(aClass, pnsIServiceManager);
|
||||
serviceMgr->Release();
|
||||
|
||||
if (nsnull == aFactory) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -26,6 +26,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "prlink.h"
|
||||
#include "nsIMalloc.h"
|
||||
#include "nsIFileUtilities.h"
|
||||
|
||||
class ns4xPlugin;
|
||||
|
||||
|
@ -54,10 +55,11 @@ public:
|
|||
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 //is this a pre-xpcom plugin?
|
||||
|
||||
class nsPluginHostImpl : public nsIPluginManager2,
|
||||
public nsIPluginHost
|
||||
public nsIPluginHost,
|
||||
public nsIFileUtilities
|
||||
{
|
||||
public:
|
||||
nsPluginHostImpl();
|
||||
nsPluginHostImpl(nsIServiceManager *serviceMgr);
|
||||
~nsPluginHostImpl();
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
|
@ -68,7 +70,7 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
//nsIPluginManager interface
|
||||
//nsIPluginManager interface - the main interface nsIPlugin communicates to
|
||||
|
||||
NS_IMETHOD
|
||||
GetValue(nsPluginManagerVariable variable, void *value);
|
||||
|
@ -79,6 +81,32 @@ public:
|
|||
NS_IMETHOD
|
||||
UserAgent(const char* *resultingAgentString);
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
|
||||
NS_IMETHOD
|
||||
GetURL(nsISupports* pluginInst,
|
||||
const char* url,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE);
|
||||
|
||||
NS_IMETHOD
|
||||
PostURL(nsISupports* pluginInst,
|
||||
const char* url,
|
||||
PRUint32 postDataLen,
|
||||
const char* postData,
|
||||
PRBool isFile = PR_FALSE,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE,
|
||||
PRUint32 postHeadersLength = 0,
|
||||
const char* postHeaders = NULL);
|
||||
#else
|
||||
|
||||
NS_IMETHOD
|
||||
GetURL(nsISupports* inst, const char* url, const char* target,
|
||||
void* notifyData = NULL, const char* altHost = NULL,
|
||||
|
@ -91,8 +119,9 @@ public:
|
|||
const char* altHost = NULL, const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE,
|
||||
PRUint32 postHeadersLength = 0, const char* postHeaders = NULL);
|
||||
#endif
|
||||
|
||||
//nsIPluginHost interface
|
||||
//nsIPluginHost interface - used to communicate to the nsPluginInstanceOwner
|
||||
|
||||
NS_IMETHOD
|
||||
Init(void);
|
||||
|
@ -104,25 +133,15 @@ public:
|
|||
LoadPlugins(void);
|
||||
|
||||
NS_IMETHOD
|
||||
InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner);
|
||||
InstantiateEmbededPlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
NS_IMETHOD
|
||||
InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner);
|
||||
InstantiateFullPagePlugin(const char *aMimeType, nsString& aURLSpec, nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
NS_IMETHOD
|
||||
InstantiatePlugin(const char *aMimeType, nsString& aURLSpec,
|
||||
nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner);
|
||||
SetUpPluginInstance(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
NS_IMETHOD
|
||||
NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData);
|
||||
|
||||
NS_IMETHOD
|
||||
NewPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, void *aNotifyData);
|
||||
|
||||
NS_IMETHOD
|
||||
NewPluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance, void *aNotifyData);
|
||||
|
||||
//nsIPluginManager2 interface
|
||||
//nsIPluginManager2 interface - secondary methods that nsIPlugin communicates to
|
||||
|
||||
NS_IMETHOD
|
||||
BeginWaitCursor(void);
|
||||
|
@ -157,7 +176,7 @@ public:
|
|||
NS_IMETHOD
|
||||
ProcessNextEvent(PRBool *bEventHandled);
|
||||
|
||||
//nsIFactory interface
|
||||
//nsIFactory interface - used to create new Plugin instances
|
||||
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
|
@ -165,11 +184,38 @@ public:
|
|||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
// nsIFileUtilities interface
|
||||
|
||||
NS_IMETHOD GetProgramPath(const char* *result);
|
||||
|
||||
NS_IMETHOD GetTempDirPath(const char* *result);
|
||||
|
||||
NS_IMETHOD NewTempFileName(const char* prefix, PRUint32 bufLen, char* resultBuf);
|
||||
|
||||
/* Called by GetURL and PostURL */
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
NS_IMETHOD
|
||||
NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
|
||||
#else
|
||||
NS_IMETHOD
|
||||
NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/* Called by InstantiatePlugin */
|
||||
|
||||
nsresult
|
||||
NewEmbededPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, nsIPluginInstance* aInstance);
|
||||
nsresult
|
||||
NewFullPagePluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance);
|
||||
|
||||
char *mPluginPath;
|
||||
nsPluginTag *mPlugins;
|
||||
nsIMalloc *mMalloc;
|
||||
PRBool mPluginsLoaded;
|
||||
nsIServiceManager *mserviceMgr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -91,7 +91,6 @@ public:
|
|||
const char* url,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
nsPluginStreamType streamType = nsPluginStreamType_Normal,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE) = 0;
|
||||
|
@ -104,7 +103,6 @@ public:
|
|||
PRBool isFile = PR_FALSE,
|
||||
const char* target = NULL,
|
||||
nsIPluginStreamListener* streamListener = NULL,
|
||||
nsPluginStreamType streamType = nsPluginStreamType_Normal,
|
||||
const char* altHost = NULL,
|
||||
const char* referrer = NULL,
|
||||
PRBool forceJSEnabled = PR_FALSE,
|
||||
|
@ -186,6 +184,15 @@ public:
|
|||
{0x81, 0x64, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
// CLSID for the browser's global plugin manager object.
|
||||
#define NS_PLUGINMANAGER_CID \
|
||||
{ /* ce768990-5a4e-11d2-8164-006008119d7a */ \
|
||||
0xce768990, \
|
||||
0x5a4e, \
|
||||
0x11d2, \
|
||||
{0x81, 0x64, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* nsIPluginManager_h___ */
|
||||
|
|
|
@ -79,6 +79,8 @@
|
|||
#ifndef nsplugins_h___
|
||||
#define nsplugins_h___
|
||||
|
||||
#define NEW_PLUGIN_STREAM_API
|
||||
|
||||
#include "nsRepository.h" // for NSGetFactory
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,6 +98,7 @@
|
|||
*/
|
||||
// (Declared in nsRepository.h)
|
||||
//extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aClass,
|
||||
// nsISupports* serviceMgr,
|
||||
// nsIFactory **aFactory);
|
||||
|
||||
/**
|
||||
|
@ -134,7 +137,7 @@
|
|||
* Note that this interface is part of a new JNI-based LiveConnect
|
||||
* implementation and superceeds that provided prior to Communicator 5.0.
|
||||
*/
|
||||
#include "nsILiveConnectPlugin.h"
|
||||
//#include "nsILiveConnectPlugin.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
|
@ -229,7 +232,7 @@
|
|||
*
|
||||
* To obtain: QueryInterface on nsIPluginInstancePeer
|
||||
*/
|
||||
#include "nsILiveConnectPlugInstPeer.h"
|
||||
//#include "nsILiveConnectPlugInstPeer.h"
|
||||
|
||||
#ifdef NEW_PLUGIN_STREAM_API
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsISupports.h"
|
||||
#include "nsINetService.h"
|
||||
#include "nsNetService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsRepository.h"
|
||||
|
||||
/* This implementation of the network service factory is presently
|
||||
|
@ -146,9 +147,9 @@ nsresult nsNetFactory::LockFactory(PRBool aLock)
|
|||
|
||||
// return the proper factory to the caller
|
||||
#if defined(XP_MAC) && defined(MAC_STATIC)
|
||||
extern "C" NS_NET nsresult NSGetFactory_NETLIB_DLL(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_NET nsresult NSGetFactory_NETLIB_DLL(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#else
|
||||
extern "C" NS_NET nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_NET nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#endif
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
|
|
|
@ -167,9 +167,9 @@ nsresult nsParserFactory::LockFactory(PRBool aLock)
|
|||
|
||||
// return the proper factory to the caller
|
||||
#if defined(XP_MAC) && defined(MAC_STATIC)
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory_PARSER_DLL(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory_PARSER_DLL(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#else
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aClass, nsISupports* servMgr, nsIFactory **aFactory)
|
||||
#endif
|
||||
{
|
||||
if (nsnull == aFactory) {
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче