diff --git a/std/assembly/atomics.ts b/std/assembly/atomics.ts new file mode 100644 index 0000000000..d506624706 --- /dev/null +++ b/std/assembly/atomics.ts @@ -0,0 +1,117 @@ +import { ArrayBufferView } from "./arraybuffer"; +import { E_INDEXOUTOFRANGE } from "./util/error"; + +export namespace Atomics { + + // @ts-ignore: decorator + @inline + export function load(array: T, index: i32): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.load>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset + ); + } + + // @ts-ignore: decorator + @inline + export function store(array: T, index: i32, value: valueof): void { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + atomic.store>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + value + ); + } + + // @ts-ignore: decorator + @inline + export function add(array: T, index: i32, value: valueof): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.add>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + value + ); + } + + // @ts-ignore: decorator + @inline + export function sub(array: T, index: i32, value: valueof): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.sub>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + value + ); + } + + // @ts-ignore: decorator + @inline + export function and(array: T, index: i32, value: valueof): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.and>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + value + ); + } + + // @ts-ignore: decorator + @inline + export function or(array: T, index: i32, value: valueof): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.or>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + value + ); + } + + // @ts-ignore: decorator + @inline + export function xor(array: T, index: i32, value: valueof): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.xor>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + value + ); + } + + // @ts-ignore: decorator + @inline + export function exchange(array: T, index: i32, value: valueof): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.xchg>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + value + ); + } + + // @ts-ignore: decorator + @inline + export function compareExchange( + array: T, + index: i32, + expectedValue: valueof, + replacementValue: valueof + ): valueof { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.cmpxchg>( + changetype(array.buffer) + (index << alignof>()) + array.byteOffset, + expectedValue, + replacementValue + ); + } + + // @ts-ignore: decorator + @inline + export function wait(array: T, value: valueof, timeout: i64 = -1): AtomicWaitResult { + return atomic.wait>(changetype(array.buffer) + array.byteOffset, value, timeout); + } + + // @ts-ignore: decorator + @inline + export function notify(array: T, index: i32, count: i32 = -1): i32 { + if (index < 0 || (index << alignof>()) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); + return atomic.notify(changetype(array.buffer) + (index << alignof>()) + array.byteOffset, count); + } + + export function isLockFree(size: usize): bool { + return size == 1 || size == 2 || size == 4; + } +} diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index d72c008f0b..a841c2fde6 100644 --- a/std/assembly/index.d.ts +++ b/std/assembly/index.d.ts @@ -1116,6 +1116,22 @@ declare namespace table { export function copy(dest: u32, src: u32, n: u32): void; } +declare namespace Atomics { + export function load(array: TypedArray, index: i32): T; + export function store(array: TypedArray, index: i32, value: T): void; + export function add(array: TypedArray, index: i32, value: T): T; + export function sub(array: TypedArray, index: i32, value: T): T; + export function and(array: TypedArray, index: i32, value: T): T; + export function or(array: TypedArray, index: i32, value: T): T; + export function xor(array: TypedArray, index: i32, value: T): T; + export function exchange(array: TypedArray, index: i32, value: T): T; + export function compareExchange(array: TypedArray, index: i32, expectedValue: T, replacementValue: T): T; + export function wait(array: TypedArray, value: T, timeout?: i64): AtomicWaitResult; + export function notify(array: TypedArray, index: i32, count?: i32): i32; + /** The static Atomics.isLockFree() method is used to determine whether to use locks or atomic operations. It returns true, if the given size is one of the BYTES_PER_ELEMENT */ + export function isLockFree(size: usize): bool; +} + /** Class representing a generic, fixed-length raw binary data buffer. */ declare class ArrayBuffer { /** The size, in bytes, of the array. */ diff --git a/tests/compiler/builtins.optimized.wat b/tests/compiler/builtins.optimized.wat index 864f454e60..30087a8ee6 100644 --- a/tests/compiler/builtins.optimized.wat +++ b/tests/compiler/builtins.optimized.wat @@ -3,9 +3,9 @@ (type $FUNCSIG$if (func (param f32) (result i32))) (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$vii (func (param i32 i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) - (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$v (func)) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) @@ -74,7 +74,22 @@ (func $start:builtins~anonymous|0 (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) nop ) - (func $~lib/string/String#get:length (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (func $~lib/atomics/Atomics.isLockFree (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + i32.const 1 + local.get $0 + i32.const 4 + i32.eq + i32.const 1 + local.get $0 + i32.const 2 + i32.eq + local.get $0 + i32.const 1 + i32.eq + select + select + ) + (func $~lib/string/String#get:length (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 16 i32.sub @@ -82,7 +97,7 @@ i32.const 1 i32.shr_u ) - (func $~lib/util/string/compareImpl (; 8 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/util/string/compareImpl (; 9 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) local.get $0 @@ -162,7 +177,7 @@ end i32.const 0 ) - (func $~lib/string/String.__eq (; 9 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/string/String.__eq (; 10 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) local.get $0 local.get $1 @@ -194,13 +209,13 @@ end i32.const 0 ) - (func $start:builtins~anonymous|1 (; 10 ;) (type $FUNCSIG$v) + (func $start:builtins~anonymous|1 (; 11 ;) (type $FUNCSIG$v) nop ) - (func $start:builtins~anonymous|2 (; 11 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (func $start:builtins~anonymous|2 (; 12 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) nop ) - (func $start:builtins (; 12 ;) (type $FUNCSIG$v) + (func $start:builtins (; 13 ;) (type $FUNCSIG$v) i32.const 31 global.set $builtins/i i32.const 0 @@ -780,6 +795,82 @@ i32.const 8 f64.const 1 f64.store + i32.const 0 + call $~lib/atomics/Atomics.isLockFree + if + i32.const 0 + i32.const 64 + i32.const 427 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $~lib/atomics/Atomics.isLockFree + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 64 + i32.const 428 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $~lib/atomics/Atomics.isLockFree + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 64 + i32.const 429 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $~lib/atomics/Atomics.isLockFree + if + i32.const 0 + i32.const 64 + i32.const 430 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + call $~lib/atomics/Atomics.isLockFree + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 64 + i32.const 431 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 5 + call $~lib/atomics/Atomics.isLockFree + if + i32.const 0 + i32.const 64 + i32.const 432 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 8 + call $~lib/atomics/Atomics.isLockFree + if + i32.const 0 + i32.const 64 + i32.const 433 + i32.const 0 + call $~lib/builtins/abort + unreachable + end i32.const 104 i32.const 5 f64.const 0 @@ -795,7 +886,7 @@ if i32.const 0 i32.const 64 - i32.const 442 + i32.const 450 i32.const 2 call $~lib/builtins/abort unreachable @@ -807,7 +898,7 @@ if i32.const 0 i32.const 64 - i32.const 443 + i32.const 451 i32.const 2 call $~lib/builtins/abort unreachable @@ -819,7 +910,7 @@ if i32.const 0 i32.const 64 - i32.const 444 + i32.const 452 i32.const 2 call $~lib/builtins/abort unreachable @@ -831,7 +922,7 @@ if i32.const 0 i32.const 64 - i32.const 445 + i32.const 453 i32.const 2 call $~lib/builtins/abort unreachable @@ -843,7 +934,7 @@ if i32.const 0 i32.const 64 - i32.const 446 + i32.const 454 i32.const 2 call $~lib/builtins/abort unreachable @@ -855,7 +946,7 @@ if i32.const 0 i32.const 64 - i32.const 447 + i32.const 455 i32.const 2 call $~lib/builtins/abort unreachable @@ -867,7 +958,7 @@ if i32.const 0 i32.const 64 - i32.const 448 + i32.const 456 i32.const 2 call $~lib/builtins/abort unreachable @@ -879,7 +970,7 @@ if i32.const 0 i32.const 64 - i32.const 449 + i32.const 457 i32.const 2 call $~lib/builtins/abort unreachable @@ -891,7 +982,7 @@ if i32.const 0 i32.const 64 - i32.const 450 + i32.const 458 i32.const 2 call $~lib/builtins/abort unreachable @@ -903,7 +994,7 @@ if i32.const 0 i32.const 64 - i32.const 451 + i32.const 459 i32.const 2 call $~lib/builtins/abort unreachable @@ -915,7 +1006,7 @@ if i32.const 0 i32.const 64 - i32.const 452 + i32.const 460 i32.const 2 call $~lib/builtins/abort unreachable @@ -927,7 +1018,7 @@ if i32.const 0 i32.const 64 - i32.const 453 + i32.const 461 i32.const 2 call $~lib/builtins/abort unreachable @@ -939,7 +1030,7 @@ if i32.const 0 i32.const 64 - i32.const 454 + i32.const 462 i32.const 2 call $~lib/builtins/abort unreachable @@ -951,7 +1042,7 @@ if i32.const 0 i32.const 64 - i32.const 455 + i32.const 463 i32.const 2 call $~lib/builtins/abort unreachable @@ -963,7 +1054,7 @@ if i32.const 0 i32.const 64 - i32.const 456 + i32.const 464 i32.const 2 call $~lib/builtins/abort unreachable @@ -975,7 +1066,7 @@ if i32.const 0 i32.const 64 - i32.const 457 + i32.const 465 i32.const 2 call $~lib/builtins/abort unreachable @@ -987,7 +1078,7 @@ if i32.const 0 i32.const 64 - i32.const 458 + i32.const 466 i32.const 2 call $~lib/builtins/abort unreachable @@ -999,7 +1090,7 @@ if i32.const 0 i32.const 64 - i32.const 459 + i32.const 467 i32.const 2 call $~lib/builtins/abort unreachable @@ -1011,7 +1102,7 @@ if i32.const 0 i32.const 64 - i32.const 460 + i32.const 468 i32.const 2 call $~lib/builtins/abort unreachable @@ -1023,13 +1114,13 @@ if i32.const 0 i32.const 64 - i32.const 461 + i32.const 469 i32.const 2 call $~lib/builtins/abort unreachable end ) - (func $start (; 13 ;) (type $FUNCSIG$v) + (func $start (; 14 ;) (type $FUNCSIG$v) call $start:builtins ) ) diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts index 01878a9f4f..93db59d2da 100644 --- a/tests/compiler/builtins.ts +++ b/tests/compiler/builtins.ts @@ -424,6 +424,14 @@ f64.store(8, 1.0); f32.trunc(1.0); f64.trunc(1.0); +assert(Atomics.isLockFree(0) == false); +assert(Atomics.isLockFree(1) == true); +assert(Atomics.isLockFree(2) == true); +assert(Atomics.isLockFree(3) == false); +assert(Atomics.isLockFree(4) == true); +assert(Atomics.isLockFree(5) == false); +assert(Atomics.isLockFree(8) == false); + { let a = idof<() => void>(); let b = idof<() => void>(); diff --git a/tests/compiler/builtins.untouched.wat b/tests/compiler/builtins.untouched.wat index 264c1b3009..ad1b718054 100644 --- a/tests/compiler/builtins.untouched.wat +++ b/tests/compiler/builtins.untouched.wat @@ -3,9 +3,9 @@ (type $FUNCSIG$if (func (param f32) (result i32))) (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$vii (func (param i32 i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) - (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$iiiiii (func (param i32 i32 i32 i32 i32) (result i32))) (type $FUNCSIG$v (func)) @@ -108,13 +108,32 @@ (func $start:builtins~anonymous|0 (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) nop ) - (func $~lib/rt/stub/__retain (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (func $~lib/atomics/Atomics.isLockFree (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 + i32.const 1 + i32.eq + if (result i32) + i32.const 1 + else + local.get $0 + i32.const 2 + i32.eq + end + if (result i32) + i32.const 1 + else + local.get $0 + i32.const 4 + i32.eq + end + ) + (func $~lib/rt/stub/__retain (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 ) - (func $~lib/rt/stub/__release (; 8 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $~lib/rt/stub/__release (; 9 ;) (type $FUNCSIG$vi) (param $0 i32) nop ) - (func $~lib/string/String#get:length (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (func $~lib/string/String#get:length (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 16 i32.sub @@ -122,7 +141,7 @@ i32.const 1 i32.shr_u ) - (func $~lib/util/string/compareImpl (; 10 ;) (type $FUNCSIG$iiiiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (func $~lib/util/string/compareImpl (; 11 ;) (type $FUNCSIG$iiiiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -242,7 +261,7 @@ call $~lib/rt/stub/__release local.get $8 ) - (func $~lib/string/String.__eq (; 11 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/string/String.__eq (; 12 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) local.get $0 @@ -315,13 +334,13 @@ call $~lib/rt/stub/__release local.get $2 ) - (func $start:builtins~anonymous|1 (; 12 ;) (type $FUNCSIG$v) + (func $start:builtins~anonymous|1 (; 13 ;) (type $FUNCSIG$v) nop ) - (func $start:builtins~anonymous|2 (; 13 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (func $start:builtins~anonymous|2 (; 14 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) nop ) - (func $start:builtins (; 14 ;) (type $FUNCSIG$v) + (func $start:builtins (; 15 ;) (type $FUNCSIG$v) (local $0 i32) (local $1 i32) (local $2 i64) @@ -1399,6 +1418,97 @@ f64.trunc drop i32.const 0 + call $~lib/atomics/Atomics.isLockFree + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 64 + i32.const 427 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $~lib/atomics/Atomics.isLockFree + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 64 + i32.const 428 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $~lib/atomics/Atomics.isLockFree + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 64 + i32.const 429 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $~lib/atomics/Atomics.isLockFree + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 64 + i32.const 430 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + call $~lib/atomics/Atomics.isLockFree + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 64 + i32.const 431 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 5 + call $~lib/atomics/Atomics.isLockFree + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 64 + i32.const 432 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 8 + call $~lib/atomics/Atomics.isLockFree + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 64 + i32.const 433 + i32.const 0 + call $~lib/builtins/abort + unreachable + end + i32.const 0 local.set $0 i32.const 0 local.set $1 @@ -1428,7 +1538,7 @@ if i32.const 144 i32.const 64 - i32.const 435 + i32.const 443 i32.const 2 call $~lib/builtins/abort unreachable @@ -1440,7 +1550,7 @@ if i32.const 0 i32.const 64 - i32.const 436 + i32.const 444 i32.const 2 call $~lib/builtins/abort unreachable @@ -1452,7 +1562,7 @@ if i32.const 0 i32.const 64 - i32.const 437 + i32.const 445 i32.const 2 call $~lib/builtins/abort unreachable @@ -1464,7 +1574,7 @@ if i32.const 0 i32.const 64 - i32.const 438 + i32.const 446 i32.const 2 call $~lib/builtins/abort unreachable @@ -1476,7 +1586,7 @@ if i32.const 0 i32.const 64 - i32.const 442 + i32.const 450 i32.const 2 call $~lib/builtins/abort unreachable @@ -1488,7 +1598,7 @@ if i32.const 0 i32.const 64 - i32.const 443 + i32.const 451 i32.const 2 call $~lib/builtins/abort unreachable @@ -1500,7 +1610,7 @@ if i32.const 0 i32.const 64 - i32.const 444 + i32.const 452 i32.const 2 call $~lib/builtins/abort unreachable @@ -1512,7 +1622,7 @@ if i32.const 0 i32.const 64 - i32.const 445 + i32.const 453 i32.const 2 call $~lib/builtins/abort unreachable @@ -1524,7 +1634,7 @@ if i32.const 0 i32.const 64 - i32.const 446 + i32.const 454 i32.const 2 call $~lib/builtins/abort unreachable @@ -1536,7 +1646,7 @@ if i32.const 0 i32.const 64 - i32.const 447 + i32.const 455 i32.const 2 call $~lib/builtins/abort unreachable @@ -1548,7 +1658,7 @@ if i32.const 0 i32.const 64 - i32.const 448 + i32.const 456 i32.const 2 call $~lib/builtins/abort unreachable @@ -1560,7 +1670,7 @@ if i32.const 0 i32.const 64 - i32.const 449 + i32.const 457 i32.const 2 call $~lib/builtins/abort unreachable @@ -1572,7 +1682,7 @@ if i32.const 0 i32.const 64 - i32.const 450 + i32.const 458 i32.const 2 call $~lib/builtins/abort unreachable @@ -1584,7 +1694,7 @@ if i32.const 0 i32.const 64 - i32.const 451 + i32.const 459 i32.const 2 call $~lib/builtins/abort unreachable @@ -1596,7 +1706,7 @@ if i32.const 0 i32.const 64 - i32.const 452 + i32.const 460 i32.const 2 call $~lib/builtins/abort unreachable @@ -1608,7 +1718,7 @@ if i32.const 0 i32.const 64 - i32.const 453 + i32.const 461 i32.const 2 call $~lib/builtins/abort unreachable @@ -1620,7 +1730,7 @@ if i32.const 0 i32.const 64 - i32.const 454 + i32.const 462 i32.const 2 call $~lib/builtins/abort unreachable @@ -1632,7 +1742,7 @@ if i32.const 0 i32.const 64 - i32.const 455 + i32.const 463 i32.const 2 call $~lib/builtins/abort unreachable @@ -1644,7 +1754,7 @@ if i32.const 0 i32.const 64 - i32.const 456 + i32.const 464 i32.const 2 call $~lib/builtins/abort unreachable @@ -1656,7 +1766,7 @@ if i32.const 0 i32.const 64 - i32.const 457 + i32.const 465 i32.const 2 call $~lib/builtins/abort unreachable @@ -1668,7 +1778,7 @@ if i32.const 0 i32.const 64 - i32.const 458 + i32.const 466 i32.const 2 call $~lib/builtins/abort unreachable @@ -1680,7 +1790,7 @@ if i32.const 0 i32.const 64 - i32.const 459 + i32.const 467 i32.const 2 call $~lib/builtins/abort unreachable @@ -1692,7 +1802,7 @@ if i32.const 0 i32.const 64 - i32.const 460 + i32.const 468 i32.const 2 call $~lib/builtins/abort unreachable @@ -1704,18 +1814,18 @@ if i32.const 0 i32.const 64 - i32.const 461 + i32.const 469 i32.const 2 call $~lib/builtins/abort unreachable end ) - (func $builtins/test (; 15 ;) (type $FUNCSIG$v) + (func $builtins/test (; 16 ;) (type $FUNCSIG$v) nop ) - (func $start (; 16 ;) (type $FUNCSIG$v) + (func $start (; 17 ;) (type $FUNCSIG$v) call $start:builtins ) - (func $null (; 17 ;) (type $FUNCSIG$v) + (func $null (; 18 ;) (type $FUNCSIG$v) ) )