From b2058b3efa65d8eb4cb737e97a8d8855e669923b Mon Sep 17 00:00:00 2001 From: "fur%netscape.com" Date: Sat, 29 Aug 1998 03:00:50 +0000 Subject: [PATCH] Transferred work from private ns tree back into mozilla. --- js/ref/liveconnect/.cvsignore | 4 - js/ref/liveconnect/LiveConnect.dsp | 144 ---- js/ref/liveconnect/README.html | 432 ---------- .../_jni/netscape_javascript_JSObject.h | 0 .../netscape/javascript/JSException.java | 4 +- .../classes/netscape/javascript/JSObject.java | 62 +- .../classes/netscape/javascript/JSProxy.java | 18 +- .../netscape/javascript/JSRunnable.java | 4 + .../classes/netscape/javascript/JSUtil.java | 18 +- js/ref/liveconnect/config/SunOS5.5.1.mk | 0 js/ref/liveconnect/jsj.c | 745 ------------------ js/ref/liveconnect/jsj_JSObject.c | 183 +++-- js/ref/liveconnect/jsj_JavaArray.c | 50 +- js/ref/liveconnect/jsj_JavaClass.c | 87 +- js/ref/liveconnect/jsj_JavaObject.c | 175 ++-- js/ref/liveconnect/jsj_JavaPackage.c | 66 +- js/ref/liveconnect/jsj_array.c | 183 ----- js/ref/liveconnect/jsj_class.c | 606 -------------- js/ref/liveconnect/jsj_convert.c | 177 +++-- js/ref/liveconnect/jsj_field.c | 386 --------- js/ref/liveconnect/jsj_hash.c | 481 ----------- js/ref/liveconnect/jsj_hash.h | 141 ---- js/ref/liveconnect/jsj_method.c | 86 +- js/ref/liveconnect/jsj_private.h | 94 ++- js/ref/liveconnect/jsj_utils.c | 56 +- js/ref/liveconnect/jsjava.h | 234 ------ .../macbuild/JavaSession/JavaSession.cpp | 147 ---- .../macbuild/JavaSession/JavaSession.h | 46 -- .../macbuild/JavaSession/OSStatusException.h | 46 -- .../liveconnect/macbuild/LiveConnectShell.mcp | Bin 40556 -> 0 bytes .../netscape_javascript_JSObject.h | 101 --- 31 files changed, 577 insertions(+), 4199 deletions(-) create mode 100644 js/ref/liveconnect/_jni/netscape_javascript_JSObject.h create mode 100644 js/ref/liveconnect/config/SunOS5.5.1.mk diff --git a/js/ref/liveconnect/.cvsignore b/js/ref/liveconnect/.cvsignore index eb4205e2a4f..e69de29bb2d 100644 --- a/js/ref/liveconnect/.cvsignore +++ b/js/ref/liveconnect/.cvsignore @@ -1,4 +0,0 @@ -*.ncb -*.opt -Debug -Release diff --git a/js/ref/liveconnect/LiveConnect.dsp b/js/ref/liveconnect/LiveConnect.dsp index ea2492b6a33..e69de29bb2d 100644 --- a/js/ref/liveconnect/LiveConnect.dsp +++ b/js/ref/liveconnect/LiveConnect.dsp @@ -1,144 +0,0 @@ -# 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_JavaObject.c -# End Source File -# Begin Source File - -SOURCE=.\jsj_JavaPackage.c -# End Source File -# Begin Source File - -SOURCE=.\jsj_JSObject.c -# 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 diff --git a/js/ref/liveconnect/README.html b/js/ref/liveconnect/README.html index 727381c072c..e69de29bb2d 100644 --- a/js/ref/liveconnect/README.html +++ b/js/ref/liveconnect/README.html @@ -1,432 +0,0 @@ - - - - - - README for LiveConnect - - - -

-Introduction

-This is the README file for the JavaScript LiveConnect implementation.  -It consists of build conventions and instructions, source code conventions, -and a brief file-by-file description of the source. - -

This document assumes basic familiarity with JSRef, the reference implementation -of JavaScript, and with the LiveConnect technology  (LiveConnect allows -JavaScript and Java virtual machines to be connected.  It enables -JavaScript to access Java fields, invoke Java methods and makes it possible -for Java to access JavaScript object properties and evaluate JavaScript.  -More information on LiveConnect can be found by searching the index on -Netscape's DevEdge site.) - -

JSRef builds a library or DLL containing the JavaScript runtime (compiler, -interpreter, decompiler, garbage collector, atom manager, standard classes).  -The LiveConnect project/makefiles build a library that links both with -JSRef and with a Java Virtual Machine (JVM) that implements the Java Native -Interface (JNI), as specified by JavaSoft.  It then compiles a small -"shell" program and links that with the library to make an interpreter -that can be used interactively and with test scripts. - -

Scott Furman, 4/8/98 -

-Compatibility

-Unlike this release, all previous versions of LiveConnect appeared only -as a component of Netscape Navigator, not as a standalone module.  -The variants of LiveConnect that appeared in Navigator versions 3.x and -4.x all behave much the same, modulo bugs.  For brevity we refer to -this classic version of LiveConnect as "LC1" and this most recent release -as "LC2".  The following incompatibilities with LC1 are known: - - -

-New Features

-Several minor features have been added to this release of LiveConnect.  -These features were not available in the versions of LiveConnect that were -integrated with Netscape Naviagtor versions 4.x and earlier. -
  -
-
  • -The Java methods of java.lang.Object are now invokeable methods -of JavaArray objects, matching the behavior -of arrays when accessed from Java.  (Java arrays are a subclass -of java.lang.Object.) For example, Java's getClass() -and hashCode() methods can now be called -on JavaArray objects.  (In prior versions -of LiveConnect, the methods of java.lang.Object were only inherited -by non-array Java objects.)
  • - - -

    Note that this change has caused the string representation of JavaArray -objects to change.  Previously, the JavaArray toString() method always -printed "[object JavaArray]" for all JavaArray's.  -Now, the Java java.lang.Object.toString() -method is called to convert JavaArray objects to strings, just as with -other, non-array Java objects that are accessible via LiveConnect.  -java.lang.Object.toString()is defined in -the Java Language Specification to return the value of the following -expression: - -

    getClass().getName() + '@' + Integer.toHexString(hashCode()) -
      -

  • -A one-character string is now an acceptable match for an argument to a -Java method of type char.  (In earlier -versions of LiveConnect, the only acceptable match for a char -had to be a JavaScript value that was convertible to a number.)  For -example, the following is now possible:
  • - - -

    c = new java.lang.Character("F") -
      -

  • -A JavaClass object is now an acceptable match for an argument to a Java -method of type java.lang.Class.  For example, you can now write:
  • - - -

    java.lang.reflect.Array.newInstance(java.lang.String, -3) - -

    instead of the more verbose: - -

    jls = java.lang.Class.forName("java.lang.String") -
    java.lang.reflect.Array.newInstance(jls, 3) -
     

    - -

    -Build conventions

    -Update your JVM's CLASSPATH to point to the -liveconnect/classes subdirectory.  If -you do not, LiveConnect will still operate but with the limitation that -JS objects may not be passed as arguments of Java methods and it will not -be possible to call from Java into JavaScript, i.e. the netscape.javascript.JSObject -class will be inaccessible.  Another downside of operating without -these classes is that Java error messages will not include a Java stack -trace, when one is available.  If your CLASSPATH -is set improperly, you will see a message like, "initialization -error: Can't load class netscape/javascript/JSObject" when -starting a LiveConnect debug build. - -

    By default, LiveConnect is not re-entrant.  To enable multi-threaded -execution, define the JS_THREADSAFE cpp macro -and flesh out the stubs and required headers in jslock.c/.h.  See -the JS API docs for more.  JSRef must also be built with JS_THREADSAFE. -
      -

    - -

    -Naming and coding conventions:

    - - - -

    -The LiveConnect API

    -All public LiveConnect entry points and callbacks are documented in jsjava.h, -the header file that exports those functions. -
      -

    -File Walk-through

    -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    jsjava.hLiveConnect's only public header file.  Defines all public API -entry points, callbacks and types. 
    jsj_private.hLiveConnect internal header file for intra-module sharing of functions -and types
    jsj.cPublic LiveConnect API entry points and initialization code
    jsj_array.cRead and write elements of a Java array, performing needed conversions -to/from JS types.
    jsj_class.cConstruct and manipulate JavaClassDescriptor structs, which are the -native representation for Java classes.  JavaClassDescriptors are -used to describe the methods and fields of a class, including their type -signatures, and include a reference to the peer java.lang.Class -object.  Since each Java object has a class, there is a JavaClassDescriptor -associated with the JavaScript reflection of each Java Object.
    jsj_convert.cConvert 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.
    jsj_field.cReflect Java fields as properties of JavaObject objects and implement -getter/setter access to those fields.
    jsj_JavaArray.cImplementation of the JavaScript JavaArray class.  Instances of -JavaArray are used to reflect Java arrays.
    jsj_JavaClass.cImplementation of the JavaScript JavaClass class.   Instances -of JavaClass are used to reflect Java classes.
    jsj_JavaObject.cImplementation of the JavaScript JavaObject class.   Instances -of JavaObject are used to reflect Java objects, except for Java arrays, -although some of the code in this file is used by the JavaArray code.
    jsj_JavaPackage.cImplementation of the JavaScript JavaPackage class.   Instances -of JavaPackage are used to reflect Java packages.  The JS properties -of a JavaPackage are either nested JavaPackage objects or a JavaClass object.
    jsj_JSObject.cImplementation of the native methods for the  netscape.javascript.JSObject -Java class, which are used for calling into JavaScript from Java.  -It also contains the code that wraps JS objects as instances of  netscape.javascript.JSObject -and the code that handles propagation of exceptions both into and out -of Java.
    jsj_method.cReflect Java methods as properties of JavaObject objects and make it -possible to invoke those methods.  Includes overloaded method resolution -and argument/return-value conversion code.
    jsj_utils.cLow-level utility code for reporting errors, etc.
    -  -
      - - diff --git a/js/ref/liveconnect/_jni/netscape_javascript_JSObject.h b/js/ref/liveconnect/_jni/netscape_javascript_JSObject.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/js/ref/liveconnect/classes/netscape/javascript/JSException.java b/js/ref/liveconnect/classes/netscape/javascript/JSException.java index 4ae02ffcb77..0b016f16d0f 100644 --- a/js/ref/liveconnect/classes/netscape/javascript/JSException.java +++ b/js/ref/liveconnect/classes/netscape/javascript/JSException.java @@ -1,4 +1,6 @@ -/* Insert copyright and license here 19** */ +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. + */ package netscape.javascript; diff --git a/js/ref/liveconnect/classes/netscape/javascript/JSObject.java b/js/ref/liveconnect/classes/netscape/javascript/JSObject.java index bada391a9e2..10d12d47382 100644 --- a/js/ref/liveconnect/classes/netscape/javascript/JSObject.java +++ b/js/ref/liveconnect/classes/netscape/javascript/JSObject.java @@ -1,4 +1,6 @@ -/* -*- Mode: C; tab-width: 4; -*- */ +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. + */ /* Insert copyright and license here 19** */ @@ -23,7 +25,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. *
  • Java arrays are wrapped with a JavaScript object that understands @@ -35,8 +37,9 @@ import java.applet.Applet; * Values passed from JavaScript to Java are converted as follows: * This means that all JavaScript values show up as some kind * of java.lang.Object in Java. In order to make much use of them, @@ -53,60 +56,74 @@ public final class JSObject { */ private static native void initClass(); static { - System.loadLibrary("LiveConnect"); - initClass(); + String liveConnectLibrary = null; + String OSName = System.getProperty("os.name", null); + + // On MRJ, this property won't exist, because the library is preloaded. + liveConnectLibrary = System.getProperty("netscape.jsj.dll", null); + + // On Mac, native methods are statically linked and manually registered. + if ((liveConnectLibrary == null) && (OSName.indexOf("Mac") == -1)) + liveConnectLibrary = "LiveConnect"; + + if (liveConnectLibrary != null) { + System.loadLibrary(liveConnectLibrary); + initClass(); + } } /** * it is illegal to construct a JSObject manually */ - private JSObject(int jsobj_addr) {internal = jsobj_addr;} + private JSObject(int jsobj_addr) { + internal = jsobj_addr; + } /** * Retrieves a named member of a JavaScript object. * Equivalent to "this.name" in JavaScript. */ - public native Object getMember(String name); + public native Object getMember(String name); /** * Retrieves an indexed member of a JavaScript object. * Equivalent to "this[index]" in JavaScript. */ -// public Object getMember(int index) { return getSlot(index); } - public native Object getSlot(int index); +// public Object getMember(int index) { return getSlot(index); } + public native Object getSlot(int index); /** * Sets a named member of a JavaScript object. * Equivalent to "this.name = value" in JavaScript. */ - public native void setMember(String name, Object value); + public native void setMember(String name, Object value); /** * Sets an indexed member of a JavaScript object. * Equivalent to "this[index] = value" in JavaScript. */ -// public void setMember(int index, Object value) { +// public void setMember(int index, Object value) { // setSlot(index, value); // } - public native void setSlot(int index, Object value); + public native void setSlot(int index, Object value); /** * Removes a named member of a JavaScript object. */ - public native void removeMember(String name); + public native void removeMember(String name); /** * Calls a JavaScript method. * Equivalent to "this.methodName(args[0], args[1], ...)" in JavaScript. */ - public native Object call(String methodName, Object args[]); + public native Object call(String methodName, Object args[]); /** * Evaluates a JavaScript expression. The expression is a string * of JavaScript source code which will be evaluated in the context * given by "this". */ - public native Object eval(String s); + public native Object eval(String s); /** * Converts a JSObject to a String. @@ -115,30 +132,23 @@ public final class JSObject { // should use some sort of identifier rather than String // is "property" the right word? - // native String[] listProperties(); + // native String[] listProperties(); /** * get a JSObject for the window containing the given applet */ - public static native JSObject getWindow(Applet applet); + public static native JSObject getWindow(Applet applet); /** * Finalization decrements the reference count on the corresponding * JavaScript object. */ - protected native void finalize(); + protected native void finalize(); /** * 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); } diff --git a/js/ref/liveconnect/classes/netscape/javascript/JSProxy.java b/js/ref/liveconnect/classes/netscape/javascript/JSProxy.java index ee266c4a538..fd40bf9920b 100644 --- a/js/ref/liveconnect/classes/netscape/javascript/JSProxy.java +++ b/js/ref/liveconnect/classes/netscape/javascript/JSProxy.java @@ -1,19 +1,5 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* ** */ /** diff --git a/js/ref/liveconnect/classes/netscape/javascript/JSRunnable.java b/js/ref/liveconnect/classes/netscape/javascript/JSRunnable.java index d9dae63a2e8..9788cd8d7cc 100644 --- a/js/ref/liveconnect/classes/netscape/javascript/JSRunnable.java +++ b/js/ref/liveconnect/classes/netscape/javascript/JSRunnable.java @@ -1,3 +1,7 @@ +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. + */ + package netscape.javascript; /** diff --git a/js/ref/liveconnect/classes/netscape/javascript/JSUtil.java b/js/ref/liveconnect/classes/netscape/javascript/JSUtil.java index 6d3cab84048..184f0f23ff2 100644 --- a/js/ref/liveconnect/classes/netscape/javascript/JSUtil.java +++ b/js/ref/liveconnect/classes/netscape/javascript/JSUtil.java @@ -1,19 +1,5 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* ** */ diff --git a/js/ref/liveconnect/config/SunOS5.5.1.mk b/js/ref/liveconnect/config/SunOS5.5.1.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/js/ref/liveconnect/jsj.c b/js/ref/liveconnect/jsj.c index 1c219f7ed84..e69de29bb2d 100644 --- a/js/ref/liveconnect/jsj.c +++ b/js/ref/liveconnect/jsj.c @@ -1,745 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 - * - * It contains the top-level initialization code and the implementation of the - * public API. - * - */ - -#include -#include -#include "prtypes.h" -#include "prassert.h" -#include "prprintf.h" -#include "prosdep.h" - -#include "jsj_private.h" /* LiveConnect internals */ -#include "jsjava.h" /* LiveConnect external API */ - -/* - * At certain times during initialization, there may be no JavaScript context - * available to direct error reports to, in which case the error messages - * are sent to this function. The caller is responsible for free'ing - * the js_error_msg argument. - */ -static void -report_java_initialization_error(JNIEnv *jEnv, const char *js_error_msg) -{ - const char *error_msg, *java_error_msg; - - java_error_msg = NULL; - - if (jEnv) { - java_error_msg = jsj_GetJavaErrorMessage(jEnv); - (*jEnv)->ExceptionClear(jEnv); - } - - if (java_error_msg) { - error_msg = PR_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", - js_error_msg); - } - - jsj_LogError(error_msg); -} - -/* - * Opaque JVM handles to Java classes and methods required for Java reflection. - * These are computed and cached during initialization. - */ - -jclass jlObject; /* java.lang.Object */ -jclass jlrMethod; /* java.lang.reflect.Method */ -jclass jlrField; /* java.lang.reflect.Field */ -jclass jlVoid; /* java.lang.Void */ -jclass jlrConstructor; /* java.lang.reflect.Constructor */ -jclass jlThrowable; /* java.lang.Throwable */ -jclass jlSystem; /* java.lang.System */ -jclass jlClass; /* java.lang.Class */ -jclass jlBoolean; /* java.lang.Boolean */ -jclass jlDouble; /* java.lang.Double */ -jclass jlString; /* java.lang.String */ -jclass njJSObject; /* netscape.javascript.JSObject */ -jclass njJSException; /* netscape.javascript.JSException */ -jclass njJSUtil; /* netscape.javascript.JSUtil */ - -jmethodID jlClass_getMethods; /* java.lang.Class.getMethods() */ -jmethodID jlClass_getConstructors; /* java.lang.Class.getConstructors() */ -jmethodID jlClass_getFields; /* java.lang.Class.getFields() */ -jmethodID jlClass_getName; /* java.lang.Class.getName() */ -jmethodID jlClass_getComponentType; /* java.lang.Class.getComponentType() */ -jmethodID jlClass_getModifiers; /* java.lang.Class.getModifiers() */ -jmethodID jlClass_isArray; /* java.lang.Class.isArray() */ - -jmethodID jlrMethod_getName; /* java.lang.reflect.Method.getName() */ -jmethodID jlrMethod_getParameterTypes; /* java.lang.reflect.Method.getParameterTypes() */ -jmethodID jlrMethod_getReturnType; /* java.lang.reflect.Method.getReturnType() */ -jmethodID jlrMethod_getModifiers; /* java.lang.reflect.Method.getModifiers() */ - -jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */ -jmethodID jlrConstructor_getModifiers; /* java.lang.reflect.Constructor.getModifiers() */ - -jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */ -jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */ -jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */ - -jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */ -jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */ -jmethodID jlDouble_Double; /* java.lang.Double constructor */ -jmethodID jlDouble_doubleValue; /* java.lang.Double.doubleValue() */ - -jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */ -jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */ - -jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() */ - -jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */ - -jmethodID njJSException_JSException; /* netscape.javascript.JSexception constructor */ -jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */ -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 */ - -/* Obtain a reference to a Java class */ -#define LOAD_CLASS(qualified_name, class) \ - { \ - jclass _##class = (*jEnv)->FindClass(jEnv, #qualified_name); \ - if (_##class == 0) { \ - report_java_initialization_error(jEnv, \ - "Can't load class " #qualified_name); \ - return JS_FALSE; \ - } \ - class = (*jEnv)->NewGlobalRef(jEnv, _##class); \ - } - -/* Obtain a methodID reference to a Java method or constructor */ -#define _LOAD_METHOD(qualified_class, method, mvar, signature, class, is_static)\ - if (is_static) { \ - class##_##mvar = \ - (*jEnv)->GetStaticMethodID(jEnv, class, #method, signature); \ - } else { \ - class##_##mvar = \ - (*jEnv)->GetMethodID(jEnv, class, #method, signature); \ - } \ - if (class##_##mvar == 0) { \ - report_java_initialization_error(jEnv, \ - "Can't get mid for " #qualified_class "." #method "()"); \ - return JS_FALSE; \ - } - -/* Obtain a methodID reference to a Java instance method */ -#define LOAD_METHOD(qualified_class, method, signature, class) \ - _LOAD_METHOD(qualified_class, method, method, signature, class, JS_FALSE) - -/* Obtain a methodID reference to a Java static method */ -#define LOAD_STATIC_METHOD(qualified_class, method, signature, class) \ - _LOAD_METHOD(qualified_class, method, method, signature, class, JS_TRUE) - -/* Obtain a methodID reference to a Java constructor */ -#define LOAD_CONSTRUCTOR(qualified_class, method, signature, class) \ - _LOAD_METHOD(qualified_class,, method, signature, class, JS_FALSE) - -/* Obtain a fieldID reference to a Java instance or static field */ -#define _LOAD_FIELDID(qualified_class, field, signature, class, is_static) \ - if (is_static) { \ - class##_##field = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\ - } else { \ - class##_##field = (*jEnv)->GetFieldID(jEnv, class, #field, signature);\ - } \ - if (class##_##field == 0) { \ - report_java_initialization_error(jEnv, \ - "Can't get fid for " #qualified_class "." #field); \ - return JS_FALSE; \ - } - -/* Obtain a fieldID reference to a Java instance field */ -#define LOAD_FIELDID(qualified_class, field, signature, class) \ - _LOAD_FIELDID(qualified_class, field, signature, class, JS_FALSE) - -/* Obtain the value of a static field in a Java class */ -#define LOAD_FIELD_VAL(qualified_class, field, signature, class, type) \ - { \ - jfieldID field_id; \ - field_id = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\ - if (field_id == 0) { \ - report_java_initialization_error(jEnv, \ - "Can't get fid for " #qualified_class "." #field); \ - return JS_FALSE; \ - } \ - class##_##field = \ - (*jEnv)->GetStatic##type##Field(jEnv, class, field_id); \ - if (class##_##field == 0) { \ - report_java_initialization_error(jEnv, \ - "Can't read static field " #qualified_class "." #field); \ - return JS_FALSE; \ - } \ - } - -/* Obtain the value of a static field in a Java class, which is known to - contain an object value. */ -#define LOAD_FIELD_OBJ(qualified_class, field, signature, class) \ - LOAD_FIELD_VAL(qualified_class, field, signature, class, Object); \ - class##_##field = (*jEnv)->NewGlobalRef(jEnv, class##_##field); - -/* - * Load the Java classes, and the method and field descriptors required for Java reflection. - * Returns JS_TRUE on success, JS_FALSE on failure. - */ -static JSBool -init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv) -{ - /* Load Java system classes and method, including java.lang.reflect classes */ - LOAD_CLASS(java/lang/Object, jlObject); - LOAD_CLASS(java/lang/Class, jlClass); - LOAD_CLASS(java/lang/reflect/Method, jlrMethod); - LOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor); - LOAD_CLASS(java/lang/reflect/Field, jlrField); - LOAD_CLASS(java/lang/Throwable, jlThrowable); - LOAD_CLASS(java/lang/System, jlSystem); - LOAD_CLASS(java/lang/Boolean, jlBoolean); - LOAD_CLASS(java/lang/Double, jlDouble); - LOAD_CLASS(java/lang/String, jlString); - LOAD_CLASS(java/lang/Void, jlVoid); - - LOAD_METHOD(java.lang.Class, getMethods, "()[Ljava/lang/reflect/Method;",jlClass); - LOAD_METHOD(java.lang.Class, getConstructors, "()[Ljava/lang/reflect/Constructor;",jlClass); - LOAD_METHOD(java.lang.Class, getFields, "()[Ljava/lang/reflect/Field;", jlClass); - LOAD_METHOD(java.lang.Class, getName, "()Ljava/lang/String;", jlClass); - LOAD_METHOD(java.lang.Class, isArray, "()Z", jlClass); - LOAD_METHOD(java.lang.Class, getComponentType, "()Ljava/lang/Class;", jlClass); - LOAD_METHOD(java.lang.Class, getModifiers, "()I", jlClass); - - LOAD_METHOD(java.lang.reflect.Method, getName, "()Ljava/lang/String;", jlrMethod); - LOAD_METHOD(java.lang.reflect.Method, getParameterTypes, "()[Ljava/lang/Class;", jlrMethod); - LOAD_METHOD(java.lang.reflect.Method, getReturnType, "()Ljava/lang/Class;", jlrMethod); - LOAD_METHOD(java.lang.reflect.Method, getModifiers, "()I", jlrMethod); - - LOAD_METHOD(java.lang.reflect.Constructor, getParameterTypes, "()[Ljava/lang/Class;", jlrConstructor); - LOAD_METHOD(java.lang.reflect.Constructor, getModifiers, "()I", jlrConstructor); - - LOAD_METHOD(java.lang.reflect.Field, getName, "()Ljava/lang/String;", jlrField); - LOAD_METHOD(java.lang.reflect.Field, getType, "()Ljava/lang/Class;", jlrField); - LOAD_METHOD(java.lang.reflect.Field, getModifiers, "()I", jlrField); - - LOAD_METHOD(java.lang.Throwable, toString, "()Ljava/lang/String;", jlThrowable); - LOAD_METHOD(java.lang.Throwable, getMessage, "()Ljava/lang/String;", jlThrowable); - - LOAD_METHOD(java.lang.Double, doubleValue, "()D", jlDouble); - - LOAD_METHOD(java.lang.Boolean, booleanValue, "()Z", jlBoolean); - - LOAD_STATIC_METHOD(java.lang.System, identityHashCode, "(Ljava/lang/Object;)I", jlSystem); - - LOAD_CONSTRUCTOR(java.lang.Boolean, Boolean, "(Z)V", jlBoolean); - LOAD_CONSTRUCTOR(java.lang.Double, Double, "(D)V", jlDouble); - - LOAD_FIELD_OBJ(java.lang.Void, TYPE, "Ljava/lang/Class;", jlVoid); - -} - -/* Load Netscape-specific Java extension classes, methods, and fields */ -static JSBool -init_netscape_java_classes(JSJavaVM *jsjava_vm, JNIEnv *jEnv) -{ - LOAD_CLASS(netscape/javascript/JSObject, njJSObject); - LOAD_CLASS(netscape/javascript/JSException, njJSException); - LOAD_CLASS(netscape/javascript/JSUtil, njJSUtil); - - LOAD_CONSTRUCTOR(netscape.javascript.JSObject, - JSObject, "(I)V", njJSObject); - LOAD_CONSTRUCTOR(netscape.javascript.JSException, - JSException, "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V", - njJSException); - LOAD_FIELDID(netscape.javascript.JSObject, - internal, "I", njJSObject); - LOAD_FIELDID(netscape.javascript.JSException, - lineno, "I", njJSException); - LOAD_FIELDID(netscape.javascript.JSException, - tokenIndex, "I", njJSException); - LOAD_FIELDID(netscape.javascript.JSException, - source, "Ljava/lang/String;", njJSException); - LOAD_FIELDID(netscape.javascript.JSException, - filename, "Ljava/lang/String;", njJSException); - - LOAD_STATIC_METHOD(netscape.javascript.JSUtil, - getStackTrace, "(Ljava/lang/Throwable;)Ljava/lang/String;", - njJSUtil); - - return JS_TRUE; -} - -JSJavaVM *jsjava_vm_list = NULL; - -/* - * Called once per Java VM, this function initializes the classes, fields, and - * methods required for Java reflection. 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_arg is non-NULL. - */ -JSJavaVM * -JSJ_ConnectToJavaVM(JavaVM *java_vm_arg, const char *user_classpath) -{ - JavaVM *java_vm; - JSJavaVM *jsjava_vm; - const char *full_classpath; - JNIEnv *jEnv; - - jsjava_vm = (JSJavaVM*)malloc(sizeof(JSJavaVM)); - if (!jsjava_vm) - return NULL; - memset(jsjava_vm, 0, sizeof(JSJavaVM)); - - java_vm = java_vm_arg; - - /* If a Java VM was passed in, try to attach to it on the current thread. */ - if (java_vm) { - if ((*java_vm)->AttachCurrentThread(java_vm, &jEnv, NULL) < 0) { - jsj_LogError("Failed to attach to Java VM thread\n"); - free(jsjava_vm); - return NULL; - } - } else { - /* No Java VM supplied, so create our own */ - JDK1_1InitArgs vm_args; - - /* Magic constant indicates JRE version 1.1 */ - vm_args.version = 0x00010001; - JNI_GetDefaultJavaVMInitArgs(&vm_args); - - /* Prepend the classpath argument to the default JVM classpath */ - if (user_classpath) { - full_classpath = PR_smprintf("%s;%s", user_classpath, vm_args.classpath); - if (!full_classpath) { - free(jsjava_vm); - return NULL; - } - vm_args.classpath = (char*)full_classpath; - } - - /* Attempt to create our own VM */ - if (JNI_CreateJavaVM(&java_vm, &jEnv, &vm_args) < 0) { - jsj_LogError("Failed to create Java VM\n"); - free(jsjava_vm); - return NULL; - } - - /* Remember that we created the VM so that we know to destroy it later */ - jsjava_vm->jsj_created_java_vm = JS_TRUE; - } - 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 - * init_java_VM_reflection, because we allow it to fail. In the case - * of failure, LiveConnect is still operative, but only when calling - * from JS to Java and not vice-versa. - */ - init_netscape_java_classes(jsjava_vm, jEnv); - - /* Put this VM on the list of all created VMs */ - jsjava_vm->next = jsjava_vm_list; - jsjava_vm_list = jsjava_vm; - - return jsjava_vm; -} - -JSJCallbacks *JSJ_callbacks = NULL; - -/* Called once to set up callbacks for all instances of LiveConnect */ -void -JSJ_Init(JSJCallbacks *callbacks) -{ - PR_ASSERT(callbacks); - JSJ_callbacks = callbacks; -} - -/* - * Initialize the provided JSContext by setting up the JS classes necessary for - * reflection and by defining JavaPackage objects for the default Java packages - * as properties of global_obj. Additional packages may be pre-defined by - * setting the predefined_packages argument. (Pre-defining a Java package at - * 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.) - */ -JSBool -JSJ_InitJSContext(JSContext *cx, JSObject *global_obj, - JavaPackageDef *predefined_packages) -{ - /* Initialize the JavaScript classes used for reflection */ - if (!jsj_init_JavaObject(cx, global_obj)) - return JS_FALSE; - -/* if (!jsj_init_JavaMember(cx, global_obj)) - return JS_FALSE; */ - - if (!jsj_init_JavaPackage(cx, global_obj, predefined_packages)) - return JS_FALSE; - - if (!jsj_init_JavaClass(cx, global_obj)) - return JS_FALSE; - - if (!jsj_init_JavaArray(cx, global_obj)) - return JS_FALSE; - - return JS_TRUE; -} - -/* Eliminate a reference to a Java class */ -#define UNLOAD_CLASS(qualified_name, class) \ - if (class) { \ - (*jEnv)->DeleteGlobalRef(jEnv, class); \ - class = NULL; \ - } - -/* - * 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. - */ -void -JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm) -{ - JNIEnv *jEnv; - JavaVM *java_vm; - - java_vm = jsjava_vm->java_vm; - (*java_vm)->AttachCurrentThread(java_vm, &jEnv, NULL); - - /* Drop all references to Java objects and classes */ - jsj_DiscardJavaObjReflections(jEnv); - jsj_DiscardJavaClassReflections(jEnv); - - if (jsjava_vm->jsj_created_java_vm) { - (*java_vm)->DestroyJavaVM(java_vm); - } else { - UNLOAD_CLASS(java/lang/Object, jlObject); - UNLOAD_CLASS(java/lang/Class, jlClass); - UNLOAD_CLASS(java/lang/reflect/Method, jlrMethod); - UNLOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor); - UNLOAD_CLASS(java/lang/reflect/Field, jlrField); - UNLOAD_CLASS(java/lang/Throwable, jlThrowable); - UNLOAD_CLASS(java/lang/System, jlSystem); - UNLOAD_CLASS(java/lang/Boolean, jlBoolean); - UNLOAD_CLASS(java/lang/Double, jlDouble); - UNLOAD_CLASS(java/lang/String, jlString); - UNLOAD_CLASS(java/lang/Void, jlVoid); - UNLOAD_CLASS(netscape/javascript/JSObject, njJSObject); - UNLOAD_CLASS(netscape/javascript/JSException, njJSException); - UNLOAD_CLASS(netscape/javascript/JSUtil, njJSUtil); - } -} - -static JSJavaThreadState *thread_list = NULL; - -static JSJavaThreadState * -new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jEnv) -{ - JSJavaThreadState *jsj_env; - - jsj_env = (JSJavaThreadState *)malloc(sizeof(JSJavaThreadState)); - if (!jsj_env) - return NULL; - memset(jsj_env, 0, sizeof(JSJavaThreadState)); - - jsj_env->jEnv = jEnv; - jsj_env->jsjava_vm = jsjava_vm; - if (thread_name) - jsj_env->name = strdup(thread_name); - - /* THREADSAFETY - need to protect against races */ - jsj_env->next = thread_list; - thread_list = jsj_env; - - return jsj_env; -} - -static JSJavaThreadState * -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; - - return jsj_env; -} - -PR_PUBLIC_API(JSJavaThreadState *) -JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *name, JNIEnv **java_envp) -{ - JNIEnv *jEnv; - JavaVM *java_vm; - JSJavaThreadState *jsj_env; - - /* Try to attach a Java thread to the current native thread */ - java_vm = jsjava_vm->java_vm; - if ((*java_vm)->AttachCurrentThread(java_vm, &jEnv, NULL) < 0) - return NULL; - - /* If we found an existing thread state, just return it. */ - jsj_env = find_jsjava_thread(jEnv); - if (jsj_env) - return jsj_env; - - /* Create a new wrapper around the thread/VM state */ - jsj_env = new_jsjava_thread_state(jsjava_vm, name, jEnv); - - if (java_envp) - *java_envp = jEnv; - return jsj_env; -} - -static JSJavaVM * -map_java_vm_to_jsjava_vm(JavaVM *java_vm) -{ - JSJavaVM *v; - for (v = jsjava_vm_list; v; v = v->next) { - if (v->java_vm == java_vm) - return v; - } - return NULL; -} - -/* - * Unfortunately, there's no standard means to associate any private data with - * a JNI thread environment, so we need to use the Java environment pointer as - * the key in a lookup table that maps it to a JSJavaThreadState structure, - * where we store all our per-thread private data. If no existing thread state - * is found, a new one is created. - * - * If an error occurs, returns NULL and sets the errp argument to an error - * message, which the caller is responsible for free'ing. - */ -JSJavaThreadState * -jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp) -{ - JSJavaThreadState *jsj_env; - JavaVM *java_vm; - JSJavaVM *jsjava_vm; - - /* If we found an existing thread state, just return it. */ - jsj_env = find_jsjava_thread(jEnv); - if (jsj_env) - return jsj_env; - - /* No one set up a LiveConnect thread state for a given Java thread. - Invoke the callback to create one on-the-fly. */ - - /* First, figure out which Java VM is calling us */ - if ((*jEnv)->GetJavaVM(jEnv, &java_vm) < 0) - 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 " - "for JavaVM 0x%08x", java_vm); - return NULL; - } - - jsj_env = new_jsjava_thread_state(jsjava_vm, NULL, jEnv); - if (!jsj_env) - return NULL; - - return jsj_env; -} - -/* - * This function is used to specify a particular JSContext as *the* JavaScript - * execution environment to be used when LiveConnect is accessed from the given - * Java thread, i.e. by using one of the methods of netscape.javascript.JSObject. - * (There can only be one such JS context for a given Java thread. To - * multiplex JSContexts among a single thread, this function must be called - * before Java is invoked on that thread.) The return value is the previous - * context associated with the given Java thread. - */ -PR_PUBLIC_API(JSContext *) -JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env) -{ - JSContext *old_context; - old_context = jsj_env->cx; - jsj_env->cx = cx; - return old_context; -} - -PR_PUBLIC_API(JSBool) -JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env) -{ - JavaVM *java_vm; - JSJavaThreadState *e, **p; - - /* Disassociate the current native thread from its corresponding Java thread */ - java_vm = jsj_env->jsjava_vm->java_vm; - if ((*java_vm)->DetachCurrentThread(java_vm) < 0) - return JS_FALSE; - - /* Destroy the LiveConnect execution environment passed in */ - jsj_ClearPendingJSErrors(jsj_env); - - /* THREADSAFETY - need to protect against races */ - for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) { - if (e == jsj_env) { - *p = jsj_env->next; - break; - } - } - - free(jsj_env); - return JS_TRUE; -} - -JSBool -JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp) -{ - JNIEnv *jEnv; - - /* Get the Java per-thread environment pointer for this JSContext */ - jsj_MapJSContextToJSJThread(cx, &jEnv); - if (!jEnv) - return JS_FALSE; - - jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp); -} - -/*===========================================================================*/ - -/* The convenience functions below present a complete, but simplified - LiveConnect API which is designed to handle the special case of a single - Java-VM, single-threaded operation, and use of only one JSContext. */ - -/* We can get away with global variables in our single-threaded, - single-JSContext case. */ -static JSJavaVM * the_jsj_vm = NULL; -static JSContext * the_cx = NULL; -static JSJavaThreadState * the_jsj_thread = NULL; -static JSObject * the_global_js_obj = NULL; - -/* Trivial implementation of callback function */ -static JSJavaThreadState * -default_map_js_context_to_jsj_thread(JSContext *cx, char **errp) -{ - return the_jsj_thread; -} - -/* Trivial implementation of callback function */ -static JSContext * -default_map_jsj_thread_to_js_context(JSJavaThreadState *jsj_env, char **errp) -{ - return the_cx; -} - -/* Trivial implementation of callback function */ -static JSObject * -default_map_java_object_to_js_object(JNIEnv *jEnv, jobject hint, char **errp) -{ - return the_global_js_obj; -} - -/* Trivial implementations of callback functions */ -JSJCallbacks jsj_default_callbacks = { - default_map_jsj_thread_to_js_context, - default_map_js_context_to_jsj_thread, - default_map_java_object_to_js_object -}; - -/* - * Initialize the provided JSContext by setting up the JS classes necessary for - * reflection and by defining JavaPackage objects for the default Java packages - * 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. - */ -JSBool -JSJ_SimpleInit(JSContext *cx, JSObject *global_obj, JavaVM *java_vm, const char *classpath) -{ - JNIEnv *jEnv; - - PR_ASSERT(!the_jsj_vm); - the_jsj_vm = JSJ_ConnectToJavaVM(java_vm, 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; - the_global_js_obj = global_obj; - - the_jsj_thread = JSJ_AttachCurrentThreadToJava(the_jsj_vm, "main thread", &jEnv); - if (!the_jsj_thread) - goto error; - - return JS_TRUE; - -error: - JSJ_SimpleShutdown(); - return JS_FALSE; -} - -/* - * Free up all LiveConnect resources. Destroy the Java VM if it was - * created by LiveConnect. - */ -PR_PUBLIC_API(void) -JSJ_SimpleShutdown() -{ - PR_ASSERT(the_jsj_vm); - JSJ_DisconnectFromJavaVM(the_jsj_vm); - the_jsj_vm = NULL; - the_cx = NULL; - the_global_js_obj = NULL; - the_jsj_thread = NULL; -} - diff --git a/js/ref/liveconnect/jsj_JSObject.c b/js/ref/liveconnect/jsj_JSObject.c index b841fff0ecd..5305e015fcd 100644 --- a/js/ref/liveconnect/jsj_JSObject.c +++ b/js/ref/liveconnect/jsj_JSObject.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* This file is part of the Java-vendor-neutral implementation of LiveConnect @@ -28,9 +13,6 @@ #include #include -#include "prtypes.h" -#include "prprintf.h" -#include "prassert.h" #include "jsj_private.h" #include "jsjava.h" @@ -53,6 +35,7 @@ struct CapturedJSError { /*********************** Reflection of JSObjects ****************************/ +#ifdef PRESERVE_JSOBJECT_IDENTITY /* * This is a hash table that maps from JS objects to Java objects. * It is used to ensure that the same Java object results when a JS @@ -72,11 +55,13 @@ static PRHashTable *js_obj_reflections = NULL; * read/write or * write/write access. */ static PRMonitor *js_obj_reflections_monitor = NULL; -#endif +#endif /* JS_THREADSAFE */ +#endif /* PRESERVE_JSOBJECT_IDENTITY */ static JSBool init_js_obj_reflections_table() { +#ifdef PRESERVE_JSOBJECT_IDENTITY js_obj_reflections = PR_NewHashTable(128, NULL, PR_CompareValues, PR_CompareValues, NULL, NULL); if (!js_obj_reflections) @@ -88,7 +73,8 @@ init_js_obj_reflections_table() PR_HashTableDestroy(js_obj_reflections); return JS_FALSE; } -#endif +#endif /* JS_THREADSAFE */ +#endif /* PRESERVE_JSOBJECT_IDENTITY */ return JS_TRUE; } @@ -101,6 +87,9 @@ init_js_obj_reflections_table() * * If an error occurs, returns NULL and reports an error. */ + +#ifdef PRESERVE_JSOBJECT_IDENTITY + jobject jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj) { @@ -115,16 +104,14 @@ jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj) /* 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, (prhashcode)js_obj, js_obj); + hep = PR_HashTableRawLookup(js_obj_reflections, (PRHashNumber)js_obj, js_obj); -#ifdef PRESERVE_JSOBJECT_IDENTITY /* 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 '==' operator works as expected in Java when comparing two JSObjects. However, it is not possible to hold a reference to a Java object without - inhibiting GC of that object, at least not in a way that is portable - to all vendor's JVM, i.e. a weak reference. So, for now, JSObject identity - is broken. */ + inhibiting GC of that object, at least not in a portable way, i.e. + a weak reference. So, for now, JSObject identity is broken. */ he = *hep; if (he) { @@ -133,7 +120,6 @@ jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj) if (java_wrapper_obj) goto done; } -#endif /* PRESERVE_JSOBJECT_IDENTITY */ /* No existing reflection found, so create a new Java object that wraps the JavaScript object by storing its address in a private integer field. */ @@ -146,7 +132,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, (prhashcode)js_obj, + he = PR_HashTableRawAdd(js_obj_reflections, hep, (PRHashNumber)js_obj, js_obj, java_wrapper_obj); if (he) { /* Tell the JavaScript GC about this object since the only reference @@ -188,7 +174,7 @@ remove_js_obj_reflection_from_hashtable(JSContext *cx, JSObject *js_obj) #endif /* Get the hash-table entry for this wrapper object */ - hep = PR_HashTableRawLookup(js_obj_reflections, (prhashcode)js_obj, js_obj); + hep = PR_HashTableRawLookup(js_obj_reflections, (PRHashNumber)js_obj, js_obj); he = *hep; PR_ASSERT(he); @@ -207,6 +193,64 @@ remove_js_obj_reflection_from_hashtable(JSContext *cx, JSObject *js_obj) return success; } +#else /* !PRESERVE_JSOBJECT_IDENTITY */ + +/* This object provides is the "anchor" by which netscape.javscript.JSObject + objects hold a reference to native JSObjects. */ +typedef struct JSObjectRoot { + JSObject *js_obj; + JSContext *cx; /* Creating context, needed for finalization */ +} JSObjectHandle; + +/* + * The caller must call DeleteLocalRef() on the returned object when no more + * references remain. + */ +jobject +jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj) +{ + jobject java_wrapper_obj; + JSObjectHandle *handle; + + /* 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) + return NULL; + 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. */ + java_wrapper_obj = + (*jEnv)->NewObject(jEnv, njJSObject, njJSObject_JSObject, (jint)handle); + if (!java_wrapper_obj) { + jsj_UnexpectedJavaError(cx, jEnv, "Couldn't create new instance of " + "netscape.javascript.JSObject"); + goto done; + } + + JS_AddRoot(cx, &handle->js_obj); + +done: + + return java_wrapper_obj; +} + +JSObject * +jsj_UnwrapJSObjectWrapper(JNIEnv *jEnv, jobject java_wrapper_obj) +{ + JSObjectHandle *handle; + + handle = (JSObjectHandle*)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal)); + PR_ASSERT(handle); + if (!handle) + return NULL; + return handle->js_obj; +} + +#endif /* !PRESERVE_JSOBJECT_IDENTITY */ + /*************** Handling of Java exceptions in JavaScript ******************/ /* @@ -498,7 +542,6 @@ done: } - /*************** Utilities for calling JavaScript from Java *****************/ /* @@ -523,14 +566,19 @@ enter_js(JNIEnv *jEnv, jobject java_wrapper_obj, /* Invoke callback, presumably used to implement concurrency constraints */ if (JSJ_callbacks->enter_js_from_java) { - if (!JSJ_callbacks->enter_js_from_java(&err_msg)) + if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg)) goto entry_failure; } - /* Check the JSObject pointer in the wrapper object for null while holding - the JS lock to deal with shutdown issues. */ + /* Check the JSObject pointer in the wrapper object. */ if (js_objp) { + +#ifdef PRESERVE_JSOBJECT_IDENTITY js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal)); +#else /* !PRESERVE_JSOBJECT_IDENTITY */ + js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_wrapper_obj); +#endif /* PRESERVE_JSOBJECT_IDENTITY */ + PR_ASSERT(js_obj); if (!js_obj) goto error; @@ -549,7 +597,7 @@ enter_js(JNIEnv *jEnv, jobject java_wrapper_obj, Java and back into JS. Invoke a callback to obtain/create a JSContext for us to use. */ if (JSJ_callbacks->map_jsj_thread_to_js_context) { - cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env, &err_msg); + cx = JSJ_callbacks->map_jsj_thread_to_js_context(jsj_env, jEnv, &err_msg); if (!cx) goto error; } else { @@ -572,7 +620,7 @@ enter_js(JNIEnv *jEnv, jobject java_wrapper_obj, error: /* Invoke callback, presumably used to implement concurrency constraints */ if (JSJ_callbacks->exit_js) - JSJ_callbacks->exit_js(); + JSJ_callbacks->exit_js(jEnv); entry_failure: if (err_msg) { @@ -617,7 +665,7 @@ exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JSErrorReporter original_repo /* Invoke callback, presumably used to implement concurrency constraints */ if (JSJ_callbacks->exit_js) - JSJ_callbacks->exit_js(); + JSJ_callbacks->exit_js(jEnv); return JS_TRUE; } @@ -680,7 +728,7 @@ Java_netscape_javascript_JSObject_getMember(JNIEnv *jEnv, property_name_ucs2 = NULL; if (!property_name_jstr) { - JS_ReportError(cx, "illegal null member name"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_NULL_MEMBER_NAME); member = NULL; goto done; } @@ -771,7 +819,7 @@ Java_netscape_javascript_JSObject_setMember(JNIEnv *jEnv, property_name_ucs2 = NULL; if (!property_name_jstr) { - JS_ReportError(cx, "illegal null member name"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_NULL_MEMBER_NAME); goto done; } @@ -847,7 +895,7 @@ Java_netscape_javascript_JSObject_removeMember(JNIEnv *jEnv, return; if (!property_name_jstr) { - JS_ReportError(cx, "illegal null member name"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_NULL_MEMBER_NAME); goto done; } /* Get the Unicode string for the JS property name */ @@ -897,7 +945,8 @@ Java_netscape_javascript_JSObject_call(JNIEnv *jEnv, jobject java_wrapper_obj, function_name_ucs2 = NULL; result = NULL; if (!function_name_jstr) { - JS_ReportError(cx, "illegal null JavaScript function name"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_NULL_FUNCTION_NAME); goto done; } @@ -985,7 +1034,7 @@ Java_netscape_javascript_JSObject_eval(JNIEnv *jEnv, result = NULL; eval_ucs2 = NULL; if (!eval_jstr) { - JS_ReportError(cx, "illegal null string eval argument"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_NULL_EVAL_ARG); goto done; } @@ -1108,15 +1157,49 @@ done: JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize(JNIEnv *jEnv, jobject java_wrapper_obj) { + JSBool success; JSContext *cx; - JSErrorReporter saved_reporter; - JSJavaThreadState *jsj_env; - JSObject *js_obj; - - jsj_env = enter_js(jEnv, java_wrapper_obj, &cx, &js_obj, &saved_reporter); - if (!jsj_env) /* Note: memory leak if we exit here */ + JSObjectHandle *handle; + + success = JS_FALSE; + + handle = (JSObjectHandle *)((*jEnv)->GetIntField(jEnv, java_wrapper_obj, njJSObject_internal)); + PR_ASSERT(handle); + if (!handle) return; - remove_js_obj_reflection_from_hashtable(cx, js_obj); - exit_js(cx, jsj_env, saved_reporter); + cx = handle->cx; + + success = JS_RemoveRoot(cx, &handle->js_obj); + JS_free(cx, handle); + + PR_ASSERT(success); } +/* + * Class: netscape_javascript_JSObject + * Method: equals + * Signature: (Ljava/lang/Object;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_netscape_javascript_JSObject_equals(JNIEnv *jEnv, + jobject java_wrapper_obj, + jobject comparison_obj) +{ +#ifdef PRESERVE_JSOBJECT_IDENTITY +# error "Missing code should be added here" +#else + JSObject *js_obj1, *js_obj2; + + /* Check that we're comparing with another netscape.javascript.JSObject */ + if (!comparison_obj) + return 0; + if (!(*jEnv)->IsInstanceOf(jEnv, comparison_obj, njJSObject)) + return 0; + + js_obj1 = jsj_UnwrapJSObjectWrapper(jEnv, java_wrapper_obj); + js_obj2 = jsj_UnwrapJSObjectWrapper(jEnv, comparison_obj); + + return (js_obj1 == js_obj2); +#endif /* PRESERVE_JSOBJECT_IDENTITY */ +} diff --git a/js/ref/liveconnect/jsj_JavaArray.c b/js/ref/liveconnect/jsj_JavaArray.c index c4914ad835f..8b4c41c4bd7 100644 --- a/js/ref/liveconnect/jsj_JavaArray.c +++ b/js/ref/liveconnect/jsj_JavaArray.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* @@ -26,13 +11,9 @@ #include #include -#include "prassert.h" #include "jsj_private.h" /* LiveConnect internals */ - -/* Shorthands for ASCII (7-bit) decimal and hex conversion. */ -#define JS7_ISDEC(c) (((c) >= '0') && ((c) <= '9')) -#define JS7_UNDEC(c) ((c) - '0') +#include "jscntxt.h" /* for error reporting */ /* * Convert any jsval v to an integer jsval if ToString(v) @@ -99,7 +80,7 @@ access_java_array_element(JSContext *cx, return JS_TRUE; } } - JS_ReportError(cx, "illegal operation on JavaArray prototype object"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_BAD_OP_JARRAY); return JS_FALSE; } class_descriptor = java_wrapper->class_descriptor; @@ -128,8 +109,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, + JSJMSG_CANT_WRITE_JARRAY, member_name); return JS_FALSE; } else { *vp = JSVAL_VOID; @@ -150,7 +131,7 @@ access_java_array_element(JSContext *cx, } } - JS_ReportError(cx, "invalid Java array index expression"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_BAD_INDEX_EXPR); return JS_FALSE; } @@ -163,7 +144,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, + JSJMSG_BAD_JARRAY_INDEX, numBuf); return JS_FALSE; } #endif @@ -223,7 +207,7 @@ 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, JSJMSG_JARRAY_PROP_DEFINE); return JS_FALSE; } @@ -241,7 +225,7 @@ JavaArray_setAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, uintN *attrsp) { /* We don't maintain JS property attributes for Java class members */ - if (*attrsp != JSPROP_PERMANENT|JSPROP_ENUMERATE) { + if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) { PR_ASSERT(0); return JS_FALSE; } @@ -258,7 +242,7 @@ 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, JSJMSG_JARRAY_PROP_DELETE); return JS_FALSE; } else { /* Attempts to delete permanent properties are silently ignored @@ -335,11 +319,11 @@ 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, 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, JSJMSG_JARRAY_PROP_EXPORT); return JS_FALSE; default: @@ -384,7 +368,7 @@ JSClass JavaArray_class = { JavaArray_getObjectOps, }; -extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps; +extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; /* Initialize the JS JavaArray class */ diff --git a/js/ref/liveconnect/jsj_JavaClass.c b/js/ref/liveconnect/jsj_JavaClass.c index 25d1fb6030b..80af7393382 100644 --- a/js/ref/liveconnect/jsj_JavaClass.c +++ b/js/ref/liveconnect/jsj_JavaClass.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* This file is part of the Java-vendor-neutral implementation of LiveConnect @@ -36,11 +21,8 @@ #include #include -#include "prtypes.h" -#include "prprintf.h" -#include "prassert.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) @@ -79,8 +61,9 @@ JavaClass_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) return JS_TRUE; default: - return JS_TRUE; + break; } + return JS_TRUE; } static JSBool @@ -107,9 +90,9 @@ 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)"); - return JS_FALSE; + JS_ReportErrorNumber(cx, + jsj_GetErrorMessage, JSJMSG_BAD_JCLASS_EXPR); + return JS_FALSE; } member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval)); @@ -120,7 +103,7 @@ 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, JSJMSG_MISSING_NAME, class_descriptor->name, member_name); return JS_FALSE; } @@ -173,8 +156,8 @@ JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp) return JS_FALSE; *vp = OBJECT_TO_JSVAL(JS_GetFunctionObject(function)); - return JS_TRUE; } + return JS_TRUE; } PR_STATIC_CALLBACK(JSBool) @@ -212,7 +195,7 @@ 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, JSJMSG_MISSING_STATIC, member_name, class_descriptor->name); return JS_FALSE; } @@ -234,7 +217,7 @@ JavaClass_finalize(JSContext *cx, JSObject *obj) if (!jEnv) return; - printf("Finalizing %s\n", class_descriptor->name); + /* printf("Finalizing %s\n", class_descriptor->name); */ jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor); } @@ -248,18 +231,25 @@ JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id, ) { JNIEnv *jEnv; + JSErrorReporter old_reporter; /* printf("In JavaClass_lookupProperty()\n"); */ - + /* Get the Java per-thread environment pointer for this JSContext */ jsj_MapJSContextToJSJThread(cx, &jEnv); if (!jEnv) return JS_FALSE; - if (!lookup_static_member_by_id(cx, jEnv, obj, NULL, id, NULL)) - return JS_FALSE; - *objp = obj; - *propp = (JSProperty*)1; + old_reporter = JS_SetErrorReporter(cx, NULL); + if (lookup_static_member_by_id(cx, jEnv, obj, NULL, id, NULL)) { + *objp = obj; + *propp = (JSProperty*)1; + } else { + *objp = NULL; + *propp = NULL; + } + + JS_SetErrorReporter(cx, old_reporter); return JS_TRUE; } @@ -268,7 +258,7 @@ 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"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_JCLASS_PROP_DEFINE); return JS_FALSE; } @@ -286,7 +276,7 @@ JavaClass_setAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, uintN *attrsp) { /* We don't maintain JS property attributes for Java class members */ - if (*attrsp != JSPROP_PERMANENT|JSPROP_ENUMERATE) { + if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) { PR_ASSERT(0); return JS_FALSE; } @@ -303,7 +293,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, + JSJMSG_JCLASS_PROP_DELETE); return JS_FALSE; } else { /* Attempts to delete permanent properties are silently ignored @@ -374,11 +365,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, + 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, + JSJMSG_JCLASS_PROP_EXPORT); return JS_FALSE; default: @@ -406,7 +399,7 @@ 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, JSJMSG_BAD_OP_JCLASS); return JS_FALSE; } @@ -424,7 +417,7 @@ 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, JSJMSG_BAD_OP_PROTO); return JS_FALSE; } java_obj = java_wrapper->java_obj; @@ -538,17 +531,17 @@ getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) 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) && + !JSVAL_IS_OBJECT(argv[0]) || + !(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"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, 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, JSJMSG_PROTO_GETCLASS); return JS_FALSE; } @@ -561,7 +554,7 @@ getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return JS_TRUE; } -extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps; +extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; JSBool jsj_init_JavaClass(JSContext *cx, JSObject *global_obj) diff --git a/js/ref/liveconnect/jsj_JavaObject.c b/js/ref/liveconnect/jsj_JavaObject.c index 2d6e52adaec..18db6f69559 100644 --- a/js/ref/liveconnect/jsj_JavaObject.c +++ b/js/ref/liveconnect/jsj_JavaObject.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* @@ -28,10 +13,10 @@ #include #include -#include "prassert.h" #include "jsj_private.h" /* LiveConnect internals */ #include "jsj_hash.h" /* Hash table with Java object as key */ +#include "jscntxt.h" /* for error reporting */ /* @@ -229,9 +214,13 @@ enumerate_remove_java_obj(JSJHashEntry *he, PRIntn i, void *arg) void jsj_DiscardJavaObjReflections(JNIEnv *jEnv) { - JSJ_HashTableEnumerateEntries(java_obj_reflections, - enumerate_remove_java_obj, - (void*)jEnv); + if (java_obj_reflections) { + JSJ_HashTableEnumerateEntries(java_obj_reflections, + enumerate_remove_java_obj, + (void*)jEnv); + JSJ_HashTableDestroy(java_obj_reflections); + java_obj_reflections = NULL; + } } PR_CALLBACK JSBool @@ -254,7 +243,7 @@ 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, JSJMSG_BAD_OP_JOBJECT); return JS_FALSE; } @@ -267,7 +256,7 @@ 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, JSJMSG_CONVERT_TO_FUNC); return JS_FALSE; case JSTYPE_VOID: @@ -278,11 +267,11 @@ JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) case JSTYPE_NUMBER: /* Call Java doubleValue() method, if applicable */ - return jsj_ConvertJavaObjectToJSNumber(cx, jEnv, java_obj, vp); + return jsj_ConvertJavaObjectToJSNumber(cx, jEnv, class_descriptor, java_obj, vp); case JSTYPE_BOOLEAN: /* Call booleanValue() method, if applicable */ - return jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, java_obj, vp); + return jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp); default: PR_ASSERT(0); @@ -312,7 +301,7 @@ lookup_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj, return JS_TRUE; } } - JS_ReportError(cx, "illegal operation on JavaObject prototype object"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_BAD_OP_JOBJECT); return JS_FALSE; } @@ -324,16 +313,16 @@ lookup_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 JavaObject property expression. " - "(methods and field properties of a JavaObject object can only be strings)"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_BAD_JOBJECT_EXPR); return JS_FALSE; } 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); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_NO_INSTANCE_NAME, + class_descriptor->name, member_name); return JS_FALSE; } @@ -353,6 +342,8 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp) JavaObjectWrapper *java_wrapper; JNIEnv *jEnv; JSObject *funobj; + jsval field_val, method_val; + JSBool success; /* printf("In JavaObject_getProperty\n"); */ @@ -372,22 +363,56 @@ JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp) } java_obj = java_wrapper->java_obj; + field_val = method_val = JSVAL_VOID; + + /* If a field member, get the value of the field */ if (member_descriptor->field) { - if (!member_descriptor->methods) { - return jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, vp); - } else { - PR_ASSERT(0); - } - } else { + success = jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, &field_val); + if (!success) + return JS_FALSE; + } + + /* If a method member, build a wrapper around the Java method */ + if (member_descriptor->methods) { /* Create a function object with this JavaObject as its parent, so that JSFUN_BOUND_METHOD binds it as the default 'this' for the function. */ funobj = JS_CloneFunctionObject(cx, member_descriptor->invoke_func_obj, obj); - if (funobj) { - *vp = OBJECT_TO_JSVAL(funobj); - return JS_TRUE; - } - return JS_FALSE; + if (!funobj) + return JS_FALSE; + method_val = OBJECT_TO_JSVAL(funobj); } + +#if TEST_JAVAMEMBER + /* Always create a JavaMember object, even though it's inefficient */ + obj = jsj_CreateJavaMember(cx, method_val, field_val); + if (!obj) + return JS_FALSE; + *vp = OBJECT_TO_JSVAL(obj); +#else /* !TEST_JAVAMEMBER */ + + if (member_descriptor->field) { + if (!member_descriptor->methods) { + /* Return value of Java field */ + *vp = field_val; + } else { + /* Handle special case of access to a property that could refer + to either a Java field or a method that share the same name. + In Java, such ambiguity is not possible because the compiler + can statically determine which is being accessed. */ + obj = jsj_CreateJavaMember(cx, method_val, field_val); + if (!obj) + return JS_FALSE; + *vp = OBJECT_TO_JSVAL(obj); + } + + } else { + /* Return wrapper around Java method */ + *vp = method_val; + } + +#endif /* !TEST_JAVAMEMBER */ + + return JS_TRUE; } PR_STATIC_CALLBACK(JSBool) @@ -427,43 +452,11 @@ 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, JSJMSG_NO_NAME_IN_CLASS, member_name, class_descriptor->name); return JS_FALSE; } -PR_CALLBACK JSBool -JavaObject_enumerate(JSContext *cx, JSObject *obj) -{ - JavaObjectWrapper *java_wrapper; - JavaClassDescriptor *class_descriptor; - JavaMemberDescriptor *member_descriptor; - JNIEnv *jEnv; - -/* printf("In JavaObject_enumerate\n"); */ - - java_wrapper = JS_GetPrivate(cx, obj); - - /* Check if this is the prototype object */ - if (!java_wrapper) - return JS_TRUE; - - /* Get the Java per-thread environment pointer for this JSContext */ - jsj_MapJSContextToJSJThread(cx, &jEnv); - if (!jEnv) - return JS_FALSE; - - class_descriptor = java_wrapper->class_descriptor; - member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor); - while (member_descriptor) { - JS_DefineProperty(cx, obj, member_descriptor->name, JSVAL_VOID, 0, 0, - JSPROP_PERMANENT|JSPROP_ENUMERATE); - member_descriptor = member_descriptor->next; - } - return JS_TRUE; -} - - static JSBool JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, JSProperty **propp @@ -473,6 +466,7 @@ JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id, ) { JNIEnv *jEnv; + JSErrorReporter old_reporter; /* printf("In JavaObject_lookupProperty()\n"); */ @@ -481,10 +475,16 @@ JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id, if (!jEnv) return JS_FALSE; - if (!lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL)) - return JS_FALSE; - *objp = obj; - *propp = (JSProperty*)1; + old_reporter = JS_SetErrorReporter(cx, NULL); + if (lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL)) { + *objp = obj; + *propp = (JSProperty*)1; + } else { + *objp = NULL; + *propp = NULL; + } + + JS_SetErrorReporter(cx, old_reporter); return JS_TRUE; } @@ -493,7 +493,7 @@ 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, JSJMSG_JOBJECT_PROP_DEFINE); return JS_FALSE; } @@ -511,7 +511,7 @@ JavaObject_setAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, uintN *attrsp) { /* We don't maintain JS property attributes for Java class members */ - if (*attrsp != JSPROP_PERMANENT|JSPROP_ENUMERATE) { + if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) { PR_ASSERT(0); return JS_FALSE; } @@ -528,7 +528,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, + JSJMSG_JOBJECT_PROP_DELETE); return JS_FALSE; } else { /* Attempts to delete permanent properties are silently ignored @@ -541,7 +542,7 @@ static JSBool JavaObject_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp) { /* printf("In JavaObject_defaultValue()\n"); */ - return JavaObject_convert(cx, obj, JSTYPE_STRING, vp); + return JavaObject_convert(cx, obj, type, vp); } static JSBool @@ -604,11 +605,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, + 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, + JSJMSG_JOBJECT_PROP_EXPORT); return JS_FALSE; default: @@ -653,7 +656,7 @@ JSClass JavaObject_class = { JavaObject_getObjectOps, }; -extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps; +extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; JSBool diff --git a/js/ref/liveconnect/jsj_JavaPackage.c b/js/ref/liveconnect/jsj_JavaPackage.c index 7a11dcd9b6c..0e36d12dada 100644 --- a/js/ref/liveconnect/jsj_JavaPackage.c +++ b/js/ref/liveconnect/jsj_JavaPackage.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* This file is part of the Java-vendor-neutral implementation of LiveConnect @@ -36,12 +21,9 @@ #include #include -#include "prtypes.h" -#include "prprintf.h" -#include "prosdep.h" - #include "jsj_private.h" /* LiveConnect internals */ #include "jsjava.h" +#include "jscntxt.h" /* for error reporting */ JSClass JavaPackage_class; /* Forward declaration */ @@ -99,11 +81,11 @@ 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, + 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, JSJMSG_DONT_ADD_TO_PACKAGE); return JS_FALSE; } @@ -121,13 +103,17 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id) char *subPath, *newPath; 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; if (!JSVAL_IS_STRING(id)) - return JS_TRUE; + return JS_TRUE; subPath = JS_GetStringBytes(JSVAL_TO_STRING(id)); /* @@ -186,6 +172,11 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id) } } else { + /* We assume that any failed attempt to load a class is because it + doesn't exist. If we wanted to do a better job, we would check + the exception type and make sure that it's NoClassDefFoundError */ + (*jEnv)->ExceptionClear(jEnv); + /* * 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 @@ -197,14 +188,12 @@ JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id) package = JS_GetPrivate(cx, obj); if (package->flags & PKG_SYSTEM) { char *msg, *cp; - - /* Painful hack for pre_define_java_packages() */ - if (quiet_resolve_failure) - return JS_FALSE; - +/* 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) { @@ -212,10 +201,10 @@ 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, + JSJMSG_MISSING_PACKAGE, msg); free((char*)msg); } - return JS_FALSE; } } @@ -357,7 +346,8 @@ standard_java_packages[] = { {"sun", NULL, PKG_USER}, {"Packages", "", PKG_USER}, - 0 + + {NULL, NULL, 0} }; /* @@ -394,7 +384,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, + JSJMSG_DOUBLE_SHIPPING, package_name); goto error; } @@ -410,7 +401,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, + JSJMSG_BAD_PACKAGE_PREDEF, package_def->name); goto error; } @@ -458,7 +450,7 @@ error: static JSBool JavaPackage_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval) + jsval *rval) { if (!JS_InstanceOf(cx, obj, &JavaPackage_class, argv)) return JS_FALSE; diff --git a/js/ref/liveconnect/jsj_array.c b/js/ref/liveconnect/jsj_array.c index 82af588e160..e69de29bb2d 100644 --- a/js/ref/liveconnect/jsj_array.c +++ b/js/ref/liveconnect/jsj_array.c @@ -1,183 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 - * - * It contains the code for reading and writing elements of a Java array. - */ - -#include "prtypes.h" -#include "prassert.h" - -#include "jsj_private.h" /* LiveConnect internals */ - -/* - * Read the Java value at a given index into a Java array and convert it - * to a JS value. The array_component_signature describes the type of - * the resulting Java value, which can be a primitive type or an object type. - * More specifically it can be an array type in the case of multidimensional - * arrays. - */ -JSBool -jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index, - JavaSignature *array_component_signature, - jsval *vp) -{ - jvalue java_value; - JavaSignatureChar component_type; - -#define GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \ - (*jEnv)->Get##Type##ArrayRegion(jEnv, java_array, index, 1, \ - &java_value.member); \ - if ((*jEnv)->ExceptionOccurred(jEnv)) { \ - jsj_ReportJavaError(cx, jEnv, "Error reading element of " \ - "Java primitive array"); \ - return JS_FALSE; \ - } - - component_type = array_component_signature->type; - switch(component_type) { - case JAVA_SIGNATURE_BYTE: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b); - break; - - case JAVA_SIGNATURE_CHAR: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c); - break; - - case JAVA_SIGNATURE_SHORT: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s); - break; - - case JAVA_SIGNATURE_INT: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i); - break; - - case JAVA_SIGNATURE_BOOLEAN: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z); - break; - - case JAVA_SIGNATURE_LONG: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j); - break; - - case JAVA_SIGNATURE_FLOAT: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f); - break; - - case JAVA_SIGNATURE_DOUBLE: - GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d); - break; - - case JAVA_SIGNATURE_CLASS: - case 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; - -#undef GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY - default: - PR_ASSERT(0); /* Unknown java type signature */ - return JS_FALSE; - } - - return jsj_ConvertJavaValueToJSValue(cx, jEnv, array_component_signature, &java_value, vp); -} - -JSBool -jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index, - JavaSignature *array_component_signature, - jsval js_val) -{ - int dummy_cost; - jvalue java_value; - JavaSignatureChar component_type; - JSBool is_local_ref; - - if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, array_component_signature, - &dummy_cost, &java_value, &is_local_ref)) - return JS_FALSE; - -#define SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \ - (*jEnv)->Set##Type##ArrayRegion(jEnv, java_array, index, 1, \ - &java_value.member); \ - if ((*jEnv)->ExceptionOccurred(jEnv)) { \ - jsj_ReportJavaError(cx, jEnv, "Error assigning to element of " \ - "Java primitive array"); \ - return JS_FALSE; \ - } - - component_type = array_component_signature->type; - switch(component_type) { - case JAVA_SIGNATURE_BYTE: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b); - break; - - case JAVA_SIGNATURE_CHAR: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c); - break; - - case JAVA_SIGNATURE_SHORT: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s); - break; - - case JAVA_SIGNATURE_INT: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i); - break; - - case JAVA_SIGNATURE_BOOLEAN: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z); - break; - - case JAVA_SIGNATURE_LONG: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j); - break; - - case JAVA_SIGNATURE_FLOAT: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f); - break; - - case JAVA_SIGNATURE_DOUBLE: - SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d); - break; - - case JAVA_SIGNATURE_CLASS: - case JAVA_SIGNATURE_ARRAY: - (*jEnv)->SetObjectArrayElement(jEnv, java_array, index, java_value.l); - if (is_local_ref) \ - (*jEnv)->DeleteLocalRef(jEnv, java_value.l); - if ((*jEnv)->ExceptionOccurred(jEnv)) { - jsj_ReportJavaError(cx, jEnv, "Error assigning to Java object array"); - return JS_FALSE; - } - break; - -#undef SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY - default: - PR_ASSERT(0); /* Unknown java type signature */ - return JS_FALSE; - } - - return JS_TRUE; -} - diff --git a/js/ref/liveconnect/jsj_class.c b/js/ref/liveconnect/jsj_class.c index c4da8678b84..e69de29bb2d 100644 --- a/js/ref/liveconnect/jsj_class.c +++ b/js/ref/liveconnect/jsj_class.c @@ -1,606 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 - * - * It contains the code that constructs and manipulates JavaClassDescriptor - * structs, which are the native wrappers for Java classes. - * JavaClassDescriptors are used to describe the signatures of methods and - * fields. There is a JavaClassDescriptor associated with the reflection of - * each Java Object. - */ - -#include -#include - -#include "prtypes.h" -#include "prprintf.h" -#include "prassert.h" - -#include "jsj_private.h" /* LiveConnect internals */ - -#include "jsj_hash.h" /* Hash tables */ - -/* A one-to-one mapping between all referenced java.lang.Class objects and - their corresponding JavaClassDescriptor objects */ -static JSJHashTable *java_class_reflections; - -/* - * Given a JVM handle to a java.lang.Class object, malloc a C-string - * containing the UTF8 encoding of the fully qualified name of the class. - * It's the caller's responsibility to free the returned string. - * - * If an error occurs, NULL is returned and the error reporter called. - */ -const char * -jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class) -{ - jstring java_class_name_jstr; - const char *java_class_name; - - /* Get java.lang.String object containing class name */ - 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; - - return java_class_name; - -error: - jsj_UnexpectedJavaError(cx, jEnv, "Can't get Java class name using" - "java.lang.Class.getName()"); - return NULL; -} - -/* - * Convert in-place a string of the form "java.lang.String" into "java/lang/String". - * Though the former style is conventionally used by Java programmers, the latter is - * what the JNI functions require. - */ -void -jsj_MakeJNIClassname(char * class_name) -{ - char * c; - for (c = class_name; *c; c++) - if (*c == '.') - *c = '/'; -} - -/* - * Classify an instance of java.lang.Class as either one of the primitive - * types, e.g. int, char, etc., as an array type or as a non-array object type - * (subclass of java.lang.Object) by returning the appropriate enum member. - * - */ -static JavaSignatureChar -get_signature_type(JSContext *cx, JavaClassDescriptor *class_descriptor) -{ - JavaSignatureChar type; - const char *java_class_name; - - /* Get UTF8 encoding of class name */ - java_class_name = class_descriptor->name; - PR_ASSERT(java_class_name); - if (!java_class_name) - return JAVA_SIGNATURE_UNKNOWN; - - if (!strcmp(java_class_name, "byte")) - type = JAVA_SIGNATURE_BYTE; - else if (!strcmp(java_class_name, "char")) - type = JAVA_SIGNATURE_CHAR; - else if (!strcmp(java_class_name, "float")) - type = JAVA_SIGNATURE_FLOAT; - else if (!strcmp(java_class_name, "double")) - type = JAVA_SIGNATURE_DOUBLE; - else if (!strcmp(java_class_name, "int")) - type = JAVA_SIGNATURE_INT; - else if (!strcmp(java_class_name, "long")) - type = JAVA_SIGNATURE_LONG; - else if (!strcmp(java_class_name, "short")) - type = JAVA_SIGNATURE_SHORT; - else if (!strcmp(java_class_name, "boolean")) - type = JAVA_SIGNATURE_BOOLEAN; - else if (!strcmp(java_class_name, "void")) - type = JAVA_SIGNATURE_VOID; - else - /* Well, I guess it's a Java class, then. */ - type = JAVA_SIGNATURE_CLASS; - - return type; -} - -static JSBool -is_java_array_class(JNIEnv *jEnv, jclass java_class) -{ - return (*jEnv)->CallBooleanMethod(jEnv, java_class, jlClass_isArray); -} - -/* - * Return the class of a Java array's component type. This is not the same - * as the array's element type. For example, the component type of an array - * of type SomeType[][][] is SomeType[][], but its element type is SomeType. - * - * If an error occurs, NULL is returned and an error reported. - */ -static jclass -get_java_array_component_class(JSContext *cx, JNIEnv *jEnv, jclass java_class) -{ - jclass result; - result = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getComponentType); - if (!result) { - jsj_UnexpectedJavaError(cx, jEnv, - "Can't get Java array component class using " - "java.lang.Class.getComponentType()"); - return NULL; - } - return result; -} - -/* - * Given a Java class, fill in the signature structure that describes the class. - * If an error occurs, JS_FALSE is returned and the error reporter called. - */ -static JSBool -compute_java_class_signature(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature) -{ - jclass java_class = signature->java_class; - - if (is_java_array_class(jEnv, java_class)) { - jclass component_class; - - signature->type = JAVA_SIGNATURE_ARRAY; - - component_class = get_java_array_component_class(cx, jEnv, java_class); - if (!component_class) - return JS_FALSE; - - signature->array_component_signature = - jsj_GetJavaClassDescriptor(cx, jEnv, component_class); - if (!signature->array_component_signature) - return JS_FALSE; - } else { - signature->type = get_signature_type(cx, signature); - } - return JS_TRUE; -} - -/* - * Convert a JavaSignature object into a string format as used by - * the JNI functions, e.g. java.lang.Object ==> "Ljava/lang/Object;" - * The caller is responsible for freeing the resulting string. - * - * If an error is encountered, NULL is returned and an error reported. - */ -const char * -jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature) -{ - char *sig; - - if (signature->type == JAVA_SIGNATURE_CLASS) { - /* A non-array object class */ - sig = PR_smprintf("L%s;", signature->name); - if (sig) - jsj_MakeJNIClassname(sig); - - } else if (signature->type == JAVA_SIGNATURE_ARRAY) { - /* An array class */ - const char *component_signature_string; - - component_signature_string = - jsj_ConvertJavaSignatureToString(cx, signature->array_component_signature); - if (!component_signature_string) - return NULL; - sig = PR_smprintf("[%s", component_signature_string); - JS_free(cx, (char*)component_signature_string); - - } else { - /* A primitive class */ - sig = PR_smprintf("%c", (char)signature->type); - } - - if (!sig) { - JS_ReportOutOfMemory(cx); - return NULL; - } - return sig; -} - -/* - * Convert a JavaSignature object into a human-readable string format as seen - * in Java source files, e.g. "byte", or "int[][]" or "java.lang.String". - * The caller is responsible for freeing the resulting string. - * - * If an error is encountered, NULL is returned and an error reported. - */ -const char * -jsj_ConvertJavaSignatureToHRString(JSContext *cx, - JavaSignature *signature) -{ - char *sig; - JavaSignature *acs; - - if (signature->type == JAVA_SIGNATURE_ARRAY) { - /* An array class */ - const char *component_signature_string; - acs = signature->array_component_signature; - component_signature_string = - jsj_ConvertJavaSignatureToHRString(cx, acs); - if (!component_signature_string) - return NULL; - sig = PR_smprintf("%s[]", component_signature_string); - JS_free(cx, (char*)component_signature_string); - - } else { - /* A primitive class or a non-array object class */ - sig = JS_strdup(cx, signature->name); - } - - if (!sig) { - JS_ReportOutOfMemory(cx); - return NULL; - } - return sig; -} - -static void -destroy_java_member_descriptor(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor) -{ - JavaMethodSpec *method, *next_method; - if (member_descriptor->field) - jsj_DestroyFieldSpec(cx, jEnv, member_descriptor->field); - - method = member_descriptor->methods; - while (method) { - next_method = method->next; - jsj_DestroyMethodSpec(cx, jEnv, method); - method = next_method; - } - - if (member_descriptor->invoke_func_obj) - JS_RemoveRoot(cx, &member_descriptor->invoke_func_obj); -} - -static void -destroy_class_member_descriptors(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor) -{ - JavaMemberDescriptor *next_member; - - while (member_descriptor) { - next_member = member_descriptor->next; - destroy_java_member_descriptor(cx, jEnv, member_descriptor); - member_descriptor = next_member; - } -} - -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) { - (*jEnv)->DeleteGlobalRef(jEnv, class_descriptor->java_class); - JSJ_HashTableRemove(java_class_reflections, - class_descriptor->java_class, (void*)jEnv); - } - - if (class_descriptor->array_component_signature) - jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor->array_component_signature); - - destroy_class_member_descriptors(cx, jEnv, class_descriptor->instance_members); - destroy_class_member_descriptors(cx, jEnv, class_descriptor->static_members); - destroy_class_member_descriptors(cx, jEnv, class_descriptor->constructors); - JS_free(cx, class_descriptor); -} - -static JavaClassDescriptor * -new_class_descriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class) -{ - JavaClassDescriptor *class_descriptor; - - class_descriptor = (JavaClassDescriptor *)JS_malloc(cx, sizeof(JavaClassDescriptor)); - if (!class_descriptor) - return NULL; - memset(class_descriptor, 0, sizeof(JavaClassDescriptor)); - - class_descriptor->name = jsj_GetJavaClassName(cx, jEnv, java_class); - if (!class_descriptor->name) - goto error; - - java_class = (*jEnv)->NewGlobalRef(jEnv, java_class); - if (!java_class) { - jsj_ReportJavaError(cx, jEnv, "Unable to reference Java class"); - goto error; - } - class_descriptor->java_class = java_class; - - if (!compute_java_class_signature(cx, jEnv, class_descriptor)) - goto error; - - class_descriptor->modifiers = - (*jEnv)->CallIntMethod(jEnv, java_class, jlClass_getModifiers); - class_descriptor->ref_count = 1; - - if (!JSJ_HashTableAdd(java_class_reflections, java_class, class_descriptor, - (void*)jEnv)) - goto error; - - return class_descriptor; - -error: - destroy_class_descriptor(cx, jEnv, class_descriptor); - return NULL; -} - -/* Trivial helper for jsj_DiscardJavaClassReflections(), below */ -static PRIntn -enumerate_remove_java_class(JSJHashEntry *he, PRIntn i, void *arg) -{ - JNIEnv *jEnv = (JNIEnv*)arg; - jclass java_class; - JavaClassDescriptor *class_descriptor; - - class_descriptor = (JavaClassDescriptor*)he->value; - - java_class = class_descriptor->java_class; - (*jEnv)->DeleteGlobalRef(jEnv, java_class); - class_descriptor->java_class = NULL; - - return HT_ENUMERATE_REMOVE; -} - -/* This shutdown routine discards all JNI references to Java objects - that have been reflected into JS, even if there are still references - to them from JS. */ -void -jsj_DiscardJavaClassReflections(JNIEnv *jEnv) -{ - JSJ_HashTableEnumerateEntries(java_class_reflections, - enumerate_remove_java_class, - (void*)jEnv); -} - -extern JavaClassDescriptor * -jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class) -{ - JavaClassDescriptor *class_descriptor; - class_descriptor = JSJ_HashTableLookup(java_class_reflections, - (const void *)java_class, - (void*)jEnv); - if (!class_descriptor) - return new_class_descriptor(cx, jEnv, java_class); - - PR_ASSERT(class_descriptor->ref_count > 0); - class_descriptor->ref_count++; - return class_descriptor; -} - -void -jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor) -{ - if (!--class_descriptor->ref_count) - destroy_class_descriptor(cx, jEnv, class_descriptor); -} - -static JSBool -reflect_java_methods_and_fields(JSContext *cx, - JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor, - JSBool reflect_statics_only) -{ - JavaMemberDescriptor *member_descriptor; - - if (reflect_statics_only) - class_descriptor->static_members_reflected = JS_TRUE; - else - class_descriptor->instance_members_reflected = JS_TRUE; - - if (!jsj_ReflectJavaMethods(cx, jEnv, class_descriptor, reflect_statics_only)) - return JS_FALSE; - if (!jsj_ReflectJavaFields(cx, jEnv, class_descriptor, reflect_statics_only)) - return JS_FALSE; - - if (reflect_statics_only) { - member_descriptor = class_descriptor->static_members; - while (member_descriptor) { - class_descriptor->num_static_members++; - member_descriptor = member_descriptor->next; - } - } else { - member_descriptor = class_descriptor->instance_members; - while (member_descriptor) { - class_descriptor->num_instance_members++; - member_descriptor = member_descriptor->next; - } - } - return JS_TRUE; -} - -JavaMemberDescriptor * -jsj_GetClassStaticMembers(JSContext *cx, - JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor) -{ - if (!class_descriptor->static_members_reflected) - reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE); - return class_descriptor->static_members; -} - -JavaMemberDescriptor * -jsj_GetClassInstanceMembers(JSContext *cx, - JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor) -{ - if (!class_descriptor->instance_members_reflected) - reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_FALSE); - return class_descriptor->instance_members; -} - -JavaMemberDescriptor * -jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx, - JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor, - jsid id) -{ - JavaMemberDescriptor *member_descriptor; - - member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor); - while (member_descriptor) { - if (id == member_descriptor->id) - return member_descriptor; - member_descriptor = member_descriptor->next; - } - return NULL; -} - -JavaMemberDescriptor * -jsj_GetJavaStaticMemberDescriptor(JSContext *cx, - JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor, - jstring member_name_jstr) -{ - JavaMemberDescriptor *member_descriptor; - jsid id; - - if (!JavaStringToId(cx, jEnv, member_name_jstr, &id)) - return NULL; - - member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id); - if (member_descriptor) - return member_descriptor; - - member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); - if (!member_descriptor) - return NULL; - memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); - - member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr); - if (!member_descriptor->name) { - JS_free(cx, member_descriptor); - return NULL; - } - member_descriptor->id = id; - - member_descriptor->next = class_descriptor->static_members; - class_descriptor->static_members = member_descriptor; - - return member_descriptor; -} - -JavaMemberDescriptor * -jsj_GetJavaClassConstructors(JSContext *cx, - JavaClassDescriptor *class_descriptor) -{ - JavaMemberDescriptor *member_descriptor; - - if (class_descriptor->constructors) - return class_descriptor->constructors; - - member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); - if (!member_descriptor) - return NULL; - memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); - - member_descriptor->name = JS_strdup(cx, ""); - if (!member_descriptor->name) { - JS_free(cx, member_descriptor); - return NULL; - } - - class_descriptor->constructors = member_descriptor; - - return member_descriptor; -} - -JavaMemberDescriptor * -jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor) -{ - if (!class_descriptor->static_members_reflected) - reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE); - return class_descriptor->constructors; -} - -JavaMemberDescriptor * -jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor, - jsid id) -{ - JavaMemberDescriptor *member_descriptor; - - member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor); - while (member_descriptor) { - if (id == member_descriptor->id) - return member_descriptor; - member_descriptor = member_descriptor->next; - } - return NULL; -} - -JavaMemberDescriptor * -jsj_GetJavaMemberDescriptor(JSContext *cx, - JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor, - jstring member_name_jstr) -{ - JavaMemberDescriptor *member_descriptor; - jsid id; - - if (!JavaStringToId(cx, jEnv, member_name_jstr, &id)) - return NULL; - - member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id); - if (member_descriptor) - return member_descriptor; - - member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); - if (!member_descriptor) - return NULL; - memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); - - member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr); - if (!member_descriptor->name) { - JS_free(cx, member_descriptor); - return NULL; - } - member_descriptor->id = id; - - member_descriptor->next = class_descriptor->instance_members; - class_descriptor->instance_members = member_descriptor; - - return member_descriptor; -} - -JSBool -jsj_InitJavaClassReflectionsTable() -{ - java_class_reflections = - JSJ_NewHashTable(64, jsj_HashJavaObject, jsj_JavaObjectComparator, - NULL, NULL, NULL); - - if (!java_class_reflections) - return JS_FALSE; - return JS_TRUE; -} diff --git a/js/ref/liveconnect/jsj_convert.c b/js/ref/liveconnect/jsj_convert.c index 254144f6b10..bf1542b4345 100644 --- a/js/ref/liveconnect/jsj_convert.c +++ b/js/ref/liveconnect/jsj_convert.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* This file is part of the Java-vendor-neutral implementation of LiveConnect @@ -26,11 +11,8 @@ #include #include -#include "prtypes.h" -#include "prprintf.h" -#include "prassert.h" - #include "jsj_private.h" /* LiveConnect internals */ +#include "jscntxt.h" /* for error reporting */ /* Floating-point double utilities, stolen from jsnum.h */ #ifdef IS_LITTLE_ENDIAN @@ -59,9 +41,7 @@ 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, JSJMSG_CANT_LOAD_JSOBJECT); return JS_FALSE; } @@ -160,27 +140,31 @@ 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 (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) { + if (*java_value) + *is_local_refp = JS_TRUE; return JS_TRUE; + } /* Fall through, to attempt conversion to a Java string */ - } else if (JS_TypeOfValue(cx, v) == JSTYPE_FUNCTION) { - /* JS functions can be wrapped as a netscape.javascript.JSObject */ - if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) - return JS_TRUE; - - /* That didn't work, so fall through, to attempt conversion to - a java.lang.String ... */ - - /* Check for a Java object wrapped inside a JS object */ + } else if (JS_InstanceOf(cx, js_obj, &JavaMember_class, 0)) { + + if (!JS_ConvertValue(cx, v, JSTYPE_OBJECT, &v)) + return JS_FALSE; + return jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost, + java_value, is_local_refp); + } else { /* Otherwise, see if the target type is the netscape.javascript.JSObject wrapper class or one of its subclasses, in which case a 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 (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) { + if (*java_value) + *is_local_refp = JS_TRUE; return JS_TRUE; + } /* Fall through, to attempt conversion to a Java string */ } @@ -235,7 +219,9 @@ 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); @@ -260,9 +246,21 @@ conversion_error: return JS_FALSE; } +/* Valid ranges for Java numeric types */ +#define jbyte_MAX_VALUE 127.0 +#define jbyte_MIN_VALUE -128.0 +#define jchar_MAX_VALUE 65535.0 +#define jchar_MIN_VALUE 0.0 +#define jshort_MAX_VALUE 32767.0 +#define jshort_MIN_VALUE -32768.0 +#define jint_MAX_VALUE 2147483647.0 +#define jint_MIN_VALUE -2147483648.0 +#define jlong_MAX_VALUE 9223372036854775807.0 +#define jlong_MIN_VALUE -9223372036854775808.0 + /* Utility macro for jsj_ConvertJSValueToJavaValue(), below */ #define JSVAL_TO_INTEGRAL_JVALUE(type_name, member_name, member_type, jsval, java_value) \ -if (!JSVAL_IS_NUMBER(v)) { \ + if (!JSVAL_IS_NUMBER(v)) { \ if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v)) \ goto conversion_error; \ (*cost)++; \ @@ -277,12 +275,20 @@ if (!JSVAL_IS_NUMBER(v)) { \ /* Check to see if the jsval's magnitude is too large to be \ representable in the target java type */ \ if (member_name != ival) \ - goto conversion_error; \ + goto numeric_conversion_error; \ } else { \ jdouble dval = *JSVAL_TO_DOUBLE(v); \ + \ + /* NaN becomes zero when converted to integral value */ \ if (JSDOUBLE_IS_NaN(dval)) \ member_name = 0; \ - else \ + \ + /* Unrepresentably large numbers, including infinities, */ \ + /* cause an error. */ \ + else if ((dval > member_type ## _MAX_VALUE) || \ + (dval < member_type ## _MIN_VALUE)) { \ + goto numeric_conversion_error; \ + } else \ member_name = (member_type) dval; \ \ /* Don't allow a non-integral number to be converted \ @@ -297,7 +303,7 @@ if (!JSVAL_IS_NUMBER(v)) { \ #if XP_MAC -// on MRJ jlong is typedef'd to wide, which is a struct. +/* on MRJ jlong is typedef'd to wide, which is a struct. */ #include static jsint jlong_to_jsint(jlong lvalue) @@ -309,7 +315,8 @@ static jsint jlong_to_jsint(jlong lvalue) static jlong jsint_to_jlong(jsint ivalue) { SInt64 val = S64Set(ivalue); - return SInt64ToWide(val); + wide wval =SInt64ToWide(val); + return *(jlong*)&wval; } static jdouble jlong_to_jdouble(jlong lvalue) @@ -321,7 +328,8 @@ static jdouble jlong_to_jdouble(jlong lvalue) static jlong jdouble_to_jlong(jdouble dvalue) { SInt64 val = LongDoubleToSInt64(dvalue); - return SInt64ToWide(val); + wide wval = SInt64ToWide(val); + return *(jlong*)&wval; } /* Mac utility macro for jsj_ConvertJSValueToJavaValue(), below */ @@ -340,9 +348,17 @@ if (!JSVAL_IS_NUMBER(jsvalue)) { \ \ } else { \ jdouble dval = *JSVAL_TO_DOUBLE(jsvalue); \ + \ + /* NaN becomes zero when converted to integral value */ \ if (JSDOUBLE_IS_NaN(dval)) \ member_name = jsint_to_jlong(0); \ - else \ + \ + /* Unrepresentably large numbers, including infinities, */ \ + /* cause an error. */ \ + else if ((dval > member_type ## _MAX_VALUE) || \ + (dval < member_type ## _MIN_VALUE)) { \ + goto numeric_conversion_error; \ + } else \ member_name = jdouble_to_jlong(dval); \ \ /* Don't allow a non-integral number to be converted \ @@ -379,6 +395,7 @@ jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v, int *cost, jvalue *java_value, JSBool *is_local_refp) { JavaSignatureChar type; + JSBool success = JS_FALSE; /* Initialize to default case, in which no new Java object is synthesized to perform the conversion and, therefore, no JNI local @@ -468,6 +485,10 @@ jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v, /* Success */ return JS_TRUE; +numeric_conversion_error: + success = JS_TRUE; + /* Fall through ... */ + conversion_error: if (java_value) { @@ -481,11 +502,11 @@ conversion_error: if (!jsval_string) jsval_string = ""; - JS_ReportError(cx, "Unable to convert JavaScript value %s to " - "Java value of type %s", + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_CANT_CONVERT_JS, jsval_string, signature->name); + return JS_FALSE; } - return JS_FALSE; + return success; } /* @@ -511,7 +532,7 @@ jsj_ConvertJavaStringToJSString(JSContext *cx, JNIEnv *jEnv, jstring java_str) js_str = NULL; - /* Unlike JS_NewString(), the string data passed into JS_NewUCString() is + /* The string data passed into JS_NewUCString() is not copied, so make a copy of the Unicode character vector. */ num_bytes = ucs2_str_len * sizeof(jchar); copy_ucs2_str = (jchar*)JS_malloc(cx, num_bytes); @@ -585,27 +606,23 @@ jsj_ConvertJavaObjectToJSString(JSContext *cx, */ JSBool jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv, + JavaClassDescriptor *class_descriptor, jobject java_obj, jsval *vp) { jdouble d; jmethodID doubleValue; + jclass java_class; -#ifndef SUN_VM_IS_NOT_GARBAGE - /* Late breaking news: calling GetMethodID() on an object that doesn't - contain the given method may cause the Sun VM to crash. So we only - call the method on instances of java.lang.Double */ - JSBool is_Double; - - /* Make sure that we have a java.lang.Double */ - is_Double = (*jEnv)->IsInstanceOf(jEnv, java_obj, jlDouble); - if (!is_Double) - return JS_FALSE; - doubleValue = jlDouble_doubleValue; -#else - doubleValue = (*jEnv)->GetMethodID(jEnv, java_obj, "doubleValue", "()D"); - if (!doubleValue) - return JS_FALSE; -#endif + java_class = class_descriptor->java_class; + doubleValue = (*jEnv)->GetMethodID(jEnv, java_class, "doubleValue", "()D"); + if (!doubleValue) { + /* There is no doubleValue() method for the object. Try toString() + instead and the JS engine will attempt to convert the result to + a number. */ + (*jEnv)->ExceptionClear(jEnv); + return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, + java_obj, vp); + } d = (*jEnv)->CallDoubleMethod(jEnv, java_obj, doubleValue); if ((*jEnv)->ExceptionOccurred(jEnv)) { @@ -626,28 +643,28 @@ jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv, */ extern JSBool jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv, + JavaClassDescriptor *class_descriptor, jobject java_obj, jsval *vp) { jboolean b; jmethodID booleanValue; + jclass java_class; -#ifndef SUN_VM_IS_NOT_GARBAGE - /* Late breaking news: calling GetMethodID() on an object that doesn't - contain the given method may cause the Sun VM to crash. So we only - call the method on instances of java.lang.Boolean */ - - JSBool is_Boolean; - - /* Make sure that we have a java.lang.Boolean */ - is_Boolean = (*jEnv)->IsInstanceOf(jEnv, java_obj, jlBoolean); - if (!is_Boolean) - return JS_FALSE; - booleanValue = jlBoolean_booleanValue; -#else + /* Null converts to false. */ + if (!java_obj) { + *vp = JSVAL_FALSE; + return JS_TRUE; + } + java_class = class_descriptor->java_class; booleanValue = (*jEnv)->GetMethodID(jEnv, java_obj, "booleanValue", "()Z"); - if (!booleanValue) - return JS_FALSE; -#endif + + /* Non-null Java object does not have a booleanValue() method, so + it converts to true. */ + if (!booleanValue) { + (*jEnv)->ExceptionClear(jEnv); + *vp = JSVAL_TRUE; + return JS_TRUE; + } b = (*jEnv)->CallBooleanMethod(jEnv, java_obj, booleanValue); if ((*jEnv)->ExceptionOccurred(jEnv)) { @@ -683,7 +700,11 @@ jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv, * it to obtain the original JS object. */ if (njJSObject && (*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) { +#ifdef PRESERVE_JSOBJECT_IDENTITY js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_obj, njJSObject_internal)); +#else + js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_obj); +#endif PR_ASSERT(js_obj); if (!js_obj) return JS_FALSE; diff --git a/js/ref/liveconnect/jsj_field.c b/js/ref/liveconnect/jsj_field.c index ee3670c5cdd..e69de29bb2d 100644 --- a/js/ref/liveconnect/jsj_field.c +++ b/js/ref/liveconnect/jsj_field.c @@ -1,386 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 - * - * It contains the code used to reflect Java fields as properties of - * JavaObject objects and the code to access those fields. - * - */ - -#include -#include "prtypes.h" -#include "prprintf.h" -#include "prassert.h" - -#include "jsj_private.h" /* LiveConnect internals */ - -/* - * Add a single field, described by java_field, to the JavaMemberDescriptor - * named by field_name within the given JavaClassDescriptor. - * - * Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error. - */ -static JSBool -add_java_field_to_class_descriptor(JSContext *cx, - JNIEnv *jEnv, - JavaClassDescriptor *class_descriptor, - jstring field_name_jstr, - jobject java_field, /* a java.lang.reflect.Field */ - jint modifiers) -{ - jclass fieldType; - jfieldID fieldID; - jclass java_class; - - JSBool is_static_field; - JavaMemberDescriptor *member_descriptor = NULL; - const char *sig_cstr = NULL; - const char *field_name = NULL; - JavaSignature *signature = NULL; - JavaFieldSpec *field_spec = NULL; - - is_static_field = modifiers & ACC_STATIC; - if (is_static_field) { - member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr); - } else { - member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr); - } - if (!member_descriptor) - goto error; - - field_spec = (JavaFieldSpec*)JS_malloc(cx, sizeof(JavaFieldSpec)); - if (!field_spec) - goto error; - - field_spec->modifiers = modifiers; - - /* Get the Java class corresponding to the type of the field */ - fieldType = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getType); - if (!fieldType) { - jsj_UnexpectedJavaError(cx, jEnv, - "Unable to determine type of field using" - " java.lang.reflect.Field.getType()"); - goto error; - } - - signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType); - if (!signature) - goto error; - field_spec->signature = signature; - - field_name = jsj_DupJavaStringUTF(cx, jEnv, field_name_jstr); - if (!field_name) - goto error; - field_spec->name = field_name; - - /* Compute the JNI-style (string-based) signature of the field type */ - sig_cstr = jsj_ConvertJavaSignatureToString(cx, signature); - if (!sig_cstr) - goto error; - - /* Compute the JNI fieldID and cache it for quick field access */ - java_class = class_descriptor->java_class; - if (is_static_field) - fieldID = (*jEnv)->GetStaticFieldID(jEnv, java_class, field_name, sig_cstr); - else - fieldID = (*jEnv)->GetFieldID(jEnv, java_class, field_name, sig_cstr); - if (!fieldID) { - jsj_UnexpectedJavaError(cx, jEnv, - "Can't get Java field ID for class %s, field %s (sig=%s)", - class_descriptor->name, field_name, sig_cstr); - goto error; - } - field_spec->fieldID = fieldID; - - JS_free(cx, (char*)sig_cstr); - - member_descriptor->field = field_spec; - - /* Success */ - return JS_TRUE; - -error: - if (field_spec) { - JS_FREE_IF(cx, (char*)field_spec->name); - JS_free(cx, field_spec); - } - JS_FREE_IF(cx, (char*)sig_cstr); - if (signature) - jsj_ReleaseJavaClassDescriptor(cx, jEnv, signature); - return JS_FALSE; -} - -/* - * Free up a JavaFieldSpec and all its resources. - */ -void -jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field) -{ - JS_FREE_IF(cx, (char*)field->name); - jsj_ReleaseJavaClassDescriptor(cx, jEnv, field->signature); - JS_free(cx, field); -} - -/* - * Add a JavaMemberDescriptor to the collection of members in class_descriptor - * for every public field of the identified Java class. (A separate collection - * is kept in class_descriptor for static and instance members.) - * If reflect_only_static_fields is set, instance fields are not reflected. If - * it isn't set, only instance fields are reflected and static fields are not - * reflected. - * - * Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error. - */ -JSBool -jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor, - JSBool reflect_only_static_fields) -{ - int i; - JSBool ok; - jint modifiers; - jobject java_field; - jstring field_name_jstr; - jarray joFieldArray; - jsize num_fields; - jclass java_class; - - /* Get a java array of java.lang.reflect.Field objects, by calling - java.lang.Class.getFields(). */ - java_class = class_descriptor->java_class; - joFieldArray = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getFields); - if (!joFieldArray) { - jsj_UnexpectedJavaError(cx, jEnv, - "Can't determine Java object's fields " - "using java.lang.Class.getFields()"); - return JS_FALSE; - } - - /* Iterate over the class fields */ - num_fields = (*jEnv)->GetArrayLength(jEnv, joFieldArray); - for (i = 0; i < num_fields; i++) { - - /* Get the i'th reflected field */ - java_field = (*jEnv)->GetObjectArrayElement(jEnv, joFieldArray, i); - if (!java_field) { - jsj_UnexpectedJavaError(cx, jEnv, "Can't access a Field[] array"); - return JS_FALSE; - } - - /* Get the field modifiers, e.g. static, public, private, etc. */ - modifiers = (*jEnv)->CallIntMethod(jEnv, java_field, jlrField_getModifiers); - if ((*jEnv)->ExceptionOccurred(jEnv)) { - jsj_UnexpectedJavaError(cx, jEnv, - "Can't access a Field's modifiers using" - "java.lang.reflect.Field.getModifiers()"); - return JS_FALSE; - } - - /* Don't allow access to private or protected Java fields. */ - if (!(modifiers & ACC_PUBLIC)) - continue; - - /* Reflect all instance fields or all static fields, but not both */ - if (reflect_only_static_fields != ((modifiers & ACC_STATIC) != 0)) - continue; - - /* Determine the unqualified name of the field */ - field_name_jstr = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getName); - if (!field_name_jstr) { - jsj_UnexpectedJavaError(cx, jEnv, - "Can't obtain a Field's name" - "java.lang.reflect.Field.getName()"); - return JS_FALSE; - } - - /* Add a JavaFieldSpec object to the JavaClassDescriptor */ - ok = add_java_field_to_class_descriptor(cx, jEnv, class_descriptor, field_name_jstr, - java_field, modifiers); - if (!ok) - return JS_FALSE; - } - - /* Success */ - return JS_TRUE; -} - -/* - * Read the value of a Java field and return it as a JavaScript value. - * If the field is static, then java_obj is a Java class, otherwise - * it's a Java instance object. - * - * Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error. - */ -JSBool -jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec, - jobject java_obj, jsval *vp) -{ - JSBool is_static_field; - jvalue java_value; - JavaSignature *signature; - JavaSignatureChar field_type; - jfieldID fieldID = field_spec->fieldID; - - is_static_field = field_spec->modifiers & ACC_STATIC; - -#define GET_JAVA_FIELD(Type,member) \ - PR_BEGIN_MACRO \ - if (is_static_field) \ - java_value.member = \ - (*jEnv)->GetStatic##Type##Field(jEnv, java_obj, fieldID); \ - else \ - java_value.member = \ - (*jEnv)->Get##Type##Field(jEnv, java_obj, fieldID); \ - if ((*jEnv)->ExceptionOccurred(jEnv)) { \ - jsj_ReportJavaError(cx, jEnv, "Error reading Java field"); \ - return JS_FALSE; \ - } \ - PR_END_MACRO - - signature = field_spec->signature; - field_type = signature->type; - switch(field_type) { - case JAVA_SIGNATURE_BYTE: - GET_JAVA_FIELD(Byte,b); - break; - - case JAVA_SIGNATURE_CHAR: - GET_JAVA_FIELD(Char,c); - break; - - case JAVA_SIGNATURE_SHORT: - GET_JAVA_FIELD(Short,s); - break; - - case JAVA_SIGNATURE_INT: - GET_JAVA_FIELD(Int,i); - break; - - case JAVA_SIGNATURE_BOOLEAN: - GET_JAVA_FIELD(Boolean,z); - break; - - case JAVA_SIGNATURE_LONG: - GET_JAVA_FIELD(Long,j); - break; - - case JAVA_SIGNATURE_FLOAT: - GET_JAVA_FIELD(Float,f); - break; - - 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 */ - return JS_FALSE; - } - - return jsj_ConvertJavaValueToJSValue(cx, jEnv, signature, &java_value, vp); -} - -JSBool -jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec, - jclass java_obj, jsval js_val) -{ - JSBool is_static_field, is_local_ref; - int dummy_cost; - jvalue java_value; - JavaSignature *signature; - JavaSignatureChar field_type; - jfieldID fieldID = field_spec->fieldID; - - is_static_field = field_spec->modifiers & ACC_STATIC; - -#define SET_JAVA_FIELD(Type,member) \ - PR_BEGIN_MACRO \ - if (is_static_field) { \ - (*jEnv)->SetStatic##Type##Field(jEnv, java_obj, fieldID, \ - java_value.member); \ - } else { \ - (*jEnv)->Set##Type##Field(jEnv, java_obj, fieldID,java_value.member);\ - } \ - if ((*jEnv)->ExceptionOccurred(jEnv)) { \ - jsj_ReportJavaError(cx, jEnv, "Error assigning to Java field"); \ - return JS_FALSE; \ - } \ - PR_END_MACRO - - signature = field_spec->signature; - if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, signature, &dummy_cost, - &java_value, &is_local_ref)) - return JS_FALSE; - - field_type = signature->type; - switch(field_type) { - case JAVA_SIGNATURE_BYTE: - SET_JAVA_FIELD(Byte,b); - break; - - case JAVA_SIGNATURE_CHAR: - SET_JAVA_FIELD(Char,c); - break; - - case JAVA_SIGNATURE_SHORT: - SET_JAVA_FIELD(Short,s); - break; - - case JAVA_SIGNATURE_INT: - SET_JAVA_FIELD(Int,i); - break; - - case JAVA_SIGNATURE_BOOLEAN: - SET_JAVA_FIELD(Boolean,z); - break; - - case JAVA_SIGNATURE_LONG: - SET_JAVA_FIELD(Long,j); - break; - - case JAVA_SIGNATURE_FLOAT: - SET_JAVA_FIELD(Float,f); - break; - - case JAVA_SIGNATURE_DOUBLE: - SET_JAVA_FIELD(Double,d); - break; - - case JAVA_SIGNATURE_CLASS: - case JAVA_SIGNATURE_ARRAY: - 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 */ - return JS_FALSE; - } - - return JS_TRUE; -} diff --git a/js/ref/liveconnect/jsj_hash.c b/js/ref/liveconnect/jsj_hash.c index 67c42d8630a..e69de29bb2d 100644 --- a/js/ref/liveconnect/jsj_hash.c +++ b/js/ref/liveconnect/jsj_hash.c @@ -1,481 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 is a copy of the NSPR hash-table library, but it has been slightly - * modified to allow an additional argument to be passed into the hash - * key-comparision function. This is used to maintain thread-safety by - * passing in a JNIEnv pointer to the key-comparison function rather - * than storing it in a global. All types,function names, etc. have - * been renamed from their original NSPR names to protect the innocent. - */ - -#include "jsj_hash.h" -#include "prtypes.h" -#include "prassert.h" -#include -#include - -/* Compute the number of buckets in ht */ -#define NBUCKETS(ht) (1 << (JSJ_HASH_BITS - (ht)->shift)) - -/* The smallest table has 16 buckets */ -#define MINBUCKETSLOG2 4 -#define MINBUCKETS (1 << MINBUCKETSLOG2) - -/* Compute the maximum entries given n buckets that we will tolerate, ~90% */ -#define OVERLOADED(n) ((n) - ((n) >> 3)) - -/* Compute the number of entries below which we shrink the table by half */ -#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0) - -/* -** Stubs for default hash allocator ops. -*/ -static void * -DefaultAllocTable(void *pool, size_t size) -{ -#if defined(XP_MAC) -#pragma unused (pool) -#endif - - return malloc(size); -} - -static void -DefaultFreeTable(void *pool, void *item) -{ -#if defined(XP_MAC) -#pragma unused (pool) -#endif - - free(item); -} - -static JSJHashEntry * -DefaultAllocEntry(void *pool, const void *key) -{ -#if defined(XP_MAC) -#pragma unused (pool,key) -#endif - - return malloc(sizeof(JSJHashEntry)); -} - -static void -DefaultFreeEntry(void *pool, JSJHashEntry *he, PRUintn flag) -{ -#if defined(XP_MAC) -#pragma unused (pool) -#endif - - if (flag == HT_FREE_ENTRY) - free(he); -} - -static JSJHashAllocOps defaultHashAllocOps = { - DefaultAllocTable, DefaultFreeTable, - DefaultAllocEntry, DefaultFreeEntry -}; - -PR_IMPLEMENT(JSJHashTable *) -JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash, - JSJHashComparator keyCompare, JSJHashComparator valueCompare, - JSJHashAllocOps *allocOps, void *allocPriv) -{ - JSJHashTable *ht; - PRUint32 nb; - - if (n <= MINBUCKETS) { - n = MINBUCKETSLOG2; - } else { - n = PR_CeilingLog2(n); - if ((PRInt32)n < 0) - return 0; - } - - if (!allocOps) allocOps = &defaultHashAllocOps; - - ht = (*allocOps->allocTable)(allocPriv, sizeof *ht); - if (!ht) - return 0; - memset(ht, 0, sizeof *ht); - ht->shift = JSJ_HASH_BITS - n; - n = 1 << n; -#if defined(XP_PC) && !defined(_WIN32) - if (n > 16000) { - (*allocOps->freeTable)(allocPriv, ht); - return 0; - } -#endif /* WIN16 */ - nb = n * sizeof(JSJHashEntry *); - ht->buckets = (*allocOps->allocTable)(allocPriv, nb); - if (!ht->buckets) { - (*allocOps->freeTable)(allocPriv, ht); - return 0; - } - memset(ht->buckets, 0, nb); - - ht->keyHash = keyHash; - ht->keyCompare = keyCompare; - ht->valueCompare = valueCompare; - ht->allocOps = allocOps; - ht->allocPriv = allocPriv; - return ht; -} - -PR_IMPLEMENT(void) -JSJ_HashTableDestroy(JSJHashTable *ht) -{ - PRUint32 i, n; - JSJHashEntry *he, *next; - JSJHashAllocOps *allocOps = ht->allocOps; - void *allocPriv = ht->allocPriv; - - n = NBUCKETS(ht); - for (i = 0; i < n; i++) { - for (he = ht->buckets[i]; he; he = next) { - next = he->next; - (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY); - } - } -#ifdef DEBUG - memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]); -#endif - (*allocOps->freeTable)(allocPriv, ht->buckets); -#ifdef DEBUG - memset(ht, 0xDB, sizeof *ht); -#endif - (*allocOps->freeTable)(allocPriv, ht); -} - -/* -** Multiplicative hash, from Knuth 6.4. -*/ -#define GOLDEN_RATIO 0x9E3779B9U - -PR_IMPLEMENT(JSJHashEntry **) -JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg) -{ - JSJHashEntry *he, **hep, **hep0; - JSJHashNumber h; - -#ifdef HASHMETER - ht->nlookups++; -#endif - h = keyHash * GOLDEN_RATIO; - h >>= ht->shift; - hep = hep0 = &ht->buckets[h]; - while ((he = *hep) != 0) { - if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key, arg)) { - /* Move to front of chain if not already there */ - if (hep != hep0) { - *hep = he->next; - he->next = *hep0; - *hep0 = he; - } - return hep0; - } - hep = &he->next; -#ifdef HASHMETER - ht->nsteps++; -#endif - } - return hep; -} - -PR_IMPLEMENT(JSJHashEntry *) -JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep, - JSJHashNumber keyHash, const void *key, void *value, - void *arg) -{ - PRUint32 i, n; - JSJHashEntry *he, *next, **oldbuckets; - PRUint32 nb; - - /* Grow the table if it is overloaded */ - n = NBUCKETS(ht); - if (ht->nentries >= OVERLOADED(n)) { -#ifdef HASHMETER - ht->ngrows++; -#endif - ht->shift--; - oldbuckets = ht->buckets; -#if defined(XP_PC) && !defined(_WIN32) - if (2 * n > 16000) - return 0; -#endif /* WIN16 */ - nb = 2 * n * sizeof(JSJHashEntry *); - ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb); - if (!ht->buckets) { - ht->buckets = oldbuckets; - return 0; - } - memset(ht->buckets, 0, nb); - - for (i = 0; i < n; i++) { - for (he = oldbuckets[i]; he; he = next) { - next = he->next; - hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg); - PR_ASSERT(*hep == 0); - he->next = 0; - *hep = he; - } - } -#ifdef DEBUG - memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); -#endif - (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); - hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg); - } - - /* Make a new key value entry */ - he = (*ht->allocOps->allocEntry)(ht->allocPriv, key); - if (!he) - return 0; - he->keyHash = keyHash; - he->key = key; - he->value = value; - he->next = *hep; - *hep = he; - ht->nentries++; - return he; -} - -PR_IMPLEMENT(JSJHashEntry *) -JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg) -{ - JSJHashNumber keyHash; - JSJHashEntry *he, **hep; - - keyHash = (*ht->keyHash)(key, arg); - hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg); - if ((he = *hep) != 0) { - /* Hit; see if values match */ - if ((*ht->valueCompare)(he->value, value, arg)) { - /* key,value pair is already present in table */ - return he; - } - if (he->value) - (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE); - he->value = value; - return he; - } - return JSJ_HashTableRawAdd(ht, hep, keyHash, key, value, arg); -} - -PR_IMPLEMENT(void) -JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg) -{ - PRUint32 i, n; - JSJHashEntry *next, **oldbuckets; - PRUint32 nb; - - *hep = he->next; - (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY); - - /* Shrink table if it's underloaded */ - n = NBUCKETS(ht); - if (--ht->nentries < UNDERLOADED(n)) { -#ifdef HASHMETER - ht->nshrinks++; -#endif - ht->shift++; - oldbuckets = ht->buckets; - nb = n * sizeof(JSJHashEntry*) / 2; - ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb); - if (!ht->buckets) { - ht->buckets = oldbuckets; - return; - } - memset(ht->buckets, 0, nb); - - for (i = 0; i < n; i++) { - for (he = oldbuckets[i]; he; he = next) { - next = he->next; - hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg); - PR_ASSERT(*hep == 0); - he->next = 0; - *hep = he; - } - } -#ifdef DEBUG - memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); -#endif - (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); - } -} - -PR_IMPLEMENT(PRBool) -JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg) -{ - JSJHashNumber keyHash; - JSJHashEntry *he, **hep; - - keyHash = (*ht->keyHash)(key, arg); - hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg); - if ((he = *hep) == 0) - return PR_FALSE; - - /* Hit; remove element */ - JSJ_HashTableRawRemove(ht, hep, he, arg); - return PR_TRUE; -} - -PR_IMPLEMENT(void *) -JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg) -{ - JSJHashNumber keyHash; - JSJHashEntry *he, **hep; - - keyHash = (*ht->keyHash)(key, arg); - hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg); - if ((he = *hep) != 0) { - return he->value; - } - return 0; -} - -/* -** Iterate over the entries in the hash table calling func for each -** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP). -** Return a count of the number of elements scanned. -*/ -PR_IMPLEMENT(int) -JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg) -{ - JSJHashEntry *he, **hep; - PRUint32 i, nbuckets; - int rv, n = 0; - JSJHashEntry *todo = 0; - - nbuckets = NBUCKETS(ht); - for (i = 0; i < nbuckets; i++) { - hep = &ht->buckets[i]; - while ((he = *hep) != 0) { - rv = (*f)(he, n, arg); - n++; - if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) { - *hep = he->next; - if (rv & HT_ENUMERATE_REMOVE) { - he->next = todo; - todo = he; - } - } else { - hep = &he->next; - } - if (rv & HT_ENUMERATE_STOP) { - goto out; - } - } - } - -out: - hep = &todo; - while ((he = *hep) != 0) { - JSJ_HashTableRawRemove(ht, hep, he, arg); - } - return n; -} - -#ifdef HASHMETER -#include -#include - -PR_IMPLEMENT(void) -JSJ_HashTableDumpMeter(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp) -{ - double mean, variance; - PRUint32 nchains, nbuckets; - PRUint32 i, n, maxChain, maxChainLen; - JSJHashEntry *he; - - variance = 0; - nchains = 0; - maxChainLen = 0; - nbuckets = NBUCKETS(ht); - for (i = 0; i < nbuckets; i++) { - he = ht->buckets[i]; - if (!he) - continue; - nchains++; - for (n = 0; he; he = he->next) - n++; - variance += n * n; - if (n > maxChainLen) { - maxChainLen = n; - maxChain = i; - } - } - mean = (double)ht->nentries / nchains; - variance = fabs(variance / nchains - mean * mean); - - fprintf(fp, "\nHash table statistics:\n"); - fprintf(fp, " number of lookups: %u\n", ht->nlookups); - fprintf(fp, " number of entries: %u\n", ht->nentries); - fprintf(fp, " number of grows: %u\n", ht->ngrows); - fprintf(fp, " number of shrinks: %u\n", ht->nshrinks); - fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps - / ht->nlookups); - fprintf(fp, "mean hash chain length: %g\n", mean); - fprintf(fp, " standard deviation: %g\n", sqrt(variance)); - fprintf(fp, " max hash chain length: %u\n", maxChainLen); - fprintf(fp, " max hash chain: [%u]\n", maxChain); - - for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++) - if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT) - break; -} -#endif /* HASHMETER */ - -PR_IMPLEMENT(int) -JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp) -{ - int count; - - count = JSJ_HashTableEnumerateEntries(ht, dump, fp); -#ifdef HASHMETER - JSJ_HashTableDumpMeter(ht, dump, fp); -#endif - return count; -} - -PR_IMPLEMENT(JSJHashNumber) -JSJ_HashString(const void *key) -{ - JSJHashNumber h; - const unsigned char *s; - - h = 0; - for (s = key; *s; s++) - h = (h >> 28) ^ (h << 4) ^ *s; - return h; -} - -PR_IMPLEMENT(int) -JSJ_CompareStrings(const void *v1, const void *v2) -{ - return strcmp(v1, v2) == 0; -} - -PR_IMPLEMENT(int) -JSJ_CompareValues(const void *v1, const void *v2) -{ - return v1 == v2; -} diff --git a/js/ref/liveconnect/jsj_hash.h b/js/ref/liveconnect/jsj_hash.h index e6fb30aa41b..e69de29bb2d 100644 --- a/js/ref/liveconnect/jsj_hash.h +++ b/js/ref/liveconnect/jsj_hash.h @@ -1,141 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 is a copy of the NSPR hash-table library, but it has been slightly - * modified to allow an additional argument to be passed into the hash - * key-comparision function. This is used to maintain thread-safety by - * passing in a JNIEnv pointer to the key-comparison function rather - * than storing it in a global. All types,function names, etc. have - * been renamed from their original NSPR names to protect the innocent. - */ - -#ifndef jsj_hash_h___ -#define jsj_hash_h___ -/* - * API to portable hash table code. - */ -#include -#include -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -typedef struct JSJHashEntry JSJHashEntry; -typedef struct JSJHashTable JSJHashTable; -typedef PRUint32 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); - -/* Flag bits in JSJHashEnumerator's return value */ -#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */ -#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */ -#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */ -#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */ - -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); -} JSJHashAllocOps; - -#define HT_FREE_VALUE 0 /* just free the entry's value */ -#define HT_FREE_ENTRY 1 /* free value and entire entry */ - -struct JSJHashEntry { - JSJHashEntry *next; /* hash chain linkage */ - JSJHashNumber keyHash; /* key hash function result */ - const void *key; /* ptr to opaque key */ - void *value; /* ptr to opaque value */ -}; - -struct JSJHashTable { - JSJHashEntry **buckets; /* vector of hash buckets */ - PRUint32 nentries; /* number of entries in table */ - PRUint32 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 */ -#endif -}; - -/* - * 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, - JSJHashComparator keyCompare, JSJHashComparator valueCompare, - JSJHashAllocOps *allocOps, void *allocPriv); - -PR_EXTERN(void) -JSJ_HashTableDestroy(JSJHashTable *ht); - -/* Low level access methods */ -PR_EXTERN(JSJHashEntry **) -JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg); - -PR_EXTERN(JSJHashEntry *) -JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep, JSJHashNumber keyHash, - const void *key, void *value, void *arg); - -PR_EXTERN(void) -JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg); - -/* Higher level access methods */ -PR_EXTERN(JSJHashEntry *) -JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg); - -PR_EXTERN(PRBool) -JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg); - -PR_EXTERN(PRIntn) -JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg); - -PR_EXTERN(void *) -JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg); - -PR_EXTERN(PRIntn) -JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp); - -/* General-purpose C string hash function. */ -PR_EXTERN(JSJHashNumber) -JSJ_HashString(const void *key); - -/* Compare strings using strcmp(), return true if equal. */ -PR_EXTERN(int) -JSJ_CompareStrings(const void *v1, const void *v2); - -/* Stub function just returns v1 == v2 */ -PR_EXTERN(PRIntn) -JSJ_CompareValues(const void *v1, const void *v2); - -PR_END_EXTERN_C - -#endif /* jsj_hash_h___ */ diff --git a/js/ref/liveconnect/jsj_method.c b/js/ref/liveconnect/jsj_method.c index 61bbb676346..9c8a8f3a22b 100644 --- a/js/ref/liveconnect/jsj_method.c +++ b/js/ref/liveconnect/jsj_method.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* @@ -28,13 +13,9 @@ #include #include -#include "prtypes.h" -#include "prprintf.h" -#include "prassert.h" -#include "prosdep.h" - #include "jsj_private.h" /* LiveConnect internals */ #include "jsjava.h" /* LiveConnect external API */ +#include "jscntxt.h" /* for error reporting */ /* * A helper function for jsj_ConvertJavaMethodSignatureToString(): @@ -322,8 +303,8 @@ jsj_InitJavaMethodSignature(JSContext *cx, JNIEnv *jEnv, a = arg_signatures[i] = jsj_GetJavaClassDescriptor(cx, jEnv, arg_class); if (!a) { - jsj_ReportJavaError(cx, jEnv, "Could not determine Java class " - "signature using java.lang.reflect"); + jsj_UnexpectedJavaError(cx, jEnv, "Could not determine Java class " + "signature using java.lang.reflect"); goto error; } } @@ -715,7 +696,7 @@ resolve_overloaded_method(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *mem static jvalue * convert_JS_method_args_to_java_argv(JSContext *cx, JNIEnv *jEnv, jsval *argv, - JavaMethodSpec *method, JSBool **localvp) + JavaMethodSpec *method, JSBool **localvp) { jvalue *jargv; JSBool ok, *localv; @@ -752,7 +733,8 @@ convert_JS_method_args_to_java_argv(JSContext *cx, JNIEnv *jEnv, jsval *argv, ok = jsj_ConvertJSValueToJavaValue(cx, jEnv, argv[i], arg_signatures[i], &dummy_cost, &jargv[i], &localv[i]); if (!ok) { - JS_ReportError(cx, "Internal error: can't convert JS value to Java value"); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_CONVERT_JS_VALUE); JS_free(cx, jargv); JS_free(cx, localv); *localvp = NULL; @@ -767,9 +749,9 @@ static JSBool invoke_java_method(JSContext *cx, JSJavaThreadState *jsj_env, jobject java_class_or_instance, JavaClassDescriptor *class_descriptor, - JavaMethodSpec *method, + JavaMethodSpec *method, JSBool is_static_method, - jsval *argv, jsval *vp) + jsval *argv, jsval *vp) { jvalue java_value; jvalue *jargv; @@ -800,10 +782,12 @@ invoke_java_method(JSContext *cx, JSJavaThreadState *jsj_env, } old_cx = JSJ_SetDefaultJSContextForJavaThread(cx, jsj_env); - if (old_cx) { - JS_ReportError(cx, "Java thread in simultaneous use by more than " - "one JSContext ?"); + +#ifdef DEBUG + if (old_cx && (old_cx != cx)) { + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_MULTIPLE_JTHREADS); } +#endif jargv = NULL; localv = NULL; @@ -1019,8 +1003,8 @@ static JSBool invoke_java_constructor(JSContext *cx, JSJavaThreadState *jsj_env, jclass java_class, - JavaMethodSpec *method, - jsval *argv, jsval *vp) + JavaMethodSpec *method, + jsval *argv, jsval *vp) { jvalue *jargv; uintN argc, i; @@ -1049,10 +1033,12 @@ invoke_java_constructor(JSContext *cx, } old_cx = JSJ_SetDefaultJSContextForJavaThread(cx, jsj_env); - if (old_cx) { - JS_ReportError(cx, "Java thread in simultaneous use by more than " - "one JSContext ?"); + +#ifdef DEBUG + if (old_cx && (old_cx != cx)) { + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, JSJMSG_MULTIPLE_JTHREADS); } +#endif /* Call the constructor */ java_object = (*jEnv)->NewObjectA(jEnv, java_class, methodID, jargv); @@ -1067,14 +1053,16 @@ invoke_java_constructor(JSContext *cx, } out: - for (i = 0; i < argc; i++) { - if (localv[i]) - (*jEnv)->DeleteLocalRef(jEnv, jargv[i].l); + if (localv) { + for (i = 0; i < argc; i++) { + if (localv[i]) + (*jEnv)->DeleteLocalRef(jEnv, jargv[i].l); + } + JS_free(cx, localv); } if (jargv) JS_free(cx, jargv); - if (localv) - JS_free(cx, localv); + if (error_occurred) return JS_FALSE; else @@ -1134,25 +1122,25 @@ jsj_JavaConstructorWrapper(JSContext *cx, JSObject *obj, /* Get class/interface flags and check them */ modifiers = class_descriptor->modifiers; if (modifiers & ACC_ABSTRACT) { - JS_ReportError(cx, "Java class %s is abstract and therefore may not " - "be instantiated", class_descriptor->name); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_ABSTRACT_JCLASS, class_descriptor->name); return JS_FALSE; } if (modifiers & ACC_INTERFACE) { - JS_ReportError(cx, "%s is a Java interface and therefore may not " - "be instantiated", class_descriptor->name); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_IS_INTERFACE, class_descriptor->name); return JS_FALSE; } if ( !(modifiers & ACC_PUBLIC) ) { - JS_ReportError(cx, "Java class %s is not public and therefore may not " - "be instantiated", class_descriptor->name); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_NOT_PUBLIC, class_descriptor->name); return JS_FALSE; } member_descriptor = jsj_LookupJavaClassConstructors(cx, jEnv, class_descriptor); if (!member_descriptor) { - JS_ReportError(cx, "No public constructors defined for Java class %s", - class_descriptor->name); + JS_ReportErrorNumber(cx, jsj_GetErrorMessage, + JSJMSG_NO_CONSTRUCTORS, class_descriptor->name); return JS_FALSE; } diff --git a/js/ref/liveconnect/jsj_private.h b/js/ref/liveconnect/jsj_private.h index 279a37e1834..1407eaaab74 100644 --- a/js/ref/liveconnect/jsj_private.h +++ b/js/ref/liveconnect/jsj_private.h @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* @@ -29,10 +14,28 @@ #ifndef _JSJAVA_PVT_H #define _JSJAVA_PVT_H +#include "prtypes.h" + +/* NSPR1 compatibility definitions */ +#ifdef NSPR20 +# include "prprf.h" +# include "prlog.h" +# include "plhash.h" /* NSPR hash-tables */ +#else +# include "prprintf.h" +# include "prassert.h" +# include "prhash.h" /* NSPR hash-tables */ +# define PRHashNumber prhashcode +#endif + +#ifdef XP_MAC +# include "prosdep.h" +#endif + #include "jsj_hash.h" /* Hash tables */ -#include "prhash.h" /* NSPR hash-tables */ #include "jni.h" /* Java Native Interface */ #include "jsapi.h" /* JavaScript engine API */ +#include "jsjava.h" /* LiveConnect public API */ /*************************** Type Declarations ******************************/ @@ -42,11 +45,7 @@ typedef struct JavaMemberDescriptor JavaMemberDescriptor; typedef struct JavaMethodSpec JavaMethodSpec; typedef struct JavaClassDescriptor JavaClassDescriptor; typedef struct JavaClassDescriptor JavaSignature; -typedef struct JSJCallbacks JSJCallbacks; typedef struct CapturedJSError CapturedJSError; -typedef struct JavaPackageDef JavaPackageDef; -typedef struct JSJavaThreadState JSJavaThreadState; -typedef struct JSJavaVM JSJavaVM; typedef struct JavaMemberVal JavaMemberVal; /* @@ -86,12 +85,12 @@ typedef struct JavaFieldSpec { /* A descriptor for the reflection of a single Java method. Each overloaded method has a separate corresponding JavaMethodSpec. */ -typedef struct JavaMethodSpec { +struct JavaMethodSpec { jmethodID methodID; /* JVM opaque access handle for method */ JavaMethodSignature signature; const char * name; /* UTF8; TODO - Should support Unicode method names */ JavaMethodSpec * next; /* next method in chain of overloaded methods */ -} JavaMethodSpec; +}; /* * A descriptor for the reflection of a single member of a Java object. @@ -100,17 +99,17 @@ typedef struct JavaMethodSpec { * they are overloaded methods sharing the same simple name.) This same * descriptor type is used for both static or instance members. */ -typedef struct JavaMemberDescriptor { +struct JavaMemberDescriptor { const char * name; /* simple name of field and/or method */ jsid id; /* hashed name for quick JS property lookup */ JavaFieldSpec * field; /* field with the given name, if any */ JavaMethodSpec * methods; /* Overloaded methods which share the same name, if any */ JavaMemberDescriptor * next; /* next descriptor in same defining class */ JSObject * invoke_func_obj; /* If non-null, JSFunction obj to invoke method */ -} JavaMemberDescriptor; +}; /* This is the native portion of a reflected Java class */ -typedef struct JavaClassDescriptor { +struct JavaClassDescriptor { 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 */ @@ -125,18 +124,18 @@ typedef struct JavaClassDescriptor { e.g. abstract, private */ int ref_count; /* # of references to this struct */ JavaSignature * array_component_signature; /* Only non-NULL for array classes */ -} JavaClassDescriptor; +}; /* This is the native portion of a reflected Java method or field */ -typedef struct JavaMemberVal { +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; -} JavaMemberVal; +}; /* This is the native portion of a reflected Java object */ -typedef struct { +typedef struct JavaObjectWrapper { jobject java_obj; /* Opaque JVM ref to Java object */ JavaClassDescriptor * class_descriptor; /* Java class info */ } JavaObjectWrapper; @@ -152,7 +151,7 @@ typedef struct { /* A JSJavaVM structure must be created for each Java VM that is accessed via LiveConnect */ -typedef struct JSJavaVM { +struct JSJavaVM { /* TODO - all LiveConnect global variables should be migrated into this structure in order to allow more than one LiveConnect-enabled Java VM to exist within the same process. */ @@ -161,17 +160,17 @@ typedef struct JSJavaVM { JSBool jsj_created_java_vm; int num_attached_threads; JSJavaVM * next; /* next VM among all created VMs */ -} JSJavaVM; +}; /* Per-thread state that encapsulates the connection to the Java VM */ -typedef struct JSJavaThreadState { +struct JSJavaThreadState { const char * name; /* Thread name, for debugging */ JSJavaVM * jsjava_vm; /* All per-JVM state */ 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 */ JSJavaThreadState * next; /* next thread state among all created threads */ -} JSJavaThreadState; +}; /******************************** Globals ***********************************/ @@ -181,6 +180,7 @@ extern JSJCallbacks *JSJ_callbacks; extern JSClass JavaObject_class; extern JSClass JavaArray_class; extern JSClass JavaClass_class; +extern JSClass JavaMember_class; /* * Opaque JVM handles to Java classes, methods and objects required for @@ -291,9 +291,11 @@ jsj_ConvertJavaObjectToJSString(JSContext *cx, JNIEnv *jEnv, jobject java_obj, jsval *vp); extern JSBool jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv, + JavaClassDescriptor *class_descriptor, jobject java_obj, jsval *vp); extern JSBool jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv, + JavaClassDescriptor *class_descriptor, jobject java_obj, jsval *vp); /************************ Java package reflection **************************/ @@ -402,6 +404,9 @@ extern JSBool jsj_ReflectJavaMethodsAndFields(JSContext *cx, JavaClassDescriptor *class_descriptor, JSBool reflect_only_statics); +extern JSObject * +jsj_CreateJavaMember(JSContext *cx, jsval method_val, jsval field_val); + /************************* Java object reflection **************************/ extern JSBool jsj_init_JavaObject(JSContext *, JSObject *); @@ -421,9 +426,6 @@ JavaObject_finalize(JSContext *cx, JSObject *obj); extern JSBool JavaObject_resolve(JSContext *cx, JSObject *obj, jsval id); -extern JSBool -JavaObject_enumerate(JSContext *cx, JSObject *obj); - extern JSBool JavaObject_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); @@ -448,6 +450,9 @@ jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, extern jobject jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj); +extern JSObject * +jsj_UnwrapJSObjectWrapper(JNIEnv *jEnv, jobject java_wrapper_obj); + extern void jsj_ClearPendingJSErrors(JSJavaThreadState *jsj_env); @@ -467,6 +472,9 @@ jsj_GetJavaErrorMessage(JNIEnv *env); extern void jsj_LogError(const char *error_msg); +extern const JSErrorFormatString * +jsj_GetErrorMessage(const uintN errorNumber); + PR_CALLBACK JSJHashNumber jsj_HashJavaObject(const void *key, void* env); @@ -504,4 +512,14 @@ jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp); JS_free(cx, x); \ PR_END_MACRO + +enum JSJErrNum { +#define MSG_DEF(name, number, format, count) \ + name = number, +#include "jsj_msg.def" +#undef MSG_DEF + JSJ_Err_Limit +#undef MSGDEF +}; + #endif /* _JSJAVA_PVT_H */ diff --git a/js/ref/liveconnect/jsj_utils.c b/js/ref/liveconnect/jsj_utils.c index 7af99d28b70..3da781b413a 100644 --- a/js/ref/liveconnect/jsj_utils.c +++ b/js/ref/liveconnect/jsj_utils.c @@ -1,20 +1,5 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved. */ /* @@ -27,11 +12,6 @@ #include #include -#include "prtypes.h" -#include "prprintf.h" -#include "prassert.h" -#include "prosdep.h" - #include "jsj_private.h" /* LiveConnect internals */ #include "jsjava.h" /* External LiveConnect API */ @@ -43,7 +23,7 @@ PR_CALLBACK JSJHashNumber jsj_HashJavaObject(const void *key, void* env) { - prhashcode hash_code; + PRHashNumber hash_code; jobject java_obj; JNIEnv *jEnv; @@ -161,7 +141,7 @@ jsj_GetJavaErrorMessage(JNIEnv *jEnv) jstring java_exception_jstring; exception = (*jEnv)->ExceptionOccurred(jEnv); - if (exception) { + if (exception && jlThrowable_toString) { java_exception_jstring = (*jEnv)->CallObjectMethod(jEnv, exception, jlThrowable_toString); java_error_msg = (*jEnv)->GetStringUTFChars(jEnv, java_exception_jstring, NULL); @@ -312,6 +292,31 @@ 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.def + + jsj_GetErrorMessage is invoked by the engine whenever it wants + to convert an error number into an error format string. +*/ +JSErrorFormatString jsj_ErrorFormatString[JSJ_Err_Limit] = { +#define MSG_DEF(name, number, count, format) \ + { format, count } , +#include "jsj_msg.def" +#undef MSG_DEF +}; + +const JSErrorFormatString * +jsj_GetErrorMessage(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) { @@ -339,7 +344,6 @@ jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp) } return NULL; } - if (envp) - *envp = jsj_env->jEnv; + *envp = jsj_env->jEnv; return jsj_env; } diff --git a/js/ref/liveconnect/jsjava.h b/js/ref/liveconnect/jsjava.h index 6abec4e8bb4..e69de29bb2d 100644 --- a/js/ref/liveconnect/jsjava.h +++ b/js/ref/liveconnect/jsjava.h @@ -1,234 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 - * - * Publicly exported functions for JavaScript <==> Java communication. - * - */ - -#ifndef _JSJAVA_H -#define _JSJAVA_H - -#include "jni.h" /* Java Native Interface */ -#include "jsapi.h" /* JavaScript engine API */ - -/* - * A JSJavaVM structure is a wrapper around a JavaVM which incorporates - * additional LiveConnect state. - */ -typedef struct JSJavaVM JSJavaVM; - -/* LiveConnect and Java state, one per thread */ -typedef struct JSJavaThreadState JSJavaThreadState; - -/* - * This callback table provides hooks to external functions that implement - * functionality specific to the embedding. For example, these callbacks are - * necessary in multi-threaded environments or to implement a security - * policy. - */ -typedef struct JSJCallbacks { - - /* This callback is invoked when there is no JavaScript execution - environment (JSContext) associated with the current Java thread and - a call is made from Java into JavaScript. (A JSContext is associated - with a Java thread by calling the JSJ_SetJSContextForJavaThread() - function.) This callback is only invoked when Java spontaneously calls - into JavaScript, i.e. it is not called when JS calls into Java which - calls back into JS. - - This callback can be used to create a JSContext lazily, or obtain - one from a pool of available JSContexts. The implementation of this - callback can call JSJ_SetJSContextForJavaThread() to avoid any further - callbacks of this type for this Java thread. */ - JSContext * (*map_jsj_thread_to_js_context)(JSJavaThreadState *jsj_env, - char **errp); - - /* This callback is invoked whenever a call is made into Java from - JavaScript. It's responsible for mapping from a JavaScript execution - environment (JSContext) to a Java thread. (A JavaContext can only - be associated with one Java thread at a time.) */ - JSJavaThreadState * (*map_js_context_to_jsj_thread)(JSContext *cx, - char **errp); - - /* This callback implements netscape.javascript.JSObject.getWindow(), - a method named for its behavior in the browser environment, where it - returns the JS "Window" object corresponding to the HTML window that an - applet is embedded within. More generally, it's a way for Java to get - hold of a JS object that has not been explicitly passed to it. */ - JSObject * (*map_java_object_to_js_object)(JNIEnv *jEnv, jobject hint, - char **errp); - - /* An interim callback function until the LiveConnect security story is - straightened out. This function pointer can be set to NULL. */ - JSPrincipals * (*get_JSPrincipals_from_java_caller)(JNIEnv *jEnv); - - /* The following two callbacks sandwich any JS evaluation performed - from Java. They may be used to implement concurrency constraints, e.g. - by suspending the current thread until some condition is met. In the - browser embedding, these are used to maintain the run-to-completion - semantics of JavaScript. It is acceptable for either function pointer - to be NULL. */ - JSBool (*enter_js_from_java)(char **errp); - void (*exit_js)(void); - - /* Most LiveConnect errors are signaled by calling JS_ReportError(), but in - some circumstances, the target JSContext for such errors is not - determinable, e.g. during initialization. In such cases any error - messages are routed to this function. If the function pointer is set to - NULL, error messages are sent to stderr. */ - void (*error_print)(const char *error_msg); - - /* Reserved for future use */ - void * reserved[10]; -} JSJCallbacks; - -/*===========================================================================*/ - -/* A flag that denotes that a Java package has no sub-packages other than those - explicitly pre-defined at the time of initialization. An access - to a simple name within such a package, therefore, must either correspond to - one of these explicitly pre-defined sub-packages or to a class within this - package. It is reasonable for LiveConnect to signal an error if a simple - name does not comply with these criteria. */ -#define PKG_SYSTEM 1 - -/* A flag that denotes that a Java package which might contain sub-packages - that are not pre-defined at initialization time, because the sub-packages - may not be the same in all installations. Therefore, an access to a simple - name within such a a package which does not correspond to either a - pre-defined sub-package or to a class, must be assummed to refer to an - unknown sub-package. This behavior may cause bogus JavaPackage objects to be - created if a package name is misspelled, e.g. sun.oi.net. */ -#define PKG_USER 2 - -/* A Java package defined at initialization time. */ -typedef struct JavaPackageDef { - const char * name; /* e.g. "java.lang" */ - const char * path; /* e.g. "java/lang", or NULL for default */ - int flags; /* PKG_USER, PKG_SYSTEM, etc. */ -} JavaPackageDef; - -/*===========================================================================*/ - -/* The following two convenience functions present a complete, but simplified - LiveConnect API which is designed to handle the special case of a single - Java-VM, with single-threaded operation, and the use of only one JSContext. - The full API is in the section below. */ - -/* Initialize the provided JSContext by setting up the JS classes necessary for - reflection and by defining JavaPackage objects for the default Java packages - 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_PUBLIC_API(JSBool) -JSJ_SimpleInit(JSContext *cx, JSObject *global_obj, - JavaVM *java_vm, const char *classpath); - -/* Free up all resources. Destroy the Java VM if it was created by LiveConnect */ -PR_PUBLIC_API(void) -JSJ_SimpleShutdown(); - -/*===========================================================================*/ - -/* The "full" LiveConnect API, required when more than one thread, Java VM, or - JSContext is involved. Initialization pseudocode might go roughly like - this: - - JSJ_Init() // Setup callbacks - for each JavaVM { - JSJ_ConnectToJavaVM(...) - } - for each JSContext { - JSJ_InitJSContext(...) - } - for each JS evaluation { - run JavaScript code in the JSContext; - } - */ - -/* Called once for all instances of LiveConnect to set up callbacks */ -PR_PUBLIC_API(void) -JSJ_Init(JSJCallbacks *callbacks); - -/* Called once per Java VM, this function initializes the classes, fields, and - methods required for Java reflection. 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_PUBLIC_API(JSJavaVM *) -JSJ_ConnectToJavaVM(JavaVM *java_vm, const char *classpath); - -/* Initialize the provided JSContext by setting up the JS classes necessary for - reflection and by defining JavaPackage objects for the default Java packages - as properties of global_obj. Additional packages may be pre-defined by - setting the predefined_packages argument. (Pre-defining a Java package at - 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_PUBLIC_API(JSBool) -JSJ_InitJSContext(JSContext *cx, JSObject *global_obj, - JavaPackageDef *predefined_packages); - -/* This function returns a structure that encapsulates the Java and JavaScript - execution environment for the current native thread. It is intended to - be called from the embedder's implementation of JSJCallback's - map_js_context_to_jsj_thread() function. The thread_name argument is only - 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_PUBLIC_API(JSJavaThreadState *) -JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *thread_name, - JNIEnv **java_envp); - -/* Destructor routine for per-thread JSJavaThreadState structure */ -PR_PUBLIC_API(JSBool) -JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env); - -/* This function is used to specify a particular JSContext as *the* JavaScript - execution environment to be used when LiveConnect is accessed from the given - Java thread, i.e. when one of the methods of netscape.javascript.JSObject - has been called. There can only be one such JS context for any given Java - thread at a time. To multiplex JSContexts among a single thread, this - function could be called before Java is invoked on that thread.) The return - value is the previous JSContext associated with the given Java thread. - - If this function has not been called for a thread and a crossing is made - into JavaScript from Java, the map_jsj_thread_to_js_context() callback will - 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_PUBLIC_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_PUBLIC_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_PUBLIC_API(JSBool) -JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp); -#endif /* _JSJAVA_H */ \ No newline at end of file diff --git a/js/ref/liveconnect/macbuild/JavaSession/JavaSession.cpp b/js/ref/liveconnect/macbuild/JavaSession/JavaSession.cpp index a12d0270c8a..e69de29bb2d 100644 --- a/js/ref/liveconnect/macbuild/JavaSession/JavaSession.cpp +++ b/js/ref/liveconnect/macbuild/JavaSession/JavaSession.cpp @@ -1,147 +0,0 @@ -/* -*- 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. - */ - -/* - JavaSession.cpp - - Uses MRJ to open a Java VM. - - by Patrick C. Beard. - */ - -#include "JavaSession.h" - -#include -#include -#include - -#include - -extern "C" { - -static void java_stdout(JMSessionRef session, const void *message, UInt32 messageLengthInBytes); -static void java_stderr(JMSessionRef session, const void *message, UInt32 messageLengthInBytes); -static SInt32 java_stdin(JMSessionRef session, void *buffer, SInt32 maxBufferLength); -static Boolean java_exit(JMSessionRef session, int value); -static Boolean java_authenticate(JMSessionRef session, const char *url, const char *realm, - char userName[255], char password[255]); -static void java_lowmem(JMSessionRef session); - -} - -static JMSessionCallbacks callbacks = { - kJMVersion, /* should be set to kJMVersion */ - &java_stdout, /* JM will route "stdout" to this function. */ - &java_stderr, /* JM will route "stderr" to this function. */ - &java_stdin, /* read from console - can be nil for default behavior (no console IO) */ - &java_exit, /* handle System.exit(int) requests */ - &java_authenticate, /* present basic authentication dialog */ - &java_lowmem /* Low Memory notification Proc */ -}; - -JavaSession::JavaSession() : mSession(NULL) -{ - OSStatus status = ::JMOpenSession(&mSession, /* eDisableJITC */ eJManager2Defaults, eCheckRemoteCode, - &callbacks, kTextEncodingMacRoman, NULL); - checkStatus(status); -} - -JavaSession::~JavaSession() -{ - if (mSession != NULL) { - OSStatus status = ::JMCloseSession(mSession); - checkStatus(status); - } -} - -JNIEnv* JavaSession::getEnv() -{ - return ::JMGetCurrentEnv(mSession); -} - -static StringPtr c2p(const char* str, StringPtr pstr) -{ - unsigned char len = strlen(str); - memcpy(pstr + 1, str, len); - *pstr = len; - return pstr; -} - -jclass JavaSession::getClass(const char* className) -{ - JNIEnv* env = getEnv(); - jclass result = env->FindClass(className); - if (result == NULL) throw OSStatusException(fnfErr); - return result; -} - -/** - * Adds a Mac-style path name to the MRJ class path. - */ -void JavaSession::addClassPath(const char* jarFilePath) -{ - Str255 pJarFilePath; - FSSpec jarFileSpec; - OSStatus status = FSMakeFSSpec( 0, 0, // use "current working directory" - c2p(jarFilePath, pJarFilePath), - &jarFileSpec); - checkStatus(status); - status = JMAddToClassPath(mSession, &jarFileSpec); - checkStatus(status); -} - -// OBLIGATORY JMSession callbacks. - -static void java_stdout(JMSessionRef session, const void *message, UInt32 messageLengthInBytes) -{ - char* msg = (char*)message; - while (messageLengthInBytes--) { - char c = *msg++; - if (c == '\r') - c = '\n'; - fputc(c, stdout); - } -} - -static void java_stderr(JMSessionRef session, const void *message, UInt32 messageLengthInBytes) -{ - char* msg = (char*)message; - while (messageLengthInBytes--) { - char c = *msg++; - if (c == '\r') - c = '\n'; - fputc(c, stderr); - } -} - -static SInt32 java_stdin(JMSessionRef session, void *buffer, SInt32 maxBufferLength) -{ - return -1; -} - -static Boolean java_exit(JMSessionRef session, int value) { return false; } - -static Boolean java_authenticate(JMSessionRef session, const char *url, const char *realm, - char userName[255], char password[255]) -{ - return true; -} - -static void java_lowmem(JMSessionRef session) -{ -} diff --git a/js/ref/liveconnect/macbuild/JavaSession/JavaSession.h b/js/ref/liveconnect/macbuild/JavaSession/JavaSession.h index 4ad066d8683..e69de29bb2d 100644 --- a/js/ref/liveconnect/macbuild/JavaSession/JavaSession.h +++ b/js/ref/liveconnect/macbuild/JavaSession/JavaSession.h @@ -1,46 +0,0 @@ -/* -*- 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. - */ - -/* - JavaSession.h - - Uses MRJ to open a Java VM. - - by Patrick C. Beard - */ - -#pragma once - -#include -#include - -#include "OSStatusException.h" - -class JavaSession { -public: - JavaSession(); - ~JavaSession(); - - JNIEnv* getEnv(); - jclass getClass(const char* className); - - void addClassPath(const char* jarFilePath); - -private: - JMSessionRef mSession; -}; diff --git a/js/ref/liveconnect/macbuild/JavaSession/OSStatusException.h b/js/ref/liveconnect/macbuild/JavaSession/OSStatusException.h index 3a7c37abf27..e69de29bb2d 100644 --- a/js/ref/liveconnect/macbuild/JavaSession/OSStatusException.h +++ b/js/ref/liveconnect/macbuild/JavaSession/OSStatusException.h @@ -1,46 +0,0 @@ -/* -*- 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. - */ - -/* - OSStatusException.h - - MacOS OSStatus exception. - - by Patrick C. Beard. - */ - -#pragma once - -#ifndef __TYPES__ -#include -#endif - -class OSStatusException { -public: - OSStatusException(OSStatus status) : mStatus(status) {} - OSStatus getStatus() { return mStatus; } - -private: - OSStatus mStatus; -}; - -inline void checkStatus(OSStatus status) -{ - if (status != noErr) - throw OSStatusException(status); -} diff --git a/js/ref/liveconnect/macbuild/LiveConnectShell.mcp b/js/ref/liveconnect/macbuild/LiveConnectShell.mcp index ec3c94fa7c401ac8f06586e882d917ffb6fa87b2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 40556 zcmeHQ3v?V;dA_r|k|o))<=Al?Cvnz~*iLNA&%{RYLvLHM)>`XfInKjgt=7`Y`^xUh zuLPpRi3uSE8eR!d;1mjh(4HivkoHg-(zM}F4oxXg2+$MCt3VDXC7b{~fct&-{<}N7 z+Fgxfl{U71`@jD;_x^L|KK}pC%s;cEU_2gCO1YJ?Rw?z~2bFsG(@Ir5g}m*S%Yrb} z5+4c;1d_>cJn8i(ay_J*U0NXXk93MC54FOp45S<{06n`(9~c7@#^RJST? z&Cir|L$%C*#!YLn?UKBOknn0v*C6!>Zh)*1?1!ur9E6-9_!wlB;QJvn$N3O&jpRQL zIaBa6kh28;8zkF7dI>yRBc*-=Imcj&x^;rDhMX&S2jnG!`yuBEjzZ2Cd>Zmn!SFY= zK=5ObmkDNj*ng1quShP}P+8xDTqO7v$SVwXaSW~$Ox>#lZ-iVdco!tw3Ub|q#7hJ` zie!m~%5^8?Qo#>FE))DQ$mN2$vT{B^t}h{3p`mhp6LO{Cmm#qlliZxQYc*7Ew*5N6 z>mgSQZiHMT_-4qpg71K=7yK~fI>BrM_XoMZfn!6FsG+Lhv9<|jTeb`KLDD8b6&&ZC8mfv1 zAR7gL3bIM?mm!-4zXaK0a3yWIRWQf0O)&G?1>XY6IR;gpK(bpyRrzkn4#7`Cb_%AQ z?-BfK$S#9t&>q=t&jhQum;)NBsu1J>!Q+s$S5ValksQ=eRsAg_Z3R^I0uuHgRK>pBs-dc;FWe@W z^K(cr%MS~F6J$W}`ymGfv;LsqZ$SztXYuUA2f^pdR#*_i*`gC0?lHdPHL!T-3NI}@JAu(pP*U)h~!QU)vTXFzR}=X z*3a<;)zXje(oogX*2V?1Pj?G`5b_?u^ug1DpM|_v@b@9v4$y2Dk~11kC$Dt`X#1Rd z&NuyuHn0`!1}_6!;OoFQg13WrfVnQvpSTtt26J7z2HXgyUD5_=le9nD9qo-iN1vcS z)_^_W3UDQO2Dl1b4W0?6-Ox{J!Lz~ivraJA2l^K6hwBB`CfZ{+nCsC#a1Xc_+y~}5 z!}X;OJQsWkcpjL3Hy?Z{I07au0Mpkl11|(~?N|h+FJ2Gky1=#fAejEZwd4Sp{zE&w z0lWen1k>L)f;WISgExVPz^lQu_YimucqRBIa1*#0d<486+yZU|w}IQi^hf&7ZtxZ0 zE5TQR7lW?`d%?GWmw=ao*Md91^xfs)H-OiHi_sZmei*}yzHyk~Pu;Fgwa=QZ_PM&$ zfa@}F7p>v0vn-yNGFOj)d;Vv$S64L^oxMGwBlU?S=dlP?oAT7j=t++71gh;lnM#ME zEs;Pf6`~y#P-XL2Y$(EkEJ=2&qQzB!E5R8Hs|BVNa#l&4MUGy^;%RxDA&wv|@ER~Z zWd*pu5@31`Er^y$Ph#)WV0sV7iq=byqU9Y2 z({pK&^aQTRcY?VBbLG7YJPy7ad=L0E_+Bt)S`fNugH1m6t41$--*V@=!O@#rYrrp=AR zwXQIWIJSF2jIRU+BcY1>KU97Ct|M)<(M!P#z=i&S{qp=G;}c7ezZA?lTMnlG(f8<+ z^h5gXbzu4t?UuGh8>RiyUhTGxP3_k%NH^F6t^m`vxh52@6*G}H3tS7H4W0w81J4Ct z0-gt^&(mk7sn`fqAg)9sxyY$9GX@!H>`-BJ$Vg`()&F&gN5|z@m>oExEzrs3(28@k zU7t!D+J?gEcv6{-_INBUu7gg(7_nJr_fbUfrbW!|3dfG-Wn?0;rqM0yT2`+{ zZP7$Hx1Y&G=r$IP4QCqC((Xfja=?xrZ+9Xcj)qTV>+TF33uME*rgC3kI2`o01QK3- zO;LE5Tyb6_bJ_V#^#@YHK%}q|$t`HC-``R&M9e8NM9j`RIy3xj?U}jbmV~ZNpHSYE zieidlp@=B;giaNn?q07igd^m&Uhmfx zhz*YghC`yuyw-TIpmnXG!Li}tP||CfDZ1@_{=E9wtF{xt5KJi^qup~*yTZppE%8_k zr?dLeK(e9GRSL`VoTjj_aFhzm^T(^OG|%}83k$ngSZ;UIVr6;OSWH0-pjc7H6bj1< z+_`vh)>kGJ8y7Fk&dpk3N!~J0SeS1tMN7p5i zX8oP8FUrbJtZl(5wl9~SqWQ826)DRtM}>uX3sYg?q`sFLi42x?KCMvF`*dkJ_tOfc z{ZAK{bUmK8HmU0B8qZRJG`%#=@bM4eyU6LnEZSJb7Y zeKA*D#2IsiCA(VA9rfaR{l4kF6KAF`hHPNiP&?~b$l^hoARopN2 zt|c8)mrmxH-rkW=BvQ^bMWd8&N^u$I6pfPJDdnZyQ;N&@r)ZRLP+Ms!54EXGoH<)z zkr|TG(oUMEP|WBu3KQH^3X1xvl$CN+DK6=$_VS6YYA-F_(JAAu`5I-0 zu7ty8_AleHHkFbSU&Lo^yOkcFQeG=NmvUPvF6y_rd&X&W;f+8hKEQZZCPKiN8{=Ih z#?ct}A~D{}_!o(BT<$|^2QwB%V(hg_BNKbA7CZ>acshx(XvWG&2{2=3B*p|8J0sl- zW(ZqERMmI8Y+wJ;u98-#qz}(DvNPQ#wS4*V~$=TV8%q3 zXs9g4!j}qW44dN)vU-tle~`s7WIPjOaokpDs4T|qR|>ull5tLu^)4igcY>_KVT=@HeHY1k4VCqCNXAS-*6)xob_#NF zZZ~PDTpS154amj1uh&qy8X?(#kZTW;EgC8p2D=2ay?kZ?a#OcML*?#)N2V{1KAFM8JQ7B%q=4JO)Yo26>)D64X$6 zz5qES_<2Yk1LXNGk|P=_&(9!-1^+kXh`|*#kYT~>%c$U0kVge`zG!El3eI6vLsh|k z#RMOQj0;Xcl0g+Gkg%Viiu;fxHB=RU44D%AA;`2~_Hj(`Q;^35bH0uX{uU(b1y!(L zCpAD2m)^%W>_KE}~pw1Z8} z%#UiUuKmmL>e?sX!A!K;)OndLexdJw@SHnzBrKCnO&rJ!3O6)iWajXaSDt7ynwTld z$b%hzuW#U>UvC$-KcfVRy7lwG>{;GcHUWB|?bglq6pY9ORRu%&GO^S)ge(N1pwae}|x`Wzsw#xO+8|2!hL9S1Gz>{0{?iKFZa^%3S>vIXKsvX__8^^B4jB2u(HZ?d`zRt-)j< z8OD1?2szlcbRpLy+>6&kNsXogiEw?8GMNmVGzia5H5kNmHVuNY^og`aLxFTi1G6Z8GgiiOhfq(tb@D9Vik9qPwya5{kX(#VZwfyll38ffyQ`q~Y6-$t%P5a5BZ`>BG?wUgT&9)W`93 z+~yX1`@!cQ$e6U=%s7T@$TV}yX8hdj)r$Zgc87vv`jwH^J(;W0Q(<^mPp5sevp4%x z92c#}0(g8bLn~VdVV*ddDeA{)W-uHk#+Sg%Hhh&MpgNm+q}hC3134L|F*y4`pCuAo z)+L!pDL3rT`0Yc-M;5A~Y>tVK+6P>6XoRxboyS>ade_&{2=K1q6q4N4q`5~r`NZe{ zd;|fLt*@iLOgD9EM}UzG-sw_SJ@NS`ey3C;BOrN{Gn~Ba>5YqM1WdRFi%4z$%>zuQ zy`zgSWiJ!CT;#Pcj(LvE*)8@L=0pm?v1U6i)f6eyE<_Mc=9?6f?%w~YG|0Yh>4?g@#NU-p+egOFO=ne zqoJiE7L1Gyg;LWtagLpWF6fs5d1N z@=oWu?Q7R&Jw9JovpugEwmn}(*NSPN9)Fj-D_p#sxsK`?XlX57gR_#uQ0wXKDbZ4A zbx`XtxUcO%U;W^SN~G|*tLp>VCtud1+n=Y7tM}B)dGBHP_pV~(o8<^X{?6s!!uL*1 zJwc+q(Ss3k%Mnp0X7=t_Lsrlx>iMLOsrS)>)1w zYfl|^*7Z!%8q{NZTc`LDO+ENtMHzBlPq1vyChONY+F;rf94Tjsj_aB5#&3Qn`To*m zq}!8HBjxzSf6Zg+F1w`fCcnFX(A*-CQob$#Y8Im($UfO6}l?MyjoJ>?xIyYfz2Px({R zIn-0OBFFXoq0ihU#-|SEcy4Fz5*20ZaeC&StR9DF?h@6EXWQfO%sp8>Q+DRYyBv>h zALkV|$K6$r*Rji7al3IzfGg~$c_w$^Opb1;*ZCQ@#7N`JeQsymlJ#(mrs9l?uVZc6 z=;iO|<)v;`Y^Pf7Ipr6q+&uv*vhQrirXGhY=A`wMU7*gPJ$Pfe3}sik$=Z`p@nGcD z=apyQH`S#Z*W))_M=QUB?fF0To;~Y%3+j=3f?P$F-}x1O0r*p|=h*Sb*#xsfVP%<; zdK|7Sx#r}J!g#hl4p)}R>Y3!S7vrNp)0WqWf(<=BN&I@H%u2#aLMeIiS{1){XSL_+ zIhm%_NAOmA8M4JlN{o=%xgI}uDN~KYtLT}R;7iuy%l(W>lxnej381l8&(sV7oCYJq<7*Dv_3jeKx1zlY=4H0?=DQG2k0Pes4r7Wpkb z_buJ8^SleL%ZyLin9k&F%hr=nT*6EGd+yAXGoYgOlfap2O6r;9%ruE#jAzCtq0da^ z`elAMmg`oYUu5e^mo?|f2O1jYCq3pjaYc8St)CO5-v23FB$cCzyhIS|T`!*6W|Cq4MH!a99RArZVw09=|XS?qjrJ3fiNi1XECt_CUn< zHI?XBVSK+>zjQq#>1aebJX2nJ`dJ<`=Q-bhiQBrKQH~<0M0=c!v#uwp%HBmWuF453 zH(&hrf~v>Q-^yG=Icbl+JDY;}((%wKsE5OwG3WCcXI&3}9eAGOvo{_Kv96M2`F#FK z?zT(rn=NPrG7(e#-Qa9~9+>g}?HT1%M+EbFTdjh<*P4TVFW>M+nnZ+M6wqLZ7 z1)1W@E!__uE!b(oX0DbAMcE8}Hpy-k2Ttm7Vi}Xo#9&uHc>P`o+$ zzqT)-qwCRUff5Q1va{D=nX^ENeVmNXR9UJ%3zTR_CVR5>G(z!UI5FwdwaMz?@tk;$ zlX+)d*|PvQijb4`a5tVLi|n4wa#RoACCctF4KCgh@Dz4^+AIo3UW zx$iy|drbTHRE*+u9T&q0T&h17XudRXG4$6#AN5&)5$wQZR~rs0yTDa=&DzmPsAT7RUmzuVihdqgew_A+f=dG$7B?fq+fD73Qf>P|K6?eFGL z?f&sX@A8Ppd#%bds_~5)AJy1=mltiocO)NVKK9)Q{Ip;^Bb)K8;M4d( z#1{o))@FTK@F(!e)jGk?0Kbda6K0*WAJ!Ph1=jU=a9rS*b2@YQ9a;2+`E%-tIVQlZ z2CHv-)tozX`E_rT{2zMN+;PFb#%EqXZLsCSXKFtsc$QaPuE$4>Tlfy_qNvVS)?$3N zR*xt0SKza?dd$^5)>f}ta!~8sYjpv~HNMZf75H9_&sfKSA0b{>GuGMBr=I)qi`W2J z%JbaIjg`1*}>_`2`*qi!=u{ZU5V^3C%u_tROY$8jZu>KbAA!c|+^*4M!q6^3M z_j@sB89TFTG_F^xyvoA-BY!Qw!)@J9tj1L%@RNcuRx|%XW8C;dx^PiO(pkRVjy5Tq z78mIVjHJ_vhIQ*0f2mLLJCyP0xMtv#cxP>ek5t9tLgW5O!!i?DL1KcP2M}r z5I41#o+H+Gf&Z7cf>rw4Sp}`0Y5N&nLD9vsS%Gt)Z4`?Am@sQq%7alMb7ep9G{OHW zS+=i22c6>mBH=hTfi>Ubc(K&iMm! z*I>KLf!OhZ?qXiE1{Ls71fgbN|7dp`Ef!^f~ z^m?JU$bla3ldo`~*AKlL9O&(b-jxpY2B3G91HA*#TkJsZCg@%5K#wsLuLHfCp|`|= z-Yw8u>Ok*S=q+=gcN_HXm`o2k(=Z zOXS17J4Egj*(kC}WV6T?k*y-zM7E3EC33gO4w0QA_lWEg=@YqEWVcAa$bBMvMD~j8 z6WK3vzsLcR2SnZ^@}S6@McyLvR*^T_hR8EBlKWc+7^7OzSuJvn$h9KtMXnRMUgQRm z8%1ssxmo1(BDaXV&DMt6nS970-#A4ZT%xm0P+Ci#4gT!Oz2Kk_0 zIm_tR^4{#I&Q`tflci?f=f0I~mE+IDI9oG}{(9P{JU1Hq4920#kJU?lAdhwm}Y>{6*-yqHlxFd=SZ2lfU5=;5RZC{rx49T9aQ{1^g!FBK$EQiCG`! zzWp)ayO@joRY=VE*ZuG*;BheM4E^p|Q_q&K1K-VDrQQtRw9GutZRNG;Jvv+6|0Lw2 wM!$0f@M)9(mV=OHeXIK%?eJd7zaMrY_O|pz -/* Header for class netscape_javascript_JSObject */ - -#ifndef _Included_netscape_javascript_JSObject -#define _Included_netscape_javascript_JSObject -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: netscape_javascript_JSObject - * Method: initClass - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_initClass - (JNIEnv *, jclass); - -/* - * Class: netscape_javascript_JSObject - * Method: getMember - * Signature: (Ljava/lang/String;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getMember - (JNIEnv *, jobject, jstring); - -/* - * Class: netscape_javascript_JSObject - * Method: getSlot - * Signature: (I)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getSlot - (JNIEnv *, jobject, jint); - -/* - * Class: netscape_javascript_JSObject - * Method: setMember - * Signature: (Ljava/lang/String;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setMember - (JNIEnv *, jobject, jstring, jobject); - -/* - * Class: netscape_javascript_JSObject - * Method: setSlot - * Signature: (ILjava/lang/Object;)V - */ -JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setSlot - (JNIEnv *, jobject, jint, jobject); - -/* - * Class: netscape_javascript_JSObject - * Method: removeMember - * Signature: (Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_removeMember - (JNIEnv *, jobject, jstring); - -/* - * Class: netscape_javascript_JSObject - * Method: call - * Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_call - (JNIEnv *, jobject, jstring, jobjectArray); - -/* - * Class: netscape_javascript_JSObject - * Method: eval - * Signature: (Ljava/lang/String;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_eval - (JNIEnv *, jobject, jstring); - -/* - * Class: netscape_javascript_JSObject - * Method: toString - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_netscape_javascript_JSObject_toString - (JNIEnv *, jobject); - -/* - * Class: netscape_javascript_JSObject - * Method: getWindow - * Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject; - */ -JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getWindow - (JNIEnv *, jclass, jobject); - -/* - * Class: netscape_javascript_JSObject - * Method: finalize - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize - (JNIEnv *, jobject); - -#ifdef __cplusplus -} -#endif -#endif