OJI MozClassic to raptor merge

This commit is contained in:
sudu%netscape.com 1999-01-25 08:05:00 +00:00
Родитель 932229f590
Коммит 6624efe2b9
126 изменённых файлов: 7729 добавлений и 4125 удалений

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

@ -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.&nbsp;
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.&nbsp; 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>.&nbsp; 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).&nbsp; 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.&nbsp;
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.&nbsp; 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.&nbsp;
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.&nbsp; 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.&nbsp;
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.&nbsp;&nbsp;
Informally, the method with Java parameter types that most&nbsp; 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.&nbsp; 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.&nbsp;&nbsp;
If necessary, it is possible to bypass the method overload resolution process
and explicitly specify the method to be invoked:</li>
<br>&nbsp;
<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.&nbsp; (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>&nbsp;&nbsp;&nbsp; s = new java.lang.String("foo")</tt>
<br><tt>&nbsp;&nbsp;&nbsp; s = s + "";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</tt>// s is now a JS string
<br><tt>&nbsp;&nbsp;&nbsp; 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.&nbsp;
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.&nbsp; Now, when JavaScript
calls into Java, any Java exceptions are converted to JS exceptions which
can be caught using JS try-catch statements.&nbsp; 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>&nbsp; (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.&nbsp; (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.&nbsp; 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.&nbsp;
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>&nbsp;
<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>.&nbsp; (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.)&nbsp; For
example, the following is now possible:</li>
<p><tt><font size=-1>c = new java.lang.Character("F")</font></tt>
<br>&nbsp;
<li>
A JavaClass object is now an acceptable match for an argument to a Java
method of type <i>java.lang.Class</i>.&nbsp; 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>&nbsp;</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.&nbsp; The
variants of LiveConnect that appeared in Navigator versions 3.x and 4.x
all behave much the same, modulo bugs.&nbsp; For brevity we refer to this
classic version of LiveConnect as "LC1" (LiveConnect version 1) and this
most recent release as "LC3".&nbsp; (There was an intermediate LiveConnect
release known as "LC2" in 7/98, but it was not used in any products.&nbsp;
"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>.&nbsp;
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.&nbsp; 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>.&nbsp;
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.&nbsp; The use of weak references
is not portable, however.&nbsp; It is not part of the JNI or the JDK and
it is not provided on all JVMs.&nbsp; The JDK1.2 release will include standard
support for weak references.
<br>&nbsp;
<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.&nbsp; LC1 and LC2 resolved these ambiguities
in a simplistic manner, by simply invoking whatever method was enumerated
first by the JVM.&nbsp; The enumeration order of reflected methods using
<i>java.lang.reflect</i>&nbsp;
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.&nbsp;
Hence, the Java method chosen when there is more than one compatible method
may vary depending on the JVM.&nbsp; 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.&nbsp; Informally,
the method with Java parameter types that most&nbsp; closely match the
JavaScript types is chosen.&nbsp; You can read all the gorey details in
the <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">spec</a>.
<br>&nbsp;
<li>
There are several minor changes in error handling to make LiveConnect more
conformant to ECMAScript.&nbsp; These include, for example, making any
attempt to delete JavaObject, JavaClass or JavaPackage properties fail
silently, rather than causing an error.&nbsp; Also, some error messages
have been changed to be more informative.&nbsp; 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.&nbsp;
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.&nbsp; In this way, the behavior of
the JS '==' and '===' operators are preserved.&nbsp; Unfortunately, the
hash table may grow quite large (objects are only removed from the hash
table when finalized).&nbsp; 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.&nbsp; 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().&nbsp; 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).&nbsp; However, the API is not fully implemented.&nbsp;
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.&nbsp; 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.&nbsp; Another
downside of operating without these classes is that Java error messages
will not include a Java stack trace, when one is available.&nbsp; 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.&nbsp; 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.&nbsp; (NSPR implements a portable threading library,
among other things.&nbsp; 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>.)&nbsp;
Next, you must define <tt>JS_THREADSAFE</tt> when building LiveConnect,
either on the command-line (gmake/nmake) or in a universal header file.&nbsp;
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>.&nbsp; This is
used to establish paths for header file inclusion, linking and execution.&nbsp;
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.&nbsp;
<font color="#993300">NOTE: makefile.win is an nmake file used only for
building the JS-engine in the Mozilla browser.&nbsp; 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.&nbsp; 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.&nbsp; (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>.&nbsp; 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> &amp; <tt>Libraries</tt> from the SDK's
<tt>Interfaces&amp;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>.&nbsp; </font><font color="#990000">NOTE:
Do not attempt to use <tt>Makefile</tt> to build.&nbsp; 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.&nbsp; The configuration file specifies the JVM headers/libraries
used and allows for customization of command-line options.&nbsp; 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.&nbsp; (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",&nbsp;
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.&nbsp; 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.&nbsp; 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()&nbsp;
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>&nbsp;
<h2>
<a NAME="File_walkthrough"></a>File walk-through</h2>
&nbsp;
<table BORDER=3 CELLSPACING=0 CELLPADDING=4 >
<tr>
<td>jsjava.h</td>
<td>LiveConnect's only public header file.&nbsp; Defines all public API
entry points, callbacks and types.&nbsp;</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.&nbsp; 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.&nbsp; 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.&nbsp; Instances of
JavaArray are used to reflect Java arrays.</td>
</tr>
<tr>
<td>jsj_JavaClass.c</td>
<td>Implementation of the JavaScript JavaClass class.&nbsp;&nbsp; Instances
of JavaClass are used to reflect Java classes.</td>
</tr>
<tr>
<td>jsj_JavaObject.c</td>
<td>Implementation of the JavaScript JavaObject class.&nbsp;&nbsp; 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.&nbsp; 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.&nbsp;&nbsp; Instances
of JavaPackage are used to reflect Java packages.&nbsp; 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&nbsp; <i>netscape.javascript.JSObject</i>
Java class, which are used for calling into JavaScript from Java.&nbsp;
It also contains the code that wraps JS objects as instances of&nbsp; <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.&nbsp; 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>&nbsp;&nbsp; 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>&nbsp;&nbsp; long abs(long)</tt>
<br><tt>&nbsp;&nbsp; float abs(float)</tt>
<br><tt>&nbsp;&nbsp; double abs(double)</tt>
<br><tt>&nbsp;&nbsp; int abs(int)</tt>
<br><tt>js> abs = java.lang.Math["abs(int)"]</tt>
<p><tt>function abs(int)() {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; [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>&nbsp;
</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
*/

58
modules/oji/src/lcglue.h Normal file
Просмотреть файл

@ -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) {

0
rdf/src/nsRDFFactory.cpp Normal file
Просмотреть файл

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше