diff --git a/src/builtins.ts b/src/builtins.ts index a824506d..86d7528b 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -640,55 +640,80 @@ export function compileCall( case TypeKind.I8: case TypeKind.I16: case TypeKind.I32: { + let currentFunction = compiler.currentFunction; + // possibly overflows, e.g. abs(-128) == 128 - let tempLocal = compiler.currentFunction.getAndFreeTempLocal(Type.i32, false); - ret = module.createSelect( // x > 0 ? x : 0-x - module.createTeeLocal(tempLocal.index, arg0), - module.createBinary(BinaryOp.SubI32, // ifFalse - module.createI32(0), - module.createGetLocal(tempLocal.index, NativeType.I32) + let tempLocal1 = currentFunction.getTempLocal(Type.i32, false); + let tempLocalIndex2 = currentFunction.getAndFreeTempLocal(Type.i32, false).index; + let tempLocalIndex1 = tempLocal1.index; + + // (x + (x >> 31)) ^ (x >> 31) + ret = module.createBinary(BinaryOp.XorI32, + module.createBinary(BinaryOp.AddI32, + module.createTeeLocal( + tempLocalIndex2, + module.createBinary(BinaryOp.ShrI32, + module.createTeeLocal(tempLocalIndex1, arg0), + module.createI32(31) + ) + ), + module.createGetLocal(tempLocalIndex1, NativeType.I32) ), - module.createBinary(BinaryOp.GtI32, - module.createGetLocal(tempLocal.index, NativeType.I32), - module.createI32(0) - ) + module.createGetLocal(tempLocalIndex2, NativeType.I32) ); + + currentFunction.freeTempLocal(tempLocal1); break; } case TypeKind.ISIZE: { - let tempLocal = compiler.currentFunction.getAndFreeTempLocal(compiler.options.usizeType, false); - ret = module.createSelect( - module.createTeeLocal(tempLocal.index, arg0), - module.createBinary( - compiler.options.isWasm64 - ? BinaryOp.SubI64 - : BinaryOp.SubI32, - compiler.options.usizeType.toNativeZero(module), - module.createGetLocal(tempLocal.index, compiler.options.nativeSizeType) + let options = compiler.options; + let currentFunction = compiler.currentFunction; + let wasm64 = options.isWasm64; + + let tempLocal1 = currentFunction.getTempLocal(options.usizeType, false); + let tempLocalIndex2 = currentFunction.getAndFreeTempLocal(options.usizeType, false).index; + let tempLocalIndex1 = tempLocal1.index; + + ret = module.createBinary(wasm64 ? BinaryOp.XorI64 : BinaryOp.XorI32, + module.createBinary(wasm64 ? BinaryOp.AddI64 : BinaryOp.AddI32, + module.createTeeLocal( + tempLocalIndex2, + module.createBinary(wasm64 ? BinaryOp.ShrI64 : BinaryOp.ShrI32, + module.createTeeLocal(tempLocalIndex1, arg0), + wasm64 ? module.createI64(63) : module.createI32(31) + ) + ), + module.createGetLocal(tempLocalIndex1, options.nativeSizeType) ), - module.createBinary( - compiler.options.isWasm64 - ? BinaryOp.GtI64 - : BinaryOp.GtI32, - module.createGetLocal(tempLocal.index, compiler.options.nativeSizeType), - compiler.options.usizeType.toNativeZero(module) - ) + module.createGetLocal(tempLocalIndex2, options.nativeSizeType) ); + + currentFunction.freeTempLocal(tempLocal1); break; } case TypeKind.I64: { - let tempLocal = compiler.currentFunction.getAndFreeTempLocal(Type.i64, false); - ret = module.createSelect( - module.createTeeLocal(tempLocal.index, arg0), - module.createBinary(BinaryOp.SubI64, - module.createI64(0, 0), - module.createGetLocal(tempLocal.index, NativeType.I64), + let currentFunction = compiler.currentFunction; + + let tempLocal1 = currentFunction.getTempLocal(Type.i64, false); + let tempLocalIndex2 = currentFunction.getAndFreeTempLocal(Type.i64, false).index; + let tempLocalIndex1 = tempLocal1.index; + + // (x + (x >> 63)) ^ (x >> 63) + ret = module.createBinary(BinaryOp.XorI64, + module.createBinary(BinaryOp.AddI64, + module.createTeeLocal( + tempLocalIndex2, + module.createBinary(BinaryOp.ShrI64, + module.createTeeLocal(tempLocalIndex1, arg0), + module.createI64(63) + ) + ), + module.createGetLocal(tempLocalIndex1, NativeType.I64) ), - module.createBinary(BinaryOp.GtI64, - module.createGetLocal(tempLocal.index, NativeType.I64), - module.createI64(0, 0) - ) + module.createGetLocal(tempLocalIndex2, NativeType.I64) ); + + currentFunction.freeTempLocal(tempLocal1); break; } case TypeKind.USIZE: { diff --git a/tests/compiler/builtins.untouched.wat b/tests/compiler/builtins.untouched.wat index 9615986f..b0a1d268 100644 --- a/tests/compiler/builtins.untouched.wat +++ b/tests/compiler/builtins.untouched.wat @@ -318,13 +318,13 @@ drop i32.const -42 tee_local $0 - i32.const 0 + i32.const 31 + i32.shr_s + tee_local $1 get_local $0 - i32.sub - get_local $0 - i32.const 0 - i32.gt_s - select + i32.add + get_local $1 + i32.xor drop i32.const 1 tee_local $0 @@ -363,13 +363,13 @@ set_global $builtins/i i32.const -42 tee_local $0 - i32.const 0 + i32.const 31 + i32.shr_s + tee_local $1 get_local $0 - i32.sub - get_local $0 - i32.const 0 - i32.gt_s - select + i32.add + get_local $1 + i32.xor set_global $builtins/i get_global $builtins/i i32.const 42 @@ -444,13 +444,13 @@ drop i64.const -42 tee_local $2 - i64.const 0 + i64.const 63 + i64.shr_s + tee_local $3 get_local $2 - i64.sub - get_local $2 - i64.const 0 - i64.gt_s - select + i64.add + get_local $3 + i64.xor drop i64.const 1 i64.clz @@ -471,13 +471,13 @@ set_global $builtins/I i64.const -42 tee_local $2 - i64.const 0 + i64.const 63 + i64.shr_s + tee_local $3 get_local $2 - i64.sub - get_local $2 - i64.const 0 - i64.gt_s - select + i64.add + get_local $3 + i64.xor set_global $builtins/I get_global $builtins/I i64.const 42 diff --git a/tests/compiler/std/string.optimized.wat b/tests/compiler/std/string.optimized.wat index 8c6dae3f..1c6be7d3 100644 --- a/tests/compiler/std/string.optimized.wat +++ b/tests/compiler/std/string.optimized.wat @@ -349,7 +349,6 @@ else get_local $3 end - tee_local $0 if get_local $3 i32.const 1 @@ -563,12 +562,10 @@ unreachable end get_local $1 - i32.eqz - if - i32.const 200 - set_local $1 - end + i32.const 200 get_local $1 + select + tee_local $1 i32.load tee_local $4 i32.eqz @@ -632,15 +629,12 @@ (local $4 i32) (local $5 i32) loop $continue|0 + get_local $1 + i32.const 3 + i32.and get_local $2 - if (result i32) - get_local $1 - i32.const 3 - i32.and - else - get_local $2 - end - tee_local $3 + get_local $2 + select if get_local $0 tee_local $4 @@ -732,14 +726,14 @@ i32.add i32.load i32.store - get_local $0 - i32.const 8 - i32.add - set_local $0 get_local $1 i32.const 8 i32.add set_local $1 + get_local $0 + i32.const 8 + i32.add + set_local $0 end get_local $2 i32.const 4 @@ -749,14 +743,14 @@ get_local $1 i32.load i32.store - get_local $0 - i32.const 4 - i32.add - set_local $0 get_local $1 i32.const 4 i32.add set_local $1 + get_local $0 + i32.const 4 + i32.add + set_local $0 end get_local $2 i32.const 2 @@ -766,21 +760,19 @@ get_local $1 i32.load16_u i32.store16 - get_local $0 - i32.const 2 - i32.add - set_local $0 get_local $1 i32.const 2 i32.add set_local $1 + get_local $0 + i32.const 2 + i32.add + set_local $0 end get_local $2 i32.const 1 i32.and if - get_local $1 - set_local $3 get_local $0 get_local $1 i32.load8_u @@ -1523,8 +1515,6 @@ i32.const 1 i32.and if - get_local $1 - set_local $3 get_local $0 get_local $1 i32.load8_u @@ -1591,7 +1581,6 @@ set_local $2 get_local $0 tee_local $4 - tee_local $3 i32.const 1 i32.add set_local $0 @@ -1637,7 +1626,6 @@ if get_local $0 tee_local $4 - tee_local $3 i32.const 1 i32.add set_local $0 @@ -2192,16 +2180,14 @@ call $~lib/env/abort unreachable end - get_local $1 - i32.eqz - if - i32.const 200 - set_local $1 - end get_local $0 i32.load set_local $3 get_local $1 + i32.const 200 + get_local $1 + select + tee_local $1 i32.load tee_local $4 i32.eqz @@ -2719,16 +2705,14 @@ call $~lib/env/abort unreachable end - get_local $1 - i32.eqz - if - i32.const 200 - set_local $1 - end get_local $0 i32.load tee_local $3 get_local $1 + i32.const 200 + get_local $1 + select + tee_local $1 i32.load tee_local $4 i32.add @@ -2756,12 +2740,9 @@ ) (func $~lib/string/String.__concat (; 26 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) get_local $0 - i32.eqz - if - i32.const 200 - set_local $0 - end + i32.const 200 get_local $0 + select get_local $1 call $~lib/string/String#concat ) @@ -2948,7 +2929,6 @@ end get_local $0 i32.eqz - tee_local $1 if i32.const 0 return @@ -3104,7 +3084,6 @@ i32.lt_s select end - tee_local $1 get_local $4 i32.sub tee_local $2 @@ -3596,27 +3575,26 @@ if i32.const 1 call $~lib/array/Array#constructor - tee_local $4 + tee_local $6 i32.load get_local $0 i32.store offset=8 - get_local $4 + get_local $6 return end get_local $0 i32.load set_local $3 - get_local $1 - i32.load - set_local $8 + i32.const 2147483647 + get_local $2 get_local $2 i32.const 0 i32.lt_s - if - i32.const 2147483647 - set_local $2 - end - get_local $8 + select + set_local $2 + get_local $1 + i32.load + tee_local $9 if get_local $3 i32.eqz @@ -3633,7 +3611,6 @@ return end get_local $3 - tee_local $4 get_local $2 get_local $3 get_local $2 @@ -3641,7 +3618,7 @@ select tee_local $3 call $~lib/array/Array#constructor - tee_local $4 + tee_local $6 i32.load set_local $7 i32.const 0 @@ -3675,23 +3652,23 @@ br $repeat|0 end end - get_local $4 + get_local $6 return end i32.const 0 call $~lib/array/Array#constructor - set_local $5 + set_local $4 loop $continue|1 get_local $0 get_local $1 - get_local $6 + get_local $5 call $~lib/string/String#indexOf - tee_local $9 + tee_local $8 i32.const -1 i32.ne if - get_local $9 - get_local $6 + get_local $8 + get_local $5 i32.sub tee_local $7 i32.const 0 @@ -3699,18 +3676,18 @@ if get_local $7 call $~lib/internal/string/allocateUnsafe - tee_local $4 + tee_local $6 i32.const 0 get_local $0 - get_local $6 + get_local $5 get_local $7 call $~lib/internal/string/copyUnsafe - get_local $5 get_local $4 + get_local $6 call $~lib/array/Array#push drop else - get_local $5 + get_local $4 i32.const 256 call $~lib/array/Array#push drop @@ -3722,17 +3699,17 @@ get_local $2 i32.eq if - get_local $5 + get_local $4 return end get_local $8 get_local $9 i32.add - set_local $6 + set_local $5 br $continue|1 end end - get_local $6 + get_local $5 i32.eqz if i32.const 1 @@ -3745,7 +3722,7 @@ return end get_local $3 - get_local $6 + get_local $5 i32.sub tee_local $1 i32.const 0 @@ -3756,20 +3733,20 @@ tee_local $2 i32.const 0 get_local $0 - get_local $6 + get_local $5 get_local $1 call $~lib/internal/string/copyUnsafe - get_local $5 + get_local $4 get_local $2 call $~lib/array/Array#push drop else - get_local $5 + get_local $4 i32.const 256 call $~lib/array/Array#push drop end - get_local $5 + get_local $4 ) (func $~lib/string/String#split|trampoline (; 41 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) @@ -4212,19 +4189,21 @@ i32.const 480 return end - get_local $0 - i64.const 0 - i64.lt_s - tee_local $1 - if - i64.const 0 + block (result i32) get_local $0 - i64.sub - set_local $0 + i64.const 0 + i64.lt_s + tee_local $1 + if + i64.const 0 + get_local $0 + i64.sub + set_local $0 + end + get_local $0 + i64.const 4294967295 + i64.le_u end - get_local $0 - i64.const 4294967295 - i64.le_u if get_local $0 i32.wrap/i64 @@ -4584,93 +4563,91 @@ i64.and tee_local $1 get_local $5 - i64.lt_u - if (result i32) - get_global $~lib/internal/number/_K - get_local $9 - i32.add - set_global $~lib/internal/number/_K - get_local $12 - i32.const 0 - get_local $9 - i32.sub - i32.const 2 - i32.shl - i32.add - i64.load32_u offset=8 + i64.ge_u + br_if $continue|3 + get_global $~lib/internal/number/_K + get_local $9 + i32.add + set_global $~lib/internal/number/_K + get_local $12 + i32.const 0 + get_local $9 + i32.sub + i32.const 2 + i32.shl + i32.add + i64.load32_u offset=8 + get_local $8 + i64.mul + set_local $8 + get_local $6 + i32.const 1 + i32.sub + i32.const 1 + i32.shl + get_local $0 + i32.add + tee_local $7 + i32.load16_u offset=4 + set_local $4 + loop $continue|4 + get_local $1 get_local $8 - i64.mul - set_local $8 - get_local $6 - i32.const 1 - i32.sub - i32.const 1 - i32.shl - get_local $0 - i32.add - tee_local $7 - i32.load16_u offset=4 - set_local $4 - loop $continue|4 + i64.lt_u + tee_local $2 + if + get_local $5 get_local $1 + i64.sub + get_local $10 + i64.ge_u + set_local $2 + end + get_local $2 + if + get_local $1 + get_local $10 + i64.add get_local $8 i64.lt_u tee_local $2 + i32.eqz if - get_local $5 + get_local $8 get_local $1 i64.sub - get_local $10 - i64.ge_u - set_local $2 - end - get_local $2 - if get_local $1 get_local $10 i64.add get_local $8 - i64.lt_u - tee_local $2 - i32.eqz - if - get_local $8 - get_local $1 - i64.sub - get_local $1 - get_local $10 - i64.add - get_local $8 - i64.sub - i64.gt_u - set_local $2 - end - end - get_local $2 - if - get_local $4 - i32.const 1 - i32.sub - set_local $4 - get_local $1 - get_local $10 - i64.add - set_local $1 - br $continue|4 + i64.sub + i64.gt_u + set_local $2 end end - get_local $7 - get_local $4 - i32.store16 offset=4 - get_local $6 - else - br $continue|3 + get_local $2 + if + get_local $4 + i32.const 1 + i32.sub + set_local $4 + get_local $1 + get_local $10 + i64.add + set_local $1 + br $continue|4 + end end + get_local $7 + get_local $4 + i32.store16 offset=4 + get_local $6 end ) (func $~lib/internal/number/prettify (; 51 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) + (local $5 i32) get_local $2 i32.eqz if @@ -4690,11 +4667,11 @@ get_local $1 get_local $2 i32.add - tee_local $4 + tee_local $5 i32.le_s tee_local $3 if - get_local $4 + get_local $5 i32.const 21 i32.le_s set_local $3 @@ -4706,7 +4683,7 @@ loop $repeat|0 block $break|0 get_local $3 - get_local $4 + get_local $5 i32.ge_s br_if $break|0 get_local $3 @@ -4723,40 +4700,41 @@ br $repeat|0 end end - get_local $4 + get_local $5 i32.const 1 i32.shl get_local $0 i32.add i32.const 3145774 i32.store offset=4 - get_local $4 + get_local $5 i32.const 2 i32.add else - get_local $4 + get_local $5 i32.const 0 i32.gt_s tee_local $3 if - get_local $4 + get_local $5 i32.const 21 i32.le_s set_local $3 end get_local $3 if (result i32) - get_local $4 + get_local $5 i32.const 1 i32.shl get_local $0 i32.add tee_local $3 - i32.const 6 - i32.add - get_local $3 i32.const 4 i32.add + tee_local $0 + i32.const 2 + i32.add + get_local $0 i32.const 0 get_local $2 i32.sub @@ -4771,11 +4749,11 @@ i32.add else i32.const -6 - get_local $4 + get_local $5 i32.lt_s tee_local $3 if - get_local $4 + get_local $5 i32.const 0 i32.le_s set_local $3 @@ -4785,16 +4763,15 @@ get_local $0 i32.const 4 i32.add + tee_local $2 i32.const 2 - get_local $4 + get_local $5 i32.sub tee_local $3 i32.const 1 i32.shl i32.add - get_local $0 - i32.const 4 - i32.add + get_local $2 get_local $1 i32.const 1 i32.shl @@ -4803,24 +4780,24 @@ i32.const 3014704 i32.store offset=4 i32.const 2 - set_local $2 + set_local $4 loop $repeat|1 block $break|1 - get_local $2 + get_local $4 get_local $3 i32.ge_s br_if $break|1 - get_local $2 + get_local $4 i32.const 1 i32.shl get_local $0 i32.add i32.const 48 i32.store16 offset=4 - get_local $2 + get_local $4 i32.const 1 i32.add - set_local $2 + set_local $4 br $repeat|1 end end @@ -4838,48 +4815,52 @@ get_local $0 i32.const 4 i32.add - set_local $3 - get_local $4 - i32.const 1 - i32.sub - tee_local $2 - i32.const 0 - i32.lt_s - tee_local $0 - if - i32.const 0 - get_local $2 + tee_local $3 + block (result i32) + get_local $5 + i32.const 1 i32.sub - set_local $2 + tee_local $4 + i32.const 0 + i32.lt_s + tee_local $2 + if + i32.const 0 + get_local $4 + i32.sub + set_local $4 + end + get_local $4 end - get_local $3 - get_local $2 - get_local $2 + get_local $4 call $~lib/internal/number/decimalCount32 i32.const 1 i32.add - tee_local $2 + tee_local $4 call $~lib/internal/number/utoa32_lut get_local $3 i32.const 45 i32.const 43 - get_local $0 + get_local $2 select i32.store16 offset=4 - get_local $2 + get_local $4 i32.const 2 i32.add else get_local $0 - i32.const 8 + i32.const 4 i32.add - get_local $0 - i32.const 6 + tee_local $3 + i32.const 4 + i32.add + get_local $3 + i32.const 2 i32.add get_local $1 i32.const 1 i32.shl - tee_local $2 + tee_local $4 i32.const 2 i32.sub call $~lib/internal/memory/memmove @@ -4887,7 +4868,7 @@ i32.const 46 i32.store16 offset=6 get_local $0 - get_local $2 + get_local $4 i32.add tee_local $0 i32.const 101 @@ -4895,36 +4876,37 @@ get_local $0 i32.const 4 i32.add - set_local $3 - get_local $4 - i32.const 1 - i32.sub - tee_local $2 - i32.const 0 - i32.lt_s - tee_local $0 - if - i32.const 0 - get_local $2 + tee_local $3 + block (result i32) + get_local $5 + i32.const 1 i32.sub - set_local $2 + tee_local $4 + i32.const 0 + i32.lt_s + tee_local $2 + if + i32.const 0 + get_local $4 + i32.sub + set_local $4 + end + get_local $4 end - get_local $3 - get_local $2 - get_local $2 + get_local $4 call $~lib/internal/number/decimalCount32 i32.const 1 i32.add - tee_local $2 + tee_local $0 call $~lib/internal/number/utoa32_lut get_local $3 i32.const 45 i32.const 43 - get_local $0 + get_local $2 select i32.store16 offset=4 + get_local $0 get_local $1 - get_local $2 i32.add i32.const 2 i32.add @@ -4937,8 +4919,8 @@ (local $2 i64) (local $3 i64) (local $4 i32) - (local $5 i32) - (local $6 i64) + (local $5 i64) + (local $6 i32) (local $7 i64) (local $8 i32) (local $9 i64) @@ -4952,15 +4934,15 @@ f64.const 0 f64.lt tee_local $13 - if - get_local $1 - f64.neg - set_local $1 + if (result f64) get_local $0 i32.const 45 i32.store16 offset=4 + get_local $1 + f64.neg + else + get_local $1 end - get_local $1 i64.reinterpret/f64 tee_local $2 i64.const 9218868437227405312 @@ -4975,7 +4957,7 @@ get_local $8 i32.const 0 i32.ne - tee_local $5 + tee_local $6 i64.extend_u/i32 i64.const 52 i64.shl @@ -4983,24 +4965,24 @@ set_local $2 get_local $8 i32.const 1 - get_local $5 + get_local $6 select i32.const 1075 i32.sub tee_local $8 i32.const 1 i32.sub - set_local $5 + set_local $6 get_local $2 i64.const 1 i64.shl i64.const 1 i64.add - tee_local $6 + tee_local $5 i64.clz i32.wrap/i64 set_local $4 - get_local $6 + get_local $5 get_local $4 i64.extend_s/i32 i64.shl @@ -5019,15 +5001,15 @@ get_local $8 get_local $14 i32.sub - get_local $5 + get_local $6 get_local $4 i32.sub - tee_local $5 + tee_local $6 i32.sub i64.extend_s/i32 i64.shl set_global $~lib/internal/number/_frc_minus - get_local $5 + get_local $6 set_global $~lib/internal/number/_exp i32.const 348 i32.const -61 @@ -5050,7 +5032,7 @@ i32.shr_s i32.const 1 i32.add - tee_local $5 + tee_local $6 i32.const 3 i32.shl i32.sub @@ -5060,14 +5042,14 @@ set_local $4 i32.const 4312 i32.load - get_local $5 + get_local $6 i32.const 3 i32.shl i32.add i64.load offset=8 set_global $~lib/internal/number/_frc_pow get_local $4 - get_local $5 + get_local $6 i32.const 1 i32.shl i32.add @@ -5085,13 +5067,13 @@ i64.and tee_local $7 get_global $~lib/internal/number/_frc_pow - tee_local $6 + tee_local $5 i64.const 4294967295 i64.and tee_local $9 i64.mul set_local $10 - get_local $6 + get_local $5 i64.const 32 i64.shr_u tee_local $11 @@ -5111,7 +5093,6 @@ i64.const 4294967295 i64.and i64.add - tee_local $2 i64.const 2147483647 i64.add i64.const 32 @@ -5125,7 +5106,7 @@ i64.add i64.add set_local $2 - get_local $6 + get_local $5 i64.const 4294967295 i64.and tee_local $11 @@ -5137,7 +5118,7 @@ i64.mul set_local $7 get_local $10 - get_local $6 + get_local $5 i64.const 32 i64.shr_u tee_local $9 @@ -5156,7 +5137,6 @@ i64.const 4294967295 i64.and i64.add - tee_local $7 i64.const 2147483647 i64.add i64.const 32 @@ -5175,13 +5155,13 @@ i64.const 4294967295 i64.and tee_local $7 - get_local $6 + get_local $5 i64.const 4294967295 i64.and tee_local $9 i64.mul set_local $10 - get_local $6 + get_local $5 i64.const 32 i64.shr_u tee_local $11 @@ -5201,7 +5181,7 @@ i64.const 4294967295 i64.and i64.add - set_local $6 + set_local $5 get_local $15 i64.const 1 i64.sub @@ -5213,7 +5193,7 @@ i64.const 32 i64.shr_u i64.add - get_local $6 + get_local $5 i64.const 2147483647 i64.add i64.const 32 @@ -5238,7 +5218,6 @@ i32.add i32.const -64 i32.sub - tee_local $5 get_local $7 get_local $4 get_global $~lib/internal/number/_exp @@ -5315,14 +5294,14 @@ get_local $4 i32.eqz tee_local $2 - if + if (result i32) get_local $0 i32.load get_local $1 i32.eq - set_local $2 + else + get_local $2 end - get_local $2 if get_local $0 return @@ -5850,7 +5829,8 @@ unreachable end get_global $std/string/str - get_global $std/string/str + tee_local $0 + get_local $0 i32.const 0 call $~lib/string/String#indexOf if @@ -6903,7 +6883,7 @@ i32.const 1 i32.eq tee_local $0 - if + if (result i32) i32.const 0 get_global $std/string/sa i32.load @@ -6918,12 +6898,11 @@ else unreachable end - tee_local $0 i32.const 256 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -6960,7 +6939,7 @@ i32.const 1 i32.eq tee_local $0 - if + if (result i32) i32.const 0 get_global $std/string/sa i32.load @@ -6975,12 +6954,11 @@ else unreachable end - tee_local $0 i32.const 256 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7001,7 +6979,7 @@ i32.const 1 i32.eq tee_local $0 - if + if (result i32) i32.const 0 get_global $std/string/sa i32.load @@ -7016,12 +6994,11 @@ else unreachable end - tee_local $0 i32.const 1216 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7037,56 +7014,58 @@ i32.const 432 call $~lib/string/String#split|trampoline set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 3 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 3 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if + if (result i32) i32.const 2 get_global $std/string/sa i32.load @@ -7103,12 +7082,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7124,56 +7102,58 @@ i32.const 1272 call $~lib/string/String#split|trampoline set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 3 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 3 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if + if (result i32) i32.const 2 get_global $std/string/sa i32.load @@ -7190,12 +7170,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7211,79 +7190,82 @@ i32.const 432 call $~lib/string/String#split|trampoline set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 4 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 4 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end + get_local $0 + end + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 2 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 8 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 256 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if - i32.const 2 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 8 - i32.add - i32.load offset=8 - else - unreachable - end - tee_local $0 - i32.const 256 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if + if (result i32) i32.const 3 get_global $std/string/sa i32.load @@ -7300,12 +7282,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7321,79 +7302,82 @@ i32.const 432 call $~lib/string/String#split|trampoline set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 4 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 4 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 256 + call $~lib/string/String.__eq + set_local $0 + end + get_local $0 + end + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 256 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 2 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 8 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if - i32.const 2 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 8 - i32.add - i32.load offset=8 - else - unreachable - end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if + if (result i32) i32.const 3 get_global $std/string/sa i32.load @@ -7410,12 +7394,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7431,79 +7414,82 @@ i32.const 432 call $~lib/string/String#split|trampoline set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 4 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 4 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end + get_local $0 + end + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 2 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 8 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 1240 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if - i32.const 2 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 8 - i32.add - i32.load offset=8 - else - unreachable - end - tee_local $0 - i32.const 1240 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if + if (result i32) i32.const 3 get_global $std/string/sa i32.load @@ -7520,12 +7506,11 @@ else unreachable end - tee_local $0 i32.const 256 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7541,56 +7526,58 @@ i32.const 256 call $~lib/string/String#split|trampoline set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 3 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 3 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if + if (result i32) i32.const 2 get_global $std/string/sa i32.load @@ -7607,12 +7594,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7647,7 +7633,7 @@ i32.const 1 i32.eq tee_local $0 - if + if (result i32) i32.const 0 get_global $std/string/sa i32.load @@ -7662,12 +7648,11 @@ else unreachable end - tee_local $0 i32.const 280 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7687,7 +7672,7 @@ i32.const 1 i32.eq tee_local $0 - if + if (result i32) i32.const 0 get_global $std/string/sa i32.load @@ -7702,12 +7687,11 @@ else unreachable end - tee_local $0 i32.const 280 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7722,56 +7706,58 @@ i32.const 4 call $~lib/string/String#split set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 3 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 3 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if + if (result i32) i32.const 2 get_global $std/string/sa i32.load @@ -7788,12 +7774,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7808,56 +7793,58 @@ i32.const -1 call $~lib/string/String#split set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 3 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 3 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if + if (result i32) i32.const 2 get_global $std/string/sa i32.load @@ -7874,12 +7861,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0 @@ -7894,56 +7880,58 @@ i32.const -1 call $~lib/string/String#split set_global $std/string/sa - get_global $std/string/sa - i32.load offset=4 - i32.const 3 - i32.eq - tee_local $0 - if - i32.const 0 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) + block (result i32) + block (result i32) + get_global $std/string/sa + i32.load offset=4 + i32.const 3 + i32.eq + tee_local $0 + if + i32.const 0 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.load offset=8 + else + unreachable + end + i32.const 280 + call $~lib/string/String.__eq + set_local $0 + end get_local $0 - i32.load offset=8 - else - unreachable end - tee_local $0 - i32.const 280 - call $~lib/string/String.__eq - set_local $0 - end - get_local $0 - if - i32.const 1 - get_global $std/string/sa - i32.load - tee_local $0 - i32.load - i32.const 2 - i32.shr_u - i32.lt_u - if (result i32) - get_local $0 - i32.const 4 - i32.add - i32.load offset=8 - else - unreachable + if + i32.const 1 + get_global $std/string/sa + i32.load + tee_local $0 + i32.load + i32.const 2 + i32.shr_u + i32.lt_u + if (result i32) + get_local $0 + i32.const 4 + i32.add + i32.load offset=8 + else + unreachable + end + i32.const 648 + call $~lib/string/String.__eq + set_local $0 end - tee_local $0 - i32.const 648 - call $~lib/string/String.__eq - set_local $0 + get_local $0 end - get_local $0 - if + if (result i32) i32.const 2 get_global $std/string/sa i32.load @@ -7960,12 +7948,11 @@ else unreachable end - tee_local $0 i32.const 1240 call $~lib/string/String.__eq - set_local $0 + else + get_local $0 end - get_local $0 i32.eqz if i32.const 0