Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
INSTALL
: See also the documentation page named "Main Page" for an overview from the JVM spec section number perspective.
Apache Harmony Bootstrap Java Virtual Machine ============================================= This implementation of the Java Virtual Machine has been written as a (notice "a", not "the") reference implementation that comprises almost all of the facilities of a JVM without any further changes. Please see the file named 'INSTALL' in this same directory for instructions on installing and building the program. The goals of this effort are: (1) To provide a working Java Virtual Machine interpreter to the Apache Harmony project as a cornerstone for a Java runtime environment, especially considering the possibility of using it as a bootstrap JVM in the final project code base, where and if applicable. (2) To provide a working Java Virtual Machine to the Apache Harmony project as a starting point for architectural discussions to help the project get started in earnest, pulling itself up "by its bootstraps," as it were. Thus a second reason to call this project the "bootstrap JVM." :-| :-O :-) (3) To provide a highly modular implementation so pieces may be added and modified and removed with minimal impact to other pieces. For example, the heap allocation component may be easily switched between three modes, 'simple' and 'bimodal' and 'other'. This is accomplished by running 'config.sh' and changing it there. In like manner, the garbage collection component or any future component so constructed may be easily replaced without any changes to other code. Other components may not be _quite_ as hermetically sealed, such as the class file loader or threading mechanism, but the structure is present to improve upon the implementations, as desired. (4) To provide a simple code implementation written in straight, vanilla ANSI 'C' using the ubiquitous GCC compiler so that the code may be easily and efficiently adapted and modified to perform all tasks without esoteric tools, and utilizing the experience and creativity of _all_ contributors. The only suggestion is that each contributor working on source code learn how to use Doxygen, a simple, powerful, and highly configurable C/C++ documentation utility. There is an abundance of example commentary in the showing how to use it for a wide variety of project documentation purposes. Furthermore, its installation also includes extensive built-in documentation about itself. (5) To provide a very clear and concise code base for teaching JVM concepts to potential contributors. (6) To organize the code as a simple static library that can be linked into any larger body of code, and also to be able to connect JNI shared object files/dynamic load libraries to it easily. (7) To provide a sample main() program entry point for how to link and use the static library. (8) To provide a start on the native side of the JNI implementation of java.lang.* and java.io.* (etc.) that may be more fully fleshed out by project contributors as a way to start becoming familiar with the core code. Also to provide a similar start on the JNI side for the same reasons, including a sample main() program there. This implementation is NOT intended to be: (1) The final Apache Harmony JVM. (2) The authority or standard against which JVM's are measured, whether by the Apache Harmony project or otherwise. (3) The most efficient possible implementation. Issues of modularity, concise implementation, and ease of understanding how the code works take precedence over runtime efficiency issues, including CPU time, memory resources, and the like. This contribution consists of about 52,000 lines of 'C', Java, shell scripts, and data files. It has been written, unit tested, and _lightly_ integration tested. It is being contributed partly with testing in mind to familiarize contributors with the code as they work with it and continue with integration testing, especially while extending its feature set into a full-fledged, bullet-proof work of art. This file contains a list of items that should be addressed, both features and bug fixes. Furthermore, the source code and therefore the pre-formatted documentation contains over 200 focused, specific enhancements, questions, and problems in the @todo list that should be addressed during this process. It is my hope that this contribution will be the seed that helps the Apache Harmony project to sprout, mature, and bloom into a first-class Java Virtual Machine that is worthy of the reputation of the Apache brand. Yours Truly Daniel Lydick September 28, 2005 --- Configuration ------------- Run the 'config.sh' script in this directory to configure for your environment. It creates a './config' sub-directory with a './config/config.h' header file containing top-level compile parameters. This file is always referenced in every source file of the core JVM code by including "arch.h". This script also creates other files there useful with the 'build.sh' scripts and contains normal compiler command line parameters. Eclipse project files are also available which contain these same compile command line parameters. Whatever Java JDK you are currently using is probably fine for now when running this JVM. Reading of JAR files is _not_ done via the JAR classes (yet), but with your '$JAVA_HOME/bin/jar' utility. The test classes may be compiled with your JDK's '$JAVA_HOME/bin/javac' compiler. All this is in an attempt to leverage the functionality of your existing JDK to "bootstrap" this bootstrap JVM into existence. Eventually, of course, all this will get replaced with Harmony versions of all of these components. A seed for these components is found in the Java classes in 'jni/src/harmony/generic/0.0'. Currently, these classes contain _only_ definitions for what is termed "local native methods". These are JNI method calls to code that has intimate knowledge of the details of the JVM implementation, such as 'java.lang.Object.wait()'. (See 'jvm/src/native.c' for more information.) Once the 'config.sh' completes successfully, run 'build.sh' in any or all directories where it is found to build that diretctory or directory tree. At the top level, 'build.sh all' will build the entire project. Call it as 'build.sh help' for options. Eclipse project files are provided to do the same things with the same options except that it does not compile the Java classes in 'jni/src/harmony/generic/0.0'. (Notice that if you change anything, it will need to be changed for both 'build.sh' and for Eclipse if you want them be both work the same.) The original development of this code was on a Sun Ultra 5 with Solaris 9 running GCC 3.3.2, Gmake 3.80, GNU binutils 2.11.2, and GDB 6.0, coordinated under Eclipse 3.0.2 with the C/C++ plugin CDT 2.1.1. The JDK was Sun's 1.4.2_06-b03. The source code was documented with Doxygen 1.4.4, Solaris version. Code organization ----------------- (The following description is also found in 'jvm/src/jni'c for display on the "Main Page" documentation.) Several directories are provided within the source tree: jvm Source code for JVM, including a main() wrapper. Builds binary file 'jvm/bin/bootjvm'. libjvm For building 'jvm' as a statically linked library archive, less main() wrapper. Builds library archive 'libjvm/lib/libjvm.a'. Source code comes from the 'jvm' directory. main A simple main() wrapper that links 'libjvm/lib/libjvm.a' and builds binary file 'main/bin/bootjvm'. Source code comes from the 'jvm' directory. jni Source code for a sample JNI shared library 'jni/harmony/generic/0.0/lib/bootjni.so' for linking with JNI code, but needs the build directives to be functional, as it currently links statically with a main() into a binary just like 'jvm'. This directory contains a tree for JNI implementations from any supplier that wants to support the Harmony project. Currently, there is one JNI implementation here, found in 'jni/src/harmony/generic/0.0'. test Builds numerous Java test classes in 'test/bin' for driving development work. With the exception of the Java test classes in 'test/src', all source code is found in 'jvm/src' and in the directory tree 'jni/src/vendor/product/version'. The purpose of 'libjvm' and 'main' for demonstrating various possible organizations for the source code, namely for building a static library archive and for linking it. The source code is about 3 MB in size. The final size of all of parts of the compiled code tree is about 12 MB. The full documentation tree in 'doc.ORIG' is about another 55 MB when fully installed. It may be removed if desired in favor of maintaining _only_ the working documentation in 'doc' as generated by 'build.sh dox' at the top level, which will be the same size as 'doc.ORIG' if all documentation formats are desired, or less if fewer documentation formats are used. For example, if only the HTML format is used, the 'doc' directory will be about 19 MB in size. Comments in the source will _always_ mention 'C' language "functions", but Java language "methods", and _never_ the reverse. This is part of an attempt to separate the two compile and runtime domains. See also comments on this subject below under 'jrtypes.h' and the source itself for additional comments about type definitions in the Java and real machine domains. Subsystem component abstraction ------------------------------- The implementation key Java concepts is performed in the following source files with corresponding navigation macros: Component Source and header Navigation --------- ----------------- ---------- Java class class.[ch] CLASS() macro classutil.c Java object object.[ch] OBJECT() macro objectutil.c Java thread thread.[ch] THREAD() macro threadstate.c threadutil.c Java method method.[ch] METHOD() macro Java class field.[ch] FIELD() macro static field, object instance JVM registers jvmreg.h STACK(), et al Java native native.[ch] -- jlObject.[ch] -- jlClass.[ch] -- jlString.[ch] -- jlThread.[ch] -- JVM spec class file classfile.[ch] Many, see cfmacros.h Heap modules heap.h HEAP_xxx() macros heap_simple.c heap_bimodal.c Garbage gc.h GC_xxx() macros collection gc_stub.c modules By simply changing out the respective source file and adjusting the main navigation macro for that component, the implementation can be changed drastically without affecting the other components. (Larger implementations will have more than one source file, see especially 'threadstate.c'.) It is _highly_ unlikely that the 'classfile.[ch]' components will _ever_ change since this is under the direct control of the Java specification, but the others are under the control of this project and may be modified to suit its needs as desired. Support Scripts =============== Following is a short description of each script file and other support files: config.sh <--- * * * START HERE AFTER READING 'INSTALL' FILE * * * --------- Introduce users to the project and how to set it up and configure it for various CPU platforms and for various functional features. This interactive shell script provides introductory material and a description of which versions of which software tools are needed to compile and document the project and how to administer the pre-formatted documentation. It then starts evaluating the existing Java JDK (as declared by the JAVA_HOME environment variable) for existence of the proper tools and verifies the name of the class library archive that will be used for temporary access to JVM startup classes such as the root object java.lang.Object.class . Once this introductory evaluation is complete, it will ask questions about how to configure the project for compile, runtime, and distribution features, as well as which components to build and to document. Once the questions are answered, the project is configured and optionally built using 'build.sh cfg'. build.sh clean.sh common.sh --------- Top-level build scripts that invokes build scripts of the same names at the various levels in the directory tree. The one named 'build.sh' compiles the source code, while the one named 'clean.sh' removes the effects of that build. The shared file 'common.sh' is used by both of these scripts. Notice that nowhere in the tree except here at the top level will the documentation build occur, as it is a global process due to interdependencies of @link and @see directives, among others. getsvndata.sh getsvndups.sh ------------- Show a list of all revisions of all source files compiled into an object file, a library archive, or a linked binary with 'getsvndata.sh'. Show a list of conflicting revisions using 'getsvndups.sh'. Object files may not have conflicts, neither may library archives. Linked binaries may or may not, depending on the particulars. echotest.sh ----------- Generic script support for 'echo -n' feature for shells that do not support it natively. jvm/build.sh libjvm/build.sh main/build.sh test/build.sh jni/src/harmony/generic/0.0/build.sh jvm/clean.sh libjvm/clean.sh main/clean.sh test/clean.sh jni/src/harmony/generic/0.0/clean.sh jvm/common.sh libjvm/common.sh main/common.sh test/common.sh jni/src/harmony/generic/0.0/common.sh ------------------------------------- Like at the top level, each relevant directory level has a build script that compiles the source code ('build.sh') and removes the output files from that build ('clean.sh'). These files share a common file ('common.sh') also. The output of 'libjvm' is stored in a 'libjvm/lib' subdirectory, while the output of the other scripts is stored in a '______/bin' subdirectory. dox.sh undox.sh commondox.sh ------------ The logic behind the documentation build using Doxygen. The output is stored by 'dox.sh' into a 'doc' subdirectory at this level, while the 'undox.sh' removes it. They share a common file 'commondox.sh'. In order to speed up the documentation build during development, define the environment variable SUPPRESS_DOXYGEN_VERYCLEAN as any non-null string. See logic of 'dox.sh' for other comments. dist-src.sh dist-doc.sh dist-bin.sh ----------- Construct a source distribution and store it above the top of the directory tree in gzipped tar, where CONFIG_RELEASE_LEVEL is the release level defined the last time that 'config.sh' was run: Type Script Output TAR file ---- ------ --------------- Source dist-src.sh ../../bootJVM-src-$CONFIG_RELEASE_LEVEL.tar.gz (plus docs) Docs dist-src.sh ../../bootJVM-doc-$CONFIG_RELEASE_LEVEL.tar.gz Binary dist-src.sh ../../bootJVM-bin-$CONFIG_RELEASE_LEVEL.tar.gz (plus docs) A side effect of the source distribution (only) is the creation of a file in this directory named 'bootJVM-docs.tar.gz'. It is included in the distribution as a part of the deliverables and contains installable documentation files. Its installation is managed with 'config.sh' where it references the "pre-formatted documentation. Other Files =========== INSTALL <--- * * * START HERE * * * ------- Instructions for installing the source code and building the binaries and the documentation. LICENSE ------- The Apache Software Foundation license text used by the ASF for all software distributions. README ------ This file. bootjvm.dox dox_filter.sh ------------- 'bootjvm.dox' is the Doxygen directive file used to create all project documentation, invoked by 'dox.sh'. 'dox_filter.sh' the filter script declared in 'bootjvm.dox' for filtering input files. It is declared as the 'INPUT_FILTER=' parameter in 'bootjvm.dox' and is necessary to properly format all files that are not explicitly '.c' or '.h' or '.java' source files. svnstat.sh ---------- Sample script from Doxygen documentation to display the status of a file in SVN. Not used in the project for any purpose. test/.project test/.classpath --------------- Eclipse project files for the 'test' Java project. jvm/.project jvm/.cdtproject jvm/.cdtbuild libjvm/.project libjvm/.cdtproject libjvm/.cdtbuild main/.project main/.cdtproject main/.cdtbuild jni/.project jni/.cdtproject jni/.cdtbuild ------------------- Eclipse project files for the several C/C++ projects. Output areas ============ bootclasspath/ -------------- Directory containing default value of BOOTCLASSPATH environment variable. THIS ABSOLUTE PATH NAME IS COMPILED INTO SOURCE CODE AND WILL NEED TO ULTIMATELY BE PHASED OUT. config/ ------- Directory where all results from 'config.sh' are stored. These files are used by the various shell scripts and by Doxygen to build various aspects of the project. jvm/bin main/bin test/bin jni/src/harmony/generic/0.0/bin ------------------------------- Output area respectively from 'jvm/build.sh', 'main/build.sh', 'test/build.sh', and 'jni/src/harmony/generic/0.0/build.sh'. libjvm/lib ---------- Output area from 'libjvm/build.sh' jni/bin ------- Output area for the Eclipse 'jni' project. Source distributions (via 'dist-src.sh') cannot be performed until this directory has been manually removed of an Eclipse 'clean' operation done for the 'jni' project. Output files ============ bootclasspath.class bootclasspath.class -------------- Java class files that are found in the BOOTCLASSPATH environment variable. They are extracted from your JDK's runtime JAR file and are used to start up the JVM. They will eventually get phased out of the project when these classes have been developed by the project team. Whether or not replacements from the project are stored here is TBD. config/config.h --------------- Although the other files stored in the 'config' directory are not listed here, they are derived along with this file from 'config.sh' to control the compile and run time features of the project. This file specifically can be used as a reference when running 'config.sh' again to remember what settings were configured. It will be very obvious from that script as to which definitions here match the questions. jvm/bin/bootjvm main/bin/bootjvm test/bin.class test/bin.class jni/src/harmony/generic/0.0/bin/bootjvm jni/src/harmony/generic/0.0/bin.class ----------------------------------------- The output files respectively from the build of the 'jvm', 'main', 'test', and 'jni/src/harmony/generic/0.0' project build. libjvm/lib/libjvm.a ------------------- Output file from the 'libjvm' project build. Source code =========== Following is a short description of each source file. All function names start with the name of their source file, 'filename_function()' in keeping with the OO concept of packaging all related code and data into the same sourcefile. See also 'jrtypes.h' for comments on naming conventions for certain data types. The JNI source code is grouped separately, as is the test suite. jvm/src/arch.h -------------- Configure the compilation of each source file with architectural parameters, especially from the configuration script 'config.sh'. Provide copyright information for the binary edition of each source file. This file MUST be included by all source files in 'jvm/include' and in 'jvm/src'. Do NOT include it in 'jni' source files. There needs to be an equivalent for the Java code written for these features (see to-do item in source). jvm/src/argv.c -------------- Parse the JVM command line. For easy help, call program with '-help' option. jvm/src/attribute.c jvm/src/attribute.h ------------------- Handle class file attributes. The type definition 'jvm_attribute_index' is the key to properly using class file attributes. jvm/src/bytegames.c ------------------- Manipulate bytes for various purposes such as byte swapping, reading 2-byte structures from 1-byte addresses, or 4-byte or 8-byte structures from 1- or 2-byte addresses, etc. (These last are due to use of structure packing, especially in parsing class file data and parsing virtual opcode operands). jvm/src/cfattrib.c ------------------ Process the attibute fields of class file data. Since attributes are a large and specialized area of the JVM spec class file definition, they have been broken out of 'classfile.c'. jvm/src/cfmacros.h ------------------ Macros for navigating the class file structures of 'classfile.h'. jvm/src/cfmsgs.c ---------------- Diagnostic messages for class file data. jvm/src/class.c jvm/src/class.h --------------- Handle Java classes in the real machine implementation. The type definition 'jvm_class_index' is the key to properly using Java file classes. Notice that this index is implemented in such a way that the underlying implementation could be completely changed from a simple array of structures to something unrelated and there would be only a few changes to some macros necessary to support that new implementation. Such an implementation might call this type definition a 'jvm_class_hash' instead, for example. The design decision, however, was to try to maintain a separate structure for classes than for objects. Each class does have an object that contains its object-ish components. This object is also implemented to satisfy the spec requirements that a class also have a class object. See 'linkage.h' as to how to navigate between classes, objects, and threads. jvm/src/classfile.c jvm/src/classfile.h ------------------- Definition of JVM spec, version 2, section 4, for JDK 1.5, namely, the class file structure, and its implemention. The version of the class file definition (section 4) is listed near the top of the header file. It is one of several that have been floating around, but appears to meet the JDK 1.5 attribute extensions rather exactly, and is _assumed_ (that is a VERY big assumption!) to be class file 'major.minor' version '49.0', namely the JDK 1.5 class file format. All symbol definitions are declared _exactly_ as shown in this specification with the single exception of array declarations like, u2 constant_pool_count; cp_info constant_pool[constant_pool_count - 1]; Such definitions are instead declared as, u2 constant_pool_count; cp_info **constant_pool; and an array of pointers to (cp_info) is allocated on the heap of size 'constant_pool_count'. (In this one case, element zero is defined as not being used, so it is always a NULL pointer.) For purposes of real machine word alignment, type 'cp_info' and 'attribute_info' have been embedded in a _slightly_ larger structure to keep 2- and 4-byte member references on the correct real machine address boundaries. The embedding structures are called 'cp_info_dup' and 'attribute_info_dup', respectively, as they duplicate the contents of the smaller structure, if you will. All symbol definitions that are not _explicitly_ found in the spec are locally defined for use in this implementation. They are prefixed with the string "LOCAL_" to distinguish them from spec definitions. For example, ACC_PUBLIC marks a class as public, but the local definition ACC_EMPTY means no defintion at all. Since it is not found in the spec, it is actually named LOCAL_ACC_EMPTY here. jvm/src/classpath.c jvm/src/classpath.h ------------------- Manage and navigate CLASSPATH environment variable. jvm/src/classutil.c ------------------- Utilities for handing real machine class structures. jvm/src/exit.c jvm/src/exit.h -------------- Exit codes for exit(3) and fatal error handing for JVM runtime. This code implements non-local subroutine returns using the standard library calls setjmp(3) and longjmp(3). If you want to understand this non-local return mechanism, you _must_ read the man pages for these functions and study the examples. They are extremely useful in processing fatal error conditions and state machine conditions under which there is no valid return or repair of an invalid state or irreconcilable condition. jvm/src/field.c jvm/src/field.h --------------- Handle Java virtual machine variables for both class static fields and object instance fields. The type definitions 'jvm_field_index' and 'jvm_field_lookup_index' are the keys to properly using Java fields. jvm/src/gc.h ------------ API for all garbage collection algorithms. jvm/src/gc_stub.c ----------------- Default implementation of garbage collection (a do-nothing implementation). This code is meant to be replaced by one or more GC algorithms. The GC insertion points in the code body corporate should stand for all algorithms. See 'heap_*.c' and header file 'heap.h' for an example of implementing multiple algorithms on a single API. jvm/src/heap.h -------------- API for all heap management algorithms. jvm/src/heap_simple.c --------------------- Default implementation of heap allocation using malloc(3) and free(3). One option is presented to return an allocated area that has been initialized to zeroes, which is useful for structure initialization. jvm/src/heap_bimodal.c ---------------------- An improvement over 'heap_simple.c' where a large memory block is allocated from whence come all allocations up to a certain size. Beyond that, the 'heap_simple.c' algorithm is used. jvm/src/jrtypes.c jvm/src/jrtypes.h ----------------- Map Java data types ('j') to real machine ('r') types. Much of the code uses these two letters prefixed to variable names to distinguish between Java and real machine data types. The other common prefix used throughout the code is 'p' for pointer, such as '(char *) pstr' or '(jint *) parray'. However, this convention is for instances of pointers to _any_ data type, and may be used for either the 'C' or the Java domains. Compiled constant definitions are found in 'jrtypes.c' also. jvm/src/jvalue.h ---------------- Java data type aggregate for storage of class static field and object instance fields. One type fits all. jvm/src/jvm.c jvm/src/jvm.h ------------- The main JVM control structure for running the Java virtual machine on this real machine. There is virtually no global storage in this code, and only sparing use of static (file scope) storage. Most everything else is either found here, is a local variable, or is on the heap. The code in 'jvm.c' initializes, runs, and shuts down the JVM. jvm/src/jvmcfg.c jvm/src/jvmcfg.h ---------------- Top-level configuration of JVM parameters (not including what is mostly compile-time setup with 'config.sh' and its 'config/config.h' header file.) All sorts of things are defined here, from OS-dependent directory delimiters to JVM command line parameter strings. A number of significant typedefs are also found here, as well as high and low limits on data types, etc. Compiled constant definitions are found in 'jvmcfg.c' also for NULL and BAD definitions for major typedefs. jvm/src/jvmclass.h ------------------ Fully qualified class name strings (internal form) for a wide variety of classes needed by the JVM at run time. Of special significance is a large number of error and exception classes. jvm/src/jvmregs.h ----------------- Definition of JVM program counter, stack, and stack navigation. jvm/src/jvmutil.c ----------------- Utilities for debug message levels, stack dumps, etc. jvm/src/linkage.c jvm/src/linkage.h ----------------- The header contains linkages between class, object, and thread structures. The source file contains late binding linkage functions to link field references and method references from one class into their definitions in another class. jvm/src/main.c main/src/main.c (symbolic link to jvm/src/main.c) --------------- A sample main() entry point that calls the JVM from either a library archive or by direct object linkage. jvm/src/manifest.c ------------------ Read and process selected properties from a JAR manifest file. jvm/src/method.c jvm/src/method.h ---------------- Handle Java virtural machine methods. The type definition 'jvm_method_index' is the key to properly using Java methods. jvm/src/native.c jvm/src/native.h ---------------- Support for JNI native methods and what are called local native methods (those with intimate knowledge of the inner workings of the JVM). Local native methods may, but are not required to, use the JNI interface, but a significant shortcut is provided for more direct connection between them and the JVM. jvm/src/nts.c jvm/src/nts.h jvm/src/unicode.c jvm/src/unicode.h jvm/src/utf8.c jvm/src/utf8.h ----------------- Utilities for null-terminated strings, UTF8 strings, and Unicode strings, including conversion back and forth, getting and putting, length functions, and examination/conversion of Java class formatting in various types. Notice that there are three types of strings in this JVM: (1) 'C' style strings of ASCII characters terminated by an ASCII '\0' (NUL) byte, also known as "pointer to real-machine character" strings, or 'prchar' variables; (2) UTF8 strings as implemented with the (CONSTANT_Utf8_info) type definition, particularly as related to Java class files; (3) Unicode strings, which consist of a (jchar)[] type array variable and a (u2) length variable. jvm/src/object.c jvm/src/object.h ---------------- Handle Java objects in the real machine implementation. The type definition 'jvm_object_hash' is the key to properly using Java objects. Notice that this hash is implemented in such a way that the underlying implementation could be completely changed from a simple array of structures to something unrelated and there would be only a few changes to some macros necessary to support that new implementation. See 'linkage.h' for how to navigate between classes, objects, and threads. jvm/src/objectutil.c -------------------- Utilities for Java objects. Support for synchronize() and unsynchronize() is found here, namely, the object monitor locks. Other utility functions may be placed here as appropriate. jvm/src/opcode.c jvm/src/opcode.h ---------------- The JVM spec, version 2, section 9, operation code list is found in the header file directly as defined in the spec. The code contains the JVM inner execution loop. jvm/src/stdio.c --------------- Standard input/output functions for stdout, stderr, buffer formatting, etc. CAVEAT EMPTOR (let the buyer beware!): This file does _NOT_ use structure packing because on the original implementation (Solaris 9 with GCC 3.3.2), the standard I/O library was _not_ compiled with structure packing and caused strange runtime errors and SIGSEGV on normal library calls. Therefore, most standard I/O was gathered into this file, with the exception of 'manifest.c', which does not seem to have to problem. jvm/src/thread.c jvm/src/thread.h ---------------- Handle JVM threads in the real machine implementation. The type definition 'jvm_thread_index' is the key to properly using threads. Notice that this index is implemented in such a way that the underlying implementation could be completely changed from a simple array of structures to something unrelated and there would be only a few changes to some macros necessary to support that new implementation. See 'linkage.h' for how to navigate between classes, objects, and threads. jvm/src/threadstate.c --------------------- Thread state machine individual states. A lengthy narrative near the beginning of this file defines the JVM thread state machine, which is then implemented in 'jvm.c' by jvm_run(). jvm/src/threadutil.c -------------------- Utilities for normal operation of the thread state machine. jvm/src/timeslice.c ------------------- Real-time JVM time slice timer for limiting the amount of time that a thread may run (see also 'jvm.c' and 'opcode.c') before the next thread is given some time. jvm/src/tmparea.c ----------------- Private disk storage area for running the JVM. It is set up and torn down by this code and is referenced through a getter function. jvm/src/util.h -------------- Miscellaneous support macros and function prototypes from various of the source files. This file contains a list of which source files have their prototypes listed here, and those that could but do _not_ for specific reasons. A WORD ABOUT FUNCTION PROTOTYPES ================================ Each and every source 'filename.c' that has a 'filename.h' associated with it will locate its function prototypes in that header file. The few exceptions are listed in 'jvm/src/util.h'. A WORD ABOUT SOURCE FORMATTING ============================== Each and every source file is formatted so that not one single line goes beyond 72 characters in width except where absolutely unavoidable. Furthermore, there is not one single TAB character (ASCII 9, 011, 0x09, \u0009) in the entire body of code. The only place it is found is in theEclipse '.project' and '.classpath' files. All indentions are made at 4-column intervals. The purpose of these two constraints is so that absolutely anyone with any text editor may view the source in a standard 80-column text editor, with line numbers, and be able to see the whole line without any line wrapping. This constraint makes the interchange of source code between project contributors much simpler. Although there is a case to be made for wider lines, many developers like 80 column constraints anyway, or some other number. This choice of constraint should provide maximum flexibility of interchange of source files amongst all contributors. JNI SOURCE CODE =============== jni/src/harmony/generic/0.0/src/java/lang/Object.java jni/src/harmony/generic/0.0/src/java/lang/Class.java jni/src/harmony/generic/0.0/src/java/lang/String.java jni/src/harmony/generic/0.0/src/java/lang/Thread.java ----------------------------------------------------- Sample segments of java.lang.* package that contain the native declarations in these classes. (Not comprehensive either for each class or for the package.) jni/src/harmony/generic/0.0/include/java_lang_Object.h jni/src/harmony/generic/0.0/include/java_lang_Class.h jni/src/harmony/generic/0.0/include/java_lang_String.h jni/src/harmony/generic/0.0/include/java_lang_Thread.h ------------------------------------------------------ JNI headers that correspond to the 'src/java/lang' equivalent Java source files in the java.lang.* package that contain the native declarations in these classes. (Not comprehensive either for each class or for the package.) jni/src/harmony/generic/0.0/src/java_lang_Object.c jni/src/harmony/generic/0.0/src/java_lang_Class.c jni/src/harmony/generic/0.0/src/java_lang_String.c jni/src/harmony/generic/0.0/src/java_lang_Thread.c -------------------------------------------------- JNI source code that correspond to the 'src/java/lang' equivalent Java source files in the java.lang.* package that contain the implementation of the local native methods in these classes. (Not comprehensive either for each class or for the package.) jvm/include/jlObject.h jvm/include/jlClass.h jvm/include/jlString.h jvm/include/jlThread.h ---------------------- Headers for connecting the JVM to the JNI interface of the above classes. There are effectively two parallel sets of runtime definitions in these files, one for generic JNI, one for the core JVM code, namely this body of source. They are _independent_ so there is NO coupling between an arbitrary JDK's JNI implementation and this JVM. Please see comments in these header files for more information. jvm/src/jlObject.c jvm/src/jlClass.c jvm/src/jlString.c jvm/src/jlThread.c ------------------ The native side of the JNI implementation of the above selected core java.lang.* classes. The functions in these files are referenced by the JNI target functions. For example, the function java_lang_Class_isPrimative() in 'java_lang_Class.c' will at some point call the 'jlClass_isPrimative()' function in 'jlClass.c'. jni/src/harmony/generic/0.0/src/sampleJNImain.c ----------------------------------------------- Sample function that calls JNI functions through the JNI interface. This is currently built as a straight binary. It needs to be built as a .so/.dll shared object file. TEST JAVA FILES =============== This area is designed to be filled in with _many_ packages and classes for testing the JVM. Here is a rudimentary but useful first pass: test/src/HelloWorld.java ------------------------ Just what it says. In order to run this main() method, however, requires a _fully_ functional JVM with most of the basic JNI in place. test/src/harmony/jvm/test/PkgHelloWorld.java -------------------------------------------- The same "hello world" program, but in a package. test/src/harmony/jvm/test/MainArgs.java --------------------------------------- A main() method that takes arguments from the command line. KNOWN ISSUES AND SUGGESTED TO-DO ITEMS ====================================== (1) The default garbage collection algorithm is 'no collection'. This means that an algorithm must be written in order to sustain JVM execution with continuous heap availability. Other heap implementations might also be written beyond the two that are supplied. (2) Anonymous strings (without a class static field reference in (rclass) or an object instance reference in (robject) may not get completely unreferenced and deallocated, but could continue to accumulate instance references. Depending on the GC algorithm, this may or may not occur and/or may or may not present a problem over a very long JVM session where reference structures grow without bound or counts wrap around to zero. (3) There has been no attempt made to process any special values of floating point data, neither NAN, +/- infinity, overflow, or anything else. The definitions per the class file spec are present, of course, but nothing has been done with them. Special care should be taken in fprintf() statements-- like the sysDbgMsg() calls in 'cfmsgs.c' -- to make sure that formats like "%lf" are followed and precise. The same goes for 64-bit integers, (long long) in real machine and (jlong) in JVM, that formats like "%ld" are followed and precise. (4) All reading of JAR files uses the 'jar' utility provided in the $JAVA_HOME directory tree in '$JAVA_HOME/bin/jar'. This will, of course, need to be enhanced to simply read the JAR files directly. To start with, the BOOTCLASSPATH could have them added to it as a part of 'config.sh', then invoked from the JVM. (5) The JNI interface in 'jni/src/harmony' contains only a cursory JNI implementation. This will need to be filled out to the complete suite of native methods needed by java.lang.*. The native side is found in 'jvm/include' for the 'jni/src/harmony' source and header files, while the implementation is in the 'jvm/src/jlClassNameXYZ.c' files (all beginning with 'jl' for "java/lang" followed by the actual class name). For example, 'jlThread.c' contains the native portions of java.lang.Thread. Certain key system calls like open(2) and exit(2) and socket(2) are located in packages like 'java.io' and 'java.system' and 'java.rmi' (?), respectively. The local native method interface will need to be extended to cover these system calls. See also item (28) below. (6) The JVM execution engine in particular will need through testing. It has been unit tested, of course, but good, solid integration testing is an excellent exercise for new contributors to learn the code, so this item has been specifically reserved for contributors for this purpose. (7) There is apparently a typographical error in the spec section 4.5.7 describing 21-bit character encoding. Therefore, this format has not been implemented pending proper resolution. It probably is correct to assume that the spurious "-1" in the second byte of the first triple should say "(bits 20-16)" instead of "(bits 20-16)-1". However, this is presented as an exercise for contributors. (8) There are a plethora of comments marked "@todo xxx" all over the code. In the Doxygen "Related Pages" section, they are gathered into one comprehensive list. These items are presented as exercises for contributors. (9) The Solaris 32-bit implementation was chosen for development as a very generic development and runtime environment. Testing partway through indicated that a transition to a 64-bit runtime environment could be compiled with little effort. However, there will have to be some adjustments to get everything to work because that one test produced a SIGSEGV during JVM initialization, and its cause was not thoroughly explored. Every effort has been made to anticipate 64-bit compilations, but that adjustment will need to be fully tested. (10) Every effort has been made to use _only_ standard Unix and Posix runtime library calls so the code could be ported to as many platforms as possible. The first targets that come to mind are, of course, Linux, HP-UX, and AIX, with CygWin in mind also, with a few changes for system(3) scripts. (*** The code intentionally does _NOT_ have the Windows version of some CONFIG_xxxx_SCRIPT definitions so that the contributor will need to get it written, possibly put into a .BAT file, then invoked through the existing infrastructure in the code. ***) (11a) There are a number of places here and there in the code where a return value is not properly checked for having an error value, such as 'jvm_class_index_null' or 'jvm_attribute_index_bad'. This is typically _not_ a throwable error condition, like from heap allocation or other error, but is an actual runtime condition that is returned. After three full passes through the code, the error code structure has morphed significantly from a fully structured approach just to get the code started to a partial OO approach, throwing errors through setjmp(3)/longjmp(3). Someone needs to go through the code in its _entirety_ and find out where invalid results are intentionally returned instead of throwing an error and _make sure_ that the calling functions check those results properly. (11b) The same goes for input parameters in various places throughout the code for the following typedefs from 'jvmcfg.h': jvm_thread_index jvm_constant_pool_index jvm_interface_index jvm_class_index jvm_method_index jvm_field_index jvm_field_lookup_index jvm_attribute_index jvm_unicode_string_index jvm_object_hash These will need to be reviewed for the same reasons as the error return codes. Either they will index an array to its NULL element, specifically (with corresponding NULL element named also), jvm_thread_index (jvm_thread_index_null) jvm_constant_pool_index (jvm_constant_pool_index_null) jvm_class_index (jvm_class_index_null) jvm_object_hash (jvm_object_hash_null) jvm_native_method_ordinal (jvm_native_method_ordinal_null) which, in the case of a 'jvm_constant_pool_index' will produce a NULL pointer SIGSEGV, or it will index way off the end at the max index for the data type, namely (with corresponding BAD element name also), jvm_interface_index (jvm_interface_index_bad) jvm_method_index (jvm_method_index_bad) jvm_field_index (jvm_field_index_bad) jvm_field_lookup_index (jvm_field_lookup_index_bad) jvm_attribute_index (jvm_attribute_index_bad) jvm_unicode_string_index (jvm_unicode_string_index_bad) A typical check might be, jvm_attribute_index attribute_find_in_field_by_cp_entry(jvm_class_index clsidx,...) { if (jvm_class_index_null == clsidx) { Somebody goofed * / exit_init_failure(EXIT_JVM_INTERNAL, JVMCLASS_JAVA_LANG_INTERNALERROR); NOTREACHED* / } } In all cases, a review of the code with format input parameters to test what goes in is simple-- there are quite a few places where this _is_ done, it just is not complete. A similar review of functions that pass these data types back _out_ will provide the inverse test. Both are _mandatory_ for integrity of the runtime environment. (12) The threading algorithm uses a simple for() loop. It could be easily generalized to using POSIX threads since there is already one POSIX thread started in the current code. This thread would go away when and if such threading were implemented. This thread is implemented in 'timeslice.c'. It is a time slice real-time clock timer that sends SIGALRM every so often on a tick boundary. This signal is connected to a handler that sets a flag in each live JVM thread and tells the JVM inner loop to quit after the current operation code so the next thread can be activated. By unwinding the thread activation for() loop, also known as the JVM outer loop, and putting in place a POSIX thread for each JVM thread, the timer would go away and the code would become a true multi-threaded application. The purpose of _this_ implementation as a for() loop is for simplicity of implementation and for education of contributors who are new to multi-threaded environments in general and the Java virtual machine multi-threaded environment in particular. (Note that such unwinding would take place exclusively in 'thread.c'. No other logic _anywhere_ should be affected in more than a minor way beyond the JVM outer look in 'jvm.c'.) (13) Commensurate with the above discussion on unwinding the JVM outer loop into a multi-threaded application is the discussion of write barriers. THERE ARE ABSOLUTELY NO WRITE BARRIERS IN THIS DESIGN!!! This is both for simplicity (per above reasons) and so that this _critical_ subject is given due consideration by the whole team JVM architecture contributors. This implementation makes no claims toward being an authority on such a vital and potentially sensitive subject. (14) The 'field_info' area of the class file definition supports the 'ConstantValue' attribute, but does not support 'Signature'. This needs to be added for conformance to JDK 5 requirements. It also should support 'Synthetic' and 'Deprecated'. The definitions are present in 'classfile.h', they just need to get implemented. (15) The 'method_info' area of the class file definition supports the 'Code' and 'Exceptions' attributes, but does not support 'Signature'. This needs to be added for conformance to JDK 5 requirements. The definitions are present in 'classfile.h', they just need to get implemented. (16) When nearing the end of the initial development, I ran across what is probably a memory configuration limit on my Solaris platform, which I did not bother to track down, but rather worked around. It seems that when calling malloc(3C) or malloc(3MALLOC), after 2,280 malloc() allocations and 612 free() invocations, there is something under the covers that does a SIGSEGV, and it can happen in either routine. I therefore extended the heap mechanism of 'heap_simple.c' to allocate a large number of slots of 'n' bytes for small allocations up to this size. Everything else still uses malloc(). In this way, I was able to finish development on the JVM without arguing with heap allocation. This implementation is found in 'heap_bimodal.c'. (In other words, I will let the team fix it!) Furthermore, I am not sure that the real project wants a static 'n + 1' MB data area just hanging around the runtime just because I did not take time to tune the system configuration! (17) In preparation for writing the actual JVM execution engine, the 'bytegames.c' utilities bytegames_getrl8() and bytegames_putrl8() and bytegames_swap8() and bytegames_mix8() were added. The 'util.h' macros GETRL8() and PUTRL8() were likewise added. Other ways of processing 64-bit values were obsoleted and the places where they were used have been replaced by these functions and macros. This substitution needs to be more rigorously tested. All places where this substitution was made have been marked as commented-out code plus new functionality with a @todo item commenting it. (18) There needs to be an examination of heap usage to make _sure_ that all instances of HEAP_GET_xxxx() eventually have a matching HEAP_FREE_xxxx() so there are no memory leaks. The existing code has been carefully written to facilitate this requirement, but it has not been rigorously regression tested. And since it is _well_ known that memory leaks are a system integrator's worst nightmare, if the code is checked early on into the project, there will be nothing to lose sleep over later on. (19) A review of the non-local return logic in 'opcode.c' from threads that throw a java.lang.Error, java.lang.Exception, and java.lang.Throwable is in order. Errors should kill the JVM, but Exceptions should allow it to proceed. What about Throwables? The framework is in place for the project team to adjust to meet the JVM spec. Also, make sure that simply creating a new class object, running its <init> method, and continuing with previous code or quitting is the right way to process the condition. The existing logic is from heuristic observation of a JVM, but an examination of the spec should provide the definitive answer. Notice that java.lang.Throwable and java.lang.StackTraceElement will need local, native implementations. The exception framework needs to be filled in in opcode_run() for exceptions thrown by Java virtual methods. All handling of errors like java.lang.NoSuchMethodError is already taken care of. (20) The concept of the ThreadGroup is not implemented here (see JVM spec section 2.16). This is given as an exercise to the project team. The default implementation consists _ONLY_ of the method java.lang.ThreadGroup.uncaughtException(). The rest of this class must be implemented. This partial implementation may also need to go away at that time. The basic reasoning for this is that the functionality of java.lang.ThreadGroup does not seem to warrant any native methods. Therefore, the whole of its functionality should likely be implemented in a Java class library and should typically behave properly without direct JVM core support. (21) The sequence of loading and initializing the three critical classes java.lang.Object, Class, and String in 'jvm_init()' is somewhat fragile and probably not really sustainable. It might be that the best thing to do is to either make classlib-specific implementations of this initialization or to unload and reload these classes once the original loading is done and let the normal <clinit> be performed during this second attempt to load each of these classes. The problem is one of chickens and eggs: Which comes first? The logic is written and somewhat tested. It needs to be firmed up. An exercise for the team. Unloading and reloading support is already provided with class_static_delete() and class_reload(). (22) The verification step (VM spec section 2.17.3) is given as an exercise for the project team. This was done in the interest of time and the fact that there may be third-party packages that may do this nicely (BCEL?) without much further effort. (23) The source code is documented using Doxygen in its normative state. Although this tool can be _significantly_ contorted to perform documentation of almost _any_ file type due to its capability to hook into a user-specfied input filter, this implementation has done nothing outside of the usual bounds of the default product configuration. With that said, there is _one_ small admission to make here: Even though all of the code was written in ANSI 'C', the OO concept of throwing exceptions is intrinsically bound up with the runtime needs of a Java Virtual Machine. Therefore, one _small_ bending of the rules was permitted in the documentation-- use of the C++ documentation keyword '@throws' (also known as '@exception' and '@throw'). Functions that instantiate a java.lang.Throwable such as 'Error' or 'Exception' (and/or their subclasses) use the following documentation syntax to present this behavioral feature to the Doxygen output. The results will show up in the bolded section named 'Exceptions:' in the same way that parameters show up in the 'Parameters:' section and return values in the 'Returns:' section: * * @brief Function fn() doc header * ... * other doc info... * ... * * @param p1 what parm 1 does * * @returns what fn returns * * @throws JVMCLASS_some_kind_of_exception_string_name * @link \#JVMCLASS_some_kind_of_exception_string_name * brief description of how to make this happen @endlink. * / *include "exit.h" *include "jvmclass.h" rettype fn(parmtype p1) { ... if (problem_happened) { exit_throw_exception(JVMCLASS_some_kind_of_exception_string_name); NOTREACHED* / } ... return(normal_value); } Notice this function call is similar to exit_jvm(), but has the added feature of initiating an exception, after which exit_jvm() will be called with an appropriate exit code to shut down the JVM. (25) When using the Eclipse C/C++ plugin, be aware of a bug in that code: Sometimes it loses its brains and wants to debug the test Java program instead of the C program. Look at the Run menu's Debug dialog (Run|Debug) and you will notice that under "C/C++ Local Application", the 'jvm' configuration is missing. To correct this, simply click on "C/C++ Local Application" and then click "New": Main: Project: jvm C/C++ Application: bin/bootjvm Connect process input & output to a terminal: yes Arguments: C/C++ Program Arguments: (anything appropriate) Use default working directory: yes Environment: (anything you like) Debugger: Debugger: GDB Debugger Stop in main() on startup: yes (typically, no is okay) Main: GDB debugger: gdb GDB command file: <empty> Share Libraries: (anything you like) Source: jvm yes test yes Common: Type of launch configuration: local Display in favorites menu: (anything appropriate) Launch in background: yes Now click 'Apply' and 'Close'. This should save it properly. Now it may be used normally. (24) A solid introductory project for someone is to go in to 'cfmsgs.c' and write and equivalent to cfmsgs_show_constant_pool() for the field table and method table, suggested names being, cfmsgs_show_fields_table() and cfmsgs_show_methods_table(). This method takes cfmsgs_typemsg() and displays each constant_pool[] item. The same approach could be taken to these two utilities. The first and most important use of these functions is in classfile_loadclassdata(). In like manner, an attribute table display function needs to be written to do the same thing for any attributes table. Currently cfmsgs_atrmsg() shows the contents of a _single_ attribute, but there is nothing that can explicitly dump an entire attribute table for fields, methods, or the (single) class attribute table. (25) While working on the above 'cfmsgs.c' display routines, that same person should probably go in to classfile_loadclassdata() and clean up the numerous individual cfmsgs_typemsg() calls for inclusion in those routines. A few should probably still be left in, such as 'cfmsgs_typemsg("this", pcfs, pcfs->this_class)' which reports the 'this_class' member, but this process was followed when writing cfmsgs_show_constant_pool() and it helped the readability of the output _immensely_ to get rid of 'ad hoc' debug messages. (26) The debug message level (DML) values need to be completely overhauled for more effective use by developers. (27) Does there need to be a tighter relationship between the declaration of a native method via ACC_NATIVE when the class file is loaded by classfile_loadclassdata() and the class resolution logic of the linkage_resolve/unresolve_class() methods? What about with thread_class_load() and related startup code that runs a method? (28) Although there have been _several_ significant passes at desk-debugging 'threadstate.c' and 'threadutil.c' and in particular, 'jlThread.c', the JVM thread state machine needs a rigorous pass at integration testing. The java.lang.Thread methods of 'jlThread.c' and 'threadstate.c' are of particular concern, along with the hooks in 'timeslice.c'. This testing has been left as an exercise for the project team. Someone who has completed their Sun Certified Java Developer certification and is good with skills in 'C' should be able to firm up this area of the code nicely. See also item (5) above. (29) In like manner to (28) above, unit testing of object monitor locking has been left as an exercise for the project team. Again, someone who has completed their Sun Certified Java Developer certification and is good with 'C' should be able to firm up this area of the code nicely. (30) The whole body of code needs to be reviewed for proper ordering of PUSH() and POP() macros for (jlong) and (jdouble) variables. The same goes for local variable access of the same. The way it _should_ be done at this time is PUSH(MS), PUSH(LS) with corresponding POP(LS), POP(MS). For local variables, var[n] := MS, var[n+1] := [LS]. However, this needs proper scrutiny for completeness and correctness. (31) A review needs to be made of the Eclipse project files. In particular, do the C/C++ project settings need to be made independent of the workspace settings for compile, link, and library archiver options? Do the Java project settings need to be made similarly independent? Should there be a workspace provided in the distribution that has all these things set up? Currently, the projects are a bit of a mixture of workspace and project settings. The 'build.sh' scripts use a hard-coded set of GCC options that are derived from the Eclipse setup. The 'config.gcc' and config.gccld' files reflect this for the C source. The Java compilations in the 'build.sh' scripts use the default Java compiler options. Does there need to be a harmonization (sic) between the Eclipse and 'build.sh' settings? Should they be manually mantained in Eclipse and 'config.sh'? These are questions that need some review. Furthermore, this author is very much a proponent of systematic use of 'gmake' as a premier project build tool across the industry. It would be a really good idea for use of 'gmake' to be reviewed. It is used internally by Eclipse, but users should not be forced to use Eclipse just to get 'gmake'. (32) The inner loop of virtual instructions in opcode.c checks various items at run time such as ACC_STATIC and ACC_FINAL and other items that a class verifier should test. This is done so that the code corresponds _directly_ with the definition of each instruction as described in JVM spec section 6. Many of these these tests (namely, the examples above) should be moved to a byte code verifier because they will not change from the time that the class is loaded until it is unloaded. Obviously, checking them each time a virtual instruction is run is _not_ efficient at run time! However, this implementation is meant also to teach the principles and requirements of virtual instructions, so the implementation of the JVM spec requirement was done in the inner loop in opcode_run() as a sort of reference implementation of each virtual instruction. (33) One very good exercise for project team members to learn this code will be to implement the exception logic as found in the exception attribute of the program counter, namely jvm_pc.excpatridx. This field is filled in correctly at method startup time, and there should be enough hooks in the structure of the code to implement it without much effort. What will be worth it is the learning process. This logic will bear some strong similarities with LATE_CLASS_LOAD() and class_load_resolve_clinit() when not using the system thread. (34) It is similarly left as an exercise for the project team to locate a method in a superclass or an interface if it is not found in the current class. Currently, a request is made for a method in the current class and a (jvm_method_index) is returned. This is fine for JVM initialization when it is known which methods are found where, but what _should_ happen in normal JVM runtime is that the INVOKEVIRTUAL, INVOKEINTERFACE, INVOKESTATIC, etc., should check if a method is in the current class. If not, check superclasses until no more superclasses. If found, return a heap pointer that contains the (jvm_class_index) and (jvm_method_index) of the located method, otherwise return 'rnull', the NULL pointer. Class loading does search for superclasses, so look for uses of 'pcfs->super_class' or 'pcfs_recurse->super_class' for examples on how to do this. (35) In the documentation, the @def and @struct tags were used to introduce specific definition types. This practice somehow was not carried through to all definitions. Similar cleanup should be done for the following tags: @enum, @fn, @var, @typedef. None of these were put in place, but would clean up the organization of the output areas and add better indexing capabilities to the result set. It also might ease the need for @link tags so that definitions may be automatically tagged better, making room for cleanup of such constructions in the narrative as: @link \#jvm_class_index jvm_class_index@endlink to be simplified into, jvm_class_index This would then ease the readability (in source code itself) of the documentation. Notice that constructions such as, @link \#jvm_class_index a resulting class index@endlink will not need cleanup since the target link is not the same as the displayed text. (36) An excellent tutorial for learning how objects are created using non-default constructors is in jvm.c and class.c where string parameters are loaded in from the argv[] command line and from CONSTANT_String_info structures of the class file, respectively. A suggestion is made in jvm.c as to how to accomplish this. (37) After going back and forth as to whether or not a @throws condition that happens in a subroutine should also be reported back up the line in the function that called it, the result is that sometimes it is reported and sometimes it is not. This needs to be regularized. It is recommended to _not_ report it in the calling function's documentation also since this is really not an OO environment. Document it where it happens and let that stand.
Definition in file README.
Go to the source code of this file.