This document specifies the run-time semantics of the Scala.js IR (Intermediate Representation), typically abbreviated as SJSIR.
This specification is to be interpreted as an addition to the ECMAScript 2018 specification. It adds the definitions of abstract operations, internal methods, exotic objects, class definitions, statements and expressions necessary for the IR. In particular, to reduce duplication with the original specification, the SJSIR specification adds new alternatives for the
The current specification concerns a linked and typechecked SJSIR codebase. It does not describe typechecking rules, nor the behavior to apply in case a codebase does not link.
The SJSIR uses specific data types to store information about classes and types. Technically, they are all subsets of the ECMAScript Language Values, except SJSIR Classes, which are Records.
An SJSIR Class represents an SJSIR class at run-time, both its static definition and its run-time per-class state. An SJSIR Class is a
Attribute Name | Value Domain | Description |
---|---|---|
[[Environment]] |
|
The |
[[IsPrimitive]] | Boolean | Whether this class represents a primitive type. |
[[IsArray]] | Boolean | Whether this class represents an array type. |
[[Name]] | String |
The fully qualified name of the class, e.g., "java.lang.Object" or "java.io.Serializable" .
|
[[ClassDef]] |
|
The Parse Node of type |
[[Superclass]] |
|
The |
[[Interfaces]] |
|
The SJSIR Classes which are the directly implemented interfaces of this class, if any. |
[[ComponentClass]] |
|
If this class represents an array type, the class representing its elements. Otherwise, |
[[ArrayClass]] |
|
The unique, lazily create |
[[StaticFields]] | Object | Null |
An Object containing the values of the static fields of this class, or |
[[ClassOf]] | Object | Undefined |
The unique, lazily created instance of java.lang.Class representing this class.
|
[[JSClassValue]] | Object | Undefined |
The unique, lazily created class value for this top-level |
[[ModuleInstance]] | Object | Null | Undefined |
The unique, lazily created singleton instance of this |
When the abstract operation CreateSJSIRClassBase is called with a
When the abstract operation CreateSJSIRPrimitiveClass is called with a
When the abstract operation CreateSJSIRClass is called with a
null
).When the abstract operation CreateSJSIRArrayClass is called with a
"void"
, then"V"
."boolean"
, then"Z"
."char"
, then"C"
."byte"
, then"B"
."short"
, then"S"
."int"
, then"I"
."long"
, then"J"
."float"
, then"F"
."double"
, then"D"
."["
and componentName."["
and componentName."[L"
, componentName and ";"
."java.lang.Object"
)."java.lang.Cloneable"
)."java.io.Serializable"
).When the abstract operation SJSIRGetArrayClassOf is called with an
The abstract operation ToInt64 converts argument to one of 264 integer values in the range
The abstract operation ToFloat32 converts argument to a number that fits in the IEEE 754-2008 binary32 format. This abstract operation functions as follows:
This algorithm is equivalent to the one performed by the function Math.fround
When the abstract operation SJSIRIsSubclass is called with two SJSIR Classes class and otherClass, the following steps are taken:
"java.lang.Object"
) is When the abstract operation SJSIRIsValueOfClass is called with an ECMAScript Language Value value and an
class
, module class
or interface
."java.lang.Boolean"
,boolean
with argument value."java.lang.Character"
,char
with argument value."java.lang.Byte"
,byte
with argument value."java.lang.Short"
,short
with argument value."java.lang.Int"
,int
with argument value."java.lang.Long"
,long
with argument value."java.lang.Float"
,float
with argument value."java.lang.Double"
,double
with argument value."java.lang.String"
,string
with argument value."scala.runtime.BoxedUnit"
,undef
with argument value.The SJSIRIsValueOfClass abstract operation cannot be called with a class that represents a type that is not valid in an isInstanceOf
tree.
When the abstract operation SJSIRIsValueOfType is called with an ECMAScript Language Value value and a Parse Node of type
This operation tests whether value is a valid value for an expression that was typed as type. It is often used in Assertions that validate type soundness.
When the abstract operation SJSIRCreateClassDataOf is called with an
"name"
, class.[[Name]])."isPrimitive"
, class.[[IsPrimitive]])."isArrayClass"
, class.[[IsArray]])."isInterface"
, "isRawJSType"
, interface
, then"isInterface"
, "isRawJSType"
, class
or module class
, then"isInterface"
, "isRawJSType"
, "isInterface"
, "isRawJSType"
, "isInstance"
, isInstance)."isAssignableFrom"
, isAssignableFrom)."getSuperclass"
, getSuperclass)."getComponentType"
, getComponentType)."newArrayOfThisClass"
, newArrayOfThisClass).An IsInstance function is an anonymous built-in function with a [[Class]] internal slot. When an IsInstance function f is called with argument value it performs the following steps:
class
nor module class
nor interface
, thenAn IsAssignableFrom function is an anonymous built-in function without internal slot. When an IsAssignableFrom function f is called with argument otherData it performs the following steps:
A GetSuperclass function is an anonymous built-in function without internal slot. When a GetSuperclass function f that expects no arguments is called it performs the following steps:
A GetComponentType function is an anonymous built-in function without internal slot. When a GetComponentType function f that expects no arguments is called it performs the following steps:
A NewArrayOfThisClass function is an anonymous built-in function with a [[Class]] internal slot. When a NewArrayOfThisClass function f is called with argument lengths it performs the following steps:
int
) is When the abstract operation SJSIRClassOf is called with an
"java.lang.Class"
)."init___O"
and static.def
=
When the abstract operation SJSIRZeroOfClass is called with an
"Z"
), return "C"
), return "J"
), return When the abstract operation SJSIRLoadConstructorOf is called with an
native js class
, thenjs class
or js module class
.When the abstract operation SJSIRLoadModule is called with an
native js module class
, thenjs module class
, thenmodule class
."init___"
and static.def
=
When the abstract operation SJSIRLookupMethodInSuperclasses is called with an
When the abstract operation SJSIRFindAllDefaultImplementationsOfMethod is called with an
interface
, thenWhen the abstract operation SJSIRResolveMethod is called with an
interface
, thenclass
or module class
.When the abstract operation SJSIRResolveReflectiveMethod is called with an
class
or module class
.def
=
SJSIRResolveReflectiveMethod first performs a loose resolution algorithm to determine what is the exact method name from the reflective proxy name. Afterwards, it reruns an actual resolution using
When the abstract operation SJSIRResolveMemberExport is called with an
class
or module class
.When the abstract operation SJSIRResolveGlobalRef is called with a String name, the following steps are taken:
A JS Global
An SJSIR program Environment Record is a declarative
SJSIR program Environment Records have the additional state fields listed in
Field Name | Value | Meaning |
---|---|---|
[[LinkingInfo]] | Object |
The Object returned by the <linking-info> |
[[ClassTable]] |
|
|
SJSIR program Environment Records support all of the declarative
An SJSIR method Environment Record is a declarative this
binding.
SJSIR method Environment Records have the additional state fields listed in
Field Name | Value | Meaning |
---|---|---|
[[ThisValue]] | Any |
This is the |
[[IsStatic]] | Boolean |
If |
SJSIR method Environment Records support all of the declarative
Method | Purpose |
---|---|
GetThisBinding() |
Return the value of this this binding.
|
The behaviour of the additional concrete specification methods for SJSIR method Environment Records is defined by the following algorithms:
"static"
.The following abstract operations are used in this specification to operate upon lexical environments:
When the abstract operation CreateSJSIRLinkingInfo is called with an ECMAScript Language Value as argument globalThis, the following steps are performed:
"asInstanceOfs"
, asInstanceOfs)."arrayIndexOutOfBounds"
, arrayIndexOutOfBounds)."moduleInit"
, moduleInit)."strictFloats"
, strictFloats)."productionMode"
, productionMode)."frozen"
)."semantics"
, semantics)."assumingES6"
, assumingES6)."linkerVersion"
, linkerVersion)."globalThis"
, globalThis)."frozen"
).When the abstract operation NewSJSIRProgramEnvironment is called with a
When the abstract operation FindSJSIRProgramEnv is called with a
FindSJSIRProgramEnv must not be called if there is no
When the abstract operation GetSJSIRLinkingInfo is called with a
When the abstract operation GetSJSIRClass is called with a
When the abstract operation RegisterSJSIRClass is called with a
When the abstract operation NewSJSIRMethodEnvironment is called with arguments E and thisValue, the following steps are performed:
The ResolveSJSIRLinkingInfo abstract operation is get the linking info of the current SJSIR program. During execution of ECMAScript code, ResolveSJSIRLinkingInfo is performed using the following algorithm:
The
An SJSIR Scala object is an exotic object that belongs to an
SJSIR Scala objects have the internal slots listed in
Internal Slot | Type | Description |
---|---|---|
[[SJSIRClass]] |
|
The class of this object, as specified when it was instantiated. |
[[Extensible]] | Boolean |
Whether this object is extensible.
Note that this internal slot is only used by [[IsExtensible]] and [[PreventExtensions]], and does not actually affect whether it is allowed to alter the properties of an |
SJSIR Scala exotic objects provide alternative definitions for all of the internal methods.
When the [[GetPrototypeOf]] internal method of an SJSIR Scala exotic object O is called, the following steps are taken:
The above specification allows some algorithms such as
When the [[SetPrototypeOf]] internal method of an SJSIR Scala exotic object O is called with argument V, the following steps are taken:
When the [[IsExtensible]] internal method of an SJSIR Scala exotic object O is called, the following steps are taken:
When the [[PreventExtensions]] internal method of an SJSIR Scala exotic object O is called, the following steps are taken:
When the [[GetOwnProperty]] internal method of an SJSIR Scala exotic object O is called with property key P, the following steps are taken:
When the [[DefineOwnProperty]] internal method of an SJSIR Scala exotic object O is called with property key P and
When the [[HasProperty]] internal method of an SJSIR Scala exotic object O is called with property key P, the following steps are taken:
When the [[Get]] internal method of an SJSIR Scala exotic object O is called with property key P and
char
) is long
) is A CharToString function is an anonymous built-in function with a [[Target]] internal slot. When a CharToString function f that expects no argument is called it performs the following steps:
A LongToString function is an anonymous built-in function with a [[Target]] internal slot. When a LongToString function f that expects no argument is called it performs the following steps:
"-"
and str.
When the [[Set]] internal method of an SJSIR Scala exotic object O is called with property key P, value V, and
char
) is long
) is When the [[Delete]] internal method of an SJSIR Scala exotic object O is called with property key P, the following steps are taken:
When the [[OwnPropertyKeys]] internal method of an SJSIR Scala exotic object O is called, the following steps are taken:
When called with an argument class of type
"java.lang.Throwable"
).An SJSIR Array object is an
In addition to the internal slots SJSIR Scala objects, SJSIR Array objects have the internal slots listed in
Internal Slot | Type | Description |
---|---|---|
[[SJSIRArrayElements]] |
|
The elements stored in this array. |
When called with arguments componentClass of type
int
) is When called with arguments componentClass of type
When called with arguments componentClass of type
When called with argument O, the abstract operation SJSIRArrayClone performs the following steps:
An SJSIR Char object is similar to an char
. It has the same implementation for the essential methods, but not the same internal slots.
SJSIR Char objects have the internal slots listed in
Internal Slot | Type | Description |
---|---|---|
[[SJSIRCharValue]] | Number |
The numerical value of the code unit that this char represents.
|
[[Extensible]] | Boolean |
Whether this object is extensible.
Note that this internal slot is only used by [[IsExtensible]] and [[PreventExtensions]], and does not actually affect whether it is allowed to alter the properties of an |
When called with an argument charValue of type Number, the abstract operation CreateSJSIRCharObject performs the following steps:
An SJSIR Long object is similar to an long
. It has the same implementation for the essential methods, but not the same internal slots.
SJSIR Long objects have the internal slots listed in
Internal Slot | Type | Description |
---|---|---|
[[SJSIRLongValue]] | Mathematical integer value |
The value represented by this |
[[Extensible]] | Boolean |
Whether this object is extensible.
Note that this internal slot is only used by [[IsExtensible]] and [[PreventExtensions]], and does not actually affect whether it is allowed to alter the properties of an |
When called with an argument longValue that is a mathematical integer value, the abstract operation CreateSJSIRLongObject performs the following steps:
With parameter labelSet.
With parameter labelSet.
With parameters iterationSet and labelSet.
SJSIR programs cannot be written in ECMAScript Language Source Code, so their Syntax is an abstract syntax.
The algorithms in this specification assume that the
"void"
)."boolean"
)."char"
)."byte"
)."short"
)."int"
)."long"
)."float"
)."double"
).No matter how control leaves the
SJSIR types cannot be written in ECMAScript Language Source Code, so their Syntax is an abstract syntax.
"void"
, "boolean"
, "char"
, "byte"
, "short"
, "int"
, "long"
, "float"
, "double"
, ""
.
With parameter value.
With parameter value.
SJSIR class and member definitions cannot be written in ECMAScript Language Source Code, so their Syntax is an abstract syntax.
\
"import_"
and name.
"export_"
and name."*"
.
"*"
) is SJSIRImportName returns the StringValue of the first (most nested) "*"
if it is completely empty.
loadfrom
With parameters methodName and static.
"__"
, thenWith argument propName.
(
)
{
}
with propertyName, uniqueFormalParameters and body as children.static
is present, thenstatic
and methodDef.get
(
)
{
}
with propertyName, and getterBody as children.static
is present, thenstatic
and getterMethodDef.set
(
)
{
}
with propertyName, setterFormalParamList and setterBody as children.static
is present, thenstatic
and setterMethodDef.With argument obj and ignoreInnermost.
SJSIRLoadSpecPath : [empty]With parameter classDef.
With parameter class.
return
With parameters fieldName and newValue.
With parameters env, argList and listIndex.
Since there are no rest parameters in
With parameters receiver, argList and body.
With parameters receiver and argList.
With parameters programEnv and receiver.
return
The returned function is intended to be called with a
An implementation is allowed to return the same function object on successive calls to this operation.
With parameters programEnv, receiver and value.
With arguments obj and static.
static
is not present, return static
is present, return static
is not present, return static
is present, return With argument captureValues.
js class
or module js class
."derived"
."constructor"
, F).These steps mimic the steps of
In the Scala.js IR, statements and expressions are all part of a unique syntactic category of
SJSIR trees cannot be written in ECMAScript Language Source Code, so their Syntax is an abstract syntax.
No matter how control leaves the
this
KeywordThe else
branch of an if
statement.
If the declared type of the Labeled Block is void
, then the Value of the
The return
keyword of SJSIR is a halfbreed between ECMAScript's return
and break
: it breaks to a labeled block, but with a result value.
const
and whose int
) is debugger
StatementEvaluating a debugger
statement may allow an implementation to cause a breakpoint when run under a debugger. If a debugger is not present or active this statement has no observable effect.
def
=
This algorithm by-passes the [[Get]] internal method of obj, which would otherwise trigger an undefined behavior.
This algorithm by-passes the [[Set]] internal method of obj, which would otherwise trigger an undefined behavior.
When the SJSIRRepresentativeClass abstract operation is called with an ECMAScript Language Value V, the following steps are taken:
"java.lang.Boolean"
)."java.lang.Character"
)."java.lang.Double"
)."java.lang.Double"
is used for all non-long
numeric values."java.lang.Long"
)."java.lang.String"
)."scala.runtime.BoxedUnit"
)."java.lang.Object"
).
"toString__T"
) is "clone__O"
) is def
=
def
=
static
def
=
"clone__"
) is def
=
int
) is int
) is int
) is With arguments lval and rval.
The algorithm performs +
boolean
) is boolean
) is boolean
) is boolean
) is boolean
) is boolean
) is boolean
) is boolean
) is int
) is int
) is long
) is long
) is int
) is int
) is int
) is boolean
) is "java.lang.Boolean"
)).char
) is "java.lang.Character"
)).byte
) is "java.lang.Byte"
)).short
) is "java.lang.Short"
)).int
) is "java.lang.Integer"
)).float
) is "java.lang.Float"
)).double
) is "java.lang.Double"
)).long
) is "java.lang.Long"
)).string
) is "java.lang.String"
)).undef
) is "scala.runtime.BoxedUnit"
)).new
This algorithm mimics that of new
operator
This algorithm mimics that of delete
operator
This algorithm mimics that of
This algorithm mimics that of this
value will not be bound to the base value of ref, if any.
super
constructor callThis algorithm mimics that of super
callthis
has been bound to result, it creates the non-static fields of the enclosing class as data properties of result.
This algorithm delegates to the evaluation of typeof
and "undefined"
rather than throwing a
This algorithm delegates to the evaluation of &&
or ||
, short-circuiting applies.
constuctorOf
,
,
...
With parameter E.
return
The evaluation of an argument list produces a
This algorithm mimics that of the production :
[
]
of
"prototype"
, superCtorObj).There is a mismatch between the semantics of the first prototype
property of the enclosing class value). This algorithm solves this mismatch by creating a temporary homeObject whose prototype will be the value of the prototype
property of superCtor.
Ecma International
Rue du Rhone 114
CH-1204 Geneva
Tel: +41 22 849 6000
Fax: +41 22 849 6001
Web: https://ecma-international.org/
© 2018 Ecma International
This draft document may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published, and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this section are included on all such copies and derivative works. However, this document itself may not be modified in any way, including by removing the copyright notice or references to Ecma International, except as needed for the purpose of developing any document or deliverable produced by Ecma International.
This disclaimer is valid only prior to final version of this document. After approval all rights on the standard are reserved by Ecma International.
The limited permissions are granted through the standardization phase and will not be revoked by Ecma International or its successors or assigns during this time.
This document and the information contained herein is provided on an "AS IS" basis and ECMA INTERNATIONAL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.