-
-
Notifications
You must be signed in to change notification settings - Fork 677
Writing portable code
When targeting both WebAssembly with asc and JavaScript with tsc, there are a few semantic differences to take care of.
While asc understands the meaning of
// non-portable
let someFloat: f32 = 1.5;
let someInt: i32 = <i32>someFloat;and then inserts the correct conversion steps, tsc does not because all numeric types are just aliases of number. Hence, when targeting JavaScript with tsc, the above will result in
// js
var someFloat = 1.5;
var someInt = someFloat;which is obviously wrong. To account for this, explicit conversions can be inserted, resulting in actually portable code. For example
// portable
let someFloat: f32 = 1.5;
let someInt: i32 = (<i32>someFloat) | 0;will result in
// js
var someFloat = 1.5;
var someInt = 1.5 | 0;which is correct.
Additionally, an equally named portable conversion function is present for each built-in type that transforms any other built-in type to a value of the target type:
// using a portable conversion function
let someFloat: f32 = 1.5;
let someInt: i32 = i32(someFloat);Likewise, again because asc knows the meaning but tsc does not, overflows must be handled explicitly:
// non-portable
let someU8: u8 = 255;
let someOtherU8: u8 = someU8 + 1;// portable
let someU8: u8 = 255;
let someOtherU8: u8 = (someU8 + 1) & 0xff;// using a portable conversion function
let someU8: u8 = 255;
let someOtherU8: u8 = u8(someU8 + 1);In JavaScript, all numeric values are IEEE754 doubles that cannot represent the full range of values fitting in a 64-bit integer (max. safe integer is 2^53-1). Hence i64 and u64 are not portable and not present in std/portable.d.ts. There are several ways to deal with this. One is to use an i64 polyfill like in this example.
Other than that, some generic built-in functions do not support the full range of type arguments. For example:
-
load<
T = u8>(offset:usize):T- and - store<T = u8>(offset:usize, value:T):void
are limited tou8because the type argument cannot be evaluated in JS.