From 0f2c98bd7d105a5ecb870eef05f6893bde38b840 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Thu, 29 May 2025 19:46:50 -0700 Subject: [PATCH 1/5] fix: support more types in switch statements --- src/compiler.ts | 45 +- tests/compiler/switch.debug.wat | 3578 ++++++++++++++++++++++++++++- tests/compiler/switch.release.wat | 1821 +++++++++++++++ tests/compiler/switch.ts | 176 +- 4 files changed, 5508 insertions(+), 112 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 29b73f2c69..5562c3256c 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -2816,19 +2816,48 @@ export class Compiler extends DiagnosticEmitter { let numCases = cases.length; // Compile the condition (always executes) - let condExpr = this.compileExpression(statement.condition, Type.u32, - Constraints.ConvImplicit - ); + let condExpr = this.compileExpression(statement.condition, Type.auto); + + // Get the type set from compiling the condition expression + let currentType = this.currentType; + + // Determine the binary operation to use for comparison + let binaryOp: BinaryOp; + switch (currentType.toRef()) { + case TypeRef.I32: { + binaryOp = BinaryOp.EqI32; + break; + } + case TypeRef.I64: { + binaryOp = BinaryOp.EqI64; + break; + } + case TypeRef.F32: { + binaryOp = BinaryOp.EqF32; + break; + } + case TypeRef.F64: { + binaryOp = BinaryOp.EqF64; + break; + } + default: { + this.error( + DiagnosticCode.Not_implemented_0, + statement.range, `Switch condition of type ${currentType}` + ); + return module.unreachable(); + } + } // Shortcut if there are no cases if (!numCases) return module.drop(condExpr); // Assign the condition to a temporary local as we compare it multiple times let outerFlow = this.currentFlow; - let tempLocal = outerFlow.getTempLocal(Type.u32); + let tempLocal = outerFlow.getTempLocal(currentType); let tempLocalIndex = tempLocal.index; let breaks = new Array(1 + numCases); - breaks[0] = module.local_set(tempLocalIndex, condExpr, false); // u32 + breaks[0] = module.local_set(tempLocalIndex, condExpr, currentType.isManaged); // Make one br_if per labeled case and leave it to Binaryen to optimize the // sequence of br_ifs to a br_table according to optimization levels @@ -2842,9 +2871,9 @@ export class Compiler extends DiagnosticEmitter { continue; } breaks[breakIndex++] = module.br(`case${i}|${label}`, - module.binary(BinaryOp.EqI32, - module.local_get(tempLocalIndex, TypeRef.I32), - this.compileExpression(assert(case_.label), Type.u32, + module.binary(binaryOp, + module.local_get(tempLocalIndex, currentType.toRef()), + this.compileExpression(assert(case_.label), currentType, Constraints.ConvImplicit ) ) diff --git a/tests/compiler/switch.debug.wat b/tests/compiler/switch.debug.wat index 6510f0aca7..5e88a056a5 100644 --- a/tests/compiler/switch.debug.wat +++ b/tests/compiler/switch.debug.wat @@ -1,13 +1,53 @@ (module (type $0 (func (param i32) (result i32))) - (type $1 (func)) - (type $2 (func (param i32 i32 i32 i32))) + (type $1 (func (param i32 i32))) + (type $2 (func (param i32))) + (type $3 (func)) + (type $4 (func (param i32 i32) (result i32))) + (type $5 (func (param i64) (result i32))) + (type $6 (func (param i32 i32 i32))) + (type $7 (func (param i32 i32 i32 i32))) + (type $8 (func (param f32) (result i32))) + (type $9 (func (param i32 i32 i64) (result i32))) + (type $10 (func (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) - (global $~lib/memory/__data_end i32 (i32.const 60)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 32828)) - (global $~lib/memory/__heap_base i32 (i32.const 32828)) + (global $switch/Foo.A i32 (i32.const 1)) + (global $switch/Foo.B i32 (i32.const 2)) + (global $switch/Foo.C i32 (i32.const 3)) + (global $switch/Foo.D i32 (i32.const 4)) + (global $~lib/rt/itcms/total (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/threshold (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/state (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/visitCount (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/pinSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/iter (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/toSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/white (mut i32) (i32.const 0)) + (global $~lib/shared/runtime/Runtime.Stub i32 (i32.const 0)) + (global $~lib/shared/runtime/Runtime.Minimal i32 (i32.const 1)) + (global $~lib/shared/runtime/Runtime.Incremental i32 (i32.const 2)) + (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) + (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) + (global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) + (global $~lib/rt/__rtti_base i32 (i32.const 592)) + (global $~lib/memory/__data_end i32 (i32.const 616)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33384)) + (global $~lib/memory/__heap_base i32 (i32.const 33384)) (memory $0 1) (data $0 (i32.const 12) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\12\00\00\00s\00w\00i\00t\00c\00h\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00") + (data $1 (i32.const 60) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\06\00\00\00o\00n\00e\00\00\00\00\00\00\00") + (data $2 (i32.const 92) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\06\00\00\00t\00w\00o\00\00\00\00\00\00\00") + (data $3 (i32.const 124) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\n\00\00\00t\00h\00r\00e\00e\00\00\00") + (data $4 (i32.const 156) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\08\00\00\00f\00o\00u\00r\00\00\00\00\00") + (data $5 (i32.const 188) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e\00\00\00\00\00") + (data $6 (i32.const 252) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $7 (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $8 (i32.const 352) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $9 (i32.const 380) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e\00\00\00\00\00\00\00\00\00") + (data $10 (i32.const 444) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00\00\00\00\00\00\00\00\00") + (data $11 (i32.const 496) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $12 (i32.const 524) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $13 (i32.const 592) "\05\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00") (table $0 1 1 funcref) (elem $0 (i32.const 1)) (export "memory" (memory $0)) @@ -50,6 +90,38 @@ i32.const 23 return ) + (func $switch/doSwitchDefaultFirst (param $n i32) (result i32) + (local $1 i32) + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i32.const 1 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case2|0 + local.get $1 + i32.const 3 + i32.eq + br_if $case3|0 + br $case0|0 + end + i32.const 0 + return + end + i32.const 1 + return + end + end + i32.const 23 + return + ) (func $switch/doSwitchDefaultOmitted (param $n i32) (result i32) (local $1 i32) block $break|0 @@ -155,410 +227,3718 @@ br $case1|0 end i32.const 1 - return + return + end + i32.const 2 + return + ) + (func $switch/doSwitchEmpty (param $n i32) (result i32) + local.get $n + drop + i32.const 2 + return + ) + (func $switch/doSwitchBoolean (param $b i32) (result i32) + (local $1 i32) + block $break|0 + block $case1|0 + block $case0|0 + local.get $b + local.set $1 + local.get $1 + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 0 + i32.eq + br_if $case1|0 + br $break|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchUInt32 (param $n i32) (result i32) + (local $1 i32) + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 3 + i32.eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 3 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchEnum (param $n i32) (result i32) + (local $1 i32) + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + global.get $switch/Foo.A + i32.eq + br_if $case0|0 + local.get $1 + global.get $switch/Foo.B + i32.eq + br_if $case1|0 + local.get $1 + global.get $switch/Foo.C + i32.eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 3 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchUint8 (param $n i32) (result i32) + (local $1 i32) + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 3 + i32.eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 3 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchFloat (param $n f32) (result i32) + (local $1 f32) + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + f32.const 1 + f32.eq + br_if $case0|0 + local.get $1 + f32.const 2 + f32.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchInt64 (param $n i64) (result i32) + (local $1 i64) + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i64.const 1 + i64.eq + br_if $case0|0 + local.get $1 + i64.const 2 + i64.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchUInt64 (param $n i64) (result i32) + (local $1 i64) + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i64.const 1 + i64.eq + br_if $case0|0 + local.get $1 + i64.const 2 + i64.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/FooClass#set:value (param $this i32) (param $value i32) + local.get $this + local.get $value + i32.store + ) + (func $~lib/rt/itcms/Object#set:nextWithColor (param $this i32) (param $nextWithColor i32) + local.get $this + local.get $nextWithColor + i32.store offset=4 + ) + (func $~lib/rt/itcms/Object#set:prev (param $this i32) (param $prev i32) + local.get $this + local.get $prev + i32.store offset=8 + ) + (func $~lib/rt/itcms/initLazy (param $space i32) (result i32) + local.get $space + local.get $space + call $~lib/rt/itcms/Object#set:nextWithColor + local.get $space + local.get $space + call $~lib/rt/itcms/Object#set:prev + local.get $space + return + ) + (func $~lib/rt/itcms/Object#get:nextWithColor (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/rt/itcms/Object#get:next (param $this i32) (result i32) + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.const -1 + i32.xor + i32.and + return + ) + (func $~lib/rt/itcms/Object#get:color (param $this i32) (result i32) + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.and + return + ) + (func $~lib/rt/itcms/visitRoots (param $cookie i32) + (local $pn i32) + (local $iter i32) + local.get $cookie + call $~lib/rt/__visit_globals + global.get $~lib/rt/itcms/pinSpace + local.set $pn + local.get $pn + call $~lib/rt/itcms/Object#get:next + local.set $iter + loop $while-continue|0 + local.get $iter + local.get $pn + i32.ne + if + i32.const 1 + drop + local.get $iter + call $~lib/rt/itcms/Object#get:color + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 272 + i32.const 160 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $iter + i32.const 20 + i32.add + local.get $cookie + call $~lib/rt/__visit_members + local.get $iter + call $~lib/rt/itcms/Object#get:next + local.set $iter + br $while-continue|0 + end + end + ) + (func $~lib/rt/itcms/Object#set:color (param $this i32) (param $color i32) + local.get $this + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $color + i32.or + call $~lib/rt/itcms/Object#set:nextWithColor + ) + (func $~lib/rt/itcms/Object#get:prev (param $this i32) (result i32) + local.get $this + i32.load offset=8 + ) + (func $~lib/rt/itcms/Object#set:next (param $this i32) (param $obj i32) + local.get $this + local.get $obj + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.and + i32.or + call $~lib/rt/itcms/Object#set:nextWithColor + ) + (func $~lib/rt/itcms/Object#unlink (param $this i32) + (local $next i32) + (local $prev i32) + local.get $this + call $~lib/rt/itcms/Object#get:next + local.set $next + local.get $next + i32.const 0 + i32.eq + if + i32.const 1 + drop + local.get $this + call $~lib/rt/itcms/Object#get:prev + i32.const 0 + i32.eq + if (result i32) + local.get $this + global.get $~lib/memory/__heap_base + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 272 + i32.const 128 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + return + end + local.get $this + call $~lib/rt/itcms/Object#get:prev + local.set $prev + i32.const 1 + drop + local.get $prev + i32.eqz + if + i32.const 0 + i32.const 272 + i32.const 132 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $next + local.get $prev + call $~lib/rt/itcms/Object#set:prev + local.get $prev + local.get $next + call $~lib/rt/itcms/Object#set:next + ) + (func $~lib/rt/itcms/Object#get:rtId (param $this i32) (result i32) + local.get $this + i32.load offset=12 + ) + (func $~lib/shared/typeinfo/Typeinfo#get:flags (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/__typeinfo (param $id i32) (result i32) + (local $ptr i32) + global.get $~lib/rt/__rtti_base + local.set $ptr + local.get $id + local.get $ptr + i32.load + i32.gt_u + if + i32.const 400 + i32.const 464 + i32.const 21 + i32.const 28 + call $~lib/builtins/abort + unreachable + end + local.get $ptr + i32.const 4 + i32.add + local.get $id + i32.const 4 + i32.mul + i32.add + call $~lib/shared/typeinfo/Typeinfo#get:flags + return + ) + (func $~lib/rt/itcms/Object#get:isPointerfree (param $this i32) (result i32) + (local $rtId i32) + local.get $this + call $~lib/rt/itcms/Object#get:rtId + local.set $rtId + local.get $rtId + i32.const 2 + i32.le_u + if (result i32) + i32.const 1 + else + local.get $rtId + call $~lib/rt/__typeinfo + i32.const 32 + i32.and + i32.const 0 + i32.ne + end + return + ) + (func $~lib/rt/itcms/Object#linkTo (param $this i32) (param $list i32) (param $withColor i32) + (local $prev i32) + local.get $list + call $~lib/rt/itcms/Object#get:prev + local.set $prev + local.get $this + local.get $list + local.get $withColor + i32.or + call $~lib/rt/itcms/Object#set:nextWithColor + local.get $this + local.get $prev + call $~lib/rt/itcms/Object#set:prev + local.get $prev + local.get $this + call $~lib/rt/itcms/Object#set:next + local.get $list + local.get $this + call $~lib/rt/itcms/Object#set:prev + ) + (func $~lib/rt/itcms/Object#makeGray (param $this i32) + (local $1 i32) + local.get $this + global.get $~lib/rt/itcms/iter + i32.eq + if + local.get $this + call $~lib/rt/itcms/Object#get:prev + local.tee $1 + i32.eqz + if (result i32) + i32.const 0 + i32.const 272 + i32.const 148 + i32.const 30 + call $~lib/builtins/abort + unreachable + else + local.get $1 + end + global.set $~lib/rt/itcms/iter + end + local.get $this + call $~lib/rt/itcms/Object#unlink + local.get $this + global.get $~lib/rt/itcms/toSpace + local.get $this + call $~lib/rt/itcms/Object#get:isPointerfree + if (result i32) + global.get $~lib/rt/itcms/white + i32.eqz + else + i32.const 2 + end + call $~lib/rt/itcms/Object#linkTo + ) + (func $~lib/rt/itcms/__visit (param $ptr i32) (param $cookie i32) + (local $obj i32) + local.get $ptr + i32.eqz + if + return + end + local.get $ptr + i32.const 20 + i32.sub + local.set $obj + i32.const 0 + drop + local.get $obj + call $~lib/rt/itcms/Object#get:color + global.get $~lib/rt/itcms/white + i32.eq + if + local.get $obj + call $~lib/rt/itcms/Object#makeGray + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.add + global.set $~lib/rt/itcms/visitCount + end + ) + (func $~lib/rt/itcms/visitStack (param $cookie i32) + (local $ptr i32) + global.get $~lib/memory/__stack_pointer + local.set $ptr + loop $while-continue|0 + local.get $ptr + global.get $~lib/memory/__heap_base + i32.lt_u + if + local.get $ptr + i32.load + local.get $cookie + call $~lib/rt/itcms/__visit + local.get $ptr + i32.const 4 + i32.add + local.set $ptr + br $while-continue|0 + end + end + ) + (func $~lib/rt/common/BLOCK#get:mmInfo (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/itcms/Object#get:size (param $this i32) (result i32) + i32.const 4 + local.get $this + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + return + ) + (func $~lib/rt/tlsf/Root#set:flMap (param $this i32) (param $flMap i32) + local.get $this + local.get $flMap + i32.store + ) + (func $~lib/rt/common/BLOCK#set:mmInfo (param $this i32) (param $mmInfo i32) + local.get $this + local.get $mmInfo + i32.store + ) + (func $~lib/rt/tlsf/Block#set:prev (param $this i32) (param $prev i32) + local.get $this + local.get $prev + i32.store offset=4 + ) + (func $~lib/rt/tlsf/Block#set:next (param $this i32) (param $next i32) + local.get $this + local.get $next + i32.store offset=8 + ) + (func $~lib/rt/tlsf/Block#get:prev (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/rt/tlsf/Block#get:next (param $this i32) (result i32) + local.get $this + i32.load offset=8 + ) + (func $~lib/rt/tlsf/Root#get:flMap (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/tlsf/removeBlock (param $root i32) (param $block i32) + (local $blockInfo i32) + (local $size i32) + (local $fl i32) + (local $sl i32) + (local $6 i32) + (local $7 i32) + (local $boundedSize i32) + (local $prev i32) + (local $next i32) + (local $root|11 i32) + (local $fl|12 i32) + (local $sl|13 i32) + (local $root|14 i32) + (local $fl|15 i32) + (local $sl|16 i32) + (local $head i32) + (local $root|18 i32) + (local $fl|19 i32) + (local $slMap i32) + (local $root|21 i32) + (local $fl|22 i32) + (local $slMap|23 i32) + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $blockInfo + i32.const 1 + drop + local.get $blockInfo + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 268 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.set $size + i32.const 1 + drop + local.get $size + i32.const 12 + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 270 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $size + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $fl + local.get $size + i32.const 4 + i32.shr_u + local.set $sl + else + local.get $size + local.tee $6 + i32.const 1073741820 + local.tee $7 + local.get $6 + local.get $7 + i32.lt_u + select + local.set $boundedSize + i32.const 31 + local.get $boundedSize + i32.clz + i32.sub + local.set $fl + local.get $boundedSize + local.get $fl + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $sl + local.get $fl + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $fl + end + i32.const 1 + drop + local.get $fl + i32.const 23 + i32.lt_u + if (result i32) + local.get $sl + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 284 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $block + call $~lib/rt/tlsf/Block#get:prev + local.set $prev + local.get $block + call $~lib/rt/tlsf/Block#get:next + local.set $next + local.get $prev + if + local.get $prev + local.get $next + call $~lib/rt/tlsf/Block#set:next + end + local.get $next + if + local.get $next + local.get $prev + call $~lib/rt/tlsf/Block#set:prev + end + local.get $block + block $~lib/rt/tlsf/GETHEAD|inlined.0 (result i32) + local.get $root + local.set $root|11 + local.get $fl + local.set $fl|12 + local.get $sl + local.set $sl|13 + local.get $root|11 + local.get $fl|12 + i32.const 4 + i32.shl + local.get $sl|13 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.0 + end + i32.eq + if + local.get $root + local.set $root|14 + local.get $fl + local.set $fl|15 + local.get $sl + local.set $sl|16 + local.get $next + local.set $head + local.get $root|14 + local.get $fl|15 + i32.const 4 + i32.shl + local.get $sl|16 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $head + i32.store offset=96 + local.get $next + i32.eqz + if + block $~lib/rt/tlsf/GETSL|inlined.0 (result i32) + local.get $root + local.set $root|18 + local.get $fl + local.set $fl|19 + local.get $root|18 + local.get $fl|19 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.0 + end + local.set $slMap + local.get $root + local.set $root|21 + local.get $fl + local.set $fl|22 + local.get $slMap + i32.const 1 + local.get $sl + i32.shl + i32.const -1 + i32.xor + i32.and + local.tee $slMap + local.set $slMap|23 + local.get $root|21 + local.get $fl|22 + i32.const 2 + i32.shl + i32.add + local.get $slMap|23 + i32.store offset=4 + local.get $slMap + i32.eqz + if + local.get $root + local.get $root + call $~lib/rt/tlsf/Root#get:flMap + i32.const 1 + local.get $fl + i32.shl + i32.const -1 + i32.xor + i32.and + call $~lib/rt/tlsf/Root#set:flMap + end + end + end + ) + (func $~lib/rt/tlsf/insertBlock (param $root i32) (param $block i32) + (local $blockInfo i32) + (local $block|3 i32) + (local $right i32) + (local $rightInfo i32) + (local $block|6 i32) + (local $block|7 i32) + (local $left i32) + (local $leftInfo i32) + (local $size i32) + (local $fl i32) + (local $sl i32) + (local $13 i32) + (local $14 i32) + (local $boundedSize i32) + (local $root|16 i32) + (local $fl|17 i32) + (local $sl|18 i32) + (local $head i32) + (local $root|20 i32) + (local $fl|21 i32) + (local $sl|22 i32) + (local $head|23 i32) + (local $root|24 i32) + (local $fl|25 i32) + (local $root|26 i32) + (local $fl|27 i32) + (local $slMap i32) + i32.const 1 + drop + local.get $block + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 201 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $blockInfo + i32.const 1 + drop + local.get $blockInfo + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 203 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETRIGHT|inlined.0 (result i32) + local.get $block + local.set $block|3 + local.get $block|3 + i32.const 4 + i32.add + local.get $block|3 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.0 + end + local.set $right + local.get $right + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $rightInfo + local.get $rightInfo + i32.const 1 + i32.and + if + local.get $root + local.get $right + call $~lib/rt/tlsf/removeBlock + local.get $block + local.get $blockInfo + i32.const 4 + i32.add + local.get $rightInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.tee $blockInfo + call $~lib/rt/common/BLOCK#set:mmInfo + block $~lib/rt/tlsf/GETRIGHT|inlined.1 (result i32) + local.get $block + local.set $block|6 + local.get $block|6 + i32.const 4 + i32.add + local.get $block|6 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.1 + end + local.set $right + local.get $right + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $rightInfo + end + local.get $blockInfo + i32.const 2 + i32.and + if + block $~lib/rt/tlsf/GETFREELEFT|inlined.0 (result i32) + local.get $block + local.set $block|7 + local.get $block|7 + i32.const 4 + i32.sub + i32.load + br $~lib/rt/tlsf/GETFREELEFT|inlined.0 + end + local.set $left + local.get $left + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $leftInfo + i32.const 1 + drop + local.get $leftInfo + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 221 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $root + local.get $left + call $~lib/rt/tlsf/removeBlock + local.get $left + local.set $block + local.get $block + local.get $leftInfo + i32.const 4 + i32.add + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.tee $blockInfo + call $~lib/rt/common/BLOCK#set:mmInfo + end + local.get $right + local.get $rightInfo + i32.const 2 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.set $size + i32.const 1 + drop + local.get $size + i32.const 12 + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 233 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + local.get $block + i32.const 4 + i32.add + local.get $size + i32.add + local.get $right + i32.eq + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 234 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $right + i32.const 4 + i32.sub + local.get $block + i32.store + local.get $size + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $fl + local.get $size + i32.const 4 + i32.shr_u + local.set $sl + else + local.get $size + local.tee $13 + i32.const 1073741820 + local.tee $14 + local.get $13 + local.get $14 + i32.lt_u + select + local.set $boundedSize + i32.const 31 + local.get $boundedSize + i32.clz + i32.sub + local.set $fl + local.get $boundedSize + local.get $fl + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $sl + local.get $fl + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $fl + end + i32.const 1 + drop + local.get $fl + i32.const 23 + i32.lt_u + if (result i32) + local.get $sl + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 251 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETHEAD|inlined.1 (result i32) + local.get $root + local.set $root|16 + local.get $fl + local.set $fl|17 + local.get $sl + local.set $sl|18 + local.get $root|16 + local.get $fl|17 + i32.const 4 + i32.shl + local.get $sl|18 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.1 + end + local.set $head + local.get $block + i32.const 0 + call $~lib/rt/tlsf/Block#set:prev + local.get $block + local.get $head + call $~lib/rt/tlsf/Block#set:next + local.get $head + if + local.get $head + local.get $block + call $~lib/rt/tlsf/Block#set:prev + end + local.get $root + local.set $root|20 + local.get $fl + local.set $fl|21 + local.get $sl + local.set $sl|22 + local.get $block + local.set $head|23 + local.get $root|20 + local.get $fl|21 + i32.const 4 + i32.shl + local.get $sl|22 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $head|23 + i32.store offset=96 + local.get $root + local.get $root + call $~lib/rt/tlsf/Root#get:flMap + i32.const 1 + local.get $fl + i32.shl + i32.or + call $~lib/rt/tlsf/Root#set:flMap + local.get $root + local.set $root|26 + local.get $fl + local.set $fl|27 + block $~lib/rt/tlsf/GETSL|inlined.1 (result i32) + local.get $root + local.set $root|24 + local.get $fl + local.set $fl|25 + local.get $root|24 + local.get $fl|25 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.1 + end + i32.const 1 + local.get $sl + i32.shl + i32.or + local.set $slMap + local.get $root|26 + local.get $fl|27 + i32.const 2 + i32.shl + i32.add + local.get $slMap + i32.store offset=4 + ) + (func $~lib/rt/tlsf/addMemory (param $root i32) (param $start i32) (param $endU64 i64) (result i32) + (local $end i32) + (local $root|4 i32) + (local $tail i32) + (local $tailInfo i32) + (local $size i32) + (local $leftSize i32) + (local $left i32) + (local $root|10 i32) + (local $tail|11 i32) + local.get $endU64 + i32.wrap_i64 + local.set $end + i32.const 1 + drop + local.get $start + i64.extend_i32_u + local.get $endU64 + i64.le_u + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 382 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $start + i32.const 4 + i32.add + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + i32.const 4 + i32.sub + local.set $start + local.get $end + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.set $end + block $~lib/rt/tlsf/GETTAIL|inlined.0 (result i32) + local.get $root + local.set $root|4 + local.get $root|4 + i32.load offset=1568 + br $~lib/rt/tlsf/GETTAIL|inlined.0 + end + local.set $tail + i32.const 0 + local.set $tailInfo + local.get $tail + if + i32.const 1 + drop + local.get $start + local.get $tail + i32.const 4 + i32.add + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 389 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $start + i32.const 16 + i32.sub + local.get $tail + i32.eq + if + local.get $start + i32.const 16 + i32.sub + local.set $start + local.get $tail + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $tailInfo + else + end + else + i32.const 1 + drop + local.get $start + local.get $root + i32.const 1572 + i32.add + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 402 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + local.get $end + local.get $start + i32.sub + local.set $size + local.get $size + i32.const 4 + i32.const 12 + i32.add + i32.const 4 + i32.add + i32.lt_u + if + i32.const 0 + return + end + local.get $size + i32.const 2 + i32.const 4 + i32.mul + i32.sub + local.set $leftSize + local.get $start + local.set $left + local.get $left + local.get $leftSize + i32.const 1 + i32.or + local.get $tailInfo + i32.const 2 + i32.and + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $left + i32.const 0 + call $~lib/rt/tlsf/Block#set:prev + local.get $left + i32.const 0 + call $~lib/rt/tlsf/Block#set:next + local.get $start + i32.const 4 + i32.add + local.get $leftSize + i32.add + local.set $tail + local.get $tail + i32.const 0 + i32.const 2 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $root + local.set $root|10 + local.get $tail + local.set $tail|11 + local.get $root|10 + local.get $tail|11 + i32.store offset=1568 + local.get $root + local.get $left + call $~lib/rt/tlsf/insertBlock + i32.const 1 + return + ) + (func $~lib/rt/tlsf/initialize + (local $rootOffset i32) + (local $pagesBefore i32) + (local $pagesNeeded i32) + (local $root i32) + (local $root|4 i32) + (local $tail i32) + (local $fl i32) + (local $root|7 i32) + (local $fl|8 i32) + (local $slMap i32) + (local $sl i32) + (local $root|11 i32) + (local $fl|12 i32) + (local $sl|13 i32) + (local $head i32) + (local $memStart i32) + i32.const 0 + drop + global.get $~lib/memory/__heap_base + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.set $rootOffset + memory.size + local.set $pagesBefore + local.get $rootOffset + i32.const 1572 + i32.add + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $pagesNeeded + local.get $pagesNeeded + local.get $pagesBefore + i32.gt_s + if (result i32) + local.get $pagesNeeded + local.get $pagesBefore + i32.sub + memory.grow + i32.const 0 + i32.lt_s + else + i32.const 0 + end + if + unreachable + end + local.get $rootOffset + local.set $root + local.get $root + i32.const 0 + call $~lib/rt/tlsf/Root#set:flMap + local.get $root + local.set $root|4 + i32.const 0 + local.set $tail + local.get $root|4 + local.get $tail + i32.store offset=1568 + i32.const 0 + local.set $fl + loop $for-loop|0 + local.get $fl + i32.const 23 + i32.lt_u + if + local.get $root + local.set $root|7 + local.get $fl + local.set $fl|8 + i32.const 0 + local.set $slMap + local.get $root|7 + local.get $fl|8 + i32.const 2 + i32.shl + i32.add + local.get $slMap + i32.store offset=4 + i32.const 0 + local.set $sl + loop $for-loop|1 + local.get $sl + i32.const 16 + i32.lt_u + if + local.get $root + local.set $root|11 + local.get $fl + local.set $fl|12 + local.get $sl + local.set $sl|13 + i32.const 0 + local.set $head + local.get $root|11 + local.get $fl|12 + i32.const 4 + i32.shl + local.get $sl|13 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $head + i32.store offset=96 + local.get $sl + i32.const 1 + i32.add + local.set $sl + br $for-loop|1 + end + end + local.get $fl + i32.const 1 + i32.add + local.set $fl + br $for-loop|0 + end + end + local.get $rootOffset + i32.const 1572 + i32.add + local.set $memStart + i32.const 0 + drop + local.get $root + local.get $memStart + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + drop + local.get $root + global.set $~lib/rt/tlsf/ROOT + ) + (func $~lib/rt/tlsf/checkUsedBlock (param $ptr i32) (result i32) + (local $block i32) + local.get $ptr + i32.const 4 + i32.sub + local.set $block + local.get $ptr + i32.const 0 + i32.ne + if (result i32) + local.get $ptr + i32.const 15 + i32.and + i32.eqz + else + i32.const 0 + end + if (result i32) + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 1 + i32.and + i32.eqz + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 562 + i32.const 3 + call $~lib/builtins/abort + unreachable + end + local.get $block + return + ) + (func $~lib/rt/tlsf/freeBlock (param $root i32) (param $block i32) + i32.const 0 + drop + local.get $block + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 1 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $root + local.get $block + call $~lib/rt/tlsf/insertBlock + ) + (func $~lib/rt/tlsf/__free (param $ptr i32) + local.get $ptr + global.get $~lib/memory/__heap_base + i32.lt_u + if + return + end + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.get $ptr + call $~lib/rt/tlsf/checkUsedBlock + call $~lib/rt/tlsf/freeBlock + ) + (func $~lib/rt/itcms/free (param $obj i32) + local.get $obj + global.get $~lib/memory/__heap_base + i32.lt_u + if + local.get $obj + i32.const 0 + call $~lib/rt/itcms/Object#set:nextWithColor + local.get $obj + i32.const 0 + call $~lib/rt/itcms/Object#set:prev + else + global.get $~lib/rt/itcms/total + local.get $obj + call $~lib/rt/itcms/Object#get:size + i32.sub + global.set $~lib/rt/itcms/total + i32.const 0 + drop + local.get $obj + i32.const 4 + i32.add + call $~lib/rt/tlsf/__free + end + ) + (func $~lib/rt/itcms/step (result i32) + (local $obj i32) + (local $1 i32) + (local $black i32) + (local $from i32) + block $break|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/rt/itcms/state + local.set $1 + local.get $1 + i32.const 0 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 1 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case2|0 + br $break|0 + end + i32.const 1 + global.set $~lib/rt/itcms/state + i32.const 0 + global.set $~lib/rt/itcms/visitCount + i32.const 0 + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/iter + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.mul + return + end + global.get $~lib/rt/itcms/white + i32.eqz + local.set $black + global.get $~lib/rt/itcms/iter + call $~lib/rt/itcms/Object#get:next + local.set $obj + loop $while-continue|1 + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $obj + global.set $~lib/rt/itcms/iter + local.get $obj + call $~lib/rt/itcms/Object#get:color + local.get $black + i32.ne + if + local.get $obj + local.get $black + call $~lib/rt/itcms/Object#set:color + i32.const 0 + global.set $~lib/rt/itcms/visitCount + local.get $obj + i32.const 20 + i32.add + i32.const 0 + call $~lib/rt/__visit_members + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.mul + return + end + local.get $obj + call $~lib/rt/itcms/Object#get:next + local.set $obj + br $while-continue|1 + end + end + i32.const 0 + global.set $~lib/rt/itcms/visitCount + i32.const 0 + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/iter + call $~lib/rt/itcms/Object#get:next + local.set $obj + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.eq + if + i32.const 0 + call $~lib/rt/itcms/visitStack + global.get $~lib/rt/itcms/iter + call $~lib/rt/itcms/Object#get:next + local.set $obj + loop $while-continue|2 + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $obj + call $~lib/rt/itcms/Object#get:color + local.get $black + i32.ne + if + local.get $obj + local.get $black + call $~lib/rt/itcms/Object#set:color + local.get $obj + i32.const 20 + i32.add + i32.const 0 + call $~lib/rt/__visit_members + end + local.get $obj + call $~lib/rt/itcms/Object#get:next + local.set $obj + br $while-continue|2 + end + end + global.get $~lib/rt/itcms/fromSpace + local.set $from + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/fromSpace + local.get $from + global.set $~lib/rt/itcms/toSpace + local.get $black + global.set $~lib/rt/itcms/white + local.get $from + call $~lib/rt/itcms/Object#get:next + global.set $~lib/rt/itcms/iter + i32.const 2 + global.set $~lib/rt/itcms/state + end + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.mul + return + end + global.get $~lib/rt/itcms/iter + local.set $obj + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $obj + call $~lib/rt/itcms/Object#get:next + global.set $~lib/rt/itcms/iter + i32.const 1 + drop + local.get $obj + call $~lib/rt/itcms/Object#get:color + global.get $~lib/rt/itcms/white + i32.eqz + i32.eq + i32.eqz + if + i32.const 0 + i32.const 272 + i32.const 229 + i32.const 20 + call $~lib/builtins/abort + unreachable + end + local.get $obj + call $~lib/rt/itcms/free + i32.const 10 + return + end + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + call $~lib/rt/itcms/Object#set:nextWithColor + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + call $~lib/rt/itcms/Object#set:prev + i32.const 0 + global.set $~lib/rt/itcms/state + br $break|0 + end + i32.const 0 + return + ) + (func $~lib/rt/itcms/interrupt + (local $budget i32) + i32.const 0 + drop + i32.const 0 + drop + i32.const 1024 + i32.const 200 + i32.mul + i32.const 100 + i32.div_u + local.set $budget + loop $do-loop|0 + local.get $budget + call $~lib/rt/itcms/step + i32.sub + local.set $budget + global.get $~lib/rt/itcms/state + i32.const 0 + i32.eq + if + i32.const 0 + drop + global.get $~lib/rt/itcms/total + i64.extend_i32_u + i32.const 200 + i64.extend_i32_u + i64.mul + i64.const 100 + i64.div_u + i32.wrap_i64 + i32.const 1024 + i32.add + global.set $~lib/rt/itcms/threshold + i32.const 0 + drop + return + end + local.get $budget + i32.const 0 + i32.gt_s + br_if $do-loop|0 + end + i32.const 0 + drop + global.get $~lib/rt/itcms/total + i32.const 1024 + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.sub + i32.const 1024 + i32.lt_u + i32.mul + i32.add + global.set $~lib/rt/itcms/threshold + i32.const 0 + drop + ) + (func $~lib/rt/tlsf/computeSize (param $size i32) (result i32) + local.get $size + i32.const 12 + i32.le_u + if (result i32) + i32.const 12 + else + local.get $size + i32.const 4 + i32.add + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + i32.const 4 + i32.sub + end + return + ) + (func $~lib/rt/tlsf/prepareSize (param $size i32) (result i32) + local.get $size + i32.const 1073741820 + i32.gt_u + if + i32.const 208 + i32.const 544 + i32.const 461 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $size + call $~lib/rt/tlsf/computeSize + return + ) + (func $~lib/rt/tlsf/roundSize (param $size i32) (result i32) + local.get $size + i32.const 536870910 + i32.lt_u + if (result i32) + local.get $size + i32.const 1 + i32.const 27 + local.get $size + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + else + local.get $size + end + return + ) + (func $~lib/rt/tlsf/searchBlock (param $root i32) (param $size i32) (result i32) + (local $fl i32) + (local $sl i32) + (local $requestSize i32) + (local $root|5 i32) + (local $fl|6 i32) + (local $slMap i32) + (local $head i32) + (local $flMap i32) + (local $root|10 i32) + (local $fl|11 i32) + (local $root|12 i32) + (local $fl|13 i32) + (local $sl|14 i32) + (local $root|15 i32) + (local $fl|16 i32) + (local $sl|17 i32) + local.get $size + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $fl + local.get $size + i32.const 4 + i32.shr_u + local.set $sl + else + local.get $size + call $~lib/rt/tlsf/roundSize + local.set $requestSize + i32.const 4 + i32.const 8 + i32.mul + i32.const 1 + i32.sub + local.get $requestSize + i32.clz + i32.sub + local.set $fl + local.get $requestSize + local.get $fl + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $sl + local.get $fl + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $fl + end + i32.const 1 + drop + local.get $fl + i32.const 23 + i32.lt_u + if (result i32) + local.get $sl + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 334 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETSL|inlined.2 (result i32) + local.get $root + local.set $root|5 + local.get $fl + local.set $fl|6 + local.get $root|5 + local.get $fl|6 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.2 + end + i32.const 0 + i32.const -1 + i32.xor + local.get $sl + i32.shl + i32.and + local.set $slMap + i32.const 0 + local.set $head + local.get $slMap + i32.eqz + if + local.get $root + call $~lib/rt/tlsf/Root#get:flMap + i32.const 0 + i32.const -1 + i32.xor + local.get $fl + i32.const 1 + i32.add + i32.shl + i32.and + local.set $flMap + local.get $flMap + i32.eqz + if + i32.const 0 + local.set $head + else + local.get $flMap + i32.ctz + local.set $fl + block $~lib/rt/tlsf/GETSL|inlined.3 (result i32) + local.get $root + local.set $root|10 + local.get $fl + local.set $fl|11 + local.get $root|10 + local.get $fl|11 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.3 + end + local.set $slMap + i32.const 1 + drop + local.get $slMap + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 347 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETHEAD|inlined.2 (result i32) + local.get $root + local.set $root|12 + local.get $fl + local.set $fl|13 + local.get $slMap + i32.ctz + local.set $sl|14 + local.get $root|12 + local.get $fl|13 + i32.const 4 + i32.shl + local.get $sl|14 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.2 + end + local.set $head + end + else + block $~lib/rt/tlsf/GETHEAD|inlined.3 (result i32) + local.get $root + local.set $root|15 + local.get $fl + local.set $fl|16 + local.get $slMap + i32.ctz + local.set $sl|17 + local.get $root|15 + local.get $fl|16 + i32.const 4 + i32.shl + local.get $sl|17 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.3 + end + local.set $head + end + local.get $head + return + ) + (func $~lib/rt/tlsf/growMemory (param $root i32) (param $size i32) + (local $pagesBefore i32) + (local $root|3 i32) + (local $pagesNeeded i32) + (local $5 i32) + (local $6 i32) + (local $pagesWanted i32) + (local $pagesAfter i32) + i32.const 0 + drop + local.get $size + i32.const 256 + i32.ge_u + if + local.get $size + call $~lib/rt/tlsf/roundSize + local.set $size + end + memory.size + local.set $pagesBefore + local.get $size + i32.const 4 + local.get $pagesBefore + i32.const 16 + i32.shl + i32.const 4 + i32.sub + block $~lib/rt/tlsf/GETTAIL|inlined.1 (result i32) + local.get $root + local.set $root|3 + local.get $root|3 + i32.load offset=1568 + br $~lib/rt/tlsf/GETTAIL|inlined.1 + end + i32.ne + i32.shl + i32.add + local.set $size + local.get $size + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $pagesNeeded + local.get $pagesBefore + local.tee $5 + local.get $pagesNeeded + local.tee $6 + local.get $5 + local.get $6 + i32.gt_s + select + local.set $pagesWanted + local.get $pagesWanted + memory.grow + i32.const 0 + i32.lt_s + if + local.get $pagesNeeded + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + memory.size + local.set $pagesAfter + local.get $root + local.get $pagesBefore + i32.const 16 + i32.shl + local.get $pagesAfter + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + drop + ) + (func $~lib/rt/tlsf/prepareBlock (param $root i32) (param $block i32) (param $size i32) + (local $blockInfo i32) + (local $remaining i32) + (local $spare i32) + (local $block|6 i32) + (local $block|7 i32) + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $blockInfo + i32.const 1 + drop + local.get $size + i32.const 4 + i32.add + i32.const 15 + i32.and + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 361 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $size + i32.sub + local.set $remaining + local.get $remaining + i32.const 4 + i32.const 12 + i32.add + i32.ge_u + if + local.get $block + local.get $size + local.get $blockInfo + i32.const 2 + i32.and + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $block + i32.const 4 + i32.add + local.get $size + i32.add + local.set $spare + local.get $spare + local.get $remaining + i32.const 4 + i32.sub + i32.const 1 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $root + local.get $spare + call $~lib/rt/tlsf/insertBlock + else + local.get $block + local.get $blockInfo + i32.const 1 + i32.const -1 + i32.xor + i32.and + call $~lib/rt/common/BLOCK#set:mmInfo + block $~lib/rt/tlsf/GETRIGHT|inlined.3 (result i32) + local.get $block + local.set $block|7 + local.get $block|7 + i32.const 4 + i32.add + local.get $block|7 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.3 + end + block $~lib/rt/tlsf/GETRIGHT|inlined.2 (result i32) + local.get $block + local.set $block|6 + local.get $block|6 + i32.const 4 + i32.add + local.get $block|6 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.2 + end + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 2 + i32.const -1 + i32.xor + i32.and + call $~lib/rt/common/BLOCK#set:mmInfo + end + ) + (func $~lib/rt/tlsf/allocateBlock (param $root i32) (param $size i32) (result i32) + (local $payloadSize i32) + (local $block i32) + local.get $size + call $~lib/rt/tlsf/prepareSize + local.set $payloadSize + local.get $root + local.get $payloadSize + call $~lib/rt/tlsf/searchBlock + local.set $block + local.get $block + i32.eqz + if + local.get $root + local.get $payloadSize + call $~lib/rt/tlsf/growMemory + local.get $root + local.get $payloadSize + call $~lib/rt/tlsf/searchBlock + local.set $block + i32.const 1 + drop + local.get $block + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 499 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 + drop + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $payloadSize + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 544 + i32.const 501 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $root + local.get $block + call $~lib/rt/tlsf/removeBlock + local.get $root + local.get $block + local.get $payloadSize + call $~lib/rt/tlsf/prepareBlock + i32.const 0 + drop + local.get $block + return + ) + (func $~lib/rt/tlsf/__alloc (param $size i32) (result i32) + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.get $size + call $~lib/rt/tlsf/allocateBlock + i32.const 4 + i32.add + return + ) + (func $~lib/rt/itcms/Object#set:rtId (param $this i32) (param $rtId i32) + local.get $this + local.get $rtId + i32.store offset=12 + ) + (func $~lib/rt/itcms/Object#set:rtSize (param $this i32) (param $rtSize i32) + local.get $this + local.get $rtSize + i32.store offset=16 + ) + (func $~lib/rt/itcms/__new (param $size i32) (param $id i32) (result i32) + (local $obj i32) + (local $ptr i32) + local.get $size + i32.const 1073741804 + i32.ge_u + if + i32.const 208 + i32.const 272 + i32.const 261 + i32.const 31 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.ge_u + if + call $~lib/rt/itcms/interrupt + end + i32.const 16 + local.get $size + i32.add + call $~lib/rt/tlsf/__alloc + i32.const 4 + i32.sub + local.set $obj + local.get $obj + local.get $id + call $~lib/rt/itcms/Object#set:rtId + local.get $obj + local.get $size + call $~lib/rt/itcms/Object#set:rtSize + local.get $obj + global.get $~lib/rt/itcms/fromSpace + global.get $~lib/rt/itcms/white + call $~lib/rt/itcms/Object#linkTo + global.get $~lib/rt/itcms/total + local.get $obj + call $~lib/rt/itcms/Object#get:size + i32.add + global.set $~lib/rt/itcms/total + local.get $obj + i32.const 20 + i32.add + local.set $ptr + local.get $ptr + i32.const 0 + local.get $size + memory.fill + local.get $ptr + return + ) + (func $switch/FooClass#get:value (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/__visit_globals (param $0 i32) + (local $1 i32) + i32.const 400 + local.get $0 + call $~lib/rt/itcms/__visit + i32.const 208 + local.get $0 + call $~lib/rt/itcms/__visit + ) + (func $~lib/arraybuffer/ArrayBufferView~visit (param $0 i32) (param $1 i32) + (local $2 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + i32.load + local.tee $2 + if + local.get $2 + local.get $1 + call $~lib/rt/itcms/__visit + end + ) + (func $~lib/object/Object~visit (param $0 i32) (param $1 i32) + ) + (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) + block $invalid + block $switch/FooClass + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $switch/FooClass $invalid + end + return + end + return + end + return + end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit + return + end + return + end + unreachable + ) + (func $~start + call $start:switch + ) + (func $~stack_check + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__data_end + i32.lt_s + if + i32.const 33408 + i32.const 33456 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $switch/FooClass#constructor (param $this i32) (param $value i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 4 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 0 + call $switch/FooClass#set:value + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + local.get $value + call $switch/FooClass#set:value + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + ) + (func $switch/doSwitchClassMember (param $foo i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + block $case2|0 + block $case1|0 + block $case0|0 + local.get $foo + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $switch/FooClass#get:value + local.set $1 + local.get $1 + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 2 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 0 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $start:switch + (local $0 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + i32.const 0 + call $switch/doSwitch + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 10 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitch + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 11 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitch + i32.const 23 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 12 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $switch/doSwitch + i32.const 23 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 13 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + call $switch/doSwitch + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 14 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchDefaultFirst + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 24 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchDefaultFirst + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 25 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitchDefaultFirst + i32.const 23 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 26 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $switch/doSwitchDefaultFirst + i32.const 23 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 27 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + call $switch/doSwitchDefaultFirst + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 28 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchDefaultOmitted + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 38 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchDefaultOmitted + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 39 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitchDefaultOmitted + i32.const 23 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 40 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $switch/doSwitchDefaultOmitted + i32.const 23 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 41 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + call $switch/doSwitchDefaultOmitted + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 42 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchBreakCase + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 51 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchBreakCase + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 52 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitchBreakCase + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 53 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchBreakDefault + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 62 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchBreakDefault + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 63 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitchBreakDefault + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 64 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchFallThroughCase + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 73 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchFallThroughCase + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 74 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitchFallThroughCase + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 75 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchFallThroughDefault + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 84 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchFallThroughDefault + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 85 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitchFallThroughDefault + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 86 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchEmpty + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 92 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchEmpty + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 93 + i32.const 1 + call $~lib/builtins/abort + unreachable end i32.const 2 - return - ) - (func $switch/doSwitchEmpty (param $n i32) (result i32) - local.get $n - drop + call $switch/doSwitchEmpty i32.const 2 - return - ) - (func $start:switch - i32.const 0 - call $switch/doSwitch - i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 10 + i32.const 94 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 1 - call $switch/doSwitch + i32.const 80 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 11 + i32.const 104 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 112 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 2 - call $switch/doSwitch - i32.const 23 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 12 + i32.const 105 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 144 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 3 - call $switch/doSwitch - i32.const 23 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 13 + i32.const 106 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 176 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 4 - call $switch/doSwitch - i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 14 + i32.const 107 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 0 - call $switch/doSwitch + call $switch/doSwitchNullableString i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 24 + i32.const 118 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 1 - call $switch/doSwitch + i32.const 80 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 25 + i32.const 119 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 112 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 2 - call $switch/doSwitch - i32.const 23 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 26 + i32.const 120 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 144 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 3 - call $switch/doSwitch - i32.const 23 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 27 + i32.const 121 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 176 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString i32.const 4 - call $switch/doSwitch + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 122 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchBoolean + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 132 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 0 + call $switch/doSwitchBoolean + i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 28 + i32.const 133 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 0 - call $switch/doSwitchDefaultOmitted + call $switch/doSwitchUInt32 i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 38 + i32.const 143 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 1 - call $switch/doSwitchDefaultOmitted + call $switch/doSwitchUInt32 i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 39 + i32.const 144 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 2 - call $switch/doSwitchDefaultOmitted - i32.const 23 + call $switch/doSwitchUInt32 + i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 40 + i32.const 145 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 3 - call $switch/doSwitchDefaultOmitted - i32.const 23 + call $switch/doSwitchUInt32 + i32.const 3 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 41 + i32.const 146 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 4 - call $switch/doSwitchDefaultOmitted + call $switch/doSwitchUInt32 i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 42 + i32.const 147 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 0 - call $switch/doSwitchBreakCase + global.get $switch/Foo.A + call $switch/doSwitchEnum + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 164 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $switch/Foo.B + call $switch/doSwitchEnum i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 51 + i32.const 165 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $switch/Foo.C + call $switch/doSwitchEnum + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 166 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $switch/Foo.D + call $switch/doSwitchEnum + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 167 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchUint8 + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 177 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 1 - call $switch/doSwitchBreakCase + call $switch/doSwitchUint8 i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 52 + i32.const 178 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 2 - call $switch/doSwitchBreakCase + call $switch/doSwitchUint8 i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 53 + i32.const 179 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 3 + call $switch/doSwitchUint8 + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 180 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 4 + call $switch/doSwitchUint8 i32.const 0 - call $switch/doSwitchBreakDefault - i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 62 + i32.const 181 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 1 - call $switch/doSwitchBreakDefault + f32.const 0 + call $switch/doSwitchFloat + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 190 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f32.const 1 + call $switch/doSwitchFloat i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 63 + i32.const 191 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 2 - call $switch/doSwitchBreakDefault + f32.const 2 + call $switch/doSwitchFloat i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 64 + i32.const 192 i32.const 1 call $~lib/builtins/abort unreachable end + i64.const 0 + call $switch/doSwitchInt64 i32.const 0 - call $switch/doSwitchFallThroughCase - i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 73 + i32.const 201 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 1 - call $switch/doSwitchFallThroughCase + i64.const 1 + call $switch/doSwitchInt64 i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 74 + i32.const 202 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 2 - call $switch/doSwitchFallThroughCase + i64.const 2 + call $switch/doSwitchInt64 i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 75 + i32.const 203 i32.const 1 call $~lib/builtins/abort unreachable end + i64.const 0 + call $switch/doSwitchUInt64 i32.const 0 - call $switch/doSwitchFallThroughDefault - i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 84 + i32.const 214 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 1 - call $switch/doSwitchFallThroughDefault + i64.const 1 + call $switch/doSwitchUInt64 i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 85 + i32.const 215 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 2 - call $switch/doSwitchFallThroughDefault + i64.const 2 + call $switch/doSwitchUInt64 i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 86 + i32.const 216 i32.const 1 call $~lib/builtins/abort unreachable end + memory.size + i32.const 16 + i32.shl + global.get $~lib/memory/__heap_base + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 320 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/pinSpace + i32.const 352 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/toSpace + i32.const 496 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/fromSpace + i32.const 0 + i32.const 0 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember i32.const 0 - call $switch/doSwitchEmpty - i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 92 + i32.const 234 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 0 + i32.const 1 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember i32.const 1 - call $switch/doSwitchEmpty - i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 93 + i32.const 235 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 0 i32.const 2 - call $switch/doSwitchEmpty + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 94 + i32.const 236 i32.const 1 call $~lib/builtins/abort unreachable end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer ) - (func $~start - call $start:switch + (func $switch/doSwitchString (param $s i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/memory/__stack_pointer + local.get $s + local.tee $1 + i32.store + local.get $1 + i32.const 80 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 112 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 144 + i32.eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 2 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 3 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 4 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $switch/doSwitchNullableString (param $s i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/memory/__stack_pointer + local.get $s + local.tee $1 + i32.store + local.get $1 + i32.const 0 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 80 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 112 + i32.eq + br_if $case2|0 + local.get $1 + i32.const 144 + i32.eq + br_if $case3|0 + br $case4|0 + end + i32.const 0 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 1 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 2 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 3 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 4 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return ) ) diff --git a/tests/compiler/switch.release.wat b/tests/compiler/switch.release.wat index b5389b07f8..37fb2432b9 100644 --- a/tests/compiler/switch.release.wat +++ b/tests/compiler/switch.release.wat @@ -1,6 +1,1827 @@ (module + (type $0 (func)) + (type $1 (func (param i32) (result i32))) + (type $2 (func (param i32))) + (type $3 (func (param i32 i32))) + (type $4 (func (result i32))) + (type $5 (func (param i32 i32 i32 i32))) + (type $6 (func (param i32 i32 i64))) + (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (global $~lib/rt/itcms/total (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/threshold (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/state (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/visitCount (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/pinSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/iter (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/toSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/white (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) + (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34408)) (memory $0 1) (data $0 (i32.const 1036) ",") (data $0.1 (i32.const 1048) "\02\00\00\00\12\00\00\00s\00w\00i\00t\00c\00h\00.\00t\00s") + (data $1 (i32.const 1084) "\1c") + (data $1.1 (i32.const 1096) "\02\00\00\00\06\00\00\00o\00n\00e") + (data $2 (i32.const 1116) "\1c") + (data $2.1 (i32.const 1128) "\02\00\00\00\06\00\00\00t\00w\00o") + (data $3 (i32.const 1148) "\1c") + (data $3.1 (i32.const 1160) "\02\00\00\00\n\00\00\00t\00h\00r\00e\00e") + (data $4 (i32.const 1180) "\1c") + (data $4.1 (i32.const 1192) "\02\00\00\00\08\00\00\00f\00o\00u\00r") + (data $5 (i32.const 1212) "<") + (data $5.1 (i32.const 1224) "\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e") + (data $6 (i32.const 1276) "<") + (data $6.1 (i32.const 1288) "\02\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s") + (data $9 (i32.const 1404) "<") + (data $9.1 (i32.const 1416) "\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e") + (data $10 (i32.const 1468) ",") + (data $10.1 (i32.const 1480) "\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s") + (data $12 (i32.const 1548) "<") + (data $12.1 (i32.const 1560) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") + (data $13 (i32.const 1616) "\05\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 ") (export "memory" (memory $0)) + (start $~start) + (func $~lib/rt/itcms/visitRoots + (local $0 i32) + (local $1 i32) + i32.const 1424 + call $~lib/rt/itcms/__visit + i32.const 1232 + call $~lib/rt/itcms/__visit + global.get $~lib/rt/itcms/pinSpace + local.tee $1 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + loop $while-continue|0 + local.get $0 + local.get $1 + i32.ne + if + local.get $0 + i32.load offset=4 + i32.const 3 + i32.and + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1296 + i32.const 160 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 20 + i32.add + call $~lib/rt/__visit_members + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + br $while-continue|0 + end + end + ) + (func $~lib/rt/itcms/__visit (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + local.get $0 + i32.eqz + if + return + end + global.get $~lib/rt/itcms/white + local.get $0 + i32.const 20 + i32.sub + local.tee $1 + i32.load offset=4 + i32.const 3 + i32.and + i32.eq + if + local.get $1 + global.get $~lib/rt/itcms/iter + i32.eq + if + local.get $1 + i32.load offset=8 + local.tee $0 + i32.eqz + if + i32.const 0 + i32.const 1296 + i32.const 148 + i32.const 30 + call $~lib/builtins/abort + unreachable + end + local.get $0 + global.set $~lib/rt/itcms/iter + end + block $__inlined_func$~lib/rt/itcms/Object#unlink$170 + local.get $1 + i32.load offset=4 + i32.const -4 + i32.and + local.tee $0 + i32.eqz + if + local.get $1 + i32.load offset=8 + i32.eqz + local.get $1 + i32.const 34408 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1296 + i32.const 128 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + br $__inlined_func$~lib/rt/itcms/Object#unlink$170 + end + local.get $1 + i32.load offset=8 + local.tee $2 + i32.eqz + if + i32.const 0 + i32.const 1296 + i32.const 132 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $2 + i32.store offset=8 + local.get $2 + local.get $0 + local.get $2 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + end + global.get $~lib/rt/itcms/toSpace + local.set $2 + local.get $1 + i32.load offset=12 + local.tee $0 + i32.const 2 + i32.le_u + if (result i32) + i32.const 1 + else + local.get $0 + i32.const 1616 + i32.load + i32.gt_u + if + i32.const 1424 + i32.const 1488 + i32.const 21 + i32.const 28 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 2 + i32.shl + i32.const 1620 + i32.add + i32.load + i32.const 32 + i32.and + end + local.set $3 + local.get $2 + i32.load offset=8 + local.set $0 + local.get $1 + global.get $~lib/rt/itcms/white + i32.eqz + i32.const 2 + local.get $3 + select + local.get $2 + i32.or + i32.store offset=4 + local.get $1 + local.get $0 + i32.store offset=8 + local.get $0 + local.get $1 + local.get $0 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + local.get $2 + local.get $1 + i32.store offset=8 + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.add + global.set $~lib/rt/itcms/visitCount + end + ) + (func $~lib/rt/tlsf/removeBlock (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + local.get $1 + i32.load + local.tee $3 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 268 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const -4 + i32.and + local.tee $3 + i32.const 12 + i32.lt_u + if + i32.const 0 + i32.const 1568 + i32.const 270 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const 256 + i32.lt_u + if (result i32) + local.get $3 + i32.const 4 + i32.shr_u + else + i32.const 31 + i32.const 1073741820 + local.get $3 + local.get $3 + i32.const 1073741820 + i32.ge_u + select + local.tee $3 + i32.clz + i32.sub + local.tee $4 + i32.const 7 + i32.sub + local.set $2 + local.get $3 + local.get $4 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + end + local.tee $3 + i32.const 16 + i32.lt_u + local.get $2 + i32.const 23 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 284 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load offset=8 + local.set $5 + local.get $1 + i32.load offset=4 + local.tee $4 + if + local.get $4 + local.get $5 + i32.store offset=8 + end + local.get $5 + if + local.get $5 + local.get $4 + i32.store offset=4 + end + local.get $1 + local.get $0 + local.get $2 + i32.const 4 + i32.shl + local.get $3 + i32.add + i32.const 2 + i32.shl + i32.add + local.tee $1 + i32.load offset=96 + i32.eq + if + local.get $1 + local.get $5 + i32.store offset=96 + local.get $5 + i32.eqz + if + local.get $0 + local.get $2 + i32.const 2 + i32.shl + i32.add + local.tee $1 + i32.load offset=4 + i32.const -2 + local.get $3 + i32.rotl + i32.and + local.set $3 + local.get $1 + local.get $3 + i32.store offset=4 + local.get $3 + i32.eqz + if + local.get $0 + local.get $0 + i32.load + i32.const -2 + local.get $2 + i32.rotl + i32.and + i32.store + end + end + end + ) + (func $~lib/rt/tlsf/insertBlock (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + local.get $1 + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 201 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load + local.tee $3 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 203 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 4 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $4 + i32.load + local.tee $2 + i32.const 1 + i32.and + if + local.get $0 + local.get $4 + call $~lib/rt/tlsf/removeBlock + local.get $1 + local.get $3 + i32.const 4 + i32.add + local.get $2 + i32.const -4 + i32.and + i32.add + local.tee $3 + i32.store + local.get $1 + i32.const 4 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $4 + i32.load + local.set $2 + end + local.get $3 + i32.const 2 + i32.and + if + local.get $1 + i32.const 4 + i32.sub + i32.load + local.tee $1 + i32.load + local.tee $6 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 221 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $1 + call $~lib/rt/tlsf/removeBlock + local.get $1 + local.get $6 + i32.const 4 + i32.add + local.get $3 + i32.const -4 + i32.and + i32.add + local.tee $3 + i32.store + end + local.get $4 + local.get $2 + i32.const 2 + i32.or + i32.store + local.get $3 + i32.const -4 + i32.and + local.tee $2 + i32.const 12 + i32.lt_u + if + i32.const 0 + i32.const 1568 + i32.const 233 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + local.get $1 + i32.const 4 + i32.add + local.get $2 + i32.add + i32.ne + if + i32.const 0 + i32.const 1568 + i32.const 234 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + i32.const 4 + i32.sub + local.get $1 + i32.store + local.get $2 + i32.const 256 + i32.lt_u + if (result i32) + local.get $2 + i32.const 4 + i32.shr_u + else + i32.const 31 + i32.const 1073741820 + local.get $2 + local.get $2 + i32.const 1073741820 + i32.ge_u + select + local.tee $2 + i32.clz + i32.sub + local.tee $3 + i32.const 7 + i32.sub + local.set $5 + local.get $2 + local.get $3 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + end + local.tee $2 + i32.const 16 + i32.lt_u + local.get $5 + i32.const 23 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 251 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $5 + i32.const 4 + i32.shl + local.get $2 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + local.set $3 + local.get $1 + i32.const 0 + i32.store offset=4 + local.get $1 + local.get $3 + i32.store offset=8 + local.get $3 + if + local.get $3 + local.get $1 + i32.store offset=4 + end + local.get $0 + local.get $5 + i32.const 4 + i32.shl + local.get $2 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $1 + i32.store offset=96 + local.get $0 + local.get $0 + i32.load + i32.const 1 + local.get $5 + i32.shl + i32.or + i32.store + local.get $0 + local.get $5 + i32.const 2 + i32.shl + i32.add + local.tee $0 + local.get $0 + i32.load offset=4 + i32.const 1 + local.get $2 + i32.shl + i32.or + i32.store offset=4 + ) + (func $~lib/rt/tlsf/addMemory (param $0 i32) (param $1 i32) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + local.get $2 + local.get $1 + i64.extend_i32_u + i64.lt_u + if + i32.const 0 + i32.const 1568 + i32.const 382 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 19 + i32.add + i32.const -16 + i32.and + i32.const 4 + i32.sub + local.set $1 + local.get $0 + i32.load offset=1568 + local.tee $3 + if + local.get $3 + i32.const 4 + i32.add + local.get $1 + i32.gt_u + if + i32.const 0 + i32.const 1568 + i32.const 389 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $3 + local.get $1 + i32.const 16 + i32.sub + local.tee $5 + i32.eq + if + local.get $3 + i32.load + local.set $4 + local.get $5 + local.set $1 + end + else + local.get $0 + i32.const 1572 + i32.add + local.get $1 + i32.gt_u + if + i32.const 0 + i32.const 1568 + i32.const 402 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + local.get $2 + i32.wrap_i64 + i32.const -16 + i32.and + local.get $1 + i32.sub + local.tee $3 + i32.const 20 + i32.lt_u + if + return + end + local.get $1 + local.get $4 + i32.const 2 + i32.and + local.get $3 + i32.const 8 + i32.sub + local.tee $3 + i32.const 1 + i32.or + i32.or + i32.store + local.get $1 + i32.const 0 + i32.store offset=4 + local.get $1 + i32.const 0 + i32.store offset=8 + local.get $1 + i32.const 4 + i32.add + local.get $3 + i32.add + local.tee $3 + i32.const 2 + i32.store + local.get $0 + local.get $3 + i32.store offset=1568 + local.get $0 + local.get $1 + call $~lib/rt/tlsf/insertBlock + ) + (func $~lib/rt/tlsf/initialize + (local $0 i32) + (local $1 i32) + memory.size + local.tee $1 + i32.const 0 + i32.le_s + if (result i32) + i32.const 1 + local.get $1 + i32.sub + memory.grow + i32.const 0 + i32.lt_s + else + i32.const 0 + end + if + unreachable + end + i32.const 34416 + i32.const 0 + i32.store + i32.const 35984 + i32.const 0 + i32.store + loop $for-loop|0 + local.get $0 + i32.const 23 + i32.lt_u + if + local.get $0 + i32.const 2 + i32.shl + i32.const 34416 + i32.add + i32.const 0 + i32.store offset=4 + i32.const 0 + local.set $1 + loop $for-loop|1 + local.get $1 + i32.const 16 + i32.lt_u + if + local.get $0 + i32.const 4 + i32.shl + local.get $1 + i32.add + i32.const 2 + i32.shl + i32.const 34416 + i32.add + i32.const 0 + i32.store offset=96 + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $for-loop|1 + end + end + local.get $0 + i32.const 1 + i32.add + local.set $0 + br $for-loop|0 + end + end + i32.const 34416 + i32.const 35988 + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + i32.const 34416 + global.set $~lib/rt/tlsf/ROOT + ) + (func $~lib/rt/itcms/step (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + block $break|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/rt/itcms/state + br_table $case0|0 $case1|0 $case2|0 $break|0 + end + i32.const 1 + global.set $~lib/rt/itcms/state + i32.const 0 + global.set $~lib/rt/itcms/visitCount + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/iter + global.get $~lib/rt/itcms/visitCount + return + end + global.get $~lib/rt/itcms/white + i32.eqz + local.set $1 + global.get $~lib/rt/itcms/iter + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + loop $while-continue|1 + local.get $0 + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $0 + global.set $~lib/rt/itcms/iter + local.get $1 + local.get $0 + i32.load offset=4 + local.tee $2 + i32.const 3 + i32.and + i32.ne + if + local.get $0 + local.get $2 + i32.const -4 + i32.and + local.get $1 + i32.or + i32.store offset=4 + i32.const 0 + global.set $~lib/rt/itcms/visitCount + local.get $0 + i32.const 20 + i32.add + call $~lib/rt/__visit_members + global.get $~lib/rt/itcms/visitCount + return + end + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + br $while-continue|1 + end + end + i32.const 0 + global.set $~lib/rt/itcms/visitCount + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/iter + i32.load offset=4 + i32.const -4 + i32.and + i32.eq + if + global.get $~lib/memory/__stack_pointer + local.set $0 + loop $while-continue|0 + local.get $0 + i32.const 34408 + i32.lt_u + if + local.get $0 + i32.load + call $~lib/rt/itcms/__visit + local.get $0 + i32.const 4 + i32.add + local.set $0 + br $while-continue|0 + end + end + global.get $~lib/rt/itcms/iter + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + loop $while-continue|2 + local.get $0 + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $1 + local.get $0 + i32.load offset=4 + local.tee $2 + i32.const 3 + i32.and + i32.ne + if + local.get $0 + local.get $2 + i32.const -4 + i32.and + local.get $1 + i32.or + i32.store offset=4 + local.get $0 + i32.const 20 + i32.add + call $~lib/rt/__visit_members + end + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + br $while-continue|2 + end + end + global.get $~lib/rt/itcms/fromSpace + local.set $0 + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/fromSpace + local.get $0 + global.set $~lib/rt/itcms/toSpace + local.get $1 + global.set $~lib/rt/itcms/white + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + global.set $~lib/rt/itcms/iter + i32.const 2 + global.set $~lib/rt/itcms/state + end + global.get $~lib/rt/itcms/visitCount + return + end + global.get $~lib/rt/itcms/iter + local.tee $0 + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $0 + i32.load offset=4 + local.tee $1 + i32.const -4 + i32.and + global.set $~lib/rt/itcms/iter + global.get $~lib/rt/itcms/white + i32.eqz + local.get $1 + i32.const 3 + i32.and + i32.ne + if + i32.const 0 + i32.const 1296 + i32.const 229 + i32.const 20 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 34408 + i32.lt_u + if + local.get $0 + i32.const 0 + i32.store offset=4 + local.get $0 + i32.const 0 + i32.store offset=8 + else + global.get $~lib/rt/itcms/total + local.get $0 + i32.load + i32.const -4 + i32.and + i32.const 4 + i32.add + i32.sub + global.set $~lib/rt/itcms/total + local.get $0 + i32.const 4 + i32.add + local.tee $0 + i32.const 34408 + i32.ge_u + if + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.set $1 + local.get $0 + i32.const 4 + i32.sub + local.set $2 + local.get $0 + i32.const 15 + i32.and + i32.const 1 + local.get $0 + select + if (result i32) + i32.const 1 + else + local.get $2 + i32.load + i32.const 1 + i32.and + end + if + i32.const 0 + i32.const 1568 + i32.const 562 + i32.const 3 + call $~lib/builtins/abort + unreachable + end + local.get $2 + local.get $2 + i32.load + i32.const 1 + i32.or + i32.store + local.get $1 + local.get $2 + call $~lib/rt/tlsf/insertBlock + end + end + i32.const 10 + return + end + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + i32.store offset=4 + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + i32.store offset=8 + i32.const 0 + global.set $~lib/rt/itcms/state + end + i32.const 0 + ) + (func $~lib/rt/tlsf/searchBlock (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + local.get $0 + i32.load offset=4 + i32.const -2 + i32.and + local.tee $1 + if (result i32) + local.get $0 + local.get $1 + i32.ctz + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + else + local.get $0 + i32.load + i32.const -2 + i32.and + local.tee $1 + if (result i32) + local.get $0 + local.get $1 + i32.ctz + local.tee $2 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + local.tee $1 + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 347 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $1 + i32.ctz + local.get $2 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + else + i32.const 0 + end + end + ) + (func $~lib/rt/itcms/__new (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.ge_u + if + block $__inlined_func$~lib/rt/itcms/interrupt$69 + i32.const 2048 + local.set $0 + loop $do-loop|0 + local.get $0 + call $~lib/rt/itcms/step + i32.sub + local.set $0 + global.get $~lib/rt/itcms/state + i32.eqz + if + global.get $~lib/rt/itcms/total + i64.extend_i32_u + i64.const 200 + i64.mul + i64.const 100 + i64.div_u + i32.wrap_i64 + i32.const 1024 + i32.add + global.set $~lib/rt/itcms/threshold + br $__inlined_func$~lib/rt/itcms/interrupt$69 + end + local.get $0 + i32.const 0 + i32.gt_s + br_if $do-loop|0 + end + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.sub + i32.const 1024 + i32.lt_u + i32.const 10 + i32.shl + i32.add + global.set $~lib/rt/itcms/threshold + end + end + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.tee $1 + call $~lib/rt/tlsf/searchBlock + local.tee $0 + i32.eqz + if + memory.size + local.tee $0 + i32.const 4 + local.get $1 + i32.load offset=1568 + local.get $0 + i32.const 16 + i32.shl + i32.const 4 + i32.sub + i32.ne + i32.shl + i32.const 65563 + i32.add + i32.const -65536 + i32.and + i32.const 16 + i32.shr_u + local.tee $2 + local.get $0 + local.get $2 + i32.gt_s + select + memory.grow + i32.const 0 + i32.lt_s + if + local.get $2 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + local.get $1 + local.get $0 + i32.const 16 + i32.shl + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + local.get $1 + call $~lib/rt/tlsf/searchBlock + local.tee $0 + i32.eqz + if + i32.const 0 + i32.const 1568 + i32.const 499 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + end + local.get $0 + i32.load + i32.const -4 + i32.and + i32.const 28 + i32.lt_u + if + i32.const 0 + i32.const 1568 + i32.const 501 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + local.get $0 + call $~lib/rt/tlsf/removeBlock + local.get $0 + i32.load + local.tee $2 + i32.const -4 + i32.and + i32.const 28 + i32.sub + local.tee $3 + i32.const 16 + i32.ge_u + if + local.get $0 + local.get $2 + i32.const 2 + i32.and + i32.const 28 + i32.or + i32.store + local.get $0 + i32.const 32 + i32.add + local.tee $2 + local.get $3 + i32.const 4 + i32.sub + i32.const 1 + i32.or + i32.store + local.get $1 + local.get $2 + call $~lib/rt/tlsf/insertBlock + else + local.get $0 + local.get $2 + i32.const -2 + i32.and + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $0 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $1 + local.get $1 + i32.load + i32.const -3 + i32.and + i32.store + end + local.get $0 + i32.const 4 + i32.store offset=12 + local.get $0 + i32.const 4 + i32.store offset=16 + global.get $~lib/rt/itcms/fromSpace + local.tee $1 + i32.load offset=8 + local.set $2 + local.get $0 + local.get $1 + global.get $~lib/rt/itcms/white + i32.or + i32.store offset=4 + local.get $0 + local.get $2 + i32.store offset=8 + local.get $2 + local.get $0 + local.get $2 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + local.get $1 + local.get $0 + i32.store offset=8 + global.get $~lib/rt/itcms/total + local.get $0 + i32.load + i32.const -4 + i32.and + i32.const 4 + i32.add + i32.add + global.set $~lib/rt/itcms/total + local.get $0 + i32.const 20 + i32.add + local.tee $0 + i32.const 0 + i32.store align=1 + local.get $0 + ) + (func $~lib/rt/__visit_members (param $0 i32) + block $invalid + block $switch/FooClass + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $switch/FooClass $invalid + end + return + end + return + end + return + end + local.get $0 + i32.load + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + return + end + return + end + unreachable + ) + (func $~start + call $start:switch + ) + (func $switch/FooClass#constructor (param $0 i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1640 + i32.lt_s + if + i32.const 34432 + i32.const 34480 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + call $~lib/rt/itcms/__new + local.tee $1 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $switch/doSwitchClassMember (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1640 + i32.lt_s + if + i32.const 34432 + i32.const 34480 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + block $case2|0 + block $case1|0 + local.get $0 + i32.load + local.tee $0 + i32.const 1 + i32.ne + if + local.get $0 + i32.const 2 + i32.eq + br_if $case1|0 + br $case2|0 + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 2 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 0 + ) + (func $start:switch + (local $0 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 1640 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 1104 + i32.store + i32.const 1104 + call $switch/doSwitchString + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 104 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1136 + i32.store + i32.const 1136 + call $switch/doSwitchString + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 105 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store + i32.const 1168 + call $switch/doSwitchString + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 106 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1200 + i32.store + i32.const 1200 + call $switch/doSwitchString + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 107 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1640 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1104 + i32.store + i32.const 1104 + call $switch/doSwitchString + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 119 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1136 + i32.store + i32.const 1136 + call $switch/doSwitchString + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 120 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store + i32.const 1168 + call $switch/doSwitchString + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 121 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1200 + i32.store + i32.const 1200 + call $switch/doSwitchString + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 122 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + memory.size + i32.const 16 + i32.shl + i32.const 34408 + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 1348 + i32.const 1344 + i32.store + i32.const 1352 + i32.const 1344 + i32.store + i32.const 1344 + global.set $~lib/rt/itcms/pinSpace + i32.const 1380 + i32.const 1376 + i32.store + i32.const 1384 + i32.const 1376 + i32.store + i32.const 1376 + global.set $~lib/rt/itcms/toSpace + i32.const 1524 + i32.const 1520 + i32.store + i32.const 1528 + i32.const 1520 + i32.store + i32.const 1520 + global.set $~lib/rt/itcms/fromSpace + i32.const 0 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + if + i32.const 0 + i32.const 1056 + i32.const 234 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 235 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 236 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + return + end + i32.const 34432 + i32.const 34480 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + ) + (func $switch/doSwitchString (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1640 + i32.lt_s + if + i32.const 34432 + i32.const 34480 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + block $case3|0 + block $case2|0 + block $case1|0 + local.get $0 + i32.const 1104 + i32.ne + if + local.get $0 + i32.const 1136 + i32.eq + br_if $case1|0 + local.get $0 + i32.const 1168 + i32.eq + br_if $case2|0 + br $case3|0 + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 2 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 3 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 4 + ) ) diff --git a/tests/compiler/switch.ts b/tests/compiler/switch.ts index bd73eb7051..5d4c6d0620 100644 --- a/tests/compiler/switch.ts +++ b/tests/compiler/switch.ts @@ -21,11 +21,11 @@ function doSwitchDefaultFirst(n: i32): i32 { case 3: return 23; } } -assert(doSwitch(0) == 0); -assert(doSwitch(1) == 1); -assert(doSwitch(2) == 23); -assert(doSwitch(3) == 23); -assert(doSwitch(4) == 0); +assert(doSwitchDefaultFirst(0) == 0); +assert(doSwitchDefaultFirst(1) == 1); +assert(doSwitchDefaultFirst(2) == 23); +assert(doSwitchDefaultFirst(3) == 23); +assert(doSwitchDefaultFirst(4) == 0); function doSwitchDefaultOmitted(n: i32): i32 { switch (n) { @@ -92,3 +92,169 @@ function doSwitchEmpty(n: i32): i32 { assert(doSwitchEmpty(0) == 2); assert(doSwitchEmpty(1) == 2); assert(doSwitchEmpty(2) == 2); + +function doSwitchString(s: string): i32 { + switch (s) { + case "one": return 1; + case "two": return 2; + case "three": return 3; + default: return 4; + } +} +assert(doSwitchString("one") == 1); +assert(doSwitchString("two") == 2); +assert(doSwitchString("three") == 3); +assert(doSwitchString("four") == 4); + +function doSwitchNullableString(s: string | null): i32 { + switch (s) { + case null: return 0; + case "one": return 1; + case "two": return 2; + case "three": return 3; + default: return 4; + } +} +assert(doSwitchNullableString(null) == 0); +assert(doSwitchString("one") == 1); +assert(doSwitchString("two") == 2); +assert(doSwitchString("three") == 3); +assert(doSwitchString("four") == 4); + +function doSwitchBoolean(b: bool): i32 { + switch (b) { + case true: return 1; + case false: return 2; + } + return 0; +} + +assert(doSwitchBoolean(true) == 1); +assert(doSwitchBoolean(false) == 2); + +function doSwitchUInt32(n: u32): i32 { + switch (n) { + case 1: return 1; + case 2: return 2; + case 3: return 3; + default: return 0; + } +} +assert(doSwitchUInt32(0) == 0); +assert(doSwitchUInt32(1) == 1); +assert(doSwitchUInt32(2) == 2); +assert(doSwitchUInt32(3) == 3); +assert(doSwitchUInt32(4) == 0); + +enum Foo { + A = 1, + B = 2, + C = 3, + D = 4, +} + +function doSwitchEnum(n: Foo): i32 { + switch (n) { + case Foo.A: return 1; + case Foo.B: return 2; + case Foo.C: return 3; + default: return 0; + } +} +assert(doSwitchEnum(Foo.A) == 1); +assert(doSwitchEnum(Foo.B) == 2); +assert(doSwitchEnum(Foo.C) == 3); +assert(doSwitchEnum(Foo.D) == 0); + +function doSwitchUint8(n: u8): i32 { + switch (n) { + case 1: return 1; + case 2: return 2; + case 3: return 3; + default: return 0; + } +} +assert(doSwitchUint8(0) == 0); +assert(doSwitchUint8(1) == 1); +assert(doSwitchUint8(2) == 2); +assert(doSwitchUint8(3) == 3); +assert(doSwitchUint8(4) == 0); + +function doSwitchFloat(n: f32): i32 { + switch (n) { + case 1.0: return 1; + case 2.0: return 2; + default: return 0; + } +} +assert(doSwitchFloat(0.0) == 0); +assert(doSwitchFloat(1.0) == 1); +assert(doSwitchFloat(2.0) == 2); + +function doSwitchInt64(n: i64): i32 { + switch (n) { + case (1): return 1; + case (2): return 2; + default: return 0; + } +} +assert(doSwitchInt64(0) == 0); +assert(doSwitchInt64(1) == 1); +assert(doSwitchInt64(2) == 2); + +function doSwitchUInt64(n: u64): i32 { + const one: u64 = 1; + const two: u64 = 2; + switch (n) { + case one: return 1; + case two: return 2; + default: return 0; + } +} +assert(doSwitchUInt64(0) == 0); +assert(doSwitchUInt64(1) == 1); +assert(doSwitchUInt64(2) == 2); + + +class FooClass { + value: i32; + + constructor(value: i32) { + this.value = value; + } +} + +function doSwitchClassMember(foo: FooClass): i32 { + switch (foo.value) { + case 1: return 1; + case 2: return 2; + default: return 0; + } +} +assert(doSwitchClassMember(new FooClass(0)) == 0); +assert(doSwitchClassMember(new FooClass(1)) == 1); +assert(doSwitchClassMember(new FooClass(2)) == 2); + + +// TODO: This should either work, or be a compile error. +// Currently it compiles but gives a runtime error, such as: +// +// abort: null in (252:1) +// --- +// RuntimeError: unreachable +// at start:switch (wasm://wasm/14e6b94a:wasm-function[75]:0x1ae9) +// at ~start (wasm://wasm/14e6b94a:wasm-function[71]:0x1300) +// --- +// function doSwitchClassInstance(foo: FooClass): i32 { +// const one = new FooClass(1); +// const two = new FooClass(2); +// switch (foo) { +// case one: return 1; +// case two: return 2; +// default: return 0; +// } +// } +// assert(doSwitchClassInstance(new FooClass(0)) == 0); +// assert(doSwitchClassInstance(new FooClass(1)) == 1); +// assert(doSwitchClassInstance(new FooClass(2)) == 2); +// assert(doSwitchClassInstance(new FooClass(3)) == 0); From f523d13b37d044c0945ecd0ad8068a1e9293d7a7 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Fri, 30 May 2025 08:58:19 -0700 Subject: [PATCH 2/5] . --- tests/compiler/switch.debug.wat | 8 +- tests/compiler/switch.release.wat | 534 +++++++++++++++++------------- tests/compiler/switch.ts | 8 +- 3 files changed, 308 insertions(+), 242 deletions(-) diff --git a/tests/compiler/switch.debug.wat b/tests/compiler/switch.debug.wat index 5e88a056a5..1c748490ce 100644 --- a/tests/compiler/switch.debug.wat +++ b/tests/compiler/switch.debug.wat @@ -3316,7 +3316,7 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 1 i32.eq i32.eqz @@ -3334,7 +3334,7 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 2 i32.eq i32.eqz @@ -3352,7 +3352,7 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 3 i32.eq i32.eqz @@ -3370,7 +3370,7 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 4 i32.eq i32.eqz diff --git a/tests/compiler/switch.release.wat b/tests/compiler/switch.release.wat index 37fb2432b9..3e05d41f76 100644 --- a/tests/compiler/switch.release.wat +++ b/tests/compiler/switch.release.wat @@ -1,6 +1,6 @@ (module - (type $0 (func)) - (type $1 (func (param i32) (result i32))) + (type $0 (func (param i32) (result i32))) + (type $1 (func)) (type $2 (func (param i32))) (type $3 (func (param i32 i32))) (type $4 (func (result i32))) @@ -125,7 +125,7 @@ local.get $0 global.set $~lib/rt/itcms/iter end - block $__inlined_func$~lib/rt/itcms/Object#unlink$170 + block $__inlined_func$~lib/rt/itcms/Object#unlink$169 local.get $1 i32.load offset=4 i32.const -4 @@ -149,7 +149,7 @@ call $~lib/builtins/abort unreachable end - br $__inlined_func$~lib/rt/itcms/Object#unlink$170 + br $__inlined_func$~lib/rt/itcms/Object#unlink$169 end local.get $1 i32.load offset=8 @@ -1515,248 +1515,238 @@ i32.const 4 i32.sub global.set $~lib/memory/__stack_pointer - block $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 1640 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1640 + i32.lt_s + if + i32.const 34432 + i32.const 34480 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 1104 + i32.store + i32.const 1104 + call $switch/doSwitchString + i32.const 1 + i32.ne + if i32.const 0 - i32.store - global.get $~lib/memory/__stack_pointer - i32.const 1104 - i32.store - i32.const 1104 - call $switch/doSwitchString + i32.const 1056 + i32.const 104 i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 104 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 1136 - i32.store - i32.const 1136 - call $switch/doSwitchString - i32.const 2 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 105 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 1168 - i32.store - i32.const 1168 - call $switch/doSwitchString - i32.const 3 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 106 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 1200 - i32.store - i32.const 1200 - call $switch/doSwitchString - i32.const 4 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 107 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1640 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1136 + i32.store + i32.const 1136 + call $switch/doSwitchString + i32.const 2 + i32.ne + if i32.const 0 - i32.store - global.get $~lib/memory/__stack_pointer + i32.const 1056 + i32.const 105 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store + i32.const 1168 + call $switch/doSwitchString + i32.const 3 + i32.ne + if i32.const 0 - i32.store - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1104 - i32.store - i32.const 1104 - call $switch/doSwitchString + i32.const 1056 + i32.const 106 i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 119 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 1136 - i32.store - i32.const 1136 - call $switch/doSwitchString - i32.const 2 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 120 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 1168 - i32.store - i32.const 1168 - call $switch/doSwitchString - i32.const 3 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 121 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 1200 - i32.store - i32.const 1200 - call $switch/doSwitchString - i32.const 4 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 122 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - memory.size - i32.const 16 - i32.shl - i32.const 34408 - i32.sub + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1200 + i32.store + i32.const 1200 + call $switch/doSwitchString + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 107 i32.const 1 - i32.shr_u - global.set $~lib/rt/itcms/threshold - i32.const 1348 - i32.const 1344 - i32.store - i32.const 1352 - i32.const 1344 - i32.store - i32.const 1344 - global.set $~lib/rt/itcms/pinSpace - i32.const 1380 - i32.const 1376 - i32.store - i32.const 1384 - i32.const 1376 - i32.store - i32.const 1376 - global.set $~lib/rt/itcms/toSpace - i32.const 1524 - i32.const 1520 - i32.store - i32.const 1528 - i32.const 1520 - i32.store - i32.const 1520 - global.set $~lib/rt/itcms/fromSpace + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchNullableString + if i32.const 0 - call $switch/FooClass#constructor - local.set $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store - local.get $0 - call $switch/doSwitchClassMember - if - i32.const 0 - i32.const 1056 - i32.const 234 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + i32.const 1056 + i32.const 118 i32.const 1 - call $switch/FooClass#constructor - local.set $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store - local.get $0 - call $switch/doSwitchClassMember + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1104 + i32.store + i32.const 1104 + call $switch/doSwitchNullableString + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 119 i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 235 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 2 - call $switch/FooClass#constructor - local.set $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store - local.get $0 - call $switch/doSwitchClassMember - i32.const 2 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 236 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - return + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1136 + i32.store + i32.const 1136 + call $switch/doSwitchNullableString + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 120 + i32.const 1 + call $~lib/builtins/abort + unreachable end - i32.const 34432 - i32.const 34480 + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store + i32.const 1168 + call $switch/doSwitchNullableString + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 121 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1200 + i32.store + i32.const 1200 + call $switch/doSwitchNullableString + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 122 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + memory.size + i32.const 16 + i32.shl + i32.const 34408 + i32.sub i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 1348 + i32.const 1344 + i32.store + i32.const 1352 + i32.const 1344 + i32.store + i32.const 1344 + global.set $~lib/rt/itcms/pinSpace + i32.const 1380 + i32.const 1376 + i32.store + i32.const 1384 + i32.const 1376 + i32.store + i32.const 1376 + global.set $~lib/rt/itcms/toSpace + i32.const 1524 + i32.const 1520 + i32.store + i32.const 1528 + i32.const 1520 + i32.store + i32.const 1520 + global.set $~lib/rt/itcms/fromSpace + i32.const 0 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + if + i32.const 0 + i32.const 1056 + i32.const 234 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 - call $~lib/builtins/abort - unreachable + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 235 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 236 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer ) (func $switch/doSwitchString (param $0 i32) (result i32) global.get $~lib/memory/__stack_pointer @@ -1824,4 +1814,80 @@ global.set $~lib/memory/__stack_pointer i32.const 4 ) + (func $switch/doSwitchNullableString (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1640 + i32.lt_s + if + i32.const 34432 + i32.const 34480 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + local.get $0 + if + local.get $0 + i32.const 1104 + i32.eq + br_if $case1|0 + local.get $0 + i32.const 1136 + i32.eq + br_if $case2|0 + local.get $0 + i32.const 1168 + i32.eq + br_if $case3|0 + br $case4|0 + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 0 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 2 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 3 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 4 + ) ) diff --git a/tests/compiler/switch.ts b/tests/compiler/switch.ts index 5d4c6d0620..a471c284b5 100644 --- a/tests/compiler/switch.ts +++ b/tests/compiler/switch.ts @@ -116,10 +116,10 @@ function doSwitchNullableString(s: string | null): i32 { } } assert(doSwitchNullableString(null) == 0); -assert(doSwitchString("one") == 1); -assert(doSwitchString("two") == 2); -assert(doSwitchString("three") == 3); -assert(doSwitchString("four") == 4); +assert(doSwitchNullableString("one") == 1); +assert(doSwitchNullableString("two") == 2); +assert(doSwitchNullableString("three") == 3); +assert(doSwitchNullableString("four") == 4); function doSwitchBoolean(b: bool): i32 { switch (b) { From 0af8cce21addad7c4b4ce7e79757c6cfd80b6e07 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 31 May 2025 13:11:04 -0700 Subject: [PATCH 3/5] revise to re-use existing equality comparison code --- src/compiler.ts | 131 +- tests/compiler/switch.debug.wat | 2295 ++++++++++++++++++++++------- tests/compiler/switch.release.wat | 1996 ++++++++++++++++++++----- tests/compiler/switch.ts | 84 +- 4 files changed, 3510 insertions(+), 996 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 5562c3256c..53a914a51c 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -2817,48 +2817,18 @@ export class Compiler extends DiagnosticEmitter { // Compile the condition (always executes) let condExpr = this.compileExpression(statement.condition, Type.auto); - - // Get the type set from compiling the condition expression - let currentType = this.currentType; + let condType = this.currentType; - // Determine the binary operation to use for comparison - let binaryOp: BinaryOp; - switch (currentType.toRef()) { - case TypeRef.I32: { - binaryOp = BinaryOp.EqI32; - break; - } - case TypeRef.I64: { - binaryOp = BinaryOp.EqI64; - break; - } - case TypeRef.F32: { - binaryOp = BinaryOp.EqF32; - break; - } - case TypeRef.F64: { - binaryOp = BinaryOp.EqF64; - break; - } - default: { - this.error( - DiagnosticCode.Not_implemented_0, - statement.range, `Switch condition of type ${currentType}` - ); - return module.unreachable(); - } - } - // Shortcut if there are no cases if (!numCases) return module.drop(condExpr); // Assign the condition to a temporary local as we compare it multiple times let outerFlow = this.currentFlow; - let tempLocal = outerFlow.getTempLocal(currentType); + let tempLocal = outerFlow.getTempLocal(condType); let tempLocalIndex = tempLocal.index; let breaks = new Array(1 + numCases); - breaks[0] = module.local_set(tempLocalIndex, condExpr, currentType.isManaged); - + breaks[0] = module.local_set(tempLocalIndex, condExpr, condType.isManaged); + // Make one br_if per labeled case and leave it to Binaryen to optimize the // sequence of br_ifs to a br_table according to optimization levels let breakIndex = 1; @@ -2870,14 +2840,24 @@ export class Compiler extends DiagnosticEmitter { defaultIndex = i; continue; } - breaks[breakIndex++] = module.br(`case${i}|${label}`, - module.binary(binaryOp, - module.local_get(tempLocalIndex, currentType.toRef()), - this.compileExpression(assert(case_.label), currentType, - Constraints.ConvImplicit - ) - ) + + // Compile the equality expression for this case + const left = statement.condition; + const leftExpr = module.local_get(tempLocalIndex, condType.toRef()); + const leftType = condType; + const right = case_.label!; + const rightExpr = this.compileExpression(assert(case_.label), condType, Constraints.ConvImplicit); + const rightType = this.currentType; + const equalityExpr = this.compileCommutativeCompareBinaryExpressionFromParts( + Token.Equals_Equals, + left, leftExpr, leftType, + right, rightExpr, rightType, + condType, + statement ); + + // Add it to the list of breaks + breaks[breakIndex++] = module.br(`case${i}|${label}`, equalityExpr); } // If there is a default case, break to it, otherwise break out of the switch @@ -3829,24 +3809,44 @@ export class Compiler extends DiagnosticEmitter { expression: BinaryExpression, contextualType: Type, ): ExpressionRef { - let module = this.module; - let left = expression.left; - let right = expression.right; + + const left = expression.left; + const leftExpr = this.compileExpression(left, contextualType); + const leftType = this.currentType; + + const right = expression.right; + const rightExpr = this.compileExpression(right, leftType); + const rightType = this.currentType; + + return this.compileCommutativeCompareBinaryExpressionFromParts( + expression.operator, + left, leftExpr, leftType, + right, rightExpr, rightType, + contextualType, + expression + ); + } - let leftExpr: ExpressionRef; - let leftType: Type; - let rightExpr: ExpressionRef; - let rightType: Type; - let commonType: Type | null; + /** + * compile `==` `===` `!=` `!==` BinaryExpression, from previously compiled left and right expressions. + * + * This is split from `compileCommutativeCompareBinaryExpression` so that the logic can be reused + * for switch cases in `compileSwitchStatement`, where the left expression only should be compiled once. + */ + private compileCommutativeCompareBinaryExpressionFromParts( + operator: Token, + left: Expression, + leftExpr: ExpressionRef, + leftType: Type, + right: Expression, + rightExpr: ExpressionRef, + rightType: Type, + contextualType: Type, + reportNode: Node + ): ExpressionRef { - let operator = expression.operator; + let module = this.module; let operatorString = operatorTokenToString(operator); - - leftExpr = this.compileExpression(left, contextualType); - leftType = this.currentType; - - rightExpr = this.compileExpression(right, leftType); - rightType = this.currentType; // check operator overload const operatorKind = OperatorKind.fromBinaryToken(operator); @@ -3854,7 +3854,8 @@ export class Compiler extends DiagnosticEmitter { const rightOverload = rightType.lookupOverload(operatorKind, this.program); if (leftOverload && rightOverload && leftOverload != rightOverload) { this.error( - DiagnosticCode.Ambiguous_operator_overload_0_conflicting_overloads_1_and_2, expression.range, + DiagnosticCode.Ambiguous_operator_overload_0_conflicting_overloads_1_and_2, + reportNode.range, operatorString, leftOverload.internalName, rightOverload.internalName @@ -3867,7 +3868,7 @@ export class Compiler extends DiagnosticEmitter { leftOverload, left, leftExpr, leftType, right, rightExpr, rightType, - expression + reportNode ); } if (rightOverload) { @@ -3875,15 +3876,15 @@ export class Compiler extends DiagnosticEmitter { rightOverload, right, rightExpr, rightType, left, leftExpr, leftType, - expression + reportNode ); } const signednessIsRelevant = false; - commonType = Type.commonType(leftType, rightType, contextualType, signednessIsRelevant); + const commonType = Type.commonType(leftType, rightType, contextualType, signednessIsRelevant); if (!commonType) { this.error( DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, - expression.range, + reportNode.range, operatorString, leftType.toString(), rightType.toString() @@ -3896,13 +3897,13 @@ export class Compiler extends DiagnosticEmitter { if (isConstExpressionNaN(module, rightExpr) || isConstExpressionNaN(module, leftExpr)) { this.warning( DiagnosticCode._NaN_does_not_compare_equal_to_any_other_value_including_itself_Use_isNaN_x_instead, - expression.range + reportNode.range ); } if (isConstNegZero(rightExpr) || isConstNegZero(leftExpr)) { this.warning( DiagnosticCode.Comparison_with_0_0_is_sign_insensitive_Use_Object_is_x_0_0_if_the_sign_matters, - expression.range + reportNode.range ); } } @@ -3916,10 +3917,10 @@ export class Compiler extends DiagnosticEmitter { switch (operator) { case Token.Equals_Equals_Equals: case Token.Equals_Equals: - return this.makeEq(leftExpr, rightExpr, commonType, expression); + return this.makeEq(leftExpr, rightExpr, commonType, reportNode); case Token.Exclamation_Equals_Equals: case Token.Exclamation_Equals: - return this.makeNe(leftExpr, rightExpr, commonType, expression); + return this.makeNe(leftExpr, rightExpr, commonType, reportNode); default: assert(false); return module.unreachable(); diff --git a/tests/compiler/switch.debug.wat b/tests/compiler/switch.debug.wat index 1c748490ce..e38ffb1605 100644 --- a/tests/compiler/switch.debug.wat +++ b/tests/compiler/switch.debug.wat @@ -1,20 +1,21 @@ (module (type $0 (func (param i32) (result i32))) (type $1 (func (param i32 i32))) - (type $2 (func (param i32))) - (type $3 (func)) - (type $4 (func (param i32 i32) (result i32))) - (type $5 (func (param i64) (result i32))) - (type $6 (func (param i32 i32 i32))) + (type $2 (func (param i32 i32) (result i32))) + (type $3 (func (param i32))) + (type $4 (func)) + (type $5 (func (param i32 i32 i32))) + (type $6 (func (param i64) (result i32))) (type $7 (func (param i32 i32 i32 i32))) - (type $8 (func (param f32) (result i32))) + (type $8 (func (param i32 i32 i32 i32 i32) (result i32))) (type $9 (func (param i32 i32 i64) (result i32))) (type $10 (func (result i32))) + (type $11 (func (param f32) (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) - (global $switch/Foo.A i32 (i32.const 1)) - (global $switch/Foo.B i32 (i32.const 2)) - (global $switch/Foo.C i32 (i32.const 3)) - (global $switch/Foo.D i32 (i32.const 4)) + (global $~lib/shared/runtime/Runtime.Stub i32 (i32.const 0)) + (global $~lib/shared/runtime/Runtime.Minimal i32 (i32.const 1)) + (global $~lib/shared/runtime/Runtime.Incremental i32 (i32.const 2)) + (global $~lib/native/ASC_SHRINK_LEVEL i32 (i32.const 0)) (global $~lib/rt/itcms/total (mut i32) (i32.const 0)) (global $~lib/rt/itcms/threshold (mut i32) (i32.const 0)) (global $~lib/rt/itcms/state (mut i32) (i32.const 0)) @@ -23,31 +24,44 @@ (global $~lib/rt/itcms/iter (mut i32) (i32.const 0)) (global $~lib/rt/itcms/toSpace (mut i32) (i32.const 0)) (global $~lib/rt/itcms/white (mut i32) (i32.const 0)) - (global $~lib/shared/runtime/Runtime.Stub i32 (i32.const 0)) - (global $~lib/shared/runtime/Runtime.Minimal i32 (i32.const 1)) - (global $~lib/shared/runtime/Runtime.Incremental i32 (i32.const 2)) (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) (global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) - (global $~lib/rt/__rtti_base i32 (i32.const 592)) - (global $~lib/memory/__data_end i32 (i32.const 616)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33384)) - (global $~lib/memory/__heap_base i32 (i32.const 33384)) + (global $switch/Foo.A i32 (i32.const 1)) + (global $switch/Foo.B i32 (i32.const 2)) + (global $switch/Foo.C i32 (i32.const 3)) + (global $switch/Foo.D i32 (i32.const 4)) + (global $switch/foo1 (mut i32) (i32.const 0)) + (global $switch/foo2 (mut i32) (i32.const 0)) + (global $~lib/rt/__rtti_base i32 (i32.const 912)) + (global $~lib/memory/__data_end i32 (i32.const 940)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33708)) + (global $~lib/memory/__heap_base i32 (i32.const 33708)) (memory $0 1) (data $0 (i32.const 12) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\12\00\00\00s\00w\00i\00t\00c\00h\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00") (data $1 (i32.const 60) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\06\00\00\00o\00n\00e\00\00\00\00\00\00\00") (data $2 (i32.const 92) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\06\00\00\00t\00w\00o\00\00\00\00\00\00\00") (data $3 (i32.const 124) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\n\00\00\00t\00h\00r\00e\00e\00\00\00") (data $4 (i32.const 156) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\08\00\00\00f\00o\00u\00r\00\00\00\00\00") - (data $5 (i32.const 188) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e\00\00\00\00\00") - (data $6 (i32.const 252) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00") - (data $7 (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") - (data $8 (i32.const 352) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") - (data $9 (i32.const 380) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e\00\00\00\00\00\00\00\00\00") - (data $10 (i32.const 444) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00\00\00\00\00\00\00\00\00") - (data $11 (i32.const 496) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") - (data $12 (i32.const 524) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") - (data $13 (i32.const 592) "\05\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00") + (data $5 (i32.const 188) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00o\00\00\00\00\00\00\00\00\00\00\00") + (data $6 (i32.const 220) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00n\00\00\00\00\00\00\00\00\00\00\00") + (data $7 (i32.const 252) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $8 (i32.const 284) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e\00\00\00\00\00") + (data $9 (i32.const 348) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $10 (i32.const 416) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $11 (i32.const 448) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $12 (i32.const 476) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e\00\00\00\00\00\00\00\00\00") + (data $13 (i32.const 540) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00\00\00\00\00\00\00\00\00") + (data $14 (i32.const 592) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $15 (i32.const 620) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $16 (i32.const 684) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00e\00\00\00\00\00\00\00\00\00\00\00") + (data $17 (i32.const 716) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00t\00\00\00\00\00\00\00\00\00\00\00") + (data $18 (i32.const 748) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00w\00\00\00\00\00\00\00\00\00\00\00") + (data $19 (i32.const 780) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00h\00\00\00\00\00\00\00\00\00\00\00") + (data $20 (i32.const 812) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00r\00\00\00\00\00\00\00\00\00\00\00") + (data $21 (i32.const 844) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00f\00\00\00\00\00\00\00\00\00\00\00") + (data $22 (i32.const 876) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\02\00\00\00u\00\00\00\00\00\00\00\00\00\00\00") + (data $23 (i32.const 912) "\06\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00") (table $0 1 1 funcref) (elem $0 (i32.const 1)) (export "memory" (memory $0)) @@ -238,217 +252,123 @@ i32.const 2 return ) - (func $switch/doSwitchBoolean (param $b i32) (result i32) - (local $1 i32) - block $break|0 - block $case1|0 - block $case0|0 - local.get $b - local.set $1 - local.get $1 - i32.const 1 - i32.eq - br_if $case0|0 - local.get $1 - i32.const 0 - i32.eq - br_if $case1|0 - br $break|0 - end - i32.const 1 - return - end - i32.const 2 - return - end - i32.const 0 - return + (func $~lib/rt/common/OBJECT#get:rtSize (param $this i32) (result i32) + local.get $this + i32.load offset=16 ) - (func $switch/doSwitchUInt32 (param $n i32) (result i32) - (local $1 i32) - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $n - local.set $1 - local.get $1 - i32.const 1 - i32.eq - br_if $case0|0 - local.get $1 - i32.const 2 - i32.eq - br_if $case1|0 - local.get $1 - i32.const 3 - i32.eq - br_if $case2|0 - br $case3|0 - end - i32.const 1 - return - end - i32.const 2 - return - end - i32.const 3 - return - end - i32.const 0 + (func $~lib/string/String#get:length (param $this i32) (result i32) + local.get $this + i32.const 20 + i32.sub + call $~lib/rt/common/OBJECT#get:rtSize + i32.const 1 + i32.shr_u return ) - (func $switch/doSwitchEnum (param $n i32) (result i32) - (local $1 i32) - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $n - local.set $1 - local.get $1 - global.get $switch/Foo.A - i32.eq - br_if $case0|0 - local.get $1 - global.get $switch/Foo.B - i32.eq - br_if $case1|0 - local.get $1 - global.get $switch/Foo.C - i32.eq - br_if $case2|0 - br $case3|0 + (func $~lib/util/string/compareImpl (param $str1 i32) (param $index1 i32) (param $str2 i32) (param $index2 i32) (param $len i32) (result i32) + (local $ptr1 i32) + (local $ptr2 i32) + (local $7 i32) + (local $a i32) + (local $b i32) + local.get $str1 + local.get $index1 + i32.const 1 + i32.shl + i32.add + local.set $ptr1 + local.get $str2 + local.get $index2 + i32.const 1 + i32.shl + i32.add + local.set $ptr2 + i32.const 0 + i32.const 2 + i32.lt_s + drop + local.get $len + i32.const 4 + i32.ge_u + if (result i32) + local.get $ptr1 + i32.const 7 + i32.and + local.get $ptr2 + i32.const 7 + i32.and + i32.or + i32.eqz + else + i32.const 0 + end + if + block $do-break|0 + loop $do-loop|0 + local.get $ptr1 + i64.load + local.get $ptr2 + i64.load + i64.ne + if + br $do-break|0 end - i32.const 1 - return + local.get $ptr1 + i32.const 8 + i32.add + local.set $ptr1 + local.get $ptr2 + i32.const 8 + i32.add + local.set $ptr2 + local.get $len + i32.const 4 + i32.sub + local.set $len + local.get $len + i32.const 4 + i32.ge_u + br_if $do-loop|0 end - i32.const 2 - return end - i32.const 3 - return end - i32.const 0 - return - ) - (func $switch/doSwitchUint8 (param $n i32) (result i32) - (local $1 i32) - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $n - local.set $1 - local.get $1 - i32.const 1 - i32.eq - br_if $case0|0 - local.get $1 - i32.const 2 - i32.eq - br_if $case1|0 - local.get $1 - i32.const 3 - i32.eq - br_if $case2|0 - br $case3|0 - end - i32.const 1 + loop $while-continue|1 + local.get $len + local.tee $7 + i32.const 1 + i32.sub + local.set $len + local.get $7 + if + local.get $ptr1 + i32.load16_u + local.set $a + local.get $ptr2 + i32.load16_u + local.set $b + local.get $a + local.get $b + i32.ne + if + local.get $a + local.get $b + i32.sub return end + local.get $ptr1 i32.const 2 - return - end - i32.const 3 - return - end - i32.const 0 - return - ) - (func $switch/doSwitchFloat (param $n f32) (result i32) - (local $1 f32) - block $case2|0 - block $case1|0 - block $case0|0 - local.get $n - local.set $1 - local.get $1 - f32.const 1 - f32.eq - br_if $case0|0 - local.get $1 - f32.const 2 - f32.eq - br_if $case1|0 - br $case2|0 - end - i32.const 1 - return - end - i32.const 2 - return - end - i32.const 0 - return - ) - (func $switch/doSwitchInt64 (param $n i64) (result i32) - (local $1 i64) - block $case2|0 - block $case1|0 - block $case0|0 - local.get $n - local.set $1 - local.get $1 - i64.const 1 - i64.eq - br_if $case0|0 - local.get $1 - i64.const 2 - i64.eq - br_if $case1|0 - br $case2|0 - end - i32.const 1 - return - end - i32.const 2 - return - end - i32.const 0 - return - ) - (func $switch/doSwitchUInt64 (param $n i64) (result i32) - (local $1 i64) - block $case2|0 - block $case1|0 - block $case0|0 - local.get $n - local.set $1 - local.get $1 - i64.const 1 - i64.eq - br_if $case0|0 - local.get $1 - i64.const 2 - i64.eq - br_if $case1|0 - br $case2|0 - end - i32.const 1 - return + i32.add + local.set $ptr1 + local.get $ptr2 + i32.const 2 + i32.add + local.set $ptr2 + br $while-continue|1 end - i32.const 2 - return end i32.const 0 return ) - (func $switch/FooClass#set:value (param $this i32) (param $value i32) - local.get $this - local.get $value - i32.store - ) (func $~lib/rt/itcms/Object#set:nextWithColor (param $this i32) (param $nextWithColor i32) local.get $this local.get $nextWithColor @@ -513,7 +433,7 @@ i32.eqz if i32.const 0 - i32.const 272 + i32.const 368 i32.const 160 i32.const 16 call $~lib/builtins/abort @@ -583,7 +503,7 @@ i32.eqz if i32.const 0 - i32.const 272 + i32.const 368 i32.const 128 i32.const 18 call $~lib/builtins/abort @@ -600,7 +520,7 @@ i32.eqz if i32.const 0 - i32.const 272 + i32.const 368 i32.const 132 i32.const 16 call $~lib/builtins/abort @@ -630,8 +550,8 @@ i32.load i32.gt_u if - i32.const 400 - i32.const 464 + i32.const 496 + i32.const 560 i32.const 21 i32.const 28 call $~lib/builtins/abort @@ -699,7 +619,7 @@ i32.eqz if (result i32) i32.const 0 - i32.const 272 + i32.const 368 i32.const 148 i32.const 30 call $~lib/builtins/abort @@ -851,7 +771,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 268 i32.const 14 call $~lib/builtins/abort @@ -871,7 +791,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 270 i32.const 14 call $~lib/builtins/abort @@ -934,7 +854,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 284 i32.const 14 call $~lib/builtins/abort @@ -1087,7 +1007,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 201 i32.const 14 call $~lib/builtins/abort @@ -1104,7 +1024,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 203 i32.const 14 call $~lib/builtins/abort @@ -1193,7 +1113,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 221 i32.const 16 call $~lib/builtins/abort @@ -1236,7 +1156,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 233 i32.const 14 call $~lib/builtins/abort @@ -1254,7 +1174,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 234 i32.const 14 call $~lib/builtins/abort @@ -1322,7 +1242,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 251 i32.const 14 call $~lib/builtins/abort @@ -1439,7 +1359,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 382 i32.const 14 call $~lib/builtins/abort @@ -1485,7 +1405,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 389 i32.const 16 call $~lib/builtins/abort @@ -1517,7 +1437,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 402 i32.const 5 call $~lib/builtins/abort @@ -1761,7 +1681,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 562 i32.const 3 call $~lib/builtins/abort @@ -1981,7 +1901,7 @@ i32.eqz if i32.const 0 - i32.const 272 + i32.const 368 i32.const 229 i32.const 20 call $~lib/builtins/abort @@ -2089,8 +2009,8 @@ i32.const 1073741820 i32.gt_u if - i32.const 208 - i32.const 544 + i32.const 304 + i32.const 640 i32.const 461 i32.const 29 call $~lib/builtins/abort @@ -2192,7 +2112,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 334 i32.const 14 call $~lib/builtins/abort @@ -2263,7 +2183,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 347 i32.const 18 call $~lib/builtins/abort @@ -2420,7 +2340,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 361 i32.const 14 call $~lib/builtins/abort @@ -2535,7 +2455,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 499 i32.const 16 call $~lib/builtins/abort @@ -2555,7 +2475,7 @@ i32.eqz if i32.const 0 - i32.const 544 + i32.const 640 i32.const 501 i32.const 14 call $~lib/builtins/abort @@ -2603,8 +2523,8 @@ i32.const 1073741804 i32.ge_u if - i32.const 208 - i32.const 272 + i32.const 304 + i32.const 368 i32.const 261 i32.const 31 call $~lib/builtins/abort @@ -2649,16 +2569,260 @@ local.get $ptr return ) + (func $switch/doSwitchBoolean (param $b i32) (result i32) + (local $1 i32) + block $break|0 + block $case1|0 + block $case0|0 + local.get $b + local.set $1 + local.get $1 + i32.const 0 + i32.ne + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 0 + i32.ne + i32.const 0 + i32.eq + br_if $case1|0 + br $break|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchUInt32 (param $n i32) (result i32) + (local $1 i32) + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 3 + i32.eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 3 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchEnum (param $n i32) (result i32) + (local $1 i32) + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + global.get $switch/Foo.A + i32.eq + br_if $case0|0 + local.get $1 + global.get $switch/Foo.B + i32.eq + br_if $case1|0 + local.get $1 + global.get $switch/Foo.C + i32.eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 3 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchUint8 (param $n i32) (result i32) + (local $1 i32) + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i32.const 255 + i32.and + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 255 + i32.and + i32.const 2 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 255 + i32.and + i32.const 3 + i32.eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 3 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchFloat (param $n f32) (result i32) + (local $1 f32) + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + f32.const 1 + f32.eq + br_if $case0|0 + local.get $1 + f32.const 2 + f32.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchInt64 (param $n i64) (result i32) + (local $1 i64) + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i64.const 1 + i64.eq + br_if $case0|0 + local.get $1 + i64.const 2 + i64.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/doSwitchUInt64 (param $n i64) (result i32) + (local $1 i64) + block $case2|0 + block $case1|0 + block $case0|0 + local.get $n + local.set $1 + local.get $1 + i64.const 1 + i64.eq + br_if $case0|0 + local.get $1 + i64.const 2 + i64.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + return + end + i32.const 2 + return + end + i32.const 0 + return + ) + (func $switch/FooClass#set:value (param $this i32) (param $value i32) + local.get $this + local.get $value + i32.store + ) (func $switch/FooClass#get:value (param $this i32) (result i32) local.get $this i32.load ) + (func $switch/BarClass#get:value (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $switch/BarClass#set:value (param $this i32) (param $value i32) + local.get $this + local.get $value + i32.store + ) (func $~lib/rt/__visit_globals (param $0 i32) (local $1 i32) - i32.const 400 + global.get $switch/foo1 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $switch/foo2 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + i32.const 496 local.get $0 call $~lib/rt/itcms/__visit - i32.const 208 + i32.const 304 local.get $0 call $~lib/rt/itcms/__visit ) @@ -2680,26 +2844,29 @@ ) (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) block $invalid - block $switch/FooClass - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - block $~lib/object/Object - local.get $0 - i32.const 8 - i32.sub - i32.load - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $switch/FooClass $invalid + block $switch/BarClass + block $switch/FooClass + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $switch/FooClass $switch/BarClass $invalid + end + return end return end return end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit return end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit return end return @@ -2714,16 +2881,17 @@ global.get $~lib/memory/__data_end i32.lt_s if - i32.const 33408 - i32.const 33456 + i32.const 33728 + i32.const 33776 i32.const 1 i32.const 1 call $~lib/builtins/abort unreachable end ) - (func $switch/FooClass#constructor (param $this i32) (param $value i32) (result i32) - (local $2 i32) + (func $~lib/string/String.__eq (param $left i32) (param $right i32) (result i32) + (local $leftLength i32) + (local $3 i32) global.get $~lib/memory/__stack_pointer i32.const 8 i32.sub @@ -2732,20 +2900,445 @@ global.get $~lib/memory/__stack_pointer i64.const 0 i64.store - local.get $this - i32.eqz + local.get $left + local.get $right + i32.eq if + i32.const 1 + local.set $3 global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.const 4 - call $~lib/rt/itcms/__new - local.tee $this - i32.store + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + return end - local.get $this - local.set $2 - global.get $~lib/memory/__stack_pointer - local.get $2 + local.get $left + i32.const 0 + i32.eq + if (result i32) + i32.const 1 + else + local.get $right + i32.const 0 + i32.eq + end + if + i32.const 0 + local.set $3 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + return + end + local.get $left + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store + local.get $3 + call $~lib/string/String#get:length + local.set $leftLength + local.get $leftLength + local.get $right + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store + local.get $3 + call $~lib/string/String#get:length + i32.ne + if + i32.const 0 + local.set $3 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + return + end + local.get $left + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store + local.get $3 + i32.const 0 + local.get $right + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + local.get $3 + i32.const 0 + local.get $leftLength + call $~lib/util/string/compareImpl + i32.eqz + local.set $3 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + return + ) + (func $switch/doSwitchString (param $s i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/memory/__stack_pointer + local.get $s + local.tee $1 + i32.store + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 80 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $~lib/string/String.__eq + br_if $case0|0 + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 112 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $~lib/string/String.__eq + br_if $case1|0 + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 144 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $~lib/string/String.__eq + br_if $case2|0 + br $case3|0 + end + i32.const 1 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 2 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 3 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 4 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $~lib/string/String#concat (param $this i32) (param $other i32) (result i32) + (local $thisSize i32) + (local $otherSize i32) + (local $outSize i32) + (local $out i32) + (local $6 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store + local.get $6 + call $~lib/string/String#get:length + i32.const 1 + i32.shl + local.set $thisSize + local.get $other + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store + local.get $6 + call $~lib/string/String#get:length + i32.const 1 + i32.shl + local.set $otherSize + local.get $thisSize + local.get $otherSize + i32.add + local.set $outSize + local.get $outSize + i32.const 0 + i32.eq + if + i32.const 272 + local.set $6 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $6 + return + end + global.get $~lib/memory/__stack_pointer + local.get $outSize + i32.const 2 + call $~lib/rt/itcms/__new + local.tee $out + i32.store offset=4 + local.get $out + local.get $this + local.get $thisSize + memory.copy + local.get $out + local.get $thisSize + i32.add + local.get $other + local.get $otherSize + memory.copy + local.get $out + local.set $6 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $6 + return + ) + (func $~lib/string/String.__concat (param $left i32) (param $right i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $left + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + local.get $right + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + call $~lib/string/String#concat + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $switch/doSwitchNullableString (param $s i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/memory/__stack_pointer + local.get $s + local.tee $1 + i32.store + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 0 + call $~lib/string/String.__eq + br_if $case0|0 + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 80 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $~lib/string/String.__eq + br_if $case1|0 + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 112 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $~lib/string/String.__eq + br_if $case2|0 + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 144 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $~lib/string/String.__eq + br_if $case3|0 + br $case4|0 + end + i32.const 0 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 1 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 2 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 3 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 4 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $switch/FooClass#constructor (param $this i32) (param $value i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 4 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 i32.store offset=4 local.get $2 i32.const 0 @@ -2784,24 +3377,233 @@ local.set $2 global.get $~lib/memory/__stack_pointer local.get $2 - i32.store - local.get $2 - call $switch/FooClass#get:value - local.set $1 - local.get $1 - i32.const 1 - i32.eq - br_if $case0|0 - local.get $1 - i32.const 2 - i32.eq - br_if $case1|0 - br $case2|0 + i32.store + local.get $2 + call $switch/FooClass#get:value + local.set $1 + local.get $1 + i32.const 1 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case1|0 + br $case2|0 + end + i32.const 1 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 2 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + i32.const 3 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $switch/BarClass.__eq (param $left i32) (param $right i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $left + local.get $right + i32.eq + if + i32.const 1 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + local.get $left + i32.eqz + if (result i32) + i32.const 1 + else + local.get $right + i32.eqz + end + if + i32.const 0 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + end + local.get $left + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $switch/BarClass#get:value + local.get $right + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $switch/BarClass#get:value + i32.eq + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $switch/BarClass#constructor (param $this i32) (param $value i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 0 + call $switch/BarClass#set:value + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + local.get $value + call $switch/BarClass#set:value + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + ) + (func $switch/doSwitchClassInstanceWithOverload (param $foo i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/memory/__stack_pointer + local.get $foo + local.tee $1 + i32.store + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 0 + call $switch/BarClass.__eq + br_if $case0|0 + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 0 + i32.const 1 + call $switch/BarClass#constructor + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $switch/BarClass.__eq + br_if $case1|0 + local.get $1 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 0 + i32.const 2 + call $switch/BarClass#constructor + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=8 + local.get $2 + call $switch/BarClass.__eq + br_if $case2|0 + br $case3|0 + end + i32.const 0 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return end i32.const 1 local.set $2 global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 12 i32.add global.set $~lib/memory/__stack_pointer local.get $2 @@ -2810,16 +3612,16 @@ i32.const 2 local.set $2 global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 12 i32.add global.set $~lib/memory/__stack_pointer local.get $2 return end - i32.const 0 + i32.const 3 local.set $2 global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 12 i32.add global.set $~lib/memory/__stack_pointer local.get $2 @@ -2828,13 +3630,14 @@ (func $start:switch (local $0 i32) global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 36 i32.sub global.set $~lib/memory/__stack_pointer call $~stack_check global.get $~lib/memory/__stack_pointer i32.const 0 - i32.store + i32.const 36 + memory.fill i32.const 0 call $switch/doSwitch i32.const 0 @@ -3194,33 +3997,339 @@ if i32.const 0 i32.const 32 - i32.const 92 + i32.const 92 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + call $switch/doSwitchEmpty + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 93 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 2 + call $switch/doSwitchEmpty + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 94 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 80 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 106 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 112 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 107 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 144 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 108 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 176 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 4 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 109 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + memory.size + i32.const 16 + i32.shl + global.get $~lib/memory/__heap_base + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 416 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/pinSpace + i32.const 448 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/toSpace + i32.const 592 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/fromSpace + i32.const 208 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 240 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 704 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 112 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 736 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 768 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 208 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 113 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 736 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=28 + local.get $0 + i32.const 800 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=32 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=20 + local.get $0 + i32.const 832 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=24 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 704 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 704 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 114 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 1 - call $switch/doSwitchEmpty - i32.const 2 + i32.const 864 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=20 + local.get $0 + i32.const 208 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=24 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 896 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 832 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 4 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 93 + i32.const 115 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 2 - call $switch/doSwitchEmpty - i32.const 2 + i32.const 0 + call $switch/doSwitchNullableString + i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 94 + i32.const 128 i32.const 1 call $~lib/builtins/abort unreachable @@ -3231,14 +4340,14 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 104 + i32.const 129 i32.const 1 call $~lib/builtins/abort unreachable @@ -3249,14 +4358,14 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 105 + i32.const 130 i32.const 1 call $~lib/builtins/abort unreachable @@ -3267,14 +4376,14 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 3 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 106 + i32.const 131 i32.const 1 call $~lib/builtins/abort unreachable @@ -3285,32 +4394,43 @@ local.get $0 i32.store local.get $0 - call $switch/doSwitchString - i32.const 4 - i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 107 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 call $switch/doSwitchNullableString - i32.const 0 + i32.const 4 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 118 + i32.const 132 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 80 + i32.const 208 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 240 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 704 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 @@ -3323,12 +4443,36 @@ if i32.const 0 i32.const 32 - i32.const 119 + i32.const 135 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 112 + i32.const 736 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 768 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 208 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 @@ -3341,12 +4485,60 @@ if i32.const 0 i32.const 32 - i32.const 120 + i32.const 136 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 144 + i32.const 736 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=28 + local.get $0 + i32.const 800 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=32 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=20 + local.get $0 + i32.const 832 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=24 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 704 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 704 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 @@ -3359,12 +4551,48 @@ if i32.const 0 i32.const 32 - i32.const 121 + i32.const 137 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 176 + i32.const 864 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=20 + local.get $0 + i32.const 208 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=24 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + i32.const 896 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + local.get $0 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 832 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $~lib/string/String.__concat local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 @@ -3377,7 +4605,7 @@ if i32.const 0 i32.const 32 - i32.const 122 + i32.const 138 i32.const 1 call $~lib/builtins/abort unreachable @@ -3390,7 +4618,7 @@ if i32.const 0 i32.const 32 - i32.const 132 + i32.const 148 i32.const 1 call $~lib/builtins/abort unreachable @@ -3403,7 +4631,7 @@ if i32.const 0 i32.const 32 - i32.const 133 + i32.const 149 i32.const 1 call $~lib/builtins/abort unreachable @@ -3416,7 +4644,7 @@ if i32.const 0 i32.const 32 - i32.const 143 + i32.const 159 i32.const 1 call $~lib/builtins/abort unreachable @@ -3429,7 +4657,7 @@ if i32.const 0 i32.const 32 - i32.const 144 + i32.const 160 i32.const 1 call $~lib/builtins/abort unreachable @@ -3442,7 +4670,7 @@ if i32.const 0 i32.const 32 - i32.const 145 + i32.const 161 i32.const 1 call $~lib/builtins/abort unreachable @@ -3455,7 +4683,7 @@ if i32.const 0 i32.const 32 - i32.const 146 + i32.const 162 i32.const 1 call $~lib/builtins/abort unreachable @@ -3468,7 +4696,7 @@ if i32.const 0 i32.const 32 - i32.const 147 + i32.const 163 i32.const 1 call $~lib/builtins/abort unreachable @@ -3481,7 +4709,7 @@ if i32.const 0 i32.const 32 - i32.const 164 + i32.const 180 i32.const 1 call $~lib/builtins/abort unreachable @@ -3494,7 +4722,7 @@ if i32.const 0 i32.const 32 - i32.const 165 + i32.const 181 i32.const 1 call $~lib/builtins/abort unreachable @@ -3507,7 +4735,7 @@ if i32.const 0 i32.const 32 - i32.const 166 + i32.const 182 i32.const 1 call $~lib/builtins/abort unreachable @@ -3520,7 +4748,7 @@ if i32.const 0 i32.const 32 - i32.const 167 + i32.const 183 i32.const 1 call $~lib/builtins/abort unreachable @@ -3533,7 +4761,7 @@ if i32.const 0 i32.const 32 - i32.const 177 + i32.const 193 i32.const 1 call $~lib/builtins/abort unreachable @@ -3546,7 +4774,7 @@ if i32.const 0 i32.const 32 - i32.const 178 + i32.const 194 i32.const 1 call $~lib/builtins/abort unreachable @@ -3559,7 +4787,7 @@ if i32.const 0 i32.const 32 - i32.const 179 + i32.const 195 i32.const 1 call $~lib/builtins/abort unreachable @@ -3572,7 +4800,7 @@ if i32.const 0 i32.const 32 - i32.const 180 + i32.const 196 i32.const 1 call $~lib/builtins/abort unreachable @@ -3585,7 +4813,7 @@ if i32.const 0 i32.const 32 - i32.const 181 + i32.const 197 i32.const 1 call $~lib/builtins/abort unreachable @@ -3598,267 +4826,318 @@ if i32.const 0 i32.const 32 - i32.const 190 + i32.const 206 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f32.const 1 + call $switch/doSwitchFloat + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 207 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f32.const 2 + call $switch/doSwitchFloat + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 208 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 0 + call $switch/doSwitchInt64 + i32.const 0 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 217 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 1 + call $switch/doSwitchInt64 + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 218 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 2 + call $switch/doSwitchInt64 + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 219 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 1 - call $switch/doSwitchFloat - i32.const 1 + i64.const 0 + call $switch/doSwitchUInt64 + i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 191 + i32.const 230 i32.const 1 call $~lib/builtins/abort unreachable end - f32.const 2 - call $switch/doSwitchFloat - i32.const 2 + i64.const 1 + call $switch/doSwitchUInt64 + i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 192 + i32.const 231 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 - call $switch/doSwitchInt64 - i32.const 0 + i64.const 2 + call $switch/doSwitchUInt64 + i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 201 + i32.const 232 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 - call $switch/doSwitchInt64 + i32.const 0 + i32.const 1 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 202 + i32.const 251 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 - call $switch/doSwitchInt64 + i32.const 0 + i32.const 2 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 203 + i32.const 252 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 - call $switch/doSwitchUInt64 i32.const 0 + i32.const 3 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + i32.const 3 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 214 + i32.const 253 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 - call $switch/doSwitchUInt64 + i32.const 0 + i32.const 1 + call $switch/FooClass#constructor + global.set $switch/foo1 + i32.const 0 + i32.const 2 + call $switch/FooClass#constructor + global.set $switch/foo2 + global.get $switch/foo1 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassInstance i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 215 + i32.const 266 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 - call $switch/doSwitchUInt64 + global.get $switch/foo2 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassInstance i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 216 + i32.const 267 i32.const 1 call $~lib/builtins/abort unreachable end - memory.size - i32.const 16 - i32.shl - global.get $~lib/memory/__heap_base - i32.sub - i32.const 1 - i32.shr_u - global.set $~lib/rt/itcms/threshold - i32.const 320 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/pinSpace - i32.const 352 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/toSpace - i32.const 496 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/fromSpace - i32.const 0 i32.const 0 + i32.const 1 call $switch/FooClass#constructor local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 i32.store local.get $0 - call $switch/doSwitchClassMember + call $switch/doSwitchClassInstance + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 268 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchClassInstanceWithOverload i32.const 0 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 234 + i32.const 293 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 0 i32.const 1 - call $switch/FooClass#constructor + call $switch/BarClass#constructor local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 i32.store local.get $0 - call $switch/doSwitchClassMember + call $switch/doSwitchClassInstanceWithOverload i32.const 1 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 235 + i32.const 294 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 0 i32.const 2 - call $switch/FooClass#constructor + call $switch/BarClass#constructor local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 i32.store local.get $0 - call $switch/doSwitchClassMember + call $switch/doSwitchClassInstanceWithOverload i32.const 2 i32.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 236 + i32.const 295 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - ) - (func $switch/doSwitchString (param $s i32) (result i32) - (local $1 i32) - (local $2 i32) - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - call $~stack_check - global.get $~lib/memory/__stack_pointer i32.const 0 + i32.const 3 + call $switch/BarClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 i32.store - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - global.get $~lib/memory/__stack_pointer - local.get $s - local.tee $1 - i32.store - local.get $1 - i32.const 80 - i32.eq - br_if $case0|0 - local.get $1 - i32.const 112 - i32.eq - br_if $case1|0 - local.get $1 - i32.const 144 - i32.eq - br_if $case2|0 - br $case3|0 - end - i32.const 1 - local.set $2 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $2 - return - end - i32.const 2 - local.set $2 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $2 - return - end - i32.const 3 - local.set $2 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $2 - return + local.get $0 + call $switch/doSwitchClassInstanceWithOverload + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 296 + i32.const 1 + call $~lib/builtins/abort + unreachable end - i32.const 4 - local.set $2 global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 36 i32.add global.set $~lib/memory/__stack_pointer - local.get $2 - return ) - (func $switch/doSwitchNullableString (param $s i32) (result i32) + (func $switch/doSwitchClassInstance (param $foo i32) (result i32) (local $1 i32) (local $2 i32) global.get $~lib/memory/__stack_pointer @@ -3869,52 +5148,24 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store - block $case4|0 - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - global.get $~lib/memory/__stack_pointer - local.get $s - local.tee $1 - i32.store - local.get $1 - i32.const 0 - i32.eq - br_if $case0|0 - local.get $1 - i32.const 80 - i32.eq - br_if $case1|0 - local.get $1 - i32.const 112 - i32.eq - br_if $case2|0 - local.get $1 - i32.const 144 - i32.eq - br_if $case3|0 - br $case4|0 - end - i32.const 0 - local.set $2 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $2 - return - end - i32.const 1 - local.set $2 + block $case2|0 + block $case1|0 + block $case0|0 global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $2 - return + local.get $foo + local.tee $1 + i32.store + local.get $1 + global.get $switch/foo1 + i32.eq + br_if $case0|0 + local.get $1 + global.get $switch/foo2 + i32.eq + br_if $case1|0 + br $case2|0 end - i32.const 2 + i32.const 1 local.set $2 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -3923,7 +5174,7 @@ local.get $2 return end - i32.const 3 + i32.const 2 local.set $2 global.get $~lib/memory/__stack_pointer i32.const 4 @@ -3932,7 +5183,7 @@ local.get $2 return end - i32.const 4 + i32.const 3 local.set $2 global.get $~lib/memory/__stack_pointer i32.const 4 diff --git a/tests/compiler/switch.release.wat b/tests/compiler/switch.release.wat index 3e05d41f76..4cc8b72c51 100644 --- a/tests/compiler/switch.release.wat +++ b/tests/compiler/switch.release.wat @@ -1,11 +1,12 @@ (module (type $0 (func (param i32) (result i32))) - (type $1 (func)) - (type $2 (func (param i32))) - (type $3 (func (param i32 i32))) - (type $4 (func (result i32))) + (type $1 (func (param i32 i32) (result i32))) + (type $2 (func)) + (type $3 (func (param i32))) + (type $4 (func (param i32 i32))) (type $5 (func (param i32 i32 i32 i32))) (type $6 (func (param i32 i32 i64))) + (type $7 (func (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (global $~lib/rt/itcms/total (mut i32) (i32.const 0)) (global $~lib/rt/itcms/threshold (mut i32) (i32.const 0)) @@ -17,7 +18,9 @@ (global $~lib/rt/itcms/white (mut i32) (i32.const 0)) (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34408)) + (global $switch/foo1 (mut i32) (i32.const 0)) + (global $switch/foo2 (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34732)) (memory $0 1) (data $0 (i32.const 1036) ",") (data $0.1 (i32.const 1048) "\02\00\00\00\12\00\00\00s\00w\00i\00t\00c\00h\00.\00t\00s") @@ -29,25 +32,57 @@ (data $3.1 (i32.const 1160) "\02\00\00\00\n\00\00\00t\00h\00r\00e\00e") (data $4 (i32.const 1180) "\1c") (data $4.1 (i32.const 1192) "\02\00\00\00\08\00\00\00f\00o\00u\00r") - (data $5 (i32.const 1212) "<") - (data $5.1 (i32.const 1224) "\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e") - (data $6 (i32.const 1276) "<") - (data $6.1 (i32.const 1288) "\02\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s") - (data $9 (i32.const 1404) "<") - (data $9.1 (i32.const 1416) "\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e") - (data $10 (i32.const 1468) ",") - (data $10.1 (i32.const 1480) "\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s") - (data $12 (i32.const 1548) "<") - (data $12.1 (i32.const 1560) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") - (data $13 (i32.const 1616) "\05\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 ") + (data $5 (i32.const 1212) "\1c") + (data $5.1 (i32.const 1224) "\02\00\00\00\02\00\00\00o") + (data $6 (i32.const 1244) "\1c") + (data $6.1 (i32.const 1256) "\02\00\00\00\02\00\00\00n") + (data $7 (i32.const 1276) "\1c") + (data $7.1 (i32.const 1288) "\02") + (data $8 (i32.const 1308) "<") + (data $8.1 (i32.const 1320) "\02\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e") + (data $9 (i32.const 1372) "<") + (data $9.1 (i32.const 1384) "\02\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s") + (data $12 (i32.const 1500) "<") + (data $12.1 (i32.const 1512) "\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e") + (data $13 (i32.const 1564) ",") + (data $13.1 (i32.const 1576) "\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s") + (data $15 (i32.const 1644) "<") + (data $15.1 (i32.const 1656) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") + (data $16 (i32.const 1708) "\1c") + (data $16.1 (i32.const 1720) "\02\00\00\00\02\00\00\00e") + (data $17 (i32.const 1740) "\1c") + (data $17.1 (i32.const 1752) "\02\00\00\00\02\00\00\00t") + (data $18 (i32.const 1772) "\1c") + (data $18.1 (i32.const 1784) "\02\00\00\00\02\00\00\00w") + (data $19 (i32.const 1804) "\1c") + (data $19.1 (i32.const 1816) "\02\00\00\00\02\00\00\00h") + (data $20 (i32.const 1836) "\1c") + (data $20.1 (i32.const 1848) "\02\00\00\00\02\00\00\00r") + (data $21 (i32.const 1868) "\1c") + (data $21.1 (i32.const 1880) "\02\00\00\00\02\00\00\00f") + (data $22 (i32.const 1900) "\1c") + (data $22.1 (i32.const 1912) "\02\00\00\00\02\00\00\00u") + (data $23 (i32.const 1936) "\06\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 ") (export "memory" (memory $0)) (start $~start) (func $~lib/rt/itcms/visitRoots (local $0 i32) (local $1 i32) - i32.const 1424 + global.get $switch/foo1 + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $switch/foo2 + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + i32.const 1520 call $~lib/rt/itcms/__visit - i32.const 1232 + i32.const 1328 call $~lib/rt/itcms/__visit global.get $~lib/rt/itcms/pinSpace local.tee $1 @@ -68,7 +103,7 @@ i32.ne if i32.const 0 - i32.const 1296 + i32.const 1392 i32.const 160 i32.const 16 call $~lib/builtins/abort @@ -116,7 +151,7 @@ i32.eqz if i32.const 0 - i32.const 1296 + i32.const 1392 i32.const 148 i32.const 30 call $~lib/builtins/abort @@ -125,7 +160,7 @@ local.get $0 global.set $~lib/rt/itcms/iter end - block $__inlined_func$~lib/rt/itcms/Object#unlink$169 + block $__inlined_func$~lib/rt/itcms/Object#unlink$186 local.get $1 i32.load offset=4 i32.const -4 @@ -137,19 +172,19 @@ i32.load offset=8 i32.eqz local.get $1 - i32.const 34408 + i32.const 34732 i32.lt_u i32.and i32.eqz if i32.const 0 - i32.const 1296 + i32.const 1392 i32.const 128 i32.const 18 call $~lib/builtins/abort unreachable end - br $__inlined_func$~lib/rt/itcms/Object#unlink$169 + br $__inlined_func$~lib/rt/itcms/Object#unlink$186 end local.get $1 i32.load offset=8 @@ -157,7 +192,7 @@ i32.eqz if i32.const 0 - i32.const 1296 + i32.const 1392 i32.const 132 i32.const 16 call $~lib/builtins/abort @@ -186,12 +221,12 @@ i32.const 1 else local.get $0 - i32.const 1616 + i32.const 1936 i32.load i32.gt_u if - i32.const 1424 - i32.const 1488 + i32.const 1520 + i32.const 1584 i32.const 21 i32.const 28 call $~lib/builtins/abort @@ -200,7 +235,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 1620 + i32.const 1940 i32.add i32.load i32.const 32 @@ -252,7 +287,7 @@ i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 268 i32.const 14 call $~lib/builtins/abort @@ -266,7 +301,7 @@ i32.lt_u if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 270 i32.const 14 call $~lib/builtins/abort @@ -312,7 +347,7 @@ i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 284 i32.const 14 call $~lib/builtins/abort @@ -395,7 +430,7 @@ i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 201 i32.const 14 call $~lib/builtins/abort @@ -409,7 +444,7 @@ i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 203 i32.const 14 call $~lib/builtins/abort @@ -470,7 +505,7 @@ i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 221 i32.const 16 call $~lib/builtins/abort @@ -503,7 +538,7 @@ i32.lt_u if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 233 i32.const 14 call $~lib/builtins/abort @@ -518,7 +553,7 @@ i32.ne if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 234 i32.const 14 call $~lib/builtins/abort @@ -569,7 +604,7 @@ i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 251 i32.const 14 call $~lib/builtins/abort @@ -641,7 +676,7 @@ i64.lt_u if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 382 i32.const 14 call $~lib/builtins/abort @@ -666,7 +701,7 @@ i32.gt_u if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 389 i32.const 16 call $~lib/builtins/abort @@ -693,7 +728,7 @@ i32.gt_u if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 402 i32.const 5 call $~lib/builtins/abort @@ -765,10 +800,10 @@ if unreachable end - i32.const 34416 + i32.const 34736 i32.const 0 i32.store - i32.const 35984 + i32.const 36304 i32.const 0 i32.store loop $for-loop|0 @@ -779,7 +814,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 34416 + i32.const 34736 i32.add i32.const 0 i32.store offset=4 @@ -797,7 +832,7 @@ i32.add i32.const 2 i32.shl - i32.const 34416 + i32.const 34736 i32.add i32.const 0 i32.store offset=96 @@ -815,14 +850,14 @@ br $for-loop|0 end end - i32.const 34416 - i32.const 35988 + i32.const 34736 + i32.const 36308 memory.size i64.extend_i32_s i64.const 16 i64.shl call $~lib/rt/tlsf/addMemory - i32.const 34416 + i32.const 34736 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (result i32) @@ -907,7 +942,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 34408 + i32.const 34732 i32.lt_u if local.get $0 @@ -996,14 +1031,14 @@ i32.ne if i32.const 0 - i32.const 1296 + i32.const 1392 i32.const 229 i32.const 20 call $~lib/builtins/abort unreachable end local.get $0 - i32.const 34408 + i32.const 34732 i32.lt_u if local.get $0 @@ -1026,7 +1061,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 34408 + i32.const 34732 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1056,7 +1091,7 @@ end if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 562 i32.const 3 call $~lib/builtins/abort @@ -1087,18 +1122,85 @@ end i32.const 0 ) - (func $~lib/rt/tlsf/searchBlock (param $0 i32) (result i32) - (local $1 i32) + (func $~lib/rt/tlsf/searchBlock (param $0 i32) (param $1 i32) (result i32) (local $2 i32) + local.get $1 + i32.const 256 + i32.lt_u + if + local.get $1 + i32.const 4 + i32.shr_u + local.set $1 + else + local.get $1 + i32.const 536870910 + i32.lt_u + if + local.get $1 + i32.const 1 + i32.const 27 + local.get $1 + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + local.set $1 + end + local.get $1 + i32.const 31 + local.get $1 + i32.clz + i32.sub + local.tee $2 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + local.set $1 + local.get $2 + i32.const 7 + i32.sub + local.set $2 + end + local.get $1 + i32.const 16 + i32.lt_u + local.get $2 + i32.const 23 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1664 + i32.const 334 + i32.const 14 + call $~lib/builtins/abort + unreachable + end local.get $0 + local.get $2 + i32.const 2 + i32.shl + i32.add i32.load offset=4 - i32.const -2 + i32.const -1 + local.get $1 + i32.shl i32.and local.tee $1 if (result i32) local.get $0 local.get $1 i32.ctz + local.get $2 + i32.const 4 + i32.shl + i32.add i32.const 2 i32.shl i32.add @@ -1106,32 +1208,36 @@ else local.get $0 i32.load - i32.const -2 + i32.const -1 + local.get $2 + i32.const 1 + i32.add + i32.shl i32.and local.tee $1 if (result i32) local.get $0 local.get $1 i32.ctz - local.tee $2 + local.tee $1 i32.const 2 i32.shl i32.add i32.load offset=4 - local.tee $1 + local.tee $2 i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 347 i32.const 18 call $~lib/builtins/abort unreachable end local.get $0 - local.get $1 - i32.ctz local.get $2 + i32.ctz + local.get $1 i32.const 4 i32.shl i32.add @@ -1144,23 +1250,35 @@ end end ) - (func $~lib/rt/itcms/__new (result i32) - (local $0 i32) - (local $1 i32) + (func $~lib/rt/itcms/__new (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + local.get $0 + i32.const 1073741804 + i32.ge_u + if + i32.const 1328 + i32.const 1392 + i32.const 261 + i32.const 31 + call $~lib/builtins/abort + unreachable + end global.get $~lib/rt/itcms/total global.get $~lib/rt/itcms/threshold i32.ge_u if - block $__inlined_func$~lib/rt/itcms/interrupt$69 + block $__inlined_func$~lib/rt/itcms/interrupt$70 i32.const 2048 - local.set $0 + local.set $2 loop $do-loop|0 - local.get $0 + local.get $2 call $~lib/rt/itcms/step i32.sub - local.set $0 + local.set $2 global.get $~lib/rt/itcms/state i32.eqz if @@ -1174,9 +1292,9 @@ i32.const 1024 i32.add global.set $~lib/rt/itcms/threshold - br $__inlined_func$~lib/rt/itcms/interrupt$69 + br $__inlined_func$~lib/rt/itcms/interrupt$70 end - local.get $0 + local.get $2 i32.const 0 i32.gt_s br_if $do-loop|0 @@ -1199,39 +1317,94 @@ call $~lib/rt/tlsf/initialize end global.get $~lib/rt/tlsf/ROOT - local.tee $1 + local.set $4 + local.get $0 + i32.const 16 + i32.add + local.tee $2 + i32.const 1073741820 + i32.gt_u + if + i32.const 1328 + i32.const 1664 + i32.const 461 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $4 + local.get $2 + i32.const 12 + i32.le_u + if (result i32) + i32.const 12 + else + local.get $2 + i32.const 19 + i32.add + i32.const -16 + i32.and + i32.const 4 + i32.sub + end + local.tee $5 call $~lib/rt/tlsf/searchBlock - local.tee $0 + local.tee $2 i32.eqz if memory.size - local.tee $0 + local.tee $2 + local.get $5 + i32.const 256 + i32.ge_u + if (result i32) + local.get $5 + i32.const 536870910 + i32.lt_u + if (result i32) + local.get $5 + i32.const 1 + i32.const 27 + local.get $5 + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + else + local.get $5 + end + else + local.get $5 + end i32.const 4 - local.get $1 + local.get $4 i32.load offset=1568 - local.get $0 + local.get $2 i32.const 16 i32.shl i32.const 4 i32.sub i32.ne i32.shl - i32.const 65563 + i32.add + i32.const 65535 i32.add i32.const -65536 i32.and i32.const 16 i32.shr_u - local.tee $2 - local.get $0 + local.tee $3 local.get $2 + local.get $3 i32.gt_s select memory.grow i32.const 0 i32.lt_s if - local.get $2 + local.get $3 memory.grow i32.const 0 i32.lt_s @@ -1239,8 +1412,8 @@ unreachable end end - local.get $1 - local.get $0 + local.get $4 + local.get $2 i32.const 16 i32.shl memory.size @@ -1248,119 +1421,136 @@ i64.const 16 i64.shl call $~lib/rt/tlsf/addMemory - local.get $1 + local.get $4 + local.get $5 call $~lib/rt/tlsf/searchBlock - local.tee $0 + local.tee $2 i32.eqz if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 499 i32.const 16 call $~lib/builtins/abort unreachable end end - local.get $0 + local.get $5 + local.get $2 i32.load i32.const -4 i32.and - i32.const 28 - i32.lt_u + i32.gt_u if i32.const 0 - i32.const 1568 + i32.const 1664 i32.const 501 i32.const 14 call $~lib/builtins/abort unreachable end - local.get $1 - local.get $0 + local.get $4 + local.get $2 call $~lib/rt/tlsf/removeBlock - local.get $0 + local.get $2 i32.load - local.tee $2 + local.set $6 + local.get $5 + i32.const 4 + i32.add + i32.const 15 + i32.and + if + i32.const 0 + i32.const 1664 + i32.const 361 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $6 i32.const -4 i32.and - i32.const 28 + local.get $5 i32.sub local.tee $3 i32.const 16 i32.ge_u if - local.get $0 local.get $2 + local.get $5 + local.get $6 i32.const 2 i32.and - i32.const 28 i32.or i32.store - local.get $0 - i32.const 32 + local.get $2 + i32.const 4 i32.add - local.tee $2 + local.get $5 + i32.add + local.tee $5 local.get $3 i32.const 4 i32.sub i32.const 1 i32.or i32.store - local.get $1 - local.get $2 + local.get $4 + local.get $5 call $~lib/rt/tlsf/insertBlock else - local.get $0 local.get $2 + local.get $6 i32.const -2 i32.and i32.store - local.get $0 + local.get $2 i32.const 4 i32.add - local.get $0 + local.get $2 i32.load i32.const -4 i32.and i32.add - local.tee $1 - local.get $1 + local.tee $3 + local.get $3 i32.load i32.const -3 i32.and i32.store end - local.get $0 - i32.const 4 + local.get $2 + local.get $1 i32.store offset=12 + local.get $2 local.get $0 - i32.const 4 i32.store offset=16 global.get $~lib/rt/itcms/fromSpace local.tee $1 i32.load offset=8 - local.set $2 - local.get $0 + local.set $3 + local.get $2 local.get $1 global.get $~lib/rt/itcms/white i32.or i32.store offset=4 - local.get $0 local.get $2 + local.get $3 i32.store offset=8 + local.get $3 local.get $2 - local.get $0 - local.get $2 + local.get $3 i32.load offset=4 i32.const 3 i32.and i32.or i32.store offset=4 local.get $1 - local.get $0 + local.get $2 i32.store offset=8 global.get $~lib/rt/itcms/total - local.get $0 + local.get $2 i32.load i32.const -4 i32.and @@ -1368,39 +1558,43 @@ i32.add i32.add global.set $~lib/rt/itcms/total - local.get $0 + local.get $2 i32.const 20 i32.add - local.tee $0 + local.tee $1 i32.const 0 - i32.store align=1 local.get $0 + memory.fill + local.get $1 ) (func $~lib/rt/__visit_members (param $0 i32) block $invalid - block $switch/FooClass - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer - block $~lib/object/Object - local.get $0 - i32.const 8 - i32.sub - i32.load - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $switch/FooClass $invalid + block $switch/BarClass + block $switch/FooClass + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $switch/FooClass $switch/BarClass $invalid + end + return end return end return end - return - end - local.get $0 - i32.load - local.tee $0 - if local.get $0 - call $~lib/rt/itcms/__visit + i32.load + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + return end return end @@ -1411,18 +1605,21 @@ (func $~start call $start:switch ) - (func $switch/FooClass#constructor (param $0 i32) (result i32) - (local $1 i32) + (func $~lib/string/String.__eq (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) global.get $~lib/memory/__stack_pointer i32.const 8 i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1640 + i32.const 1964 i32.lt_s if - i32.const 34432 - i32.const 34480 + i32.const 34752 + i32.const 34800 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -1431,115 +1628,1042 @@ global.get $~lib/memory/__stack_pointer i64.const 0 i64.store - global.get $~lib/memory/__stack_pointer + local.get $0 + local.get $1 + i32.eq + if + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + block $folding-inner0 + local.get $1 + i32.eqz + local.get $0 + i32.eqz + i32.or + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + i32.const 20 + i32.sub + i32.load offset=16 + i32.const 1 + i32.shr_u + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $3 + local.get $1 + i32.const 20 + i32.sub + i32.load offset=16 + i32.const 1 + i32.shr_u + i32.ne + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $3 + local.tee $0 + i32.const 4 + i32.ge_u + if (result i32) + local.get $2 + i32.const 7 + i32.and + local.get $1 + i32.const 7 + i32.and + i32.or + else + i32.const 1 + end + i32.eqz + if + loop $do-loop|0 + local.get $2 + i64.load + local.get $1 + i64.load + i64.eq + if + local.get $2 + i32.const 8 + i32.add + local.set $2 + local.get $1 + i32.const 8 + i32.add + local.set $1 + local.get $0 + i32.const 4 + i32.sub + local.tee $0 + i32.const 4 + i32.ge_u + br_if $do-loop|0 + end + end + end + block $__inlined_func$~lib/util/string/compareImpl$76 + loop $while-continue|1 + local.get $0 + local.tee $3 + i32.const 1 + i32.sub + local.set $0 + local.get $3 + if + local.get $2 + i32.load16_u + local.tee $5 + local.get $1 + i32.load16_u + local.tee $4 + i32.sub + local.set $3 + local.get $4 + local.get $5 + i32.ne + br_if $__inlined_func$~lib/util/string/compareImpl$76 + local.get $2 + i32.const 2 + i32.add + local.set $2 + local.get $1 + i32.const 2 + i32.add + local.set $1 + br $while-continue|1 + end + end + i32.const 0 + local.set $3 + end + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + i32.eqz + return + end + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 0 + ) + (func $switch/doSwitchString (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1104 + i32.store offset=8 + block $case3|0 + block $case2|0 + block $case1|0 + local.get $0 + i32.const 1104 + call $~lib/string/String.__eq + i32.eqz + if + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1136 + i32.store offset=8 + local.get $0 + i32.const 1136 + call $~lib/string/String.__eq + br_if $case1|0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store offset=8 + local.get $0 + i32.const 1168 + call $~lib/string/String.__eq + br_if $case2|0 + br $case3|0 + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 2 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 3 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 4 + ) + (func $~lib/string/String.__concat (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + local.get $0 + local.tee $2 + i32.store + local.get $0 + i32.const 20 + i32.sub + i32.load offset=16 + i32.const -2 + i32.and + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + block $__inlined_func$~lib/string/String#concat$191 + local.get $1 + i32.const 20 + i32.sub + i32.load offset=16 + i32.const -2 + i32.and + local.tee $4 + local.get $3 + i32.add + local.tee $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1296 + local.set $0 + br $__inlined_func$~lib/string/String#concat$191 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.const 2 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store offset=4 + local.get $0 + local.get $2 + local.get $3 + memory.copy + local.get $0 + local.get $3 + i32.add + local.get $1 + local.get $4 + memory.copy + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + end + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + return + end + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + ) + (func $switch/doSwitchNullableString (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + local.get $0 + i32.const 0 + call $~lib/string/String.__eq + i32.eqz + if + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1104 + i32.store offset=8 + local.get $0 + i32.const 1104 + call $~lib/string/String.__eq + br_if $case1|0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1136 + i32.store offset=8 + local.get $0 + i32.const 1136 + call $~lib/string/String.__eq + br_if $case2|0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store offset=8 + local.get $0 + i32.const 1168 + call $~lib/string/String.__eq + br_if $case3|0 + br $case4|0 + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 0 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 2 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 3 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 4 + ) + (func $switch/FooClass#constructor (param $0 i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 4 + call $~lib/rt/itcms/__new + local.tee $1 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $switch/doSwitchClassMember (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + block $case2|0 + block $case1|0 + local.get $0 + i32.load + local.tee $0 + i32.const 1 + i32.ne + if + local.get $0 + i32.const 2 + i32.eq + br_if $case1|0 + br $case2|0 + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 2 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 3 + ) + (func $switch/BarClass.__eq (param $0 i32) (param $1 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $0 + local.get $1 + i32.eq + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + local.get $1 + i32.eqz + local.get $0 + i32.eqz + i32.or + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 0 + return + end + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + i32.load + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $0 + local.get $1 + i32.load + i32.eq + local.set $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) + (func $switch/BarClass#constructor (param $0 i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 5 call $~lib/rt/itcms/__new local.tee $1 i32.store global.get $~lib/memory/__stack_pointer - local.get $1 - i32.store offset=4 - local.get $1 - i32.const 0 - i32.store + local.get $1 + i32.store offset=4 + local.get $1 + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $switch/doSwitchClassInstanceWithOverload (param $0 i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + block $case3|0 + block $case2|0 + block $case1|0 + local.get $0 + i32.const 0 + call $switch/BarClass.__eq + i32.eqz + if + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + i32.const 1 + call $switch/BarClass#constructor + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=8 + local.get $0 + local.get $1 + call $switch/BarClass.__eq + br_if $case1|0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + i32.const 2 + call $switch/BarClass#constructor + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=8 + local.get $0 + local.get $1 + call $switch/BarClass.__eq + br_if $case2|0 + br $case3|0 + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 0 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 1 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 2 + return + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 3 + ) + (func $start:switch + (local $0 i32) + global.get $~lib/memory/__stack_pointer + i32.const 36 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1964 + i32.lt_s + if + i32.const 34752 + i32.const 34800 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 36 + memory.fill + global.get $~lib/memory/__stack_pointer + i32.const 1104 + i32.store + i32.const 1104 + call $switch/doSwitchString + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 106 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1136 + i32.store + i32.const 1136 + call $switch/doSwitchString + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 107 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store + i32.const 1168 + call $switch/doSwitchString + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 108 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1200 + i32.store + i32.const 1200 + call $switch/doSwitchString + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 109 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + memory.size + i32.const 16 + i32.shl + i32.const 34732 + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 1444 + i32.const 1440 + i32.store + i32.const 1448 + i32.const 1440 + i32.store + i32.const 1440 + global.set $~lib/rt/itcms/pinSpace + i32.const 1476 + i32.const 1472 + i32.store + i32.const 1480 + i32.const 1472 + i32.store + i32.const 1472 + global.set $~lib/rt/itcms/toSpace + i32.const 1620 + i32.const 1616 + i32.store + i32.const 1624 + i32.const 1616 + i32.store + i32.const 1616 + global.set $~lib/rt/itcms/fromSpace + global.get $~lib/memory/__stack_pointer + i32.const 1232 + i32.store offset=12 global.get $~lib/memory/__stack_pointer - local.get $1 + i32.const 1264 + i32.store offset=16 + i32.const 1232 + i32.const 1264 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 i32.store offset=4 - local.get $1 + global.get $~lib/memory/__stack_pointer + i32.const 1728 + i32.store offset=8 + local.get $0 + i32.const 1728 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer local.get $0 i32.store + local.get $0 + call $switch/doSwitchString + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 112 + i32.const 1 + call $~lib/builtins/abort + unreachable + end global.get $~lib/memory/__stack_pointer - i32.const 8 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $1 - ) - (func $switch/doSwitchClassMember (param $0 i32) (result i32) + i32.const 1760 + i32.store offset=12 global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer + i32.const 1792 + i32.store offset=16 + i32.const 1760 + i32.const 1792 + call $~lib/string/String.__concat + local.set $0 global.get $~lib/memory/__stack_pointer - i32.const 1640 - i32.lt_s + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1232 + i32.store offset=8 + local.get $0 + i32.const 1232 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 2 + i32.ne if - i32.const 34432 - i32.const 34480 - i32.const 1 + i32.const 0 + i32.const 1056 + i32.const 113 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store + i32.const 1760 + i32.store offset=28 + global.get $~lib/memory/__stack_pointer + i32.const 1824 + i32.store offset=32 + i32.const 1760 + i32.const 1824 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=20 + global.get $~lib/memory/__stack_pointer + i32.const 1856 + i32.store offset=24 + local.get $0 + i32.const 1856 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 1728 + i32.store offset=16 + local.get $0 + i32.const 1728 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1728 + i32.store offset=8 + local.get $0 + i32.const 1728 + call $~lib/string/String.__concat + local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 i32.store - block $case2|0 - block $case1|0 - local.get $0 - i32.load - local.tee $0 - i32.const 1 - i32.ne - if - local.get $0 - i32.const 2 - i32.eq - br_if $case1|0 - br $case2|0 - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 1 - return - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 2 - return + local.get $0 + call $switch/doSwitchString + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 114 + i32.const 1 + call $~lib/builtins/abort + unreachable end global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 0 - ) - (func $start:switch - (local $0 i32) + i32.const 1888 + i32.store offset=20 global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer + i32.const 1232 + i32.store offset=24 + i32.const 1888 + i32.const 1232 + call $~lib/string/String.__concat + local.set $0 global.get $~lib/memory/__stack_pointer - i32.const 1640 - i32.lt_s + local.get $0 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 1920 + i32.store offset=16 + local.get $0 + i32.const 1920 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1856 + i32.store offset=8 + local.get $0 + i32.const 1856 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchString + i32.const 4 + i32.ne if - i32.const 34432 - i32.const 34480 - i32.const 1 + i32.const 0 + i32.const 1056 + i32.const 115 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/memory/__stack_pointer i32.const 0 - i32.store + call $switch/doSwitchNullableString + if + i32.const 0 + i32.const 1056 + i32.const 128 + i32.const 1 + call $~lib/builtins/abort + unreachable + end global.get $~lib/memory/__stack_pointer i32.const 1104 i32.store i32.const 1104 - call $switch/doSwitchString + call $switch/doSwitchNullableString i32.const 1 i32.ne if i32.const 0 i32.const 1056 - i32.const 104 + i32.const 129 i32.const 1 call $~lib/builtins/abort unreachable @@ -1548,283 +2672,407 @@ i32.const 1136 i32.store i32.const 1136 - call $switch/doSwitchString + call $switch/doSwitchNullableString + i32.const 2 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 130 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1168 + i32.store + i32.const 1168 + call $switch/doSwitchNullableString + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 131 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1200 + i32.store + i32.const 1200 + call $switch/doSwitchNullableString + i32.const 4 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 132 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1232 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 1264 + i32.store offset=16 + i32.const 1232 + i32.const 1264 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1728 + i32.store offset=8 + local.get $0 + i32.const 1728 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchNullableString + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 135 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 1760 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 1792 + i32.store offset=16 + i32.const 1760 + i32.const 1792 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1232 + i32.store offset=8 + local.get $0 + i32.const 1232 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchNullableString i32.const 2 i32.ne if i32.const 0 i32.const 1056 - i32.const 105 + i32.const 136 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 1168 + i32.const 1760 + i32.store offset=28 + global.get $~lib/memory/__stack_pointer + i32.const 1824 + i32.store offset=32 + i32.const 1760 + i32.const 1824 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=20 + global.get $~lib/memory/__stack_pointer + i32.const 1856 + i32.store offset=24 + local.get $0 + i32.const 1856 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 1728 + i32.store offset=16 + local.get $0 + i32.const 1728 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1728 + i32.store offset=8 + local.get $0 + i32.const 1728 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 i32.store - i32.const 1168 - call $switch/doSwitchString + local.get $0 + call $switch/doSwitchNullableString i32.const 3 i32.ne if i32.const 0 i32.const 1056 - i32.const 106 + i32.const 137 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 1200 + i32.const 1888 + i32.store offset=20 + global.get $~lib/memory/__stack_pointer + i32.const 1232 + i32.store offset=24 + i32.const 1888 + i32.const 1232 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 1920 + i32.store offset=16 + local.get $0 + i32.const 1920 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 1856 + i32.store offset=8 + local.get $0 + i32.const 1856 + call $~lib/string/String.__concat + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 i32.store - i32.const 1200 - call $switch/doSwitchString + local.get $0 + call $switch/doSwitchNullableString i32.const 4 i32.ne if i32.const 0 i32.const 1056 - i32.const 107 + i32.const 138 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 0 - call $switch/doSwitchNullableString + i32.const 1 + call $switch/FooClass#constructor + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassMember + i32.const 1 + i32.ne if i32.const 0 i32.const 1056 - i32.const 118 + i32.const 251 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 2 + call $switch/FooClass#constructor + local.set $0 global.get $~lib/memory/__stack_pointer - i32.const 1104 + local.get $0 i32.store - i32.const 1104 - call $switch/doSwitchNullableString - i32.const 1 + local.get $0 + call $switch/doSwitchClassMember + i32.const 2 i32.ne if i32.const 0 i32.const 1056 - i32.const 119 + i32.const 252 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 3 + call $switch/FooClass#constructor + local.set $0 global.get $~lib/memory/__stack_pointer - i32.const 1136 + local.get $0 i32.store - i32.const 1136 - call $switch/doSwitchNullableString - i32.const 2 + local.get $0 + call $switch/doSwitchClassMember + i32.const 3 i32.ne if i32.const 0 i32.const 1056 - i32.const 120 + i32.const 253 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 1 + call $switch/FooClass#constructor + global.set $switch/foo1 + i32.const 2 + call $switch/FooClass#constructor + global.set $switch/foo2 global.get $~lib/memory/__stack_pointer - i32.const 1168 + global.get $switch/foo1 + local.tee $0 i32.store - i32.const 1168 - call $switch/doSwitchNullableString - i32.const 3 + local.get $0 + call $switch/doSwitchClassInstance + i32.const 1 i32.ne if i32.const 0 i32.const 1056 - i32.const 121 + i32.const 266 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 1200 + global.get $switch/foo2 + local.tee $0 i32.store - i32.const 1200 - call $switch/doSwitchNullableString - i32.const 4 + local.get $0 + call $switch/doSwitchClassInstance + i32.const 2 i32.ne if i32.const 0 i32.const 1056 - i32.const 122 + i32.const 267 i32.const 1 call $~lib/builtins/abort unreachable end - memory.size - i32.const 16 - i32.shl - i32.const 34408 - i32.sub i32.const 1 - i32.shr_u - global.set $~lib/rt/itcms/threshold - i32.const 1348 - i32.const 1344 - i32.store - i32.const 1352 - i32.const 1344 - i32.store - i32.const 1344 - global.set $~lib/rt/itcms/pinSpace - i32.const 1380 - i32.const 1376 - i32.store - i32.const 1384 - i32.const 1376 - i32.store - i32.const 1376 - global.set $~lib/rt/itcms/toSpace - i32.const 1524 - i32.const 1520 - i32.store - i32.const 1528 - i32.const 1520 - i32.store - i32.const 1520 - global.set $~lib/rt/itcms/fromSpace - i32.const 0 call $switch/FooClass#constructor local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 i32.store local.get $0 - call $switch/doSwitchClassMember + call $switch/doSwitchClassInstance + i32.const 3 + i32.ne if i32.const 0 i32.const 1056 - i32.const 234 + i32.const 268 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $switch/doSwitchClassInstanceWithOverload + if + i32.const 0 + i32.const 1056 + i32.const 293 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 1 - call $switch/FooClass#constructor + call $switch/BarClass#constructor local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 i32.store local.get $0 - call $switch/doSwitchClassMember + call $switch/doSwitchClassInstanceWithOverload i32.const 1 i32.ne if i32.const 0 i32.const 1056 - i32.const 235 + i32.const 294 i32.const 1 call $~lib/builtins/abort unreachable end i32.const 2 - call $switch/FooClass#constructor + call $switch/BarClass#constructor local.set $0 global.get $~lib/memory/__stack_pointer local.get $0 i32.store local.get $0 - call $switch/doSwitchClassMember + call $switch/doSwitchClassInstanceWithOverload i32.const 2 i32.ne if i32.const 0 i32.const 1056 - i32.const 236 + i32.const 295 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 3 + call $switch/BarClass#constructor + local.set $0 global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - ) - (func $switch/doSwitchString (param $0 i32) (result i32) - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1640 - i32.lt_s + local.get $0 + i32.store + local.get $0 + call $switch/doSwitchClassInstanceWithOverload + i32.const 3 + i32.ne if - i32.const 34432 - i32.const 34480 - i32.const 1 + i32.const 0 + i32.const 1056 + i32.const 296 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store - block $case3|0 - block $case2|0 - block $case1|0 - local.get $0 - i32.const 1104 - i32.ne - if - local.get $0 - i32.const 1136 - i32.eq - br_if $case1|0 - local.get $0 - i32.const 1168 - i32.eq - br_if $case2|0 - br $case3|0 - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 1 - return - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 2 - return - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 3 - return - end - global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 36 i32.add global.set $~lib/memory/__stack_pointer - i32.const 4 ) - (func $switch/doSwitchNullableString (param $0 i32) (result i32) + (func $switch/doSwitchClassInstance (param $0 i32) (result i32) global.get $~lib/memory/__stack_pointer i32.const 4 i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1640 + i32.const 1964 i32.lt_s if - i32.const 34432 - i32.const 34480 + i32.const 34752 + i32.const 34800 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -1836,58 +3084,36 @@ global.get $~lib/memory/__stack_pointer local.get $0 i32.store - block $case4|0 - block $case3|0 - block $case2|0 - block $case1|0 - local.get $0 - if - local.get $0 - i32.const 1104 - i32.eq - br_if $case1|0 - local.get $0 - i32.const 1136 - i32.eq - br_if $case2|0 - local.get $0 - i32.const 1168 - i32.eq - br_if $case3|0 - br $case4|0 - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 0 - return - end - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - i32.const 1 - return + block $case2|0 + block $case1|0 + global.get $switch/foo1 + local.get $0 + i32.ne + if + local.get $0 + global.get $switch/foo2 + i32.eq + br_if $case1|0 + br $case2|0 end global.get $~lib/memory/__stack_pointer i32.const 4 i32.add global.set $~lib/memory/__stack_pointer - i32.const 2 + i32.const 1 return end global.get $~lib/memory/__stack_pointer i32.const 4 i32.add global.set $~lib/memory/__stack_pointer - i32.const 3 + i32.const 2 return end global.get $~lib/memory/__stack_pointer i32.const 4 i32.add global.set $~lib/memory/__stack_pointer - i32.const 4 + i32.const 3 ) ) diff --git a/tests/compiler/switch.ts b/tests/compiler/switch.ts index a471c284b5..11167dc19f 100644 --- a/tests/compiler/switch.ts +++ b/tests/compiler/switch.ts @@ -101,11 +101,19 @@ function doSwitchString(s: string): i32 { default: return 4; } } + +// these will pass regardless of whether the comparison is done by value or reference assert(doSwitchString("one") == 1); assert(doSwitchString("two") == 2); assert(doSwitchString("three") == 3); assert(doSwitchString("four") == 4); +// these would fail if the comparison was done by reference +assert(doSwitchString("o" + "n" + "e") == 1); +assert(doSwitchString("t" + "w" + "o") == 2); +assert(doSwitchString("t" + "h" + "r" + "e" + "e") == 3); +assert(doSwitchString("f" + "o" + "u" + "r") == 4); + function doSwitchNullableString(s: string | null): i32 { switch (s) { case null: return 0; @@ -115,12 +123,20 @@ function doSwitchNullableString(s: string | null): i32 { default: return 4; } } + +// these will pass regardless of whether the comparison is done by value or reference assert(doSwitchNullableString(null) == 0); assert(doSwitchNullableString("one") == 1); assert(doSwitchNullableString("two") == 2); assert(doSwitchNullableString("three") == 3); assert(doSwitchNullableString("four") == 4); +// these would fail if the comparison was done by reference +assert(doSwitchNullableString("o" + "n" + "e") == 1); +assert(doSwitchNullableString("t" + "w" + "o") == 2); +assert(doSwitchNullableString("t" + "h" + "r" + "e" + "e") == 3); +assert(doSwitchNullableString("f" + "o" + "u" + "r") == 4); + function doSwitchBoolean(b: bool): i32 { switch (b) { case true: return 1; @@ -216,6 +232,7 @@ assert(doSwitchUInt64(1) == 1); assert(doSwitchUInt64(2) == 2); +// class members should switch like any other expression class FooClass { value: i32; @@ -228,33 +245,52 @@ function doSwitchClassMember(foo: FooClass): i32 { switch (foo.value) { case 1: return 1; case 2: return 2; - default: return 0; + default: return 3; } } -assert(doSwitchClassMember(new FooClass(0)) == 0); assert(doSwitchClassMember(new FooClass(1)) == 1); assert(doSwitchClassMember(new FooClass(2)) == 2); +assert(doSwitchClassMember(new FooClass(3)) == 3); + + +// class instances switch using reference equality by default +const foo1 = new FooClass(1); +const foo2 = new FooClass(2); +function doSwitchClassInstance(foo: FooClass): i32 { + switch (foo) { + case foo1: return 1; + case foo2: return 2; + default: return 3; + } +} +assert(doSwitchClassInstance(foo1) == 1); +assert(doSwitchClassInstance(foo2) == 2); +assert(doSwitchClassInstance(new FooClass(1)) == 3); + +// class instances can switch using value equality with an operator overload +class BarClass { + value: i32; + + constructor(value: i32) { + this.value = value; + } + @operator("==") private static __eq(left: BarClass | null, right: BarClass | null): bool { + if (changetype(left) == changetype(right)) return true; + if (!left || !right) return false; + return left.value == right.value; + } +} -// TODO: This should either work, or be a compile error. -// Currently it compiles but gives a runtime error, such as: -// -// abort: null in (252:1) -// --- -// RuntimeError: unreachable -// at start:switch (wasm://wasm/14e6b94a:wasm-function[75]:0x1ae9) -// at ~start (wasm://wasm/14e6b94a:wasm-function[71]:0x1300) -// --- -// function doSwitchClassInstance(foo: FooClass): i32 { -// const one = new FooClass(1); -// const two = new FooClass(2); -// switch (foo) { -// case one: return 1; -// case two: return 2; -// default: return 0; -// } -// } -// assert(doSwitchClassInstance(new FooClass(0)) == 0); -// assert(doSwitchClassInstance(new FooClass(1)) == 1); -// assert(doSwitchClassInstance(new FooClass(2)) == 2); -// assert(doSwitchClassInstance(new FooClass(3)) == 0); +function doSwitchClassInstanceWithOverload(foo: BarClass | null): i32 { + switch (foo) { + case null: return 0; + case new BarClass(1): return 1; + case new BarClass(2): return 2; + default: return 3; + } +} +assert(doSwitchClassInstanceWithOverload(null) == 0); +assert(doSwitchClassInstanceWithOverload(new BarClass(1)) == 1); +assert(doSwitchClassInstanceWithOverload(new BarClass(2)) == 2); +assert(doSwitchClassInstanceWithOverload(new BarClass(3)) == 3); From 761db6d08738075b967abfa54c4bab503822dbd2 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 31 May 2025 13:13:31 -0700 Subject: [PATCH 4/5] . --- src/compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler.ts b/src/compiler.ts index 53a914a51c..d5061527f7 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -2828,7 +2828,7 @@ export class Compiler extends DiagnosticEmitter { let tempLocalIndex = tempLocal.index; let breaks = new Array(1 + numCases); breaks[0] = module.local_set(tempLocalIndex, condExpr, condType.isManaged); - + // Make one br_if per labeled case and leave it to Binaryen to optimize the // sequence of br_ifs to a br_table according to optimization levels let breakIndex = 1; From 902977229279aaaf6703a708a7f2124603435949 Mon Sep 17 00:00:00 2001 From: CountBleck Date: Tue, 3 Jun 2025 15:53:42 -0700 Subject: [PATCH 5/5] Update fixture with upstream changes --- tests/compiler/switch.release.wat | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/compiler/switch.release.wat b/tests/compiler/switch.release.wat index 4cc8b72c51..ef3d9d9622 100644 --- a/tests/compiler/switch.release.wat +++ b/tests/compiler/switch.release.wat @@ -1070,7 +1070,6 @@ call $~lib/rt/tlsf/initialize end global.get $~lib/rt/tlsf/ROOT - local.set $1 local.get $0 i32.const 4 i32.sub @@ -1103,7 +1102,6 @@ i32.const 1 i32.or i32.store - local.get $1 local.get $2 call $~lib/rt/tlsf/insertBlock end @@ -2209,20 +2207,16 @@ i32.store local.get $0 i32.load - local.set $0 global.get $~lib/memory/__stack_pointer local.get $1 i32.store - local.get $0 local.get $1 i32.load i32.eq - local.set $0 global.get $~lib/memory/__stack_pointer i32.const 4 i32.add global.set $~lib/memory/__stack_pointer - local.get $0 ) (func $switch/BarClass#constructor (param $0 i32) (result i32) (local $1 i32)