layout | toc_group | link_title | permalink |
---|---|---|---|
docs |
js |
GraalJS Compatibility |
/reference-manual/js/JavaScriptCompatibility/ |
GraalJS is an ECMAScript-compliant JavaScript language runtime. This document explains the public API it presents for user applications written in JavaScript.
GraalJS implements the ECMAScript (ECMA-262) specification and is fully compatible with the ECMAScript 2024 specification (sometimes referred to as the 15th edition).
New features are frequently added to GraalVM when they are confirmed to be part of ECMAScript 2024, see the CHANGELOG.md for details.
Older versions starting from ECMAScript 5 can be enabled with a configuration option (by number: --js.ecmascript-version=5
or by year: --js.ecmascript-version=2024
).
In a production environment, you might consider specifying a fixed ECMAScript version to be used, as future versions of GraalJS will use newer versions of the specification once available.
GraalJS provides the following function objects in the global scope as specified by ECMAScript, representing the JavaScript core library: Array, ArrayBuffer, Boolean, DataView, Date, Error, Function, JSON, Map, Math, Number, Object, Promise, Proxy, Reflect, RegExp, Set, SharedArrayBuffer, String, Symbol, TypedArray, WeakMap, and WeakSet.
Additional objects are available under options, for example, --js.temporal
.
Run js --help
for the list of available options.
Several of these function objects and some of their members are only available when a certain version of the specification is selected for execution. For a list of methods provided, inspect the ECMAScript specification. Extensions to the specification are specified below.
GraalJS comes with an implementation of the ECMA-402 Internationalization API, enabled by default (can be disabled using the following option: --js.intl-402=false
).
This includes the following extensions:
Intl.Collator
Intl.DateTimeFormat
Intl.DisplayNames
Intl.ListFormat
Intl.Locale
Intl.NumberFormat
Intl.PluralRules
Intl.RelativeTimeFormat
Intl.Segmenter
The functionality of a few other built-ins, such as toLocaleString
, is also updated according to the ECMA-402 specification.
GraalJS supports modules as defined by ECMAScript 6 and later. Be aware that the support for this feature continues to increase. Be sure to use the latest ECMAScript version for the all the latest features.
When loading modules via a polyglot Source
, you can use the unofficial application/javascript+module
MIME type to specify that you are loading a module.
When loading with JavaScript code from a file, make sure the module is loaded from a file with the .mjs extension.
Loading with the import
keyword is not limited by that, and can import
from a file of any extension.
The following objects and methods are available in GraalJS for compatibility with other JavaScript engines. Note that the behavior of such methods might not strictly match the semantics of those methods in all existing engines.
GraalJS supports conditional catch clauses if the js.syntax-extensions
option is enabled:
try {
myMethod(); // can throw
} catch (e if e instanceof TypeError) {
print("TypeError caught");
} catch (e) {
print("another Error caught");
}
- loads (parses and executes) the specified JavaScript source code
Source can be of type:
- a String: the path of the source file or a URL to execute.
java.lang.URL
: the URL is queried for the source code to execute if thejs.load-from-url
option is set totrue
.java.io.File
: the file is read for the source code to execute.- a JavaScript object: the object is queried for a
name
and ascript
property, which represent the source name and code, respectively. - all other types: the source is converted to a String.
load
is available by default and can be deactivated by setting the js.load
option to false
.
- prints the arguments on the console (
stdout
andstderr
, respectively) - provides a best-effort human readable output
print
and printErr
are available by default and can be deactivated by setting the js.print
option to false
.
A global console
object is provided that offers several methods for debugging purposes.
These methods strive to provide similar functionality as provided in other engines, but do not guarantee identical results.
Note that those methods behave differently when GraalJS is executed in Node.js mode (for example, the node
executable is started instead of js
).
Node.js provides its own implementation that is used instead.
console.log
,console.info
, andconsole.debug
: an alias forprint(...arg)
console.error
, andconsole.warn
: similar toprint
, but using the error IO streamconsole.assert(check, message)
: printsmessage
whencheck
is falsyconsole.clear
: clears the console window if possibleconsole.count()
, andconsole.countReset()
: counts and prints how many times it has been called, or resets this counterconsole.group
, andconsole.groupEnd
: increases or decreases the indentation for succeeding outputs to the consoleconsole.time()
,console.timeLog()
, andconsole.timeEnd()
: starts a timer, prints the duration the timer has been active, or prints the duration and stops the timer, respectively
The console
object is available by default and can be deactivated by setting the option js.console
to false
.
- exits the engine and returns the specified status code
- reads the content of
file
The result is returned as a String.
The argument file
can be of type:
java.io.File
: the file is used directly.- all other types:
file
is converted to a String and interpreted as a file name.
- reads the content of
file
similar to theread
function
The result is returned as a JavaScript ArrayBuffer
object.
- reads one line of input from the input stream
The result is returned as a String.
- defines the
prop
property ofthis
to be the getter functionfunc
This functionality is deprecated in most JavaScript engines. In recent ECMAScript versions, getters and setters are natively supported by the language.
- defines the
prop
property ofthis
to be the setter functionfunc
This functionality is deprecated in most JavaScript engines. In recent ECMAScript versions, getters and setters are natively supported by the language.
- returns the getter function for property
prop
of the object as set by__defineGetter__
This functionality is deprecated in most JavaScript engines. In recent ECMAScript versions, getters and setters are natively supported by the language.
- returns the setter function for property
prop
of the object as set by__defineSetter__
This functionality is deprecated in most JavaScript engines. In recent ECMAScript versions, getters and setters are natively supported by the language.
GraalJS provides a scripting mode compatible with the one provided by the Nashorn engine.
It is enabled with the js.scripting
option. Make sure to have --experimental-options
set:
js --experimental-options --js.scripting=true
In scripting mode, several properties and functions are added to the global object, including readFully, readLine, $ARG
, $ENV
, and $EXEC
.
There are migration guides available for code previously targeted to the Nashorn or Rhino engines.
The Graal
object is provided as a property of the global object.
It provides Graal-specific information.
The existence of the property can be used to identify whether GraalJS is the current language engine:
if (typeof Graal != 'undefined') {
print(Graal.versionECMAScript);
print(Graal.versionGraalVM);
print(Graal.isGraalRuntime());
}
The Graal object is available in GraalJS by default, unless deactivated by an option (js.graal-builtin=false
).
- provides the version number (year value) of the GraalJS ECMAScript compatibility mode
- provides the version of GraalVM, if the current engine is executed on GraalVM
- indicates if GraalJS is executed on a GraalVM-enabled runtime
- If
true
, hot code is compiled by the Graal compiler, resulting in high peak performance. - If
false
, GraalJS will not be optimized by the Graal Compiler, typically resulting in lower performance.
- provides the unhandled promise rejection handler when using option (
js.unhandled-rejections=handler
). - the handler is called with two arguments: (rejectionReason, unhandledPromise).
Graal.setUnhandledPromiseRejectionHandler
can be called withnull
,undefined
, or empty arguments to clear the handler.
The Java
object is only available when host class lookup is allowed.
To access Java host classes and its members, they first need to be allowed by the host access policy, and when running from a native executable, be registered for runtime reflection.
Note that some functions require the Nashorn compatibility mode to be set (--js.nashorn-compat=true
).
Java.type
loads the specified Java class and returns a constructible object that has the static members (for example, methods and fields) of the class and can be used with the new
keyword to construct new instances:
var BigDecimal = Java.type('java.math.BigDecimal');
var point1 = new BigDecimal("0.1");
var two = BigDecimal.TWO;
console.log(point1.multiply(two).toString());
Note that when used directly with the new
operator, Java.type(...)
needs to be enclosed in parentheses:
console.log(new (Java.type('java.math.BigDecimal'))("1.1").pow(15));
Java.from
creates a shallow copy of the Java data structure (Array, List) as a JavaScript array.
In many cases, this is not necessary; you can typically use the Java data structure directly from JavaScript.
Java.to
converts the argument to the Java type.
The source object jsData
is expected to be a JavaScript array, or an array-like object with a length
property.
The target javaType
can either be a String (for example, an "int[]"
) or a type object (such as Java.type("int[]")
).
Valid target types are Java arrays.
When the target type is omitted, it defaults to Object[]
.
var jsArray = ["a", "b", "c"];
var stringArrayType = Java.type("java.lang.String[]");
var javaArray = Java.to(jsArray, stringArrayType);
assertEquals('class java.lang.String[]', String(javaArray.getClass()));
var javaArray = Java.to(jsArray);
assertEquals('class java.lang.Object[]', String(javaArray.getClass()));
The conversion methods as defined by ECMAScript (for example, ToString
and ToDouble
) are executed when a JavaScript value has to be converted to a Java type.
Lossy conversion is disallowed and results in a TypeError
.
- returns
true
ifobj
is a Java host object - returns
false
for native JavaScript objects, as well as for objects of other polyglot languages
- returns
true
ifobj
is an object representing the constructor and static members of a Java class, as obtained byJava.type()
or package objects. - returns
false
for all other arguments
- returns the Java
Class
name ofobj
whenobj
represents a Java type (isType(obj) === true
) or JavaClass
instance - returns
undefined
otherwise
- returns whether
fn
is an object of the Java language that represents a Java function - returns
false
for all other types, including native JavaScript function, and functions of other polyglot languages
This function is only available in Nashorn compatibility mode (
--js.nashorn-compat=true
).
- returns whether
obj
is an object of the JavaScript language - returns
false
for all other types, including objects of Java and other polyglot languages
This function is only available in Nashorn compatibility mode (
--js.nashorn-compat=true
).
- returns whether
fn
is a JavaScript function - returns
false
for all other types, including Java function, and functions of other polyglot languages
This function is only available in Nashorn compatibility mode (
--js.nashorn-compat=true
).
- adds the specified location (a
.jar
file or directory path string) to Java's classpath
The functions of the Polyglot
object allow to interact with values from other polyglot languages.
The Polyglot
object is available by default, unless deactivated by setting the js.polyglot-builtin
option to false
.
- exports the JavaScript
value
under the namekey
(a string) to the polyglot bindings:
function helloWorld() { print("Hello, JavaScript world"); }
Polyglot.export("helloJSWorld", helloWorld);
If the polyglot bindings already had a value identified by key
, it is overwritten with the new value.
The value
may be any valid Polyglot value.
- throws a
TypeError
ifkey
is not a String or is missing
- imports the value identified by
key
(a string) from the polyglot bindings and returns it:
var rubyHelloWorld = Polyglot.import("helloRubyWorld");
rubyHelloWorld();
If no language has exported a value identified by key
, undefined
is returned.
- throws a
TypeError
ifkey
is not a string or missing
- parses and evaluates the
sourceCode
with the interpreter identified bylanguageId
The value of sourceCode
is expected to be a String (or convertible to one).
- returns the evaluation result, depending on the
sourceCode
and/or the semantics of the language evaluated:
var pyArray = Polyglot.eval('python', 'import random; [random.uniform(0.0, 1.0) for _ in range(1000)]');
Exceptions can occur when an invalid languageId
is passed, when the sourceCode
cannot be evaluated by the language, or when the executed program throws one.
- parses the file
sourceFileName
with the interpreter identified bylanguageId
The value of sourceFileName
is expected to be a String (or convertible to one), representing a file reachable by the current path.
- returns an executable object, typically a function:
var rFunc = Polyglot.evalFile('R', 'myExample.r');
var result = rFunc();
Exceptions can occur when an invalid languageId
is passed, when the file identified by sourceFileName
cannot be found, or when the language throws an exception during parsing (parse time errors, for example, syntax errors).
Exceptions thrown by the evaluated program are only thrown once the resulting function is evaluated.
The Polyglot.evalFile
function is available by default when the Polyglot
builtin is available, unless deactivated by setting the js.polyglot-evalfile
option to false
.
It is also available when js.debug-builtin
is activated.
- requires starting the engine with the
js.debug-builtin
option
Debug
is a GraalJS specific function object that provides functionality for debugging JavaScript code and the JavaScript engine.
This API might change without notice. Do not use for production purposes.
- behaves identically to
print
The only difference is that the error stream is used to print to, instead of the default output stream.
- behaves similarly to
load
function
The relevant difference is that the code is evaluated in a new global scope (Realm, as defined by ECMAScript).
Source can be of type:
java.lang.URL
: the URL is queried for the source code to execute.- a JavaScript object: the object is queried for a
name
and ascript
property. - all other types: the source is converted to a String.
The value of arguments
is provided to the loaded code upon execution.