To allow efficient single-pass validation and avoid semantic corner cases with FFI calls, ValidateCall currently requires all callsites to be explicitly coerced. This coercion determines the expected return type of the callee:
f()|0 for signed,
+f() for double,
fround(f()) for float32,
(…, f(), …) for void.
Of course, this coercion isn’t necessary for stdlib functions, whose return types are locally determined by the name of the callee and types of arguments. Incorporating SIMD.js into asm.js makes this wart much more noticeable since all SIMD operations are stdlib calls.
The proposed change here (landed in Firefox 34) is to drop this requirement for all stdlib functions. Since stdlib functions can now be used without coercion, some of their signatures change to reflect the range of the value returned before coercion (previous signatures reflected the range of the value after coercion):
- The signed overload of
Math.abs now returns unsigned (instead of signed)
- The float? overloads of
Math.ceil,floor,sqrt,abs now return floatish (instead of float)
Since the return types of stdlib functions are subtypes of the previously-required callsite coercions, this is a backwards-compatible change.
Sounds reasonable to me. Dropping extraneous syntax requirements is good and in these cases shouldn’t have any adverse effects on readability (I agree that the opposite is likely!), and the return type changes seem correct.
abs appears twice in that list?
There are float, int, and double signatures for Math.abs. As I understand it, both float and int abs are affected, but not double.
That’s right. Updated the list to be more explicit.
Is there any gain besides saving a few characters? If not, then I’d prefer not having yet more special-casing like this.
(That is, I disagree with Tab: dropping extraneous syntax requirements is not good if it creates more irregularity. There needs to be a strong reason.)
The advantage is SIMD.js-in-asm.js is really, unpleasantly verbose otherwise, and this is something we actually expect people to read/write by hand.
Edit: I also meant to ask: does this irregularity cause any trouble for TF? I would’ve naturally assumed that TF wouldn’t care whether these coercions were present or not.
Oops, there is a bug in the spec as posted: the integer overload of Math.min/max should take ‘signed’ (and continue to return ‘signed’) (since min/max only perform ToNumber, not ToInt32, on arguments).
My thoughts on this are that, if we require coercions on SIMD calls, then it means a bunch of extra function calls. This would be harmful mostly for engines not using the asm.js type system (with the type system the calls go away immediately). With ints and doubles we have just
+, so it at least isn’t a call - so this becomes more important with SIMD.
To avoid those extra calls, we can either special-case SIMD, or drop the requirement for all stdlib callees. So in that sense, dropping for all stdlib callees makes things more consistent, at least compared to the option of doing it only for SIMD.