This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

The Taurus Java Virtual Machine has been produced, as a "clean room"
implementation, in accordance with Sun Microsystems, Inc's (SUN) licence
agreement for "The Java™ Virtual Machine" specification. Also, in
accordance with this agreement the virtual machine distribution does NOT, to
the author's knowledge, contain ANY material which is copyrighted by SUN.
As such the class files relied upon by the virtual machine must be obtained
separately, directly from SUN. The use of this specifcation does not in any
way imply that the software conforms to it, nor does it imply that it will ever
wholey do so. The Taurus Java Virtual Machine does not, and will not, ever
pretend to be "Java-compliant", it will always remain as closer approximation
as time and money will allow. Users of this software do so at their own risk.
Developers of any Java software should NEVER use this as a reference platform.

All references to Taurus Software directly refer to the non-profit
freeware/shareware software development unit run from the UK by myself. Any
conflict with names of companies inside or outside of the UK is unintentional
and should be disregarded.

Platform Support
The Taurus Java Virtual Machine version 1.1.0 is provided as binaries
for the following platforms:

Win32 - should work with any i386 based Microsoft Windows™ OS
(95/98/ME/NT/2K/XP)

Linux-i386 - any i386 based Linux™ distribution

Cygwin - Cygwin running on Win32

RISC OS - Archimedes or RISC PC running Acorn RISC OS 3.10 or
later

EPOC32 - The EPOC32 platform Releases 5 and 6

For space reasons is provided without any of the required support libraries
(DLLs, .so or RMs). In order to run this software you must install these
libraries yourself (they are likely to be already installed on most systems).
Binaries for other platforms may follow at some later date.

Java Support
This alpha release provides an incomplete implementation of the SUN Java
Virtual Machine Specification 1.0. The key features of this release are as
follows:

Loading and execution of Java applications - the VM should be able to load
and begin executing any Java application.

Dynamic loading - classes are loaded as needed, exceptions or errors are
reported when a class cannot be found

Complete virtual instruction set implementation - 100% of the virtual
instructions have been implemented (one or two are dummy implementations as
they relate to threading). This means that the VM can interpret large programs
like the javac and javadoc.

Can read and write files on disk.

Support for exceptions - most exceptions generated by the VM can be caught,
all exceptions generated by user code can be caught. All Java exceptions support
the stack trace facility.

Runs with standard JDK classes - there are no modified class files used by
the VM. This version can run with either JDK 1.1 or J2SDK 1.4.

Non-conformant arithmetic implementation - the VM uses its own internal
format (that of C) to represent numbers on the stack. In particular
floating-point numbers may not behave quite correctly for NaN, +Inf and
-Inf. Also beware of bitwise logic on large numbers, as shifts etc. may
not be 100% correctly implemented. All tests so far have shown that the
current implementation is correct, but without access to the official Java
Test Suite, it is very difficult to prove the implementation is correct.

Incomplete native method implementation - only those native methods which
have been encountered in pratice have been implemented. This leaves a lot
of unimplemented native methods, the vast majority of which fall outside
the core implementation, namely those found in the "winawt" and "net"
libraries. No attempt has been made to support the full Java Native
Interface (JNI) specification, so extension DLLs/libraries cannot be added.
However the interface has been designed to be as similar to JNI as possible
in order that this might be supported in future.

Single thread of execution - multi-threading may be added in the form of
"green" threads in a later release. Native threads are unlikely to be
supported as the smaller target platforms do not support threading.

No AWT - the standard Java AWT classes require far too much native
support and are tied too closely to the host platform for implementation in
a truely "portable" VM. Mechanisms to implement the AWT may be provided in
a later release.

No Networking - as with the AWT, the standard java.net
classes require a lot of native support. Mechanisms to implement
networking may be provided in a later release.

No Swing - the Swing toolkit it based partly on the AWT, but uses
lightweight components for most window gadgetry, however Swing cannot work
without support for AWT Windows and Canvasses.

No Garbage Collector - due to the complexity of GC, its implementation
has been left until a later release. It is likely to be necessary to adopt
a smarter GC technique than that normally employed by Java in order to
allow the Java VM to run on really small platforms.

No JIT or Hotspot - a performance enhancing JIT may be added later. The
development of a JIT is difficult and ties the VM to a host platform. JITs
are also a complex technology to develop and even some of the commercial
Java vendors struggled to get it right!

Incomplete refelection interface - reflection is implemented sufficiently
to be able to run serialver, and to startup JDK 1.4.

Basic support for CLASSPATH - only a single directory (or on some
platforms, the current directory) and the standard Zip or Jar files are
checked for class files.

No support for Applets or sandbox - at the moment the VM must be run as a
stand-alone application. Applet support invariably requires either the AWT
or Swing, so fir this reason they are not supported.

Support for "Standard Applications"
Below is a table of the "standard Java applications", which come with most
JVM's. They are all written in Java, so should run on any virtual machine.
As a simple test of the Taurus Java VM, here is what happens when they are run
with the scripts provided:

Application

Status

Comments

appletviewer

Will not run

Needs Threads and native AWT support.

jar

Runs

Uses native Zip support, new in this release.

javac

Runs

Compiles Java code correctly for both JDK 1.1 and J2SDK 1.4.

javadoc

Runs

Successfully documents my Hello.java example

javakey

Runs buggily

Always prints the message "could not initialize scope".

javap

Don't know

I don't have all the class files for javap to test it.

jdb

Will not run

Needs native network support.

native2ascii

Runs

But I don't know what it does!

rmic

Runs

Generates and compiles RMI stubs and skeletons correctly.

rmiregistry

Will not run

Needs native network support.

serialver

Runs

Produces correct UID as per Sun's implementation.

Installation
The Taurus JavaVM is shipped as an archive (usually ZIP) without the standard
class files. If you haven't done so already, you need to download a copy
of JDK 1.1 or JDK 1.4 from java.sun.com.
For 1.1 pick the latest release, for 1.4 pick 1.4.0.

Win32, Linux and Cygwin
Create a suitable directory (e.g. C:\JavaVM or
/home/robert/javavm), and unpack the downloaded ZIP file
containing the VM into this directory. It is important that you create the
javavm directory and cd into it, as the Zip files do not contain a top level
directory.

Next install the class files from the JDK - these come packed as a zero
compression Zip or Jar file. For JDK 1.1.x, this is called
classes.zip and is approx 8Mb in size, for J2SDK 1.4 there are two
Jar files rt.jar and tools.jar. You need to copy
these files directly into the JavaVM lib directory (you may need
to create this, if there isn't one already).

If you chose to install J2SDK 1.4 classes, then you need to swap the javavm
for the 140 version in the bin directory. For Windows and Cygwin,
rename javavm.exe to javavm110.exe and then rename
javavm140.exe to javavm.exe. For Linux, do exactly
the same, but without the .exe extension.

RISC OS
Unpack the downloaded ZIP file using !ZipEE or similar into a suitable
directory e.g. $.Apps. This will create an !JavaVM
application directory containing the necessary files.

Next install the class files from the JDK - these come packed as a zero
compression Zip or Jar file. For JDK 1.1.x this is called
classes.zip and is approx 8Mb in size. For JDK 1.4 here are two
Jar files rt.jar and tools.jar.
For performance reasons, you may wish to unpack these files into
$.Classes (unlike !JavaVM, this cannot be moved anywhere else).
You then need to rename all the files to remove the .class file
extensions.

If you choose to run without unpacking the Zip/Jar files, be aware that this
uses a lot of memory and the performance degrades a bit. The main reason for
this is because RISC OS machines simple don't have enough RAM to cache the
file and its index. On larger machines, commonly used files are often held
tempoarily in RAM, which improves performance enormously.

If you chose to install J2SDK 1.4 classes, then you need to swap the javavm
for the _140 version in the !JavaVM.bin directory.
Rename javavm to javavm_110 and then rename
javavm_140 to javavm.

Running
Running JavaVM is very simple, and it is designed to be run in a similar way to
other virtual machine implementations.

Win32, Linux and Cygwin
To run the VM you must either add JavaVM's bin directory
to your path, or if you have other VM's installed, you must cd
to this directory and type, for example, .\java (Win32) or
./java (Cygwin and Linux).

To run your own programs, you must place your .class files in
the lib directory along with the standard Java classes.

RISC OS
Before you can run the VM under RISC OS, you must first double-click the
!JavaVM application. This doesn't actually launch an
application, it just sets up various environment variables, adds the VM's
bin directory to you path and loads the appropriate modules.

To actually run the VM, open a Task Window (Ctrl+F12). As with most large
programs, you need to increase the wimpslot of the task with
wimpslot -min 3000k for example. Larger programs will need a
bigger wimpslot. The VM is then run by typing, for example, java,
in the same manner as other platforms.

To run your own programs, you must place your .class files in
the $.Classes directory along with the standard Java classes.

Testing the VM
To make sure that the VM is setup properly and that you are running the
right VM (if you have more than one installed), run the VM with the
-version switch. This should result in something similar to the
following:

If you don't get this, or you get a similar message which does not
contain the word "Taurus", then check your path, or make sure you are using
.\java -version (Windows) or ./java -version. On
RISC OS make sure you have double-clicked !JavaVM.

Minimum requirements
The VM can function in a much smaller environment than provided by the JDK
classes. If you wist to implement your own "standard" classes, then the JDK
1.1 VM really only needs the following classes and methods to function:

Class

Usage

java.lang.Object

All classes derive from it, either directly or indirectly.

java.lang.System

Loaded at system startup.

initializeSystemClass()

Called at system startup.

java.lang.Thread

For the "main" thread object.

java.lang.ThreadGroup

For the "system" thread group.

java.lang.String

For strings (Note: this can be cut down a lot).

java.lang.Throwable

For all exceptions and errors.

java.lang.Error

For all errors.

java.lang.Exception

For all exceptions.

java.lang.InternalError

Can be generated by any field or method access.

java.lang.NullPointerException

Can be generated by any field or method access.

java.lang.ArrayIndexOutOfBoundsException

Can be generated by any array access

java.lang.ArithmeticException

Can be generated by maths ops (e.g divide by zero)

java.lang.ClassCastException

Can be generated by any explicit or implicit cast.

java.lang.ClassNotFoundException

Generated by dynamic loading.

It is also advisable to include the following error/exception classes, as
they can be raised directly by the VM (either in response to class-loading or
by being thrown by native method implementations):

Class

Usage

java.lang.VerifyError

Can be raised by the verifier.

java.lang.NoClassDefFoundError

Can be raised by the linker.

java.lang.IllegalAccessError

Will be used in future releases.

java.lang.ClassFormatError

Raised by the loader when it encounters a corrupt class file.

java.lang.NoSuchFieldError

Will be used in future releases (1.06a erroniously raises
NoSuchMethodError's instead).

java.lang.NoSuchMethodError

Raised by the VM in response to incompatible class changes.

java.lang.UnsatisfiedLinkError

Raised by the VM when linking fails.

java.lang.IOException

Can be raised by native I/O methods.

java.lang.NegativeArraySizeException

Can be raised by the VM when dereferencing arrays.

To make your own environment, you need to implement a set of Java classes
similar to those provided by Sun. The main reason for doing this on a small
platform is the amount of rubbish that gets loaded before any of your classes.
I am currently looking at the Personal Java and Embedded Java specifications
for some ideas on how to shrink the VM - Just using System.out loads an awful
lot of classes, if you use the standard JDK!