Skip to content
dherman edited this page Nov 6, 2012 · 3 revisions

Subtyping relation

This is the type poset for asm.js:

lattice

The white boxes are types that can be exposed to external JavaScript; the gray boxes are types whose values cannot escape asm.js. The important properties of the gray types are:

  • their behavior is still completely correct when interpreted as regular JS
  • they can be given an internal representation in an optimizing JS engine that loses information that would be needed for general JS

The extern type

This is the base type of values that are allowed to escape into external JavaScript.

The boolish type

The boolish type elides the difference between what would ordinarily be JavaScript booleans and JavaScript numbers. Because these values are only observed in conditionals, their behavior is consistent with JavaScript (0 is treated as false, everything else as true). But we can implement them uniformly as integers internally, regardless of which JS type they actually represent. As a result they cannot be allowed to escape, because they have lost the information of which JS type they really are.

The int type

This type represents a 32-bit integer whose sign is irrelevant and unknown. For asm.js internally, we don't track the sign of variables, parameters, or function results. Signs only show up on the types of particular arithmetic operations. The int type can't be exposed directly to JS, because JS distinguishes signed and unsigned values.

The intish type

This type represents the results of an integer operation that, in the JS semantics, can result in a non-integer (such as overflow on + or *, or floating-point results of /), but that results in the expected result of the integer operation when coerced via ToInt32 or ToUint32. This allows us to provide compositional type rules that deal separately with the integer operations (e.g., +) and their subsequent coercions (e.g., |0).

Variables, parameters, and function returns never have the type intish. As a result, the type is restricted from flowing into any context except an immediate coercion. This maintains the invariant that integer operations will always be immediately coerced back into the proper range.

The bit type

This is the type of boolean operations. It can be represented internally as an integer, because it does not escape into external JavaScript.

The unknown type

This is the type of the result of FFI function calls. Like intish (and in fact, because it is a subtype of intish), it can only be immediately coerced. This ensures that all dynamic JavaScript happens contiguously, so that any GC bookkeeping and register spilling and unspilling can happen in one single chunk of code, at the point where the FFI call is performed.

The double type

This is the straightforward 64-bit floating-point type. Note that int and double are unrelated by subtyping, so they can only be interconverted by explicit coercions.

The signed type

This is the type of signed 32-bit integers, which is needed to disambiguate some signed arithmetic and conditional operators from their unsigned counterparts.

The unsigned type

This is the type of unsigned 32-bit integers, which is needed to disambiguate some unsigned arithmetic and conditional operators from their signed counterparts.

The constant type

This is the type of literals, which are simultaneously usable as either signed or unsigned numbers, because the arithmetic and conditional operators can use the other operand to disambiguate between the signed and unsigned operation.

Clone this wiki locally