Here is a description of the proposed changes to asm.js validation to incorporate ES7 SIMD.js. These changes have landed in Firefox Nightly but (along with SIMD.js) will not be released until SIMD.js has stabilized in TC39. Thus, we are definitely open to feedback, comments and suggestions concerning the validation rules. (For any discussion of SIMD.js itself; please go to the GitHub repo or es-discuss.)
The extension to asm.js validation is comprised of:
- New value types for SIMD expressions:
- int32x4, float32x4
- These vector types are not super/sub-types of anything:
- Since not a subtype of extern, vector types cannot be passed/returned from FFI (see topic)
- Other 16-byte SIMD vector types are being proposed (e.g. float64x2, int8x16). The rest of the proposal will stick to just int32x4, float32x4, though.
- New stdlib imports and global types for SIMD constructors and operations:
- SIMD constructor imports
stdlib.SIMD.(int32x4|float32x4)
are given types {int32x4ctor, float32x4ctor}, resp. - Ability to import SIMD operations off of SIMD constructors.
- Same link-time validation rules apply as with stdlib Math imports.
- For example,
var i4 = stdlib.SIMD.int32x4; var i4add = i4.add;
has signature (int32x4,int32x4)->int32x4. - Still working on the full list (will post later), but basically: everything in SIMD.js.
- New numeric literal form:
simdCtor(x,y,z,w)
- where
simdCtor
is a global of type {int32x4ctor, float32x4ctor}. - For int32x4ctor, x,y,z,w must each be int numeric literals
- For float32x4ctor, x,y,z,w must each be numeric literals (no fround coercion necessary/allowed)
- Can be used in return, variable, and global variable type annotations.
- New type annotation form:
check(…)
. - where
check
is a stdlib import of(int32x4ctor|float32x4).check
, an operation that throws if the operand is not already a value of the associated SIMD vector type, otherwise returning the operand unmodified. - Can be used for parameter, return, and global variable import type annotations.
- Can be used to provide the actual return type of a SIMD-returning function in ValidateCall.
- A new value type, “doublelit”, which is a subtype of double and the type given to numeric literals containing a decimal character.
- The reason for splitting double is to allow certain float32x4 SIMD ops to be passed double literals without requiring fround.
- For example, float32x4.splat has signature: float -> float32x4 ∧ doublit -> float32x4.
- The SIMD constructors can be called as stdlib functions:
- int32x4ctor has signature: (intish4)->int32x4
- float32x4ctor has signature: ((floatish + doublelit)4)->float32x4
- New dot-access expression forms:
-
expr.(x|y|z|w)
, whereexpr
has type {int32x4, float32x4} and the result type is {signed, float}, resp. -
expr.signMask
, whereexpr
has type {int32x4, float32x4} and the result type is signed
Here is an example asm.js module that uses these features:
function asmModule(stdlib, imports) {
"use asm";
var i4 = stdlib.SIMD.int32x4; // simd constructor
var i4c = i4.check; // used for type annotations
var i4add = i4.add; // import simd op
var g1 = i4c(imports.g1); // global var import
var g2 = i4(0,1,2,3); // global var initialized
function f(i,j) {
i = i|0;
j = i4c(j); // simd parameter
var k = i4(0,0,0,0); // simd local var
k = i4(i, i+1, i+2, i+3); // simd constructor call
k = i4add(j, k); // operation call
return i4c(k); // simd return
}
function g(i) {
i = i|0;
g2 = i4c(f(i, g1)); // simd-returning callsite
i = g2.w; // simd property access
return i|0;
}
return g
}
print(asmModule(this, {g1:SIMD.int32x4(9,9,9,9)})(5)); // 17
Again, comments welcome. Sorry for the liberties taken with mixed regex/set syntax. I will update the proposal in-place in response to discussion.