JavaScript Runtime

Table of contents

  1. Interpretation
  2. Compilation to Java Bytecode
  3. Types and Values
  4. Property Access
  5. Defining Host Objects
  6. Contexts and Threads

Interpretation

Beginning with Rhino 1.4 Release 2, an interpretive mode is supported. When scripts are compiled in interpretive mode, an internal representation of the compiled form is created and stored rather than generating a Java class. Execution proceeds by evaluating this compiled form using support routines in Rhino.

Compilation to Java Bytecode

For improved performance, Rhino may compile JavaScript scripts to Java bytecode. The generated bytecode in turn depend upon runtime support routines. Each JavaScript script or function is compiled to a separate class.

Compilation of JavaScript source to class files is supported. It is possible to specify the class files as well as the packages to generate into.

Types and Values

There are six fundamental types in JavaScript. These types are implemented with the following Java types and values:

JavaScript fundamental type Java type
undefined A singleton object defined by [Context.getUndefinedType()](https://javadoc.io/doc/org.mozilla/rhino/latest/org/mozilla/javascript/Context.html#getUndefinedValue--)
null null
boolean java.lang.Boolean
number java.lang.Number, that is, any of java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Float, or java.lang.Double. Not java.lang.Long, since a double representation of a long may lose precision.
string java.lang.CharSequence (java.lang.String or org.mozilla.javascript.ConsString)
object org.mozilla.javascript.Scriptable

In addition, ECMAScript refers to objects that implement [[Call]] as functions. These object types are represented by implementing the Function interface.

Since JavaScript is a dynamically typed language, the static Java type of a JavaScript value is java.lang.Object.

The behavior of the JavaScript engine is undefined if a value of any type other than the ones described above is introduced into JavaScript. (This caveat does not apply to scripts that use LiveConnect: the Java values are wrapped and unwrapped as appropriate to conform to the above type constraints.)

Property Access

Properties in JavaScript objects may be accessed using either string or numeric identifiers. Conceptually, all accessors are converted to strings in order to perform the lookup of the property in the object. However, this is not the implementation used in practice because a number to string conversion is too expensive to be performed on every array access.

Instead, every property accessor method in Scriptable (has, get, set, remove, getAttributes, and setAttributes) has overloaded forms that take either a String or an int argument. It is the responsibility of the caller to invoke the appropriate overloaded form. For example, evaluating the expression obj["3"] will invoke the get(int, Scriptable) method even though the property name was presented in the script as a string. Similarly, values of numbers that do not fit in integers (like 1.1 and 0x100000000) must be converted to strings.

Defining Host Objects

Host objects are JavaScript objects that provide special access to the host environment. For example, in a browser environment, the Window and Document objects are host objects.

The easiest way to define new host objects is by using ScriptableObject.defineClass(). This method defines a set of JavaScript objects using a Java class. Several of the examples define host objects this way.

If the services provided by defineClass are insufficient, try other methods of ScriptableObject and FunctionObject, such as defineProperty and defineFunctionProperties.

Contexts and Threads

Every thread that executes JavaScript must have an associated Context. Multiple threads (with multiple associated Contexts) may act upon the same set of objects. Any host objects that are defined are responsible for any synchronization required to run safely from multiple threads.