From 8fa4b7b2a3737e55e6f1ec2fc3d9dd2fc2fbbeeb Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 7 Dec 2022 18:44:48 +0100 Subject: [PATCH 01/16] Assume that interfaces represent a derived object --- src/compiler.ts | 18 ++- src/program.ts | 12 ++ tests/compiler/instanceof.debug.wat | 157 +++++++++++++++---- tests/compiler/instanceof.release.wat | 210 ++++++++++++++++++-------- tests/compiler/instanceof.ts | 9 ++ 5 files changed, 303 insertions(+), 103 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index e4d86c7dc2..abf4ae29be 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -556,12 +556,18 @@ export class Compiler extends DiagnosticEmitter { for (let _keys = Map_keys(this.pendingInstanceOf), i = 0, k = _keys.length; i < k; ++i) { let elem = _keys[i]; let name = assert(this.pendingInstanceOf.get(elem)); - if (elem.kind == ElementKind.Class) { - this.finalizeInstanceOf(elem, name); - } else if (elem.kind == ElementKind.ClassPrototype) { - this.finalizeAnyInstanceOf(elem, name); - } else { - assert(false); + switch (elem.kind) { + case ElementKind.Class: + case ElementKind.Interface: { + this.finalizeInstanceOf(elem, name); + break; + } + case ElementKind.ClassPrototype: + case ElementKind.InterfacePrototype: { + this.finalizeAnyInstanceOf(elem, name); + break; + } + default: assert(false); } } diff --git a/src/program.ts b/src/program.ts index 2116651eb8..25bd0c3711 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4784,6 +4784,18 @@ export class Interface extends Class { // FIXME true ); } + + /** Tests if a value of this interface type is assignable to a target of the specified class type. */ + override isAssignableTo(target: Class): boolean { + // Unlike classes, interfaces do not include `Object` in their inheritance + // graph, yet we know that an assignment would succeed because any class + // implementing an interface directly or indirectly extends `Object`. + if (target == this.program.objectInstance) { + assert(this.type.isManaged); + return true; + } + return super.isAssignableTo(target); + } } /** Registers a concrete element with a program. */ diff --git a/tests/compiler/instanceof.debug.wat b/tests/compiler/instanceof.debug.wat index 10167dda24..aaffe370de 100644 --- a/tests/compiler/instanceof.debug.wat +++ b/tests/compiler/instanceof.debug.wat @@ -42,10 +42,11 @@ (global $instanceof/nullAnimal (mut i32) (i32.const 0)) (global $instanceof/nullCat (mut i32) (i32.const 0)) (global $instanceof/nullBlackcat (mut i32) (i32.const 0)) + (global $instanceof/impl (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 464)) - (global $~lib/memory/__data_end i32 (i32.const 524)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33292)) - (global $~lib/memory/__heap_base i32 (i32.const 33292)) + (global $~lib/memory/__data_end i32 (i32.const 532)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33300)) + (global $~lib/memory/__heap_base i32 (i32.const 33300)) (memory $0 1) (data (i32.const 12) "<\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 (i32.const 76) "<\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") @@ -56,7 +57,7 @@ (data (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 348) "<\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 (i32.const 412) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1a\00\00\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s\00\00\00") - (data (i32.const 464) "\0e\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00") + (data (i32.const 464) "\10\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\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)) @@ -2300,14 +2301,15 @@ (local $18 i32) (local $19 i32) (local $20 i32) + (local $21 i32) global.get $~lib/memory/__stack_pointer - i32.const 84 + i32.const 88 i32.sub global.set $~lib/memory/__stack_pointer call $~stack_check global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 84 + i32.const 88 memory.fill $0 memory.size $0 i32.const 16 @@ -3103,8 +3105,34 @@ call $~lib/builtins/abort unreachable end + i32.const 0 + call $instanceof/ImplemensIFace#constructor + global.set $instanceof/impl + i32.const 1 + drop global.get $~lib/memory/__stack_pointer - i32.const 84 + global.get $instanceof/impl + local.tee $21 + i32.store $0 offset=84 + local.get $21 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $21 + call $~instanceof|instanceof/IFace + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 161 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 88 i32.add global.set $~lib/memory/__stack_pointer ) @@ -3201,6 +3229,27 @@ end i32.const 1 ) + (func $~instanceof|instanceof/IFace (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 15 + i32.eq + br_if $is_instance + local.get $1 + i32.const 14 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) (func $~lib/rt/__visit_globals (type $i32_=>_none) (param $0 i32) (local $1 i32) global.get $instanceof/a @@ -3301,6 +3350,13 @@ local.get $0 call $~lib/rt/itcms/__visit end + global.get $instanceof/impl + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end i32.const 224 local.get $0 call $~lib/rt/itcms/__visit @@ -3327,35 +3383,41 @@ ) (func $~lib/rt/__visit_members (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) block $invalid - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $invalid + block $instanceof/IFace + block $instanceof/ImplemensIFace + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/ImplemensIFace $instanceof/IFace $invalid + end + return + end + return end return end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit return end return end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit return end return @@ -3388,8 +3450,8 @@ global.get $~lib/memory/__data_end i32.lt_s if - i32.const 33312 - i32.const 33360 + i32.const 33328 + i32.const 33376 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -3721,4 +3783,37 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $instanceof/ImplemensIFace#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (local $1 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 $0 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 14 + call $~lib/rt/itcms/__new + local.tee $this + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $this + call $~lib/object/Object#constructor + local.tee $this + i32.store $0 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) ) diff --git a/tests/compiler/instanceof.release.wat b/tests/compiler/instanceof.release.wat index 285a61dcad..b30825eb20 100644 --- a/tests/compiler/instanceof.release.wat +++ b/tests/compiler/instanceof.release.wat @@ -28,7 +28,8 @@ (global $instanceof/nullableAnimal (mut i32) (i32.const 0)) (global $instanceof/nullableCat (mut i32) (i32.const 0)) (global $instanceof/nullableBlackcat (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34316)) + (global $instanceof/impl (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34324)) (memory $0 1) (data (i32.const 1036) "<") (data (i32.const 1048) "\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") @@ -42,7 +43,7 @@ (data (i32.const 1384) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") (data (i32.const 1436) ",") (data (i32.const 1448) "\02\00\00\00\1a\00\00\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s") - (data (i32.const 1488) "\0e\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 ") + (data (i32.const 1488) "\10\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\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 (type $none_=>_none) @@ -114,6 +115,12 @@ local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end + global.get $instanceof/impl + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end i32.const 1248 call $byn-split-outlined-A$~lib/rt/itcms/__visit i32.const 1056 @@ -191,7 +198,7 @@ i32.load $0 offset=8 i32.eqz local.get $0 - i32.const 34316 + i32.const 34324 i32.lt_u i32.and i32.eqz @@ -819,10 +826,10 @@ if unreachable end - i32.const 34320 + i32.const 34336 i32.const 0 i32.store $0 - i32.const 35888 + i32.const 35904 i32.const 0 i32.store $0 loop $for-loop|0 @@ -833,7 +840,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 34320 + i32.const 34336 i32.add i32.const 0 i32.store $0 offset=4 @@ -851,7 +858,7 @@ i32.add i32.const 2 i32.shl - i32.const 34320 + i32.const 34336 i32.add i32.const 0 i32.store $0 offset=96 @@ -869,13 +876,13 @@ br $for-loop|0 end end - i32.const 34320 - i32.const 35892 + i32.const 34336 + i32.const 35908 memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - i32.const 34320 + i32.const 34336 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (type $none_=>_i32) (result i32) @@ -960,7 +967,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 34316 + i32.const 34324 i32.lt_u if local.get $0 @@ -1060,7 +1067,7 @@ unreachable end local.get $0 - i32.const 34316 + i32.const 34324 i32.lt_u if local.get $0 @@ -1083,7 +1090,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 34316 + i32.const 34324 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1439,22 +1446,22 @@ (local $0 i32) (local $1 i32) global.get $~lib/memory/__stack_pointer - i32.const 84 + i32.const 88 i32.sub global.set $~lib/memory/__stack_pointer block $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 84 + i32.const 88 memory.fill $0 memory.size $0 i32.const 16 i32.shl - i32.const 34316 + i32.const 34324 i32.sub i32.const 1 i32.shr_u @@ -1491,7 +1498,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1553,7 +1560,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1571,7 +1578,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1609,7 +1616,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1627,7 +1634,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2147,13 +2154,78 @@ i32.const 0 i32.store $0 offset=80 local.get $0 - i32.const 84 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1556 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 14 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/impl + global.get $~lib/memory/__stack_pointer + global.get $instanceof/impl + local.tee $0 + i32.store $0 offset=84 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/IFace (result i32) + block $is_instance37 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 15 + i32.eq + br_if $is_instance37 + local.get $0 + i32.const 14 + i32.eq + br_if $is_instance37 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/IFace + end + i32.const 1 + end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 161 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 88 i32.add global.set $~lib/memory/__stack_pointer return end - i32.const 34336 - i32.const 34384 + i32.const 34352 + i32.const 34400 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2161,39 +2233,45 @@ ) (func $~lib/rt/__visit_members (type $i32_=>_none) (param $0 i32) block $invalid - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $invalid + block $instanceof/IFace + block $instanceof/ImplemensIFace + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/ImplemensIFace $instanceof/IFace $invalid + end + return + end + return end return end + local.get $0 + i32.load $0 + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end return end return end - local.get $0 - i32.load $0 - local.tee $0 - if - local.get $0 - call $byn-split-outlined-A$~lib/rt/itcms/__visit - end return end return @@ -2227,11 +2305,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s if - i32.const 34336 - i32.const 34384 + i32.const 34352 + i32.const 34400 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2261,11 +2339,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s if - i32.const 34336 - i32.const 34384 + i32.const 34352 + i32.const 34400 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2300,11 +2378,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s if - i32.const 34336 - i32.const 34384 + i32.const 34352 + i32.const 34400 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2339,11 +2417,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s if - i32.const 34336 - i32.const 34384 + i32.const 34352 + i32.const 34400 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2379,11 +2457,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1548 + i32.const 1556 i32.lt_s if - i32.const 34336 - i32.const 34384 + i32.const 34352 + i32.const 34400 i32.const 1 i32.const 1 call $~lib/builtins/abort diff --git a/tests/compiler/instanceof.ts b/tests/compiler/instanceof.ts index c394d51808..1b77f79bb8 100644 --- a/tests/compiler/instanceof.ts +++ b/tests/compiler/instanceof.ts @@ -150,3 +150,12 @@ assert(!(nullCat instanceof BlackCat)); // dynamic false assert(!(nullBlackcat instanceof Animal)); // static false assert(!(nullBlackcat instanceof Cat)); // dynamic false assert(!(nullBlackcat instanceof BlackCat)); // dynamic false + +// Interfaces participate and are Object instances + +interface IFace {} +class ImplemensIFace implements IFace {} + +let impl = new ImplemensIFace(); +assert(impl instanceof IFace); // static true +assert(impl as Object instanceof IFace); // dynamic true From a1826049353db0fb85a63b932a9f6e2b1f6a5fa4 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 8 Dec 2022 19:41:28 +0100 Subject: [PATCH 02/16] Add infrastructure to do precise subtype checks --- src/bindings/js.ts | 42 ++++++------- src/bindings/tsd.ts | 12 ++-- src/builtins.ts | 12 ++-- src/compiler.ts | 21 +++---- src/program.ts | 142 +++++++++++++++++++++++++++++++++++--------- src/types.ts | 8 +++ 6 files changed, 165 insertions(+), 72 deletions(-) diff --git a/src/bindings/js.ts b/src/bindings/js.ts index 59f9685c43..a75272bae2 100644 --- a/src/bindings/js.ts +++ b/src/bindings/js.ts @@ -950,13 +950,13 @@ export class JSBuilder extends ExportsWalker { if (type.isInternalReference) { // Lift reference types const clazz = assert(type.getClassOrWrapper(this.program)); - if (clazz.extends(this.program.arrayBufferInstance.prototype)) { + if (clazz.extendsPrototype(this.program.arrayBufferInstance.prototype)) { sb.push("__liftBuffer("); this.needsLiftBuffer = true; - } else if (clazz.extends(this.program.stringInstance.prototype)) { + } else if (clazz.extendsPrototype(this.program.stringInstance.prototype)) { sb.push("__liftString("); this.needsLiftString = true; - } else if (clazz.extends(this.program.arrayPrototype)) { + } else if (clazz.extendsPrototype(this.program.arrayPrototype)) { let valueType = clazz.getArrayValueType(); sb.push("__liftArray("); this.makeLiftFromMemory(valueType, sb); @@ -964,7 +964,7 @@ export class JSBuilder extends ExportsWalker { sb.push(valueType.alignLog2.toString()); sb.push(", "); this.needsLiftArray = true; - } else if (clazz.extends(this.program.staticArrayPrototype)) { + } else if (clazz.extendsPrototype(this.program.staticArrayPrototype)) { let valueType = clazz.getArrayValueType(); sb.push("__liftStaticArray("); this.makeLiftFromMemory(valueType, sb); @@ -972,7 +972,7 @@ export class JSBuilder extends ExportsWalker { sb.push(valueType.alignLog2.toString()); sb.push(", "); this.needsLiftStaticArray = true; - } else if (clazz.extends(this.program.arrayBufferViewInstance.prototype)) { + } else if (clazz.extendsPrototype(this.program.arrayBufferViewInstance.prototype)) { sb.push("__liftTypedArray("); if (clazz.name == "Uint64Array") { sb.push("BigUint64Array"); @@ -1021,13 +1021,13 @@ export class JSBuilder extends ExportsWalker { if (type.isInternalReference) { // Lower reference types const clazz = assert(type.getClassOrWrapper(this.program)); - if (clazz.extends(this.program.arrayBufferInstance.prototype)) { + if (clazz.extendsPrototype(this.program.arrayBufferInstance.prototype)) { sb.push("__lowerBuffer("); this.needsLowerBuffer = true; - } else if (clazz.extends(this.program.stringInstance.prototype)) { + } else if (clazz.extendsPrototype(this.program.stringInstance.prototype)) { sb.push("__lowerString("); this.needsLowerString = true; - } else if (clazz.extends(this.program.arrayPrototype)) { + } else if (clazz.extendsPrototype(this.program.arrayPrototype)) { let valueType = clazz.getArrayValueType(); sb.push("__lowerArray("); this.makeLowerToMemory(valueType, sb); @@ -1037,7 +1037,7 @@ export class JSBuilder extends ExportsWalker { sb.push(clazz.getArrayValueType().alignLog2.toString()); sb.push(", "); this.needsLowerArray = true; - } else if (clazz.extends(this.program.staticArrayPrototype)) { + } else if (clazz.extendsPrototype(this.program.staticArrayPrototype)) { let valueType = clazz.getArrayValueType(); sb.push("__lowerStaticArray("); this.makeLowerToMemory(valueType, sb); @@ -1047,7 +1047,7 @@ export class JSBuilder extends ExportsWalker { sb.push(valueType.alignLog2.toString()); sb.push(", "); this.needsLowerStaticArray = true; - } else if (clazz.extends(this.program.arrayBufferViewInstance.prototype)) { + } else if (clazz.extendsPrototype(this.program.arrayBufferViewInstance.prototype)) { let valueType = clazz.getArrayValueType(); sb.push("__lowerTypedArray("); if (valueType == Type.u64) { @@ -1079,7 +1079,7 @@ export class JSBuilder extends ExportsWalker { this.needsLowerInternref = true; } sb.push(name); - if (clazz.extends(this.program.staticArrayPrototype)) { + if (clazz.extendsPrototype(this.program.staticArrayPrototype)) { // optional last argument for __lowerStaticArray let valueType = clazz.getArrayValueType(); if (valueType.isNumericValue) { @@ -1397,16 +1397,16 @@ export function liftRequiresExportRuntime(type: Type): bool { let program = clazz.program; // flat collections lift via memory copy if ( - clazz.extends(program.arrayBufferInstance.prototype) || - clazz.extends(program.stringInstance.prototype) || - clazz.extends(program.arrayBufferViewInstance.prototype) + clazz.extendsPrototype(program.arrayBufferInstance.prototype) || + clazz.extendsPrototype(program.stringInstance.prototype) || + clazz.extendsPrototype(program.arrayBufferViewInstance.prototype) ) { return false; } // nested collections lift depending on element type if ( - clazz.extends(program.arrayPrototype) || - clazz.extends(program.staticArrayPrototype) + clazz.extendsPrototype(program.arrayPrototype) || + clazz.extendsPrototype(program.staticArrayPrototype) ) { return liftRequiresExportRuntime(clazz.getArrayValueType()); } @@ -1428,11 +1428,11 @@ export function lowerRequiresExportRuntime(type: Type): bool { // lowers using __new let program = clazz.program; if ( - clazz.extends(program.arrayBufferInstance.prototype) || - clazz.extends(program.stringInstance.prototype) || - clazz.extends(program.arrayBufferViewInstance.prototype) || - clazz.extends(program.arrayPrototype) || - clazz.extends(program.staticArrayPrototype) + clazz.extendsPrototype(program.arrayBufferInstance.prototype) || + clazz.extendsPrototype(program.stringInstance.prototype) || + clazz.extendsPrototype(program.arrayBufferViewInstance.prototype) || + clazz.extendsPrototype(program.arrayPrototype) || + clazz.extendsPrototype(program.staticArrayPrototype) ) { return true; } diff --git a/src/bindings/tsd.ts b/src/bindings/tsd.ts index 75a9af7f91..a7f65bfd9d 100644 --- a/src/bindings/tsd.ts +++ b/src/bindings/tsd.ts @@ -249,26 +249,26 @@ export class TSDBuilder extends ExportsWalker { if (type.isInternalReference) { const sb = new Array(); const clazz = assert(type.getClassOrWrapper(this.program)); - if (clazz.extends(this.program.arrayBufferInstance.prototype)) { + if (clazz.extendsPrototype(this.program.arrayBufferInstance.prototype)) { sb.push("ArrayBuffer"); - } else if (clazz.extends(this.program.stringInstance.prototype)) { + } else if (clazz.extendsPrototype(this.program.stringInstance.prototype)) { sb.push("string"); - } else if (clazz.extends(this.program.arrayPrototype)) { + } else if (clazz.extendsPrototype(this.program.arrayPrototype)) { const valueType = clazz.getArrayValueType(); sb.push("Array<"); sb.push(this.toTypeScriptType(valueType, mode)); sb.push(">"); - } else if (clazz.extends(this.program.staticArrayPrototype)) { + } else if (clazz.extendsPrototype(this.program.staticArrayPrototype)) { const valueType = clazz.getArrayValueType(); sb.push("ArrayLike<"); sb.push(this.toTypeScriptType(valueType, mode)); sb.push(">"); - } else if (clazz.extends(this.program.arrayBufferViewInstance.prototype)) { + } else if (clazz.extendsPrototype(this.program.arrayBufferViewInstance.prototype)) { const valueType = clazz.getArrayValueType(); if (valueType == Type.i8) { sb.push("Int8Array"); } else if (valueType == Type.u8) { - if (clazz.extends(this.program.uint8ClampedArrayPrototype)) { + if (clazz.extendsPrototype(this.program.uint8ClampedArrayPrototype)) { sb.push("Uint8ClampedArray"); } else { sb.push("Uint8Array"); diff --git a/src/builtins.ts b/src/builtins.ts index 711f10c152..559dd6d8b4 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -861,7 +861,7 @@ function builtin_isArray(ctx: BuiltinContext): ExpressionRef { let classReference = type.getClass(); return reifyConstantType(ctx, module.i32( - classReference && classReference.extends(compiler.program.arrayPrototype) + classReference && classReference.extendsPrototype(compiler.program.arrayPrototype) ? 1 : 0 ) @@ -10420,26 +10420,26 @@ export function compileRTTI(compiler: Compiler): void { assert(instanceId == lastId++); let flags: TypeinfoFlags = 0; if (instance.isPointerfree) flags |= TypeinfoFlags.POINTERFREE; - if (instance != abvInstance && instance.extends(abvPrototype)) { + if (instance != abvInstance && instance.extendsPrototype(abvPrototype)) { let valueType = instance.getArrayValueType(); flags |= TypeinfoFlags.ARRAYBUFFERVIEW; flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(valueType); - } else if (instance.extends(arrayPrototype)) { + } else if (instance.extendsPrototype(arrayPrototype)) { let valueType = instance.getArrayValueType(); flags |= TypeinfoFlags.ARRAY; flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(valueType); - } else if (instance.extends(setPrototype)) { + } else if (instance.extendsPrototype(setPrototype)) { let typeArguments = assert(instance.getTypeArgumentsTo(setPrototype)); assert(typeArguments.length == 1); flags |= TypeinfoFlags.SET; flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[0]); - } else if (instance.extends(mapPrototype)) { + } else if (instance.extendsPrototype(mapPrototype)) { let typeArguments = assert(instance.getTypeArgumentsTo(mapPrototype)); assert(typeArguments.length == 2); flags |= TypeinfoFlags.MAP; flags |= TypeinfoFlags.KEY_ALIGN_0 * typeToRuntimeFlags(typeArguments[0]); flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[1]); - } else if (instance.extends(staticArrayPrototype)) { + } else if (instance.extendsPrototype(staticArrayPrototype)) { let valueType = instance.getArrayValueType(); flags |= TypeinfoFlags.STATICARRAY; flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(valueType); diff --git a/src/compiler.ts b/src/compiler.ts index abf4ae29be..549e239cc4 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -7438,7 +7438,7 @@ export class Compiler extends DiagnosticEmitter { // instanceof - LHS must be != 0 if (actualType.isNullableReference && !expectedType.isNullableReference) { - // upcast - check statically + // same or upcast - check statically if (actualType.nonNullableType.isAssignableTo(expectedType)) { return module.binary( sizeTypeRef == TypeRef.I64 @@ -7449,8 +7449,8 @@ export class Compiler extends DiagnosticEmitter { ); } - // downcast - check dynamically - if (expectedType.isAssignableTo(actualType)) { + // potential downcast - check dynamically + if (actualType.nonNullableType.hasSubtypeAssignableTo(expectedType)) { if (!(actualType.isUnmanaged || expectedType.isUnmanaged)) { if (this.options.pedantic) { this.pedantic( @@ -7483,12 +7483,13 @@ export class Compiler extends DiagnosticEmitter { // either none or both nullable } else { - // upcast - check statically + // same or upcast - check statically if (actualType.isAssignableTo(expectedType)) { return module.maybeDropCondition(expr, module.i32(1)); + } - // downcast - check dynamically - } else if (expectedType.isAssignableTo(actualType)) { + // potential downcast - check dynamically + if (actualType.hasSubtypeAssignableTo(expectedType)) { if (!(actualType.isUnmanaged || expectedType.isUnmanaged)) { let temp = flow.getTempLocal(actualType); let tempIndex = temp.index; @@ -7605,7 +7606,7 @@ export class Compiler extends DiagnosticEmitter { if (classReference) { // static check - if (classReference.extends(prototype)) { + if (classReference.extendsPrototype(prototype)) { // instanceof - LHS must be != 0 if (actualType.isNullableReference) { @@ -7952,7 +7953,7 @@ export class Compiler extends DiagnosticEmitter { let parameterTypes = instance.signature.parameterTypes; if (parameterTypes.length) { let first = parameterTypes[0].getClass(); - if (first && !first.extends(tsaArrayInstance.prototype)) { + if (first && !first.extendsPrototype(tsaArrayInstance.prototype)) { arrayInstance = assert(this.resolver.resolveClass(this.program.arrayPrototype, [ stringType ])); } } @@ -8020,7 +8021,7 @@ export class Compiler extends DiagnosticEmitter { // handle static arrays let contextualClass = contextualType.getClass(); - if (contextualClass && contextualClass.extends(program.staticArrayPrototype)) { + if (contextualClass && contextualClass.extendsPrototype(program.staticArrayPrototype)) { return this.compileStaticArrayLiteral(expression, contextualType, constraints); } @@ -8153,7 +8154,7 @@ export class Compiler extends DiagnosticEmitter { ): ExpressionRef { let program = this.program; let module = this.module; - assert(!arrayInstance.extends(program.staticArrayPrototype)); + assert(!arrayInstance.extendsPrototype(program.staticArrayPrototype)); let elementType = arrayInstance.getArrayValueType(); // asserts // __newArray(length, alignLog2, classId, staticBuffer) diff --git a/src/program.ts b/src/program.ts index 25bd0c3711..e20648234b 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4453,21 +4453,46 @@ export class Class extends TypedElement { /** Tests if a value of this class type is assignable to a target of the specified class type. */ isAssignableTo(target: Class): bool { - let current: Class | null = this; - do { - if (current == target) return true; - if (target.kind == ElementKind.Interface) { - let interfaces = current.interfaces; - if (interfaces) { - for (let _values = Set_values(interfaces), i = 0, k = _values.length; i < k; ++i) { - let iface = _values[i]; - if (iface.isAssignableTo(target)) return true; - } - } + // Q: When does the assignment in the comment below succeed? + if (target.isInterface) { + if (this.isInterface) { + // targetInterface = thisInterface + return this == target || this.extends(target); + } else { + // targetInterface = thisClass + return this.implements(target); } - current = current.base; - } while (current); - return false; + } else { + if (this.isInterface) { + // targetClass = thisInterface + return target == this.program.objectInstance; + } else { + // targetClass = thisClass + return this == target || this.extends(target); + } + } + } + + /** Tests if any subclass of this class is assignable to a target of the specified class type. */ + hasSubclassAssignableTo(target: Class): bool { + // Q: When can the cast in the comment below succeed? (while an assignment would not) + if (target.isInterface) { + if (this.isInterface) { + // thisInterface + return this.hasImplementerImplementing(target); + } else { + // thisClass + return this.hasExtendeeImplementing(target); + } + } else { + if (this.isInterface) { + // thisInterface + return this.hasImplementer(target); + } else { + // thisClass + return this.hasExtendee(target); + } + } } /** Looks up the operator overload of the specified kind. */ @@ -4608,7 +4633,7 @@ export class Class extends TypedElement { } /** Tests if this class extends the specified prototype. */ - extends(prototype: ClassPrototype): bool { + extendsPrototype(prototype: ClassPrototype): bool { return this.prototype.extends(prototype); } @@ -4627,11 +4652,11 @@ export class Class extends TypedElement { let current: Class = this; let program = this.program; let arrayPrototype = program.arrayPrototype; - if (this.extends(arrayPrototype)) { + if (this.extendsPrototype(arrayPrototype)) { return this.getTypeArgumentsTo(arrayPrototype)![0]; } let staticArrayPrototype = program.staticArrayPrototype; - if (this.extends(staticArrayPrototype)) { + if (this.extendsPrototype(staticArrayPrototype)) { return this.getTypeArgumentsTo(staticArrayPrototype)![0]; } let abvInstance = program.arrayBufferViewInstance; @@ -4743,6 +4768,77 @@ export class Class extends TypedElement { } return out; } + + /** Tests if this class or interface extends the given classs or interface. */ + extends(other: Class): bool { + let base = this.base; + while (base) { + if (base == other) return true; + base = base.base; + } + return false; + } + + /** Tests if this class has a direct or indirect extendee matching the given class. */ + hasExtendee(other: Class): bool { + let extendees = this.extendees; + if (extendees) { + for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { + let extendee = _values[i]; + if (extendee == other || extendee.hasExtendee(other)) return true; + } + } + return false; + } + + /** Tests if this class has a direct or indirect extendee that implements the given interface. */ + hasExtendeeImplementing(other: Class): bool { + let extendees = this.extendees; + if (extendees) { + for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { + let extendee = _values[i]; + if (extendee.implements(other) || extendee.hasExtendeeImplementing(other)) return true; + } + } + return false; + } + + /** Tests if this class implements the given interface. */ + implements(other: Class): bool { + let interfaces = this.interfaces; + if (interfaces) { + for (let _values = Set_values(interfaces), i = 0, k = _values.length; i < k; ++i) { + let iface = _values[i]; + if (iface == other || iface.extends(other)) return true; + } + } + let base = this.base; + return base ? base.implements(other) : false; + } + + /** Tests if this interface has a direct or indirect implementer matching the given class. */ + hasImplementer(other: Class): bool { + let implementers = this.implementers; + if (implementers) { + for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) { + let implementer = _values[i]; + if (implementer == other || implementer.extends(other)) return true; + } + } + return false; + } + + /** Tests if this interface has an implementer implementing the given interface. */ + hasImplementerImplementing(other: Class): bool { + let implementers = this.implementers; + if (implementers) { + for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) { + let implementer = _values[i]; + if (implementer.implements(other)) return true; + } + } + return false; + } } /** A yet unresolved interface. */ @@ -4784,18 +4880,6 @@ export class Interface extends Class { // FIXME true ); } - - /** Tests if a value of this interface type is assignable to a target of the specified class type. */ - override isAssignableTo(target: Class): boolean { - // Unlike classes, interfaces do not include `Object` in their inheritance - // graph, yet we know that an assignment would succeed because any class - // implementing an interface directly or indirectly extends `Object`. - if (target == this.program.objectInstance) { - assert(this.type.isManaged); - return true; - } - return super.isAssignableTo(target); - } } /** Registers a concrete element with a program. */ diff --git a/src/types.ts b/src/types.ts index baad2a89f5..5e22db7ce3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -506,6 +506,14 @@ export class Type { return this.kind == target.kind; } + /** Tests if this type has a subtype assignable to the target type. */ + hasSubtypeAssignableTo(target: Type): bool { + let thisClass = this.getClass(); + let targetClass = target.getClass(); + if (!thisClass || !targetClass) return false; // TODO: what about basic types? + return thisClass.hasSubclassAssignableTo(targetClass); + } + /** Tests if a value of this type can be changed to the target type using `changetype`. */ isChangeableTo(target: Type): bool { // special in that it allows integer references as well From a0553c515107b401cf879bb31e68a0dfb09ccd08 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 8 Dec 2022 23:05:15 +0100 Subject: [PATCH 03/16] optimize slightly --- src/program.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/program.ts b/src/program.ts index e20648234b..9bf2097d64 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4783,9 +4783,10 @@ export class Class extends TypedElement { hasExtendee(other: Class): bool { let extendees = this.extendees; if (extendees) { + if (extendees.has(other)) return true; for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { let extendee = _values[i]; - if (extendee == other || extendee.hasExtendee(other)) return true; + if (/* extendee == other || */extendee.hasExtendee(other)) return true; } } return false; @@ -4807,9 +4808,10 @@ export class Class extends TypedElement { implements(other: Class): bool { let interfaces = this.interfaces; if (interfaces) { + if (interfaces.has(other)) return true; for (let _values = Set_values(interfaces), i = 0, k = _values.length; i < k; ++i) { let iface = _values[i]; - if (iface == other || iface.extends(other)) return true; + if (/* iface == other || */iface.extends(other)) return true; } } let base = this.base; @@ -4820,9 +4822,10 @@ export class Class extends TypedElement { hasImplementer(other: Class): bool { let implementers = this.implementers; if (implementers) { + if (implementers.has(other)) return true; for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) { let implementer = _values[i]; - if (implementer == other || implementer.extends(other)) return true; + if (/* implementer == other || */implementer.extends(other)) return true; } } return false; From df299c019cbaa17702bf71f42a17934abeccc7c8 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 8 Dec 2022 23:35:47 +0100 Subject: [PATCH 04/16] Add a few initial tests --- tests/compiler/instanceof.debug.wat | 208 +++++++++++++++++++----- tests/compiler/instanceof.release.wat | 223 ++++++++++++++++++-------- tests/compiler/instanceof.ts | 28 +++- 3 files changed, 342 insertions(+), 117 deletions(-) diff --git a/tests/compiler/instanceof.debug.wat b/tests/compiler/instanceof.debug.wat index aaffe370de..ee8b05dca1 100644 --- a/tests/compiler/instanceof.debug.wat +++ b/tests/compiler/instanceof.debug.wat @@ -42,11 +42,12 @@ (global $instanceof/nullAnimal (mut i32) (i32.const 0)) (global $instanceof/nullCat (mut i32) (i32.const 0)) (global $instanceof/nullBlackcat (mut i32) (i32.const 0)) - (global $instanceof/impl (mut i32) (i32.const 0)) + (global $instanceof/a_i1 (mut i32) (i32.const 0)) + (global $instanceof/b_i1_i2 (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 464)) - (global $~lib/memory/__data_end i32 (i32.const 532)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33300)) - (global $~lib/memory/__heap_base i32 (i32.const 33300)) + (global $~lib/memory/__data_end i32 (i32.const 540)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33308)) + (global $~lib/memory/__heap_base i32 (i32.const 33308)) (memory $0 1) (data (i32.const 12) "<\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 (i32.const 76) "<\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") @@ -57,7 +58,7 @@ (data (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 348) "<\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 (i32.const 412) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1a\00\00\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s\00\00\00") - (data (i32.const 464) "\10\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00") + (data (i32.const 464) "\12\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\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)) @@ -2302,14 +2303,16 @@ (local $19 i32) (local $20 i32) (local $21 i32) + (local $22 i32) + (local $23 i32) global.get $~lib/memory/__stack_pointer - i32.const 88 + i32.const 96 i32.sub global.set $~lib/memory/__stack_pointer call $~stack_check global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 88 + i32.const 96 memory.fill $0 memory.size $0 i32.const 16 @@ -3106,12 +3109,14 @@ unreachable end i32.const 0 - call $instanceof/ImplemensIFace#constructor - global.set $instanceof/impl + call $instanceof/A_I1#constructor + global.set $instanceof/a_i1 + i32.const 1 + drop i32.const 1 drop global.get $~lib/memory/__stack_pointer - global.get $instanceof/impl + global.get $instanceof/a_i1 local.tee $21 i32.store $0 offset=84 local.get $21 @@ -3120,19 +3125,75 @@ i32.const 0 else local.get $21 - call $~instanceof|instanceof/IFace + call $~instanceof|instanceof/I1 end i32.eqz if i32.const 0 i32.const 432 - i32.const 161 + i32.const 165 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 0 + i32.eqz + drop + i32.const 0 + call $instanceof/B_I1_I2#constructor + global.set $instanceof/b_i1_i2 + i32.const 1 + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop global.get $~lib/memory/__stack_pointer - i32.const 88 + global.get $instanceof/a_i1 + local.tee $22 + i32.store $0 offset=88 + local.get $22 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $22 + call $~instanceof|instanceof/B_I1_I2 + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 172 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/b_i1_i2 + local.tee $23 + i32.store $0 offset=92 + local.get $23 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $23 + call $~instanceof|instanceof/B_I1_I2 + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 173 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 96 i32.add global.set $~lib/memory/__stack_pointer ) @@ -3229,7 +3290,7 @@ end i32.const 1 ) - (func $~instanceof|instanceof/IFace (type $i32_=>_i32) (param $0 i32) (result i32) + (func $~instanceof|instanceof/I1 (type $i32_=>_i32) (param $0 i32) (result i32) (local $1 i32) block $is_instance local.get $0 @@ -3245,6 +3306,27 @@ i32.const 14 i32.eq br_if $is_instance + local.get $1 + i32.const 17 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/B_I1_I2 (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 17 + i32.eq + br_if $is_instance i32.const 0 return end @@ -3350,7 +3432,14 @@ local.get $0 call $~lib/rt/itcms/__visit end - global.get $instanceof/impl + global.get $instanceof/a_i1 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/b_i1_i2 local.tee $1 if local.get $1 @@ -3383,37 +3472,43 @@ ) (func $~lib/rt/__visit_members (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) block $invalid - block $instanceof/IFace - block $instanceof/ImplemensIFace - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/ImplemensIFace $instanceof/IFace $invalid + block $instanceof/B_I1_I2 + block $instanceof/I2 + block $instanceof/I1 + block $instanceof/A_I1 + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid + end + return + end + return end return end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit return end return end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit return end return @@ -3783,7 +3878,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $instanceof/ImplemensIFace#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (func $instanceof/A_I1#constructor (type $i32_=>_i32) (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -3816,4 +3911,37 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $instanceof/B_I1_I2#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (local $1 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 $0 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 17 + call $~lib/rt/itcms/__new + local.tee $this + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $this + call $~lib/object/Object#constructor + local.tee $this + i32.store $0 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) ) diff --git a/tests/compiler/instanceof.release.wat b/tests/compiler/instanceof.release.wat index b30825eb20..8e0fe91553 100644 --- a/tests/compiler/instanceof.release.wat +++ b/tests/compiler/instanceof.release.wat @@ -28,8 +28,9 @@ (global $instanceof/nullableAnimal (mut i32) (i32.const 0)) (global $instanceof/nullableCat (mut i32) (i32.const 0)) (global $instanceof/nullableBlackcat (mut i32) (i32.const 0)) - (global $instanceof/impl (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34324)) + (global $instanceof/a_i1 (mut i32) (i32.const 0)) + (global $instanceof/b_i1_i2 (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34332)) (memory $0 1) (data (i32.const 1036) "<") (data (i32.const 1048) "\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") @@ -43,7 +44,7 @@ (data (i32.const 1384) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") (data (i32.const 1436) ",") (data (i32.const 1448) "\02\00\00\00\1a\00\00\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s") - (data (i32.const 1488) "\10\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 ") + (data (i32.const 1488) "\12\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\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 (type $none_=>_none) @@ -115,7 +116,13 @@ local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end - global.get $instanceof/impl + global.get $instanceof/a_i1 + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $instanceof/b_i1_i2 local.tee $0 if local.get $0 @@ -198,7 +205,7 @@ i32.load $0 offset=8 i32.eqz local.get $0 - i32.const 34324 + i32.const 34332 i32.lt_u i32.and i32.eqz @@ -967,7 +974,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 34324 + i32.const 34332 i32.lt_u if local.get $0 @@ -1067,7 +1074,7 @@ unreachable end local.get $0 - i32.const 34324 + i32.const 34332 i32.lt_u if local.get $0 @@ -1090,7 +1097,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 34324 + i32.const 34332 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1446,22 +1453,22 @@ (local $0 i32) (local $1 i32) global.get $~lib/memory/__stack_pointer - i32.const 88 + i32.const 96 i32.sub global.set $~lib/memory/__stack_pointer block $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 88 + i32.const 96 memory.fill $0 memory.size $0 i32.const 16 i32.shl - i32.const 34324 + i32.const 34332 i32.sub i32.const 1 i32.shr_u @@ -1498,7 +1505,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1560,7 +1567,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1578,7 +1585,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1616,7 +1623,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1634,7 +1641,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2158,7 +2165,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2180,29 +2187,26 @@ i32.add global.set $~lib/memory/__stack_pointer local.get $0 - global.set $instanceof/impl + global.set $instanceof/a_i1 global.get $~lib/memory/__stack_pointer - global.get $instanceof/impl + global.get $instanceof/a_i1 local.tee $0 i32.store $0 offset=84 local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/IFace (result i32) + block $__inlined_func$~instanceof|instanceof/I1 (result i32) block $is_instance37 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 15 - i32.eq - br_if $is_instance37 - local.get $0 - i32.const 14 - i32.eq - br_if $is_instance37 + block $tablify|0 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 14 + i32.sub + br_table $is_instance37 $is_instance37 $tablify|0 $is_instance37 $tablify|0 + end i32.const 0 - br $__inlined_func$~instanceof|instanceof/IFace + br $__inlined_func$~instanceof|instanceof/I1 end i32.const 1 end @@ -2213,13 +2217,88 @@ if i32.const 0 i32.const 1456 - i32.const 161 + i32.const 165 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 88 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 17 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/b_i1_i2 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/a_i1 + local.tee $0 + i32.store $0 offset=88 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 17 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 172 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/b_i1_i2 + local.tee $0 + i32.store $0 offset=92 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 17 + i32.eq + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 173 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 96 i32.add global.set $~lib/memory/__stack_pointer return @@ -2233,41 +2312,47 @@ ) (func $~lib/rt/__visit_members (type $i32_=>_none) (param $0 i32) block $invalid - block $instanceof/IFace - block $instanceof/ImplemensIFace - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/ImplemensIFace $instanceof/IFace $invalid + block $instanceof/B_I1_I2 + block $instanceof/I2 + block $instanceof/I1 + block $instanceof/A_I1 + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid + end + return + end + return end return end + local.get $0 + i32.load $0 + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end return end return end - local.get $0 - i32.load $0 - local.tee $0 - if - local.get $0 - call $byn-split-outlined-A$~lib/rt/itcms/__visit - end return end return @@ -2305,7 +2390,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s if i32.const 34352 @@ -2339,7 +2424,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s if i32.const 34352 @@ -2378,7 +2463,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s if i32.const 34352 @@ -2417,7 +2502,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s if i32.const 34352 @@ -2457,7 +2542,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1556 + i32.const 1564 i32.lt_s if i32.const 34352 diff --git a/tests/compiler/instanceof.ts b/tests/compiler/instanceof.ts index 1b77f79bb8..25165f4665 100644 --- a/tests/compiler/instanceof.ts +++ b/tests/compiler/instanceof.ts @@ -151,11 +151,23 @@ assert(!(nullBlackcat instanceof Animal)); // static false assert(!(nullBlackcat instanceof Cat)); // dynamic false assert(!(nullBlackcat instanceof BlackCat)); // dynamic false -// Interfaces participate and are Object instances - -interface IFace {} -class ImplemensIFace implements IFace {} - -let impl = new ImplemensIFace(); -assert(impl instanceof IFace); // static true -assert(impl as Object instanceof IFace); // dynamic true +// Interfaces + +interface I1 {} +interface I2 {} +interface I3 extends I1 {} +class A_I1 implements I1 {} +class B_I1_I2 implements I1, I2 {} + +let a_i1 = new A_I1(); +assert(a_i1 instanceof Object); // static true +assert(a_i1 instanceof I1); // static true +assert(a_i1 as Object instanceof I1); // dynamic true +assert(!(a_i1 instanceof I2)); // static false + +let b_i1_i2 = new B_I1_I2(); +assert(b_i1_i2 instanceof I1); // static true +assert(b_i1_i2 instanceof I2); // static true +assert(!(a_i1 instanceof B_I1_I2)); // dynamic false +assert(!(a_i1 as I1 instanceof B_I1_I2)); // dynamic false +assert(b_i1_i2 as I1 instanceof B_I1_I2); // dynamic true From 3e111ee7d75c75e230b007c6dc96fdcde59d71de Mon Sep 17 00:00:00 2001 From: dcode Date: Fri, 9 Dec 2022 11:48:47 +0100 Subject: [PATCH 05/16] fix --- src/program.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/program.ts b/src/program.ts index 9bf2097d64..b589c85bb8 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4460,7 +4460,7 @@ export class Class extends TypedElement { return this == target || this.extends(target); } else { // targetInterface = thisClass - return this.implements(target); + return this.implements(target); } } else { if (this.isInterface) { @@ -4479,10 +4479,10 @@ export class Class extends TypedElement { if (target.isInterface) { if (this.isInterface) { // thisInterface - return this.hasImplementerImplementing(target); + return this.hasImplementerImplementing(target); } else { // thisClass - return this.hasExtendeeImplementing(target); + return this.hasExtendeeImplementing(target); } } else { if (this.isInterface) { @@ -4793,7 +4793,7 @@ export class Class extends TypedElement { } /** Tests if this class has a direct or indirect extendee that implements the given interface. */ - hasExtendeeImplementing(other: Class): bool { + hasExtendeeImplementing(other: Interface): bool { let extendees = this.extendees; if (extendees) { for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { @@ -4805,7 +4805,7 @@ export class Class extends TypedElement { } /** Tests if this class implements the given interface. */ - implements(other: Class): bool { + implements(other: Interface): bool { let interfaces = this.interfaces; if (interfaces) { if (interfaces.has(other)) return true; @@ -4832,7 +4832,7 @@ export class Class extends TypedElement { } /** Tests if this interface has an implementer implementing the given interface. */ - hasImplementerImplementing(other: Class): bool { + hasImplementerImplementing(other: Interface): bool { let implementers = this.implementers; if (implementers) { for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) { From 4795ff00728fa06c08613c6c2b595ff6090fdda7 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 13 Dec 2022 00:23:43 +0100 Subject: [PATCH 06/16] simplify --- src/program.ts | 34 +- tests/compiler/instanceof.debug.wat | 1654 ++++++++++++----------- tests/compiler/instanceof.release.wat | 1731 +++++++++++++------------ tests/compiler/instanceof.ts | 41 +- 4 files changed, 1792 insertions(+), 1668 deletions(-) diff --git a/src/program.ts b/src/program.ts index b589c85bb8..01535c492e 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4298,9 +4298,9 @@ export class Class extends TypedElement { prototype: ClassPrototype; /** Resolved type arguments. */ typeArguments: Type[] | null; - /** Base class, if applicable. */ + /** Base class, if any. */ base: Class | null = null; - /** Implemented interfaces, if applicable. */ + /** Directly implemented interfaces, if any. */ interfaces: Set | null = null; /** Contextual type arguments for fields and methods. */ contextualTypeArguments: Map | null = null; @@ -4318,9 +4318,9 @@ export class Class extends TypedElement { rttiFlags: u32 = 0; /** Wrapped type, if a wrapper for a basic type. */ wrappedType: Type | null = null; - /** Classes directly extending this class. */ + /** Classes directly extending this class, if any. */ extendees: Set | null = null; - /** Classes implementing this interface. */ + /** Classes directly implementing this interface, if any. */ implementers: Set | null = null; /** Whether the field initialization check has already been performed. */ didCheckFieldInitialization: bool = false; @@ -4748,7 +4748,7 @@ export class Class extends TypedElement { return out; } - /** Gets all extendees and implementers of this class. */ + /** Gets all extendees and implementers of this class or interface. */ getAllExtendeesAndImplementers(out: Set = new Set()): Set { let extendees = this.extendees; if (extendees) { @@ -4769,7 +4769,7 @@ export class Class extends TypedElement { return out; } - /** Tests if this class or interface extends the given classs or interface. */ + /** Tests if this class or interface extends the given class or interface. */ extends(other: Class): bool { let base = this.base; while (base) { @@ -4781,15 +4781,7 @@ export class Class extends TypedElement { /** Tests if this class has a direct or indirect extendee matching the given class. */ hasExtendee(other: Class): bool { - let extendees = this.extendees; - if (extendees) { - if (extendees.has(other)) return true; - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - if (/* extendee == other || */extendee.hasExtendee(other)) return true; - } - } - return false; + return other.extends(this); } /** Tests if this class has a direct or indirect extendee that implements the given interface. */ @@ -4804,7 +4796,7 @@ export class Class extends TypedElement { return false; } - /** Tests if this class implements the given interface. */ + /** Tests if this class directly or indirectly implements the given interface. */ implements(other: Interface): bool { let interfaces = this.interfaces; if (interfaces) { @@ -4820,15 +4812,7 @@ export class Class extends TypedElement { /** Tests if this interface has a direct or indirect implementer matching the given class. */ hasImplementer(other: Class): bool { - let implementers = this.implementers; - if (implementers) { - if (implementers.has(other)) return true; - for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) { - let implementer = _values[i]; - if (/* implementer == other || */implementer.extends(other)) return true; - } - } - return false; + return other.implements(this); } /** Tests if this interface has an implementer implementing the given interface. */ diff --git a/tests/compiler/instanceof.debug.wat b/tests/compiler/instanceof.debug.wat index ee8b05dca1..cbcc1c2094 100644 --- a/tests/compiler/instanceof.debug.wat +++ b/tests/compiler/instanceof.debug.wat @@ -2280,258 +2280,733 @@ i32.const 0 return ) - (func $start:instanceof (type $none_=>_none) - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i32) - (local $14 i32) - (local $15 i32) - (local $16 i32) - (local $17 i32) - (local $18 i32) - (local $19 i32) - (local $20 i32) - (local $21 i32) - (local $22 i32) - (local $23 i32) - global.get $~lib/memory/__stack_pointer - i32.const 96 - i32.sub - global.set $~lib/memory/__stack_pointer - call $~stack_check - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.const 96 - memory.fill $0 - memory.size $0 - 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 144 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/pinSpace - i32.const 176 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/toSpace - i32.const 320 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/fromSpace - i32.const 0 - call $instanceof/A#constructor - global.set $instanceof/a - i32.const 0 - call $instanceof/B#constructor - global.set $instanceof/b + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) i32.const 0 i32.eqz drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a - local.tee $0 - i32.store $0 - local.get $0 + return + ) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/I1> (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $0 - call $~instanceof|instanceof/B + local.get $1 + call $~instanceof|instanceof/I1 end i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 18 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) i32.const 0 i32.eqz drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 1 - drop - i32.const 0 - call $instanceof/isI32 + return + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz - if + if (result i32) i32.const 0 - i32.const 432 - i32.const 62 - i32.const 1 - call $~lib/builtins/abort - unreachable + else + local.get $1 + call $~instanceof|instanceof/B_I1_I2 end - f64.const 0 - call $instanceof/isI32 - i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 63 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $instanceof/isI32 - i32.eqz - i32.eqz - if + local.set $check i32.const 0 - i32.const 432 - i32.const 64 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - i32.const 0 - call $instanceof/isI32 - i32.eqz + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz - if + if (result i32) i32.const 0 - i32.const 432 - i32.const 65 - i32.const 1 - call $~lib/builtins/abort - unreachable + else + local.get $1 + call $~instanceof|instanceof/B_I1_I2 end - global.get $instanceof/an - i32.const 0 - i32.ne - i32.eqz i32.eqz if i32.const 0 - i32.const 432 - i32.const 68 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - drop - i32.const 1 - global.set $instanceof/an - global.get $instanceof/an - i32.const 0 - i32.ne - i32.eqz - if + local.set $check i32.const 0 - i32.const 432 - i32.const 71 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 + drop + ) + (func $~instanceof|instanceof/B (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 5 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 8 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~anyinstanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 6 + i32.eq + br_if $is_instance + local.get $1 + i32.const 8 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/Cat (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 12 + i32.eq + br_if $is_instance + local.get $1 + i32.const 13 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/BlackCat (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 13 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/I1 (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 15 + i32.eq + br_if $is_instance + local.get $1 + i32.const 14 + i32.eq + br_if $is_instance + local.get $1 + i32.const 17 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/B_I1_I2 (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 17 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~lib/rt/__visit_globals (type $i32_=>_none) (param $0 i32) + (local $1 i32) + global.get $instanceof/a + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/b + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/an + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/child + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/childAsParent + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/animal + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/cat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/blackcat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullableAnimal + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullableCat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullableBlackcat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullAnimal + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullCat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullBlackcat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/a_i1 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/b_i1_i2 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + i32.const 224 + local.get $0 + call $~lib/rt/itcms/__visit + i32.const 32 + local.get $0 + call $~lib/rt/itcms/__visit + ) + (func $~lib/arraybuffer/ArrayBufferView~visit (type $i32_i32_=>_none) (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 $0 + local.tee $2 + if + local.get $2 + local.get $1 + call $~lib/rt/itcms/__visit + end + ) + (func $~lib/object/Object~visit (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) + nop + ) + (func $~lib/rt/__visit_members (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) + block $invalid + block $instanceof/B_I1_I2 + block $instanceof/I2 + block $instanceof/I1 + block $instanceof/A_I1 + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid + end + return + end + return + end + return + end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + unreachable + ) + (func $~start (type $none_=>_none) + call $start:instanceof + ) + (func $~stack_check (type $none_=>_none) + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__data_end + i32.lt_s + if + i32.const 33328 + i32.const 33376 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $start:instanceof (type $none_=>_none) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (local $14 i32) + (local $15 i32) + (local $16 i32) + (local $17 i32) + (local $18 i32) + (local $19 i32) + (local $20 i32) + (local $21 i32) + global.get $~lib/memory/__stack_pointer + i32.const 88 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 88 + memory.fill $0 + memory.size $0 + 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 144 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/pinSpace + i32.const 176 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/toSpace + i32.const 320 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/fromSpace + i32.const 0 + call $instanceof/A#constructor + global.set $instanceof/a + i32.const 0 + call $instanceof/B#constructor + global.set $instanceof/b + i32.const 1 + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + global.get $~lib/memory/__stack_pointer + global.get $instanceof/a + local.tee $0 + i32.store $0 + local.get $0 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $0 + call $~instanceof|instanceof/B + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 41 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + call $instanceof/isI32 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 85 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 0 + call $instanceof/isI32 + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 86 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/isI32 + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 87 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/isI32 + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 88 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/an + i32.const 0 + i32.ne + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 91 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + i32.const 1 + global.set $instanceof/an + global.get $instanceof/an + i32.const 0 + i32.ne + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 94 + i32.const 1 + call $~lib/builtins/abort + unreachable end i32.const 1 drop @@ -2584,7 +3059,7 @@ if i32.const 0 i32.const 432 - i32.const 94 + i32.const 117 i32.const 1 call $~lib/builtins/abort unreachable @@ -2608,7 +3083,7 @@ if i32.const 0 i32.const 432 - i32.const 96 + i32.const 119 i32.const 1 call $~lib/builtins/abort unreachable @@ -2647,7 +3122,7 @@ if i32.const 0 i32.const 432 - i32.const 111 + i32.const 134 i32.const 1 call $~lib/builtins/abort unreachable @@ -2669,7 +3144,7 @@ if i32.const 0 i32.const 432 - i32.const 112 + i32.const 135 i32.const 1 call $~lib/builtins/abort unreachable @@ -2692,7 +3167,7 @@ if i32.const 0 i32.const 432 - i32.const 115 + i32.const 138 i32.const 1 call $~lib/builtins/abort unreachable @@ -2714,7 +3189,7 @@ if i32.const 0 i32.const 432 - i32.const 116 + i32.const 139 i32.const 1 call $~lib/builtins/abort unreachable @@ -2737,7 +3212,7 @@ if i32.const 0 i32.const 432 - i32.const 119 + i32.const 142 i32.const 1 call $~lib/builtins/abort unreachable @@ -2758,7 +3233,7 @@ if i32.const 0 i32.const 432 - i32.const 120 + i32.const 143 i32.const 1 call $~lib/builtins/abort unreachable @@ -2779,7 +3254,7 @@ if i32.const 0 i32.const 432 - i32.const 126 + i32.const 149 i32.const 1 call $~lib/builtins/abort unreachable @@ -2801,7 +3276,7 @@ if i32.const 0 i32.const 432 - i32.const 127 + i32.const 150 i32.const 1 call $~lib/builtins/abort unreachable @@ -2823,7 +3298,7 @@ if i32.const 0 i32.const 432 - i32.const 128 + i32.const 151 i32.const 1 call $~lib/builtins/abort unreachable @@ -2835,7 +3310,7 @@ if i32.const 0 i32.const 432 - i32.const 130 + i32.const 153 i32.const 1 call $~lib/builtins/abort unreachable @@ -2856,7 +3331,7 @@ if i32.const 0 i32.const 432 - i32.const 131 + i32.const 154 i32.const 1 call $~lib/builtins/abort unreachable @@ -2878,7 +3353,7 @@ if i32.const 0 i32.const 432 - i32.const 132 + i32.const 155 i32.const 1 call $~lib/builtins/abort unreachable @@ -2890,7 +3365,7 @@ if i32.const 0 i32.const 432 - i32.const 134 + i32.const 157 i32.const 1 call $~lib/builtins/abort unreachable @@ -2911,7 +3386,7 @@ if i32.const 0 i32.const 432 - i32.const 135 + i32.const 158 i32.const 1 call $~lib/builtins/abort unreachable @@ -2932,7 +3407,7 @@ if i32.const 0 i32.const 432 - i32.const 136 + i32.const 159 i32.const 1 call $~lib/builtins/abort unreachable @@ -2945,613 +3420,242 @@ if i32.const 0 i32.const 432 - i32.const 142 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullAnimal - local.tee $15 - i32.store $0 offset=60 - local.get $15 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $15 - call $~instanceof|instanceof/Cat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 143 + i32.const 165 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer global.get $instanceof/nullAnimal - local.tee $16 - i32.store $0 offset=64 - local.get $16 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $16 - call $~instanceof|instanceof/BlackCat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 144 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullCat - i32.const 0 - i32.ne - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 146 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullCat - local.tee $17 - i32.store $0 offset=68 - local.get $17 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $17 - call $~instanceof|instanceof/Cat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 147 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullCat - local.tee $18 - i32.store $0 offset=72 - local.get $18 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $18 - call $~instanceof|instanceof/BlackCat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 148 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullBlackcat - i32.const 0 - i32.ne - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 150 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullBlackcat - local.tee $19 - i32.store $0 offset=76 - local.get $19 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $19 - call $~instanceof|instanceof/Cat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 151 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullBlackcat - local.tee $20 - i32.store $0 offset=80 - local.get $20 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $20 - call $~instanceof|instanceof/BlackCat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 152 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $instanceof/A_I1#constructor - global.set $instanceof/a_i1 - i32.const 1 - drop - i32.const 1 - drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a_i1 - local.tee $21 - i32.store $0 offset=84 - local.get $21 + local.tee $15 + i32.store $0 offset=60 + local.get $15 i32.eqz if (result i32) i32.const 0 else - local.get $21 - call $~instanceof|instanceof/I1 + local.get $15 + call $~instanceof|instanceof/Cat end i32.eqz + i32.eqz if i32.const 0 i32.const 432 - i32.const 165 + i32.const 166 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 0 - i32.eqz - drop - i32.const 0 - call $instanceof/B_I1_I2#constructor - global.set $instanceof/b_i1_i2 - i32.const 1 - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop global.get $~lib/memory/__stack_pointer - global.get $instanceof/a_i1 - local.tee $22 - i32.store $0 offset=88 - local.get $22 + global.get $instanceof/nullAnimal + local.tee $16 + i32.store $0 offset=64 + local.get $16 i32.eqz if (result i32) i32.const 0 else - local.get $22 - call $~instanceof|instanceof/B_I1_I2 + local.get $16 + call $~instanceof|instanceof/BlackCat end i32.eqz i32.eqz if i32.const 0 i32.const 432 - i32.const 172 + i32.const 167 i32.const 1 call $~lib/builtins/abort unreachable end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/b_i1_i2 - local.tee $23 - i32.store $0 offset=92 - local.get $23 + global.get $instanceof/nullCat + i32.const 0 + i32.ne i32.eqz - if (result i32) - i32.const 0 - else - local.get $23 - call $~instanceof|instanceof/B_I1_I2 - end i32.eqz if i32.const 0 i32.const 432 - i32.const 173 + i32.const 169 i32.const 1 call $~lib/builtins/abort unreachable end global.get $~lib/memory/__stack_pointer - i32.const 96 - i32.add - global.set $~lib/memory/__stack_pointer - ) - (func $~instanceof|instanceof/B (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 5 - i32.eq - br_if $is_instance - i32.const 0 - return - end - i32.const 1 - ) - (func $~instanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 8 - i32.eq - br_if $is_instance - i32.const 0 - return - end - i32.const 1 - ) - (func $~anyinstanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 6 - i32.eq - br_if $is_instance - local.get $1 - i32.const 8 - i32.eq - br_if $is_instance - i32.const 0 - return - end - i32.const 1 - ) - (func $~instanceof|instanceof/Cat (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 12 - i32.eq - br_if $is_instance - local.get $1 - i32.const 13 - i32.eq - br_if $is_instance - i32.const 0 - return - end - i32.const 1 - ) - (func $~instanceof|instanceof/BlackCat (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 13 - i32.eq - br_if $is_instance - i32.const 0 - return - end - i32.const 1 - ) - (func $~instanceof|instanceof/I1 (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 15 - i32.eq - br_if $is_instance - local.get $1 - i32.const 14 - i32.eq - br_if $is_instance - local.get $1 - i32.const 17 - i32.eq - br_if $is_instance - i32.const 0 - return - end - i32.const 1 - ) - (func $~instanceof|instanceof/B_I1_I2 (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 17 - i32.eq - br_if $is_instance - i32.const 0 - return - end - i32.const 1 - ) - (func $~lib/rt/__visit_globals (type $i32_=>_none) (param $0 i32) - (local $1 i32) - global.get $instanceof/a - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/b - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/an - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/child - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/childAsParent - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/animal - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/cat - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/blackcat - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/nullableAnimal - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/nullableCat - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/nullableBlackcat - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + global.get $instanceof/nullCat + local.tee $17 + i32.store $0 offset=68 + local.get $17 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $17 + call $~instanceof|instanceof/Cat end - global.get $instanceof/nullAnimal - local.tee $1 + i32.eqz + i32.eqz if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + i32.const 432 + i32.const 170 + i32.const 1 + call $~lib/builtins/abort + unreachable end + global.get $~lib/memory/__stack_pointer global.get $instanceof/nullCat - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + local.tee $18 + i32.store $0 offset=72 + local.get $18 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $18 + call $~instanceof|instanceof/BlackCat end - global.get $instanceof/nullBlackcat - local.tee $1 + i32.eqz + i32.eqz if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + i32.const 432 + i32.const 171 + i32.const 1 + call $~lib/builtins/abort + unreachable end - global.get $instanceof/a_i1 - local.tee $1 + global.get $instanceof/nullBlackcat + i32.const 0 + i32.ne + i32.eqz + i32.eqz if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + i32.const 432 + i32.const 173 + i32.const 1 + call $~lib/builtins/abort + unreachable end - global.get $instanceof/b_i1_i2 - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullBlackcat + local.tee $19 + i32.store $0 offset=76 + local.get $19 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $19 + call $~instanceof|instanceof/Cat end - i32.const 224 - local.get $0 - call $~lib/rt/itcms/__visit - i32.const 32 - local.get $0 - call $~lib/rt/itcms/__visit - ) - (func $~lib/arraybuffer/ArrayBufferView~visit (type $i32_i32_=>_none) (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 $0 - local.tee $2 + i32.eqz + i32.eqz if - local.get $2 - local.get $1 - call $~lib/rt/itcms/__visit - end - ) - (func $~lib/object/Object~visit (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) - nop - ) - (func $~lib/rt/__visit_members (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) - block $invalid - block $instanceof/B_I1_I2 - block $instanceof/I2 - block $instanceof/I1 - block $instanceof/A_I1 - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid - end - return - end - return - end - return - end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return + i32.const 0 + i32.const 432 + i32.const 174 + i32.const 1 + call $~lib/builtins/abort + unreachable end - unreachable - ) - (func $~start (type $none_=>_none) - call $start:instanceof - ) - (func $~stack_check (type $none_=>_none) global.get $~lib/memory/__stack_pointer - global.get $~lib/memory/__data_end - i32.lt_s + global.get $instanceof/nullBlackcat + local.tee $20 + i32.store $0 offset=80 + local.get $20 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $20 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz if - i32.const 33328 - i32.const 33376 - i32.const 1 + i32.const 0 + i32.const 432 + i32.const 175 i32.const 1 call $~lib/builtins/abort unreachable end + i32.const 0 + call $instanceof/A_I1#constructor + global.set $instanceof/a_i1 + global.get $instanceof/a_i1 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/a_i1 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/a_i1 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/a_i1 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/I1> + i32.const 0 + call $instanceof/B_I1_I2#constructor + global.set $instanceof/b_i1_i2 + global.get $instanceof/b_i1_i2 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/b_i1_i2 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/a_i1 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/a_i1 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/b_i1_i2 + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $~lib/memory/__stack_pointer + i32.const 88 + i32.add + global.set $~lib/memory/__stack_pointer ) (func $~lib/object/Object#constructor (type $i32_=>_i32) (param $this i32) (result i32) (local $1 i32) diff --git a/tests/compiler/instanceof.release.wat b/tests/compiler/instanceof.release.wat index 8e0fe91553..ad30a01ed2 100644 --- a/tests/compiler/instanceof.release.wat +++ b/tests/compiler/instanceof.release.wat @@ -1449,941 +1449,954 @@ memory.fill $0 local.get $0 ) + (func $~lib/rt/__visit_members (type $i32_=>_none) (param $0 i32) + block $invalid + block $instanceof/B_I1_I2 + block $instanceof/I2 + block $instanceof/I1 + block $instanceof/A_I1 + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid + end + return + end + return + end + return + end + local.get $0 + i32.load $0 + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + unreachable + ) + (func $~start (type $none_=>_none) + call $start:instanceof + ) (func $start:instanceof (type $none_=>_none) (local $0 i32) (local $1 i32) global.get $~lib/memory/__stack_pointer - i32.const 96 + i32.const 88 i32.sub global.set $~lib/memory/__stack_pointer - block $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.const 96 - memory.fill $0 - memory.size $0 - i32.const 16 - i32.shl - i32.const 34332 - i32.sub - i32.const 1 - i32.shr_u - global.set $~lib/rt/itcms/threshold - i32.const 1172 - i32.const 1168 - i32.store $0 - i32.const 1176 - i32.const 1168 - i32.store $0 - i32.const 1168 - global.set $~lib/rt/itcms/pinSpace - i32.const 1204 - i32.const 1200 - i32.store $0 - i32.const 1208 - i32.const 1200 - i32.store $0 - i32.const 1200 - global.set $~lib/rt/itcms/toSpace - i32.const 1348 - i32.const 1344 - i32.store $0 - i32.const 1352 - i32.const 1344 - i32.store $0 - i32.const 1344 - global.set $~lib/rt/itcms/fromSpace - i32.const 0 - call $instanceof/A#constructor - global.set $instanceof/a - 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 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 5 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $instanceof/A#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/b - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a - local.tee $0 - i32.store $0 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 5 - i32.eq - else - i32.const 0 - end - if + block $folding-inner1 + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 1456 - i32.const 18 + i32.const 88 + memory.fill $0 + memory.size $0 + i32.const 16 + i32.shl + i32.const 34332 + i32.sub i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/an - if + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 1172 + i32.const 1168 + i32.store $0 + i32.const 1176 + i32.const 1168 + i32.store $0 + i32.const 1168 + global.set $~lib/rt/itcms/pinSpace + i32.const 1204 + i32.const 1200 + i32.store $0 + i32.const 1208 + i32.const 1200 + i32.store $0 + i32.const 1200 + global.set $~lib/rt/itcms/toSpace + i32.const 1348 + i32.const 1344 + i32.store $0 + i32.const 1352 + i32.const 1344 + i32.store $0 + i32.const 1344 + global.set $~lib/rt/itcms/fromSpace i32.const 0 - i32.const 1456 - i32.const 68 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - global.set $instanceof/an - 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 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 6 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.tee $1 - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store $0 - local.get $0 - i32.eqz - if + call $instanceof/A#constructor + global.set $instanceof/a + 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 1564 + i32.lt_s + br_if $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 7 + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 5 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 - end - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $1 - local.get $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/child - 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 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 8 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.tee $1 - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store $0 - local.get $0 - i32.eqz - if global.get $~lib/memory/__stack_pointer - i32.const 9 + local.get $0 + call $instanceof/A#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/b + global.get $~lib/memory/__stack_pointer + global.get $instanceof/a + local.tee $0 + i32.store $0 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 5 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 41 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/an + if + i32.const 0 + i32.const 1456 + i32.const 91 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + global.set $instanceof/an + 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 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 6 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 - end - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $1 - local.get $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/childAsParent - global.get $~lib/memory/__stack_pointer - global.get $instanceof/childAsParent - local.tee $0 - i32.store $0 offset=4 - local.get $0 - if (result i32) + global.get $~lib/memory/__stack_pointer + local.tee $1 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 local.get $0 - i32.const 8 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 7 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + local.get $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/child + global.get $~lib/memory/__stack_pointer + i32.const 4 i32.sub - i32.load $0 - i32.const 8 - i32.eq - else + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 i32.const 0 - end - i32.eqz - if + i32.store $0 + local.get $0 + i32.const 8 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.tee $1 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 1456 - i32.const 94 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/childAsParent - local.tee $0 - i32.store $0 offset=8 - local.get $0 - if (result i32) - block $__inlined_func$~anyinstanceof|instanceof/Child (result i32) - block $is_instance2 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 6 - i32.eq - br_if $is_instance2 - local.get $0 - i32.const 8 - i32.eq - br_if $is_instance2 - i32.const 0 - br $__inlined_func$~anyinstanceof|instanceof/Child - end + i32.store $0 + local.get $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 9 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + local.get $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/childAsParent + global.get $~lib/memory/__stack_pointer + global.get $instanceof/childAsParent + local.tee $0 + i32.store $0 offset=4 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 8 + i32.eq + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 117 i32.const 1 + call $~lib/builtins/abort + unreachable end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 96 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $instanceof/Animal#constructor - global.set $instanceof/animal - i32.const 0 - call $instanceof/Cat#constructor - global.set $instanceof/cat - call $instanceof/BlackCat#constructor - global.set $instanceof/blackcat - global.get $~lib/memory/__stack_pointer - global.get $instanceof/animal - local.tee $0 - i32.store $0 offset=12 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat (result i32) - block $is_instance3 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance3 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance3 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat + global.get $~lib/memory/__stack_pointer + global.get $instanceof/childAsParent + local.tee $0 + i32.store $0 offset=8 + local.get $0 + if (result i32) + block $__inlined_func$~anyinstanceof|instanceof/Child (result i32) + block $is_instance2 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 6 + i32.eq + br_if $is_instance2 + local.get $0 + i32.const 8 + i32.eq + br_if $is_instance2 + i32.const 0 + br $__inlined_func$~anyinstanceof|instanceof/Child + end + i32.const 1 end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 119 i32.const 1 + call $~lib/builtins/abort + unreachable end - else i32.const 0 - end - if + call $instanceof/Animal#constructor + global.set $instanceof/animal i32.const 0 - i32.const 1456 - i32.const 111 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/animal - local.tee $0 - i32.store $0 offset=16 - local.get $0 - if (result i32) + call $instanceof/Cat#constructor + global.set $instanceof/cat + call $instanceof/BlackCat#constructor + global.set $instanceof/blackcat + global.get $~lib/memory/__stack_pointer + global.get $instanceof/animal + local.tee $0 + i32.store $0 offset=12 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 112 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/cat - local.tee $0 - i32.store $0 offset=20 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat5 (result i32) - block $is_instance6 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance6 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance6 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat5 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat (result i32) + block $is_instance3 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance3 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance3 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat + end + i32.const 1 end + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 134 i32.const 1 + call $~lib/builtins/abort + unreachable end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 115 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/cat - local.tee $0 - i32.store $0 offset=24 - local.get $0 - if (result i32) + global.get $~lib/memory/__stack_pointer + global.get $instanceof/animal + local.tee $0 + i32.store $0 offset=16 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 116 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/blackcat - local.tee $0 - i32.store $0 offset=28 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat9 (result i32) - block $is_instance10 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance10 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance10 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat9 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 135 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/cat + local.tee $0 + i32.store $0 offset=20 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat5 (result i32) + block $is_instance6 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance6 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance6 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat5 + end + i32.const 1 end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 138 i32.const 1 + call $~lib/builtins/abort + unreachable end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 119 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/blackcat - local.tee $0 - i32.store $0 offset=32 - local.get $0 - if (result i32) + global.get $~lib/memory/__stack_pointer + global.get $instanceof/cat + local.tee $0 + i32.store $0 offset=24 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 120 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $instanceof/Animal#constructor - global.set $instanceof/nullableAnimal - i32.const 0 - call $instanceof/Cat#constructor - global.set $instanceof/nullableCat - call $instanceof/BlackCat#constructor - global.set $instanceof/nullableBlackcat - global.get $instanceof/nullableAnimal - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 126 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableAnimal - local.tee $0 - i32.store $0 offset=36 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat13 (result i32) - block $is_instance14 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance14 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance14 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat13 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 139 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/blackcat + local.tee $0 + i32.store $0 offset=28 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat9 (result i32) + block $is_instance10 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance10 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance10 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat9 + end + i32.const 1 end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 142 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/blackcat + local.tee $0 + i32.store $0 offset=32 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 143 i32.const 1 + call $~lib/builtins/abort + unreachable end - else i32.const 0 - end - if + call $instanceof/Animal#constructor + global.set $instanceof/nullableAnimal i32.const 0 - i32.const 1456 - i32.const 127 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableAnimal - local.tee $0 - i32.store $0 offset=40 - local.get $0 - if (result i32) + call $instanceof/Cat#constructor + global.set $instanceof/nullableCat + call $instanceof/BlackCat#constructor + global.set $instanceof/nullableBlackcat + global.get $instanceof/nullableAnimal + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 149 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableAnimal + local.tee $0 + i32.store $0 offset=36 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 128 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullableCat - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 130 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableCat - local.tee $0 - i32.store $0 offset=44 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat17 (result i32) - block $is_instance18 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance18 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance18 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat17 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat13 (result i32) + block $is_instance14 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance14 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance14 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat13 + end + i32.const 1 end + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 150 i32.const 1 + call $~lib/builtins/abort + unreachable end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 131 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableCat - local.tee $0 - i32.store $0 offset=48 - local.get $0 - if (result i32) + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableAnimal + local.tee $0 + i32.store $0 offset=40 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 132 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullableBlackcat - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 134 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableBlackcat - local.tee $0 - i32.store $0 offset=52 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat21 (result i32) - block $is_instance22 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance22 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance22 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat21 - end + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 151 i32.const 1 + call $~lib/builtins/abort + unreachable end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 135 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableBlackcat - local.tee $0 - i32.store $0 offset=56 - local.get $0 - if (result i32) + global.get $instanceof/nullableCat + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 153 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableCat + local.tee $0 + i32.store $0 offset=44 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 136 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 offset=60 - local.get $0 - i32.const 0 - i32.store $0 offset=64 - local.get $0 - i32.const 0 - i32.store $0 offset=68 - local.get $0 - i32.const 0 - i32.store $0 offset=72 - local.get $0 - i32.const 0 - i32.store $0 offset=76 - local.get $0 - i32.const 0 - i32.store $0 offset=80 - local.get $0 - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 14 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/a_i1 - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a_i1 - local.tee $0 - i32.store $0 offset=84 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/I1 (result i32) - block $is_instance37 - block $tablify|0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat17 (result i32) + block $is_instance18 local.get $0 i32.const 8 i32.sub i32.load $0 - i32.const 14 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance18 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance18 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat17 + end + i32.const 1 + end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 154 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableCat + local.tee $0 + i32.store $0 offset=48 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 155 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullableBlackcat + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 157 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableBlackcat + local.tee $0 + i32.store $0 offset=52 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat21 (result i32) + block $is_instance22 + local.get $0 + i32.const 8 i32.sub - br_table $is_instance37 $is_instance37 $tablify|0 $is_instance37 $tablify|0 + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance22 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance22 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat21 end - i32.const 0 - br $__inlined_func$~instanceof|instanceof/I1 + i32.const 1 end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 158 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableBlackcat + local.tee $0 + i32.store $0 offset=56 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 159 i32.const 1 + call $~lib/builtins/abort + unreachable end - else + global.get $~lib/memory/__stack_pointer + local.tee $0 i32.const 0 - end - i32.eqz - if + i32.store $0 offset=60 + local.get $0 i32.const 0 - i32.const 1456 - i32.const 165 - 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 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 17 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/b_i1_i2 - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a_i1 - local.tee $0 - i32.store $0 offset=88 - local.get $0 - if (result i32) + i32.store $0 offset=64 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 17 - i32.eq - else i32.const 0 - end - if + i32.store $0 offset=68 + local.get $0 i32.const 0 - i32.const 1456 - i32.const 172 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/b_i1_i2 - local.tee $0 - i32.store $0 offset=92 - local.get $0 - if (result i32) + i32.store $0 offset=72 local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 17 - i32.eq - else i32.const 0 - end - i32.eqz - if + i32.store $0 offset=76 + local.get $0 i32.const 0 - i32.const 1456 - i32.const 173 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - i32.const 96 - i32.add - global.set $~lib/memory/__stack_pointer - return - end - i32.const 34352 - i32.const 34400 - i32.const 1 - i32.const 1 - call $~lib/builtins/abort - unreachable - ) - (func $~lib/rt/__visit_members (type $i32_=>_none) (param $0 i32) - block $invalid - block $instanceof/B_I1_I2 - block $instanceof/I2 - block $instanceof/I1 - block $instanceof/A_I1 - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid - end - return - end - return - end - return - end - local.get $0 - i32.load $0 - local.tee $0 - if - local.get $0 - call $byn-split-outlined-A$~lib/rt/itcms/__visit - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return + i32.store $0 offset=80 + local.get $0 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 14 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/a_i1 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/a_i1 + local.tee $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/I1 (result i32) + block $is_instance13 + block $tablify|0 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 14 + i32.sub + br_table $is_instance13 $is_instance13 $tablify|0 $is_instance13 $tablify|0 end - return + i32.const 0 + br $__inlined_func$~instanceof|instanceof/I1 end - return + i32.const 1 end - return + else + i32.const 0 + end + i32.eqz + br_if $folding-inner1 + 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 1564 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 17 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/b_i1_i2 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/b_i1_i2 + local.tee $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/a_i1 + local.tee $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 17 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/b_i1_i2 + local.tee $0 + i32.store $0 offset=84 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 17 + i32.eq + else + i32.const 0 end + i32.eqz + br_if $folding-inner1 + global.get $~lib/memory/__stack_pointer + i32.const 88 + i32.add + global.set $~lib/memory/__stack_pointer return end - return + i32.const 34352 + i32.const 34400 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable end + i32.const 0 + i32.const 1456 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort unreachable ) - (func $~start (type $none_=>_none) - call $start:instanceof - ) (func $~lib/object/Object#constructor (type $i32_=>_i32) (param $0 i32) (result i32) global.get $~lib/memory/__stack_pointer i32.const 4 diff --git a/tests/compiler/instanceof.ts b/tests/compiler/instanceof.ts index 25165f4665..3911cfe063 100644 --- a/tests/compiler/instanceof.ts +++ b/tests/compiler/instanceof.ts @@ -1,3 +1,26 @@ +function assertStaticTrue(value: T): void { + if (value instanceof U) return; + ERROR("should be statically true"); +} +function assertStaticFalse(value: T): void { + if (!(value instanceof U)) return; + ERROR("should be statically false"); +} +function assertDynamicTrue(value: T): void { + if (!(value instanceof U)) { + var check: i32 = 0; + assert(false); + } + assert(isDefined(check)); +} +function assertDynamicFalse(value: T): void { + if (value instanceof U) { + var check: i32 = 0; + assert(false); + } + assert(isDefined(check)); +} + class A {} class B extends A {} @@ -160,14 +183,14 @@ class A_I1 implements I1 {} class B_I1_I2 implements I1, I2 {} let a_i1 = new A_I1(); -assert(a_i1 instanceof Object); // static true -assert(a_i1 instanceof I1); // static true -assert(a_i1 as Object instanceof I1); // dynamic true -assert(!(a_i1 instanceof I2)); // static false +assertStaticTrue(a_i1); +assertStaticTrue(a_i1); +assertStaticFalse(a_i1); +assertDynamicTrue(a_i1); let b_i1_i2 = new B_I1_I2(); -assert(b_i1_i2 instanceof I1); // static true -assert(b_i1_i2 instanceof I2); // static true -assert(!(a_i1 instanceof B_I1_I2)); // dynamic false -assert(!(a_i1 as I1 instanceof B_I1_I2)); // dynamic false -assert(b_i1_i2 as I1 instanceof B_I1_I2); // dynamic true +assertStaticTrue(b_i1_i2); +assertStaticTrue(b_i1_i2); +assertStaticFalse(a_i1); +assertDynamicFalse(a_i1); +assertDynamicTrue(b_i1_i2); From 87f3d64a23653be1eff3b2c23607a56b140cd097 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 13 Dec 2022 18:06:03 +0100 Subject: [PATCH 07/16] propagate extendees and implementers early --- src/compiler.ts | 71 +++++++++---- src/program.ts | 144 ++++++++++++++------------ tests/compiler/instanceof.debug.wat | 4 - tests/compiler/instanceof.release.wat | 21 ++-- 4 files changed, 143 insertions(+), 97 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 549e239cc4..84186cc590 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -6576,10 +6576,16 @@ export class Compiler extends DiagnosticEmitter { let classInstance = assert(overrideInstance.getBoundClassOrInterface()); builder.addCase(classInstance.id, stmts); // Also alias each extendee inheriting this exact overload - let extendees = classInstance.getAllExtendees(instance.declaration.name.text); // without get:/set: - for (let _values = Set_values(extendees), a = 0, b = _values.length; a < b; ++a) { - let extendee = _values[a]; - builder.addCase(extendee.id, stmts); + let extendees = classInstance.extendees; + if (extendees) { + for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { + let extendee = _values[i]; + let instanceMembers = extendee.prototype.instanceMembers; + if (instanceMembers && instanceMembers.has(instance.declaration.name.text)) { + continue; // skip those not inheriting + } + builder.addCase(extendee.id, stmts); + } } } } @@ -7565,19 +7571,32 @@ export class Compiler extends DiagnosticEmitter { ), false // managedness is irrelevant here, isn't interrupted ) ); - let allInstances = new Set(); - allInstances.add(instance); - instance.getAllExtendeesAndImplementers(allInstances); - for (let _values = Set_values(allInstances), i = 0, k = _values.length; i < k; ++i) { - let instance = _values[i]; - stmts.push( - module.br("is_instance", - module.binary(BinaryOp.EqI32, - module.local_get(1, TypeRef.I32), - module.i32(instance.id) + let allInstances: Set | null; + if (instance.isInterface) { + allInstances = instance.implementers; + } else { + allInstances = new Set(); + allInstances.add(instance); + let extendees = instance.extendees; + if (extendees) { + for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { + let extendee = _values[i]; + allInstances.add(extendee); + } + } + } + if (allInstances) { + for (let _values = Set_values(allInstances), i = 0, k = _values.length; i < k; ++i) { + let instance = _values[i]; + stmts.push( + module.br("is_instance", + module.binary(BinaryOp.EqI32, + module.local_get(1, TypeRef.I32), + module.i32(instance.id) + ) ) - ) - ); + ); + } } stmts.push( module.return( @@ -7695,8 +7714,24 @@ export class Compiler extends DiagnosticEmitter { let allInstances = new Set(); for (let _values = Map_values(instances), i = 0, k = _values.length; i < k; ++i) { let instance = _values[i]; - allInstances.add(instance); - instance.getAllExtendeesAndImplementers(allInstances); + if (instance.isInterface) { + let implementers = instance.implementers; + if (implementers) { + for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) { + let implementer = _values[i]; + allInstances.add(implementer); + } + } + } else { + allInstances.add(instance); + let extendees = instance.extendees; + if (extendees) { + for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { + let extendee = _values[i]; + allInstances.add(extendee); + } + } + } } for (let _values = Set_values(allInstances), i = 0, k = _values.length; i < k; ++i) { let instance = _values[i]; diff --git a/src/program.ts b/src/program.ts index 01535c492e..c8aa1eea51 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4318,9 +4318,9 @@ export class Class extends TypedElement { rttiFlags: u32 = 0; /** Wrapped type, if a wrapper for a basic type. */ wrappedType: Type | null = null; - /** Classes directly extending this class, if any. */ + /** Classes directly or indirectly extending this class, if any. */ extendees: Set | null = null; - /** Classes directly implementing this interface, if any. */ + /** Classes directly or indirectly implementing this interface, if any. */ implementers: Set | null = null; /** Whether the field initialization check has already been performed. */ didCheckFieldInitialization: bool = false; @@ -4419,9 +4419,6 @@ export class Class extends TypedElement { setBase(base: Class): void { assert(!this.base); this.base = base; - let extendees = base.extendees; - if (!extendees) base.extendees = extendees = new Set(); - extendees.add(this); // Inherit contextual type arguments from base class let inheritedTypeArguments = base.contextualTypeArguments; @@ -4439,16 +4436,81 @@ export class Class extends TypedElement { } } } + + // This class is now an extendee of the base class + let extendees = base.extendees; + if (!extendees) base.extendees = extendees = new Set(); + extendees.add(this); + + let iter: Class | null = base; + let extendeesArray = Set_values(extendees); + do { + // Extendees of this class are now also extendees of its base classes + for (let i = 0, k = extendeesArray.length; i < k; ++i) { + let thisExtendee = extendeesArray[i]; + let baseExtendees = iter.extendees; + if (!baseExtendees) iter.extendees = baseExtendees = new Set(); + baseExtendees.add(thisExtendee); + } + // Interfaces directly or indirectly implemented by a base class are now + // also implemented by this class and its extendees + let baseInterfaces = iter.interfaces; + if (baseInterfaces) { + for (let _values = Set_values(baseInterfaces), i = 0, k = _values.length; i < k; ++i) { + let baseInterface: Interface | null = _values[i]; + do { + let baseInterfaceImplementers = baseInterface.implementers; + if (!baseInterfaceImplementers) baseInterface.implementers = baseInterfaceImplementers = new Set(); + baseInterfaceImplementers.add(this); + for (let i = 0, k = extendeesArray.length; i < k; ++i) { + let thisExtendee = extendeesArray[i]; + baseInterfaceImplementers.add(thisExtendee); + } + baseInterface = baseInterface.base; + } while (baseInterface); + } + } + iter = iter.base; + } while (iter); } /** Adds an interface. */ addInterface(iface: Interface): void { - let interfaces = this.interfaces; - if (!interfaces) this.interfaces = interfaces = new Set(); - interfaces.add(iface); - let implementers = iface.implementers; - if (!implementers) iface.implementers = implementers = new Set(); - implementers.add(this); + let thisInterfaces = this.interfaces; + if (!thisInterfaces) this.interfaces = thisInterfaces = new Set(); + thisInterfaces.add(iface); + + // The interface is now implemented by this class + let interfaceImplementers = iface.implementers; + if (!interfaceImplementers) iface.implementers = interfaceImplementers = new Set(); + interfaceImplementers.add(this); + + // The interface's base interfaces are implemented by this class as well + let baseInterface = iface.base; + while (baseInterface) { + let baseInterfaceImplementers = baseInterface.implementers; + if (!baseInterfaceImplementers) baseInterface.implementers = baseInterfaceImplementers = new Set(); + baseInterfaceImplementers.add(this); + baseInterface = baseInterface.base; + } + + // Propagate the interface to this class's extendees + let thisExtendees = this.extendees; + if (thisExtendees) { + for (let _values = Set_values(thisExtendees), i = 0, k = _values.length; i < k; ++i) { + // The interface is now also implemented by any of this class's extendees + let thisExtendee = _values[i]; + interfaceImplementers.add(thisExtendee); + // Base interfaces of the interface are implemented by extendees as well + let baseInterface = iface.base; + while (baseInterface) { + let baseInterfaceImplementers = baseInterface.implementers; + if (!baseInterfaceImplementers) baseInterface.implementers = baseInterfaceImplementers = new Set(); + baseInterfaceImplementers.add(thisExtendee); + baseInterface = baseInterface.base; + } + } + } } /** Tests if a value of this class type is assignable to a target of the specified class type. */ @@ -4731,52 +4793,10 @@ export class Class extends TypedElement { return true; } - /** Gets all extendees of this class (that do not have the specified instance member). */ - getAllExtendees(exceptIfMember: string | null = null, out: Set = new Set()): Set { - let extendees = this.extendees; - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - if (exceptIfMember) { - let instanceMembers = extendee.prototype.instanceMembers; - if (instanceMembers && instanceMembers.has(exceptIfMember)) continue; - } - out.add(extendee); - extendee.getAllExtendees(exceptIfMember, out); - } - } - return out; - } - - /** Gets all extendees and implementers of this class or interface. */ - getAllExtendeesAndImplementers(out: Set = new Set()): Set { - let extendees = this.extendees; - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - out.add(extendee); - extendee.getAllExtendeesAndImplementers(out); - } - } - let implementers = this.implementers; - if (implementers) { - for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) { - let implementer = _values[i]; - out.add(implementer); - implementer.getAllExtendeesAndImplementers(out); - } - } - return out; - } - /** Tests if this class or interface extends the given class or interface. */ extends(other: Class): bool { - let base = this.base; - while (base) { - if (base == other) return true; - base = base.base; - } - return false; + let extendees = other.extendees; + return extendees != null && extendees.has(this); } /** Tests if this class has a direct or indirect extendee matching the given class. */ @@ -4790,7 +4810,7 @@ export class Class extends TypedElement { if (extendees) { for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { let extendee = _values[i]; - if (extendee.implements(other) || extendee.hasExtendeeImplementing(other)) return true; + if (extendee.implements(other)) return true; } } return false; @@ -4798,16 +4818,8 @@ export class Class extends TypedElement { /** Tests if this class directly or indirectly implements the given interface. */ implements(other: Interface): bool { - let interfaces = this.interfaces; - if (interfaces) { - if (interfaces.has(other)) return true; - for (let _values = Set_values(interfaces), i = 0, k = _values.length; i < k; ++i) { - let iface = _values[i]; - if (/* iface == other || */iface.extends(other)) return true; - } - } - let base = this.base; - return base ? base.implements(other) : false; + let implementers = other.implementers; + return implementers != null && implementers.has(this); } /** Tests if this interface has a direct or indirect implementer matching the given class. */ diff --git a/tests/compiler/instanceof.debug.wat b/tests/compiler/instanceof.debug.wat index cbcc1c2094..fe2c3cc86f 100644 --- a/tests/compiler/instanceof.debug.wat +++ b/tests/compiler/instanceof.debug.wat @@ -2503,10 +2503,6 @@ i32.load $0 local.set $1 local.get $1 - i32.const 15 - i32.eq - br_if $is_instance - local.get $1 i32.const 14 i32.eq br_if $is_instance diff --git a/tests/compiler/instanceof.release.wat b/tests/compiler/instanceof.release.wat index ad30a01ed2..baa63c5f28 100644 --- a/tests/compiler/instanceof.release.wat +++ b/tests/compiler/instanceof.release.wat @@ -2280,15 +2280,18 @@ if (result i32) block $__inlined_func$~instanceof|instanceof/I1 (result i32) block $is_instance13 - block $tablify|0 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 14 - i32.sub - br_table $is_instance13 $is_instance13 $tablify|0 $is_instance13 $tablify|0 - end + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 14 + i32.eq + br_if $is_instance13 + local.get $0 + i32.const 17 + i32.eq + br_if $is_instance13 i32.const 0 br $__inlined_func$~instanceof|instanceof/I1 end From 37ac0df6b7257746163944e6673d36f7d8ba70e9 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 13 Dec 2022 18:22:49 +0100 Subject: [PATCH 08/16] fix --- src/program.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/program.ts b/src/program.ts index c8aa1eea51..69f59fecd6 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4466,7 +4466,8 @@ export class Class extends TypedElement { let thisExtendee = extendeesArray[i]; baseInterfaceImplementers.add(thisExtendee); } - baseInterface = baseInterface.base; + baseInterface = baseInterface.base; + assert(!baseInterface || baseInterface.isInterface); } while (baseInterface); } } @@ -4817,13 +4818,14 @@ export class Class extends TypedElement { } /** Tests if this class directly or indirectly implements the given interface. */ - implements(other: Interface): bool { + implements(other: Class): bool { let implementers = other.implementers; return implementers != null && implementers.has(this); } /** Tests if this interface has a direct or indirect implementer matching the given class. */ hasImplementer(other: Class): bool { + assert(this.isInterface); return other.implements(this); } From c0087f8a9dd912e6904491442b1df757bc9618ef Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 13 Dec 2022 18:27:57 +0100 Subject: [PATCH 09/16] fix --- src/program.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/program.ts b/src/program.ts index 69f59fecd6..5482e79202 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4466,7 +4466,7 @@ export class Class extends TypedElement { let thisExtendee = extendeesArray[i]; baseInterfaceImplementers.add(thisExtendee); } - baseInterface = baseInterface.base; + baseInterface = baseInterface.base; assert(!baseInterface || baseInterface.isInterface); } while (baseInterface); } From 8d5d5f234ce342bc8455189045d0670c98657e0d Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 13 Dec 2022 23:40:39 +0100 Subject: [PATCH 10/16] make this half-way bearable --- src/program.ts | 110 +++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/src/program.ts b/src/program.ts index 5482e79202..419f82187e 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4437,81 +4437,63 @@ export class Class extends TypedElement { } } - // This class is now an extendee of the base class - let extendees = base.extendees; - if (!extendees) base.extendees = extendees = new Set(); - extendees.add(this); + // This class and its extendees now extend each direct or indirect base class + base.propagateExtendeeUp(this); + let extendees = this.extendees; + if (extendees) { + for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { + base.propagateExtendeeUp(_values[i]); + } + } - let iter: Class | null = base; - let extendeesArray = Set_values(extendees); + // Direct or indirect base interfaces are now implemented by this class and its extendees + let nextBase: Class | null = base; do { - // Extendees of this class are now also extendees of its base classes - for (let i = 0, k = extendeesArray.length; i < k; ++i) { - let thisExtendee = extendeesArray[i]; - let baseExtendees = iter.extendees; - if (!baseExtendees) iter.extendees = baseExtendees = new Set(); - baseExtendees.add(thisExtendee); - } - // Interfaces directly or indirectly implemented by a base class are now - // also implemented by this class and its extendees - let baseInterfaces = iter.interfaces; + let baseInterfaces = nextBase.interfaces; if (baseInterfaces) { for (let _values = Set_values(baseInterfaces), i = 0, k = _values.length; i < k; ++i) { - let baseInterface: Interface | null = _values[i]; - do { - let baseInterfaceImplementers = baseInterface.implementers; - if (!baseInterfaceImplementers) baseInterface.implementers = baseInterfaceImplementers = new Set(); - baseInterfaceImplementers.add(this); - for (let i = 0, k = extendeesArray.length; i < k; ++i) { - let thisExtendee = extendeesArray[i]; - baseInterfaceImplementers.add(thisExtendee); - } - baseInterface = baseInterface.base; - assert(!baseInterface || baseInterface.isInterface); - } while (baseInterface); + this.propagateInterfaceDown(_values[i]); } } - iter = iter.base; - } while (iter); + nextBase = nextBase.base; + } while (nextBase); } - /** Adds an interface. */ - addInterface(iface: Interface): void { - let thisInterfaces = this.interfaces; - if (!thisInterfaces) this.interfaces = thisInterfaces = new Set(); - thisInterfaces.add(iface); - - // The interface is now implemented by this class - let interfaceImplementers = iface.implementers; - if (!interfaceImplementers) iface.implementers = interfaceImplementers = new Set(); - interfaceImplementers.add(this); - - // The interface's base interfaces are implemented by this class as well - let baseInterface = iface.base; - while (baseInterface) { - let baseInterfaceImplementers = baseInterface.implementers; - if (!baseInterfaceImplementers) baseInterface.implementers = baseInterfaceImplementers = new Set(); - baseInterfaceImplementers.add(this); - baseInterface = baseInterface.base; - } + /** Propagates an extendee to this class as its base classes. */ + private propagateExtendeeUp(extendee: Class): void { + let nextBase: Class | null = this; + do { + let extendees = nextBase.extendees; + if (!extendees) nextBase.extendees = extendees = new Set(); + extendees.add(extendee); + nextBase = nextBase.base; + } while (nextBase); + } - // Propagate the interface to this class's extendees - let thisExtendees = this.extendees; - if (thisExtendees) { - for (let _values = Set_values(thisExtendees), i = 0, k = _values.length; i < k; ++i) { - // The interface is now also implemented by any of this class's extendees - let thisExtendee = _values[i]; - interfaceImplementers.add(thisExtendee); - // Base interfaces of the interface are implemented by extendees as well - let baseInterface = iface.base; - while (baseInterface) { - let baseInterfaceImplementers = baseInterface.implementers; - if (!baseInterfaceImplementers) baseInterface.implementers = baseInterfaceImplementers = new Set(); - baseInterfaceImplementers.add(thisExtendee); - baseInterface = baseInterface.base; + /** Propagates an interface and its base interfaces to this class and its extendees. */ + private propagateInterfaceDown(iface: Interface): void { + let nextIface: Interface | null = iface; + let extendees = this.extendees; + do { + let implementers = nextIface.implementers; + if (!implementers) nextIface.implementers = implementers = new Set(); + implementers.add(this); + if (extendees) { + for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { + let extendee = _values[i]; + implementers.add(extendee); } } - } + nextIface = nextIface.base; + } while (nextIface); + } + + /** Adds an interface. */ + addInterface(iface: Interface): void { + let interfaces = this.interfaces; + if (!interfaces) this.interfaces = interfaces = new Set(); + interfaces.add(iface); + this.propagateInterfaceDown(iface); } /** Tests if a value of this class type is assignable to a target of the specified class type. */ From a79322aa40eac3a16bff1c17eb4bc42355572b04 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 13 Dec 2022 23:42:10 +0100 Subject: [PATCH 11/16] typo --- src/program.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/program.ts b/src/program.ts index 419f82187e..dfcc355324 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4459,7 +4459,7 @@ export class Class extends TypedElement { } while (nextBase); } - /** Propagates an extendee to this class as its base classes. */ + /** Propagates an extendee to this class and its base classes. */ private propagateExtendeeUp(extendee: Class): void { let nextBase: Class | null = this; do { From bbb29b3182c8077f778b7f96edbe5ab8476e1ca3 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 13 Dec 2022 23:53:30 +0100 Subject: [PATCH 12/16] rename extendee to extender, matching implementer --- src/compiler.ts | 36 +++++++++++++-------------- src/program.ts | 66 ++++++++++++++++++++++++------------------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 84186cc590..6ca16116e6 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -6575,16 +6575,16 @@ export class Compiler extends DiagnosticEmitter { } let classInstance = assert(overrideInstance.getBoundClassOrInterface()); builder.addCase(classInstance.id, stmts); - // Also alias each extendee inheriting this exact overload - let extendees = classInstance.extendees; - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - let instanceMembers = extendee.prototype.instanceMembers; + // Also alias each extender inheriting this exact overload + let extenders = classInstance.extenders; + if (extenders) { + for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) { + let extender = _values[i]; + let instanceMembers = extender.prototype.instanceMembers; if (instanceMembers && instanceMembers.has(instance.declaration.name.text)) { continue; // skip those not inheriting } - builder.addCase(extendee.id, stmts); + builder.addCase(extender.id, stmts); } } } @@ -6593,7 +6593,7 @@ export class Compiler extends DiagnosticEmitter { // Call the original function if no other id matches and the method is not // abstract or part of an interface. Note that doing so will not catch an // invalid id, but can reduce code size significantly since we also don't - // have to add branches for extendees inheriting the original function. + // have to add branches for extender inheriting the original function. let body: ExpressionRef; let instanceClass = instance.getBoundClassOrInterface(); if (!instance.is(CommonFlags.Abstract) && !(instanceClass && instanceClass.kind == ElementKind.Interface)) { @@ -7577,11 +7577,11 @@ export class Compiler extends DiagnosticEmitter { } else { allInstances = new Set(); allInstances.add(instance); - let extendees = instance.extendees; - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - allInstances.add(extendee); + let extenders = instance.extenders; + if (extenders) { + for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) { + let extender = _values[i]; + allInstances.add(extender); } } } @@ -7724,11 +7724,11 @@ export class Compiler extends DiagnosticEmitter { } } else { allInstances.add(instance); - let extendees = instance.extendees; - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - allInstances.add(extendee); + let extenders = instance.extenders; + if (extenders) { + for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) { + let extender = _values[i]; + allInstances.add(extender); } } } diff --git a/src/program.ts b/src/program.ts index dfcc355324..82331d3163 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4182,7 +4182,7 @@ export class ClassPrototype extends DeclaredElement { /** Already resolved instances. */ instances: Map | null = null; /** Classes extending this class. */ - extendees: Set = new Set(); + extenders: Set = new Set(); /** Whether this class implicitly extends `Object`. */ implicitlyExtendsObject: bool = false; @@ -4319,7 +4319,7 @@ export class Class extends TypedElement { /** Wrapped type, if a wrapper for a basic type. */ wrappedType: Type | null = null; /** Classes directly or indirectly extending this class, if any. */ - extendees: Set | null = null; + extenders: Set | null = null; /** Classes directly or indirectly implementing this interface, if any. */ implementers: Set | null = null; /** Whether the field initialization check has already been performed. */ @@ -4437,16 +4437,16 @@ export class Class extends TypedElement { } } - // This class and its extendees now extend each direct or indirect base class - base.propagateExtendeeUp(this); - let extendees = this.extendees; - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - base.propagateExtendeeUp(_values[i]); + // This class and its extenders now extend each direct or indirect base class + base.propagateExtenderUp(this); + let extenders = this.extenders; + if (extenders) { + for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) { + base.propagateExtenderUp(_values[i]); } } - // Direct or indirect base interfaces are now implemented by this class and its extendees + // Direct or indirect base interfaces are now implemented by this class and its extenders let nextBase: Class | null = base; do { let baseInterfaces = nextBase.interfaces; @@ -4459,29 +4459,29 @@ export class Class extends TypedElement { } while (nextBase); } - /** Propagates an extendee to this class and its base classes. */ - private propagateExtendeeUp(extendee: Class): void { + /** Propagates an extender to this class and its base classes. */ + private propagateExtenderUp(extender: Class): void { let nextBase: Class | null = this; do { - let extendees = nextBase.extendees; - if (!extendees) nextBase.extendees = extendees = new Set(); - extendees.add(extendee); + let baseExtenders = nextBase.extenders; + if (!baseExtenders) nextBase.extenders = baseExtenders = new Set(); + baseExtenders.add(extender); nextBase = nextBase.base; } while (nextBase); } - /** Propagates an interface and its base interfaces to this class and its extendees. */ + /** Propagates an interface and its base interfaces to this class and its extenders. */ private propagateInterfaceDown(iface: Interface): void { let nextIface: Interface | null = iface; - let extendees = this.extendees; + let extenders = this.extenders; do { let implementers = nextIface.implementers; if (!implementers) nextIface.implementers = implementers = new Set(); implementers.add(this); - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - implementers.add(extendee); + if (extenders) { + for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) { + let extender = _values[i]; + implementers.add(extender); } } nextIface = nextIface.base; @@ -4527,7 +4527,7 @@ export class Class extends TypedElement { return this.hasImplementerImplementing(target); } else { // thisClass - return this.hasExtendeeImplementing(target); + return this.hasExtenderImplementing(target); } } else { if (this.isInterface) { @@ -4535,7 +4535,7 @@ export class Class extends TypedElement { return this.hasImplementer(target); } else { // thisClass - return this.hasExtendee(target); + return this.hasExtender(target); } } } @@ -4778,22 +4778,22 @@ export class Class extends TypedElement { /** Tests if this class or interface extends the given class or interface. */ extends(other: Class): bool { - let extendees = other.extendees; - return extendees != null && extendees.has(this); + let extenders = other.extenders; + return extenders != null && extenders.has(this); } - /** Tests if this class has a direct or indirect extendee matching the given class. */ - hasExtendee(other: Class): bool { + /** Tests if this class has a direct or indirect extender matching the given class. */ + hasExtender(other: Class): bool { return other.extends(this); } - /** Tests if this class has a direct or indirect extendee that implements the given interface. */ - hasExtendeeImplementing(other: Interface): bool { - let extendees = this.extendees; - if (extendees) { - for (let _values = Set_values(extendees), i = 0, k = _values.length; i < k; ++i) { - let extendee = _values[i]; - if (extendee.implements(other)) return true; + /** Tests if this class has a direct or indirect extender that implements the given interface. */ + hasExtenderImplementing(other: Interface): bool { + let extenders = this.extenders; + if (extenders) { + for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) { + let extender = _values[i]; + if (extender.implements(other)) return true; } } return false; From a62840d7971752804562b3656466ed5810fd2020 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 14 Dec 2022 00:00:25 +0100 Subject: [PATCH 13/16] typo --- src/compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler.ts b/src/compiler.ts index 6ca16116e6..2d55c91e12 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -6593,7 +6593,7 @@ export class Compiler extends DiagnosticEmitter { // Call the original function if no other id matches and the method is not // abstract or part of an interface. Note that doing so will not catch an // invalid id, but can reduce code size significantly since we also don't - // have to add branches for extender inheriting the original function. + // have to add branches for extenders inheriting the original function. let body: ExpressionRef; let instanceClass = instance.getBoundClassOrInterface(); if (!instance.is(CommonFlags.Abstract) && !(instanceClass && instanceClass.kind == ElementKind.Interface)) { From 7a19fd9d6f9e7ac05d9e01d211150917593fc7f8 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 14 Dec 2022 00:08:37 +0100 Subject: [PATCH 14/16] invert these --- src/program.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/program.ts b/src/program.ts index 82331d3163..1e64b3c916 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4778,13 +4778,13 @@ export class Class extends TypedElement { /** Tests if this class or interface extends the given class or interface. */ extends(other: Class): bool { - let extenders = other.extenders; - return extenders != null && extenders.has(this); + return other.hasExtender(this); } /** Tests if this class has a direct or indirect extender matching the given class. */ hasExtender(other: Class): bool { - return other.extends(this); + let extenders = this.extenders; + return extenders != null && extenders.has(other); } /** Tests if this class has a direct or indirect extender that implements the given interface. */ @@ -4801,14 +4801,13 @@ export class Class extends TypedElement { /** Tests if this class directly or indirectly implements the given interface. */ implements(other: Class): bool { - let implementers = other.implementers; - return implementers != null && implementers.has(this); + return other.hasImplementer(this); } /** Tests if this interface has a direct or indirect implementer matching the given class. */ hasImplementer(other: Class): bool { - assert(this.isInterface); - return other.implements(this); + let implementers = this.implementers; + return implementers != null && implementers.has(other); } /** Tests if this interface has an implementer implementing the given interface. */ From 677bf24f2aff101f887e9cd3bbc2a749dfe9729d Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 14 Dec 2022 01:07:14 +0100 Subject: [PATCH 15/16] document --- src/program.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/program.ts b/src/program.ts index 1e64b3c916..7ca4cab9f4 100644 --- a/src/program.ts +++ b/src/program.ts @@ -4442,7 +4442,8 @@ export class Class extends TypedElement { let extenders = this.extenders; if (extenders) { for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) { - base.propagateExtenderUp(_values[i]); + let extender = _values[i]; + base.propagateExtenderUp(extender); } } @@ -4452,7 +4453,8 @@ export class Class extends TypedElement { let baseInterfaces = nextBase.interfaces; if (baseInterfaces) { for (let _values = Set_values(baseInterfaces), i = 0, k = _values.length; i < k; ++i) { - this.propagateInterfaceDown(_values[i]); + let baseInterface = _values[i]; + this.propagateInterfaceDown(baseInterface); } } nextBase = nextBase.base; @@ -4461,17 +4463,22 @@ export class Class extends TypedElement { /** Propagates an extender to this class and its base classes. */ private propagateExtenderUp(extender: Class): void { + // Start with this class, adding the extender to it. Repeat for the class's + // bases that are indirectly extended by the extender. let nextBase: Class | null = this; do { - let baseExtenders = nextBase.extenders; - if (!baseExtenders) nextBase.extenders = baseExtenders = new Set(); - baseExtenders.add(extender); + let extenders = nextBase.extenders; + if (!extenders) nextBase.extenders = extenders = new Set(); + extenders.add(extender); nextBase = nextBase.base; } while (nextBase); } /** Propagates an interface and its base interfaces to this class and its extenders. */ private propagateInterfaceDown(iface: Interface): void { + // Start with the interface itself, adding this class and its extenders to + // its implementers. Repeat for the interface's bases that are indirectly + // implemented by means of being extended by the interface. let nextIface: Interface | null = iface; let extenders = this.extenders; do { @@ -4493,6 +4500,8 @@ export class Class extends TypedElement { let interfaces = this.interfaces; if (!interfaces) this.interfaces = interfaces = new Set(); interfaces.add(iface); + + // This class and its extenders now implement the interface and its bases this.propagateInterfaceDown(iface); } @@ -4800,7 +4809,7 @@ export class Class extends TypedElement { } /** Tests if this class directly or indirectly implements the given interface. */ - implements(other: Class): bool { + implements(other: Interface): bool { return other.hasImplementer(this); } From 7c660f14aca1a915cc5f54bc9ff658f2a69688ac Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 14 Dec 2022 16:00:13 +0100 Subject: [PATCH 16/16] better tests --- tests/compiler/instanceof.debug.wat | 4227 +++++++++++++++++++------ tests/compiler/instanceof.release.wat | 2515 ++++++++++----- tests/compiler/instanceof.ts | 203 +- 3 files changed, 5069 insertions(+), 1876 deletions(-) diff --git a/tests/compiler/instanceof.debug.wat b/tests/compiler/instanceof.debug.wat index fe2c3cc86f..fc52a65e08 100644 --- a/tests/compiler/instanceof.debug.wat +++ b/tests/compiler/instanceof.debug.wat @@ -1,7 +1,7 @@ (module + (type $i32_=>_none (func_subtype (param i32) func)) (type $i32_=>_i32 (func_subtype (param i32) (result i32) func)) (type $i32_i32_=>_none (func_subtype (param i32 i32) func)) - (type $i32_=>_none (func_subtype (param i32) func)) (type $none_=>_none (func_subtype func)) (type $i32_i32_=>_i32 (func_subtype (param i32 i32) (result i32) func)) (type $i32_i32_i32_=>_none (func_subtype (param i32 i32 i32) func)) @@ -42,12 +42,14 @@ (global $instanceof/nullAnimal (mut i32) (i32.const 0)) (global $instanceof/nullCat (mut i32) (i32.const 0)) (global $instanceof/nullBlackcat (mut i32) (i32.const 0)) - (global $instanceof/a_i1 (mut i32) (i32.const 0)) - (global $instanceof/b_i1_i2 (mut i32) (i32.const 0)) + (global $instanceof/w (mut i32) (i32.const 0)) + (global $instanceof/x (mut i32) (i32.const 0)) + (global $instanceof/y (mut i32) (i32.const 0)) + (global $instanceof/z (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 464)) - (global $~lib/memory/__data_end i32 (i32.const 540)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33308)) - (global $~lib/memory/__heap_base i32 (i32.const 33308)) + (global $~lib/memory/__data_end i32 (i32.const 560)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33328)) + (global $~lib/memory/__heap_base i32 (i32.const 33328)) (memory $0 1) (data (i32.const 12) "<\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 (i32.const 76) "<\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") @@ -58,7 +60,7 @@ (data (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 348) "<\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 (i32.const 412) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1a\00\00\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s\00\00\00") - (data (i32.const 464) "\12\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00") + (data (i32.const 464) "\17\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\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)) @@ -2280,23 +2282,47 @@ i32.const 0 return ) - (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop return ) - (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop return ) - (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) - i32.const 0 - i32.eqz + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 drop return ) - (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/I1> (type $i32_=>_none) (param $value i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/W> (type $i32_=>_none) (param $value i32) (local $1 i32) (local $check i32) local.get $value @@ -2306,7 +2332,7 @@ i32.const 0 else local.get $1 - call $~instanceof|instanceof/I1 + call $~instanceof|instanceof/W end i32.eqz if @@ -2326,23 +2352,7 @@ i32.const 1 drop ) - (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) - i32.const 1 - drop - return - ) - (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) - i32.const 1 - drop - return - ) - (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) - i32.const 0 - i32.eqz - drop - return - ) - (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> (type $i32_=>_none) (param $value i32) (local $1 i32) (local $check i32) local.get $value @@ -2352,8 +2362,9 @@ i32.const 0 else local.get $1 - call $~instanceof|instanceof/B_I1_I2 + call $~instanceof|instanceof/X end + i32.eqz if i32.const 0 local.set $check @@ -2362,7 +2373,7 @@ if i32.const 0 i32.const 432 - i32.const 19 + i32.const 12 i32.const 5 call $~lib/builtins/abort unreachable @@ -2371,7 +2382,7 @@ i32.const 1 drop ) - (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> (type $i32_=>_none) (param $value i32) (local $1 i32) (local $check i32) local.get $value @@ -2381,7 +2392,7 @@ i32.const 0 else local.get $1 - call $~instanceof|instanceof/B_I1_I2 + call $~instanceof|instanceof/Y end i32.eqz if @@ -2401,1253 +2412,3439 @@ i32.const 1 drop ) - (func $~instanceof|instanceof/B (type $i32_=>_i32) (param $0 i32) (result i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> (type $i32_=>_none) (param $value i32) (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 5 - i32.eq - br_if $is_instance + (local $check i32) + local.get $value + local.tee $1 + i32.eqz + if (result i32) i32.const 0 - return - end - i32.const 1 - ) - (func $~instanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 + else local.get $1 - i32.const 8 - i32.eq - br_if $is_instance - i32.const 0 - return + call $~instanceof|instanceof/Z end - i32.const 1 - ) - (func $~anyinstanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 6 - i32.eq - br_if $is_instance - local.get $1 - i32.const 8 - i32.eq - br_if $is_instance + i32.eqz + if i32.const 0 - return - end - i32.const 1 - ) - (func $~instanceof|instanceof/Cat (type $i32_=>_i32) (param $0 i32) (result i32) - (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 12 - i32.eq - br_if $is_instance - local.get $1 - i32.const 13 - i32.eq - br_if $is_instance + local.set $check i32.const 0 - return + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 + drop ) - (func $~instanceof|instanceof/BlackCat (type $i32_=>_i32) (param $0 i32) (result i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IA> (type $i32_=>_none) (param $value i32) (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 + (local $check i32) + local.get $value + local.tee $1 + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - i32.const 13 - i32.eq - br_if $is_instance + call $~instanceof|instanceof/IA + end + i32.eqz + if i32.const 0 - return + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 + drop ) - (func $~instanceof|instanceof/I1 (type $i32_=>_i32) (param $0 i32) (result i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IB> (type $i32_=>_none) (param $value i32) (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 - local.get $1 - i32.const 14 - i32.eq - br_if $is_instance + (local $check i32) + local.get $value + local.tee $1 + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - i32.const 17 - i32.eq - br_if $is_instance + call $~instanceof|instanceof/IB + end + i32.eqz + if i32.const 0 - return + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 + drop ) - (func $~instanceof|instanceof/B_I1_I2 (type $i32_=>_i32) (param $0 i32) (result i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC> (type $i32_=>_none) (param $value i32) (local $1 i32) - block $is_instance - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.set $1 + (local $check i32) + local.get $value + local.tee $1 + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - i32.const 17 - i32.eq - br_if $is_instance + call $~instanceof|instanceof/IC + end + i32.eqz + if i32.const 0 - return + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 + drop ) - (func $~lib/rt/__visit_globals (type $i32_=>_none) (param $0 i32) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/ID> (type $i32_=>_none) (param $value i32) (local $1 i32) - global.get $instanceof/a + (local $check i32) + local.get $value local.tee $1 - if + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + call $~instanceof|instanceof/ID end - global.get $instanceof/b - local.tee $1 + i32.eqz if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $instanceof/an - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/child - local.tee $1 - if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit - end - global.get $instanceof/childAsParent + i32.const 1 + drop + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value local.tee $1 - if + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + call $~instanceof|instanceof/Y end - global.get $instanceof/animal - local.tee $1 if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $instanceof/cat + i32.const 1 + drop + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value local.tee $1 - if + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + call $~instanceof|instanceof/Z end - global.get $instanceof/blackcat - local.tee $1 if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $instanceof/nullableAnimal + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value local.tee $1 - if + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + call $~instanceof|instanceof/Y end - global.get $instanceof/nullableCat - local.tee $1 + i32.eqz if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $instanceof/nullableBlackcat + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value local.tee $1 - if + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + call $~instanceof|instanceof/Z end - global.get $instanceof/nullAnimal - local.tee $1 + i32.eqz if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $instanceof/nullCat + i32.const 1 + drop + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value local.tee $1 - if + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + call $~instanceof|instanceof/Z end - global.get $instanceof/nullBlackcat - local.tee $1 if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $instanceof/a_i1 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value local.tee $1 - if + i32.eqz + if (result i32) + i32.const 0 + else local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + call $~instanceof|instanceof/Z end - global.get $instanceof/b_i1_i2 - local.tee $1 + i32.eqz if - local.get $1 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - i32.const 224 - local.get $0 - call $~lib/rt/itcms/__visit - i32.const 32 - local.get $0 - call $~lib/rt/itcms/__visit + i32.const 1 + drop ) - (func $~lib/arraybuffer/ArrayBufferView~visit (type $i32_i32_=>_none) (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 $0 - local.tee $2 - if - local.get $2 - local.get $1 - call $~lib/rt/itcms/__visit - end - ) - (func $~lib/object/Object~visit (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) - nop - ) - (func $~lib/rt/__visit_members (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) - block $invalid - block $instanceof/B_I1_I2 - block $instanceof/I2 - block $instanceof/I1 - block $instanceof/A_I1 - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid - end - return - end - return - end - return - end - local.get $0 - local.get $1 - call $~lib/arraybuffer/ArrayBufferView~visit - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - return - end - unreachable - ) - (func $~start (type $none_=>_none) - call $start:instanceof - ) - (func $~stack_check (type $none_=>_none) - global.get $~lib/memory/__stack_pointer - global.get $~lib/memory/__data_end - i32.lt_s - if - i32.const 33328 - i32.const 33376 - i32.const 1 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - ) - (func $start:instanceof (type $none_=>_none) - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i32) - (local $14 i32) - (local $15 i32) - (local $16 i32) - (local $17 i32) - (local $18 i32) - (local $19 i32) - (local $20 i32) - (local $21 i32) - global.get $~lib/memory/__stack_pointer - i32.const 88 - i32.sub - global.set $~lib/memory/__stack_pointer - call $~stack_check - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.const 88 - memory.fill $0 - memory.size $0 - 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 144 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/pinSpace - i32.const 176 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/toSpace - i32.const 320 - call $~lib/rt/itcms/initLazy - global.set $~lib/rt/itcms/fromSpace - i32.const 0 - call $instanceof/A#constructor - global.set $instanceof/a - i32.const 0 - call $instanceof/B#constructor - global.set $instanceof/b + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 drop - i32.const 0 + return + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz + if (result i32) + i32.const 0 + else + local.get $1 + call $~instanceof|instanceof/IC + end + if + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 drop - i32.const 0 + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz + if (result i32) + i32.const 0 + else + local.get $1 + call $~instanceof|instanceof/IC + end + if + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a - local.tee $0 - i32.store $0 - local.get $0 + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $0 - call $~instanceof|instanceof/B + local.get $1 + call $~instanceof|instanceof/ID end - i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 41 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 drop - i32.const 0 + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz + if (result i32) + i32.const 0 + else + local.get $1 + call $~instanceof|instanceof/ID + end + if + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 drop + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) i32.const 0 i32.eqz drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) i32.const 0 i32.eqz drop - i32.const 0 + return + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 1 - drop - i32.const 0 - call $instanceof/isI32 - i32.eqz - if + if (result i32) i32.const 0 - i32.const 432 - i32.const 85 - i32.const 1 - call $~lib/builtins/abort - unreachable + else + local.get $1 + call $~instanceof|instanceof/IC end - f64.const 0 - call $instanceof/isI32 - i32.eqz i32.eqz if i32.const 0 - i32.const 432 - i32.const 86 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $instanceof/isI32 - i32.eqz - i32.eqz - if + local.set $check i32.const 0 - i32.const 432 - i32.const 87 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - i32.const 0 - call $instanceof/isI32 - i32.eqz + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz - if + if (result i32) i32.const 0 - i32.const 432 - i32.const 88 - i32.const 1 - call $~lib/builtins/abort - unreachable + else + local.get $1 + call $~instanceof|instanceof/IC end - global.get $instanceof/an - i32.const 0 - i32.ne - i32.eqz i32.eqz if i32.const 0 - i32.const 432 - i32.const 91 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - drop - i32.const 1 - global.set $instanceof/an - global.get $instanceof/an - i32.const 0 - i32.ne - i32.eqz - if + local.set $check i32.const 0 - i32.const 432 - i32.const 94 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 drop - i32.const 0 - call $instanceof/Child#constructor - global.set $instanceof/child - i32.const 1 - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop - i32.const 1 - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - i32.eqz - drop - i32.const 0 - call $instanceof/Child#constructor - global.set $instanceof/childAsParent - i32.const 1 - drop - i32.const 1 - drop - i32.const 0 - i32.eqz - drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/childAsParent + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value local.tee $1 - i32.store $0 offset=4 - local.get $1 i32.eqz if (result i32) i32.const 0 else local.get $1 - call $~instanceof|instanceof/Child + call $~instanceof|instanceof/ID end i32.eqz if i32.const 0 - i32.const 432 - i32.const 117 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - i32.const 0 - i32.eqz + i32.const 1 drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/childAsParent - local.tee $2 - i32.store $0 offset=8 - local.get $2 + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $2 - call $~anyinstanceof|instanceof/Child + local.get $1 + call $~instanceof|instanceof/ID end i32.eqz if i32.const 0 - i32.const 432 - i32.const 119 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - i32.const 0 - i32.eqz + i32.const 1 drop - i32.const 0 - i32.eqz + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 drop - i32.const 0 - call $instanceof/Animal#constructor - global.set $instanceof/animal - i32.const 0 - call $instanceof/Cat#constructor - global.set $instanceof/cat - i32.const 0 - call $instanceof/BlackCat#constructor - global.set $instanceof/blackcat + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) i32.const 1 drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/animal - local.tee $3 - i32.store $0 offset=12 - local.get $3 + return + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $3 - call $~instanceof|instanceof/Cat + local.get $1 + call $~instanceof|instanceof/ID end - i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 134 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/animal - local.tee $4 - i32.store $0 offset=16 - local.get $4 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $4 - call $~instanceof|instanceof/BlackCat + local.get $1 + call $~instanceof|instanceof/IC end - i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 135 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/cat - local.tee $5 - i32.store $0 offset=20 - local.get $5 + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $5 - call $~instanceof|instanceof/Cat + local.get $1 + call $~instanceof|instanceof/ID end i32.eqz if i32.const 0 - i32.const 432 - i32.const 138 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/cat - local.tee $6 - i32.store $0 offset=24 - local.get $6 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $6 - call $~instanceof|instanceof/BlackCat + local.get $1 + call $~instanceof|instanceof/IC end i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 139 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end i32.const 1 drop - global.get $~lib/memory/__stack_pointer - global.get $instanceof/blackcat - local.tee $7 - i32.store $0 offset=28 - local.get $7 + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticTrue (type $i32_=>_none) (param $value i32) + i32.const 1 + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertStaticFalse (type $i32_=>_none) (param $value i32) + i32.const 0 + i32.eqz + drop + return + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $7 - call $~instanceof|instanceof/Cat + local.get $1 + call $~instanceof|instanceof/X end i32.eqz if i32.const 0 - i32.const 432 - i32.const 142 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/blackcat - local.tee $8 - i32.store $0 offset=32 - local.get $8 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $8 - call $~instanceof|instanceof/BlackCat + local.get $1 + call $~instanceof|instanceof/X end i32.eqz if i32.const 0 - i32.const 432 - i32.const 143 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $instanceof/Animal#constructor - global.set $instanceof/nullableAnimal - i32.const 0 - call $instanceof/Cat#constructor - global.set $instanceof/nullableCat - i32.const 0 - call $instanceof/BlackCat#constructor - global.set $instanceof/nullableBlackcat - global.get $instanceof/nullableAnimal - i32.const 0 - i32.ne - i32.eqz - if + local.set $check i32.const 0 - i32.const 432 - i32.const 149 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableAnimal - local.tee $9 - i32.store $0 offset=36 - local.get $9 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $9 - call $~instanceof|instanceof/Cat + local.get $1 + call $~instanceof|instanceof/Y end i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 150 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableAnimal - local.tee $10 - i32.store $0 offset=40 - local.get $10 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $10 - call $~instanceof|instanceof/BlackCat + local.get $1 + call $~instanceof|instanceof/Y end i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 151 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullableCat - i32.const 0 - i32.ne - i32.eqz - if + local.set $check i32.const 0 - i32.const 432 - i32.const 153 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableCat - local.tee $11 - i32.store $0 offset=44 - local.get $11 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $11 - call $~instanceof|instanceof/Cat + local.get $1 + call $~instanceof|instanceof/Y end i32.eqz if i32.const 0 - i32.const 432 - i32.const 154 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableCat - local.tee $12 - i32.store $0 offset=48 - local.get $12 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $12 - call $~instanceof|instanceof/BlackCat + local.get $1 + call $~instanceof|instanceof/Y end i32.eqz - i32.eqz if i32.const 0 - i32.const 432 - i32.const 155 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullableBlackcat - i32.const 0 - i32.ne - i32.eqz - if + local.set $check i32.const 0 - i32.const 432 - i32.const 157 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableBlackcat - local.tee $13 - i32.store $0 offset=52 - local.get $13 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $13 - call $~instanceof|instanceof/Cat + local.get $1 + call $~instanceof|instanceof/Z end i32.eqz if i32.const 0 - i32.const 432 - i32.const 158 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableBlackcat - local.tee $14 - i32.store $0 offset=56 - local.get $14 + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz if (result i32) i32.const 0 else - local.get $14 - call $~instanceof|instanceof/BlackCat + local.get $1 + call $~instanceof|instanceof/Z end i32.eqz if i32.const 0 - i32.const 432 - i32.const 159 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end end - global.get $instanceof/nullAnimal - i32.const 0 - i32.ne + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 i32.eqz + if (result i32) + i32.const 0 + else + local.get $1 + call $~instanceof|instanceof/Z + end i32.eqz if i32.const 0 - i32.const 432 - i32.const 165 - i32.const 1 - call $~lib/builtins/abort - unreachable + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 + drop + ) + (func $instanceof/assertDynamicTrue (type $i32_=>_none) (param $value i32) + (local $1 i32) + (local $check i32) + local.get $value + local.tee $1 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $1 + call $~instanceof|instanceof/Z + end + i32.eqz + if + i32.const 0 + local.set $check + i32.const 0 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 + drop + ) + (func $~instanceof|instanceof/B (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 5 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 8 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~anyinstanceof|instanceof/Child (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 6 + i32.eq + br_if $is_instance + local.get $1 + i32.const 8 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/Cat (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 12 + i32.eq + br_if $is_instance + local.get $1 + i32.const 13 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/BlackCat (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 13 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/W (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 14 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/X (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 15 + i32.eq + br_if $is_instance + local.get $1 + i32.const 18 + i32.eq + br_if $is_instance + local.get $1 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/Y (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 18 + i32.eq + br_if $is_instance + local.get $1 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/Z (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/IA (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 15 + i32.eq + br_if $is_instance + local.get $1 + i32.const 18 + i32.eq + br_if $is_instance + local.get $1 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/IB (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 15 + i32.eq + br_if $is_instance + local.get $1 + i32.const 18 + i32.eq + br_if $is_instance + local.get $1 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + return end + i32.const 1 + ) + (func $~instanceof|instanceof/IC (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 18 + i32.eq + br_if $is_instance + local.get $1 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~instanceof|instanceof/ID (type $i32_=>_i32) (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.set $1 + local.get $1 + i32.const 18 + i32.eq + br_if $is_instance + local.get $1 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~lib/rt/__visit_globals (type $i32_=>_none) (param $0 i32) + (local $1 i32) + global.get $instanceof/a + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/b + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/an + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/child + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/childAsParent + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/animal + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/cat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/blackcat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullableAnimal + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullableCat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullableBlackcat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullAnimal + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullCat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/nullBlackcat + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/w + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/x + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/y + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $instanceof/z + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + i32.const 224 + local.get $0 + call $~lib/rt/itcms/__visit + i32.const 32 + local.get $0 + call $~lib/rt/itcms/__visit + ) + (func $~lib/arraybuffer/ArrayBufferView~visit (type $i32_i32_=>_none) (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 $0 + local.tee $2 + if + local.get $2 + local.get $1 + call $~lib/rt/itcms/__visit + end + ) + (func $~lib/object/Object~visit (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) + nop + ) + (func $~lib/rt/__visit_members (type $i32_i32_=>_none) (param $0 i32) (param $1 i32) + block $invalid + block $instanceof/IE + block $instanceof/Z + block $instanceof/IC + block $instanceof/ID + block $instanceof/Y + block $instanceof/IA + block $instanceof/IB + block $instanceof/X + block $instanceof/W + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/W $instanceof/X $instanceof/IB $instanceof/IA $instanceof/Y $instanceof/ID $instanceof/IC $instanceof/Z $instanceof/IE $invalid + end + return + end + return + end + return + end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + unreachable + ) + (func $~start (type $none_=>_none) + call $start:instanceof + ) + (func $~stack_check (type $none_=>_none) + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__data_end + i32.lt_s + if + i32.const 33360 + i32.const 33408 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $start:instanceof (type $none_=>_none) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (local $14 i32) + (local $15 i32) + (local $16 i32) + (local $17 i32) + (local $18 i32) + (local $19 i32) + (local $20 i32) + (local $21 i32) + global.get $~lib/memory/__stack_pointer + i32.const 88 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 88 + memory.fill $0 + memory.size $0 + 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 144 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/pinSpace + i32.const 176 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/toSpace + i32.const 320 + call $~lib/rt/itcms/initLazy + global.set $~lib/rt/itcms/fromSpace + i32.const 0 + call $instanceof/A#constructor + global.set $instanceof/a + i32.const 0 + call $instanceof/B#constructor + global.set $instanceof/b + i32.const 1 + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + global.get $~lib/memory/__stack_pointer + global.get $instanceof/a + local.tee $0 + i32.store $0 + local.get $0 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $0 + call $~instanceof|instanceof/B + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 41 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 0 + call $instanceof/isI32 + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 85 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 0 + call $instanceof/isI32 + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 86 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/isI32 + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 87 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/isI32 + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 88 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/an + i32.const 0 + i32.ne + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 91 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + i32.const 1 + global.set $instanceof/an + global.get $instanceof/an + i32.const 0 + i32.ne + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 94 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + i32.const 0 + call $instanceof/Child#constructor + global.set $instanceof/child + i32.const 1 + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 1 + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + call $instanceof/Child#constructor + global.set $instanceof/childAsParent + i32.const 1 + drop + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + global.get $~lib/memory/__stack_pointer + global.get $instanceof/childAsParent + local.tee $1 + i32.store $0 offset=4 + local.get $1 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $1 + call $~instanceof|instanceof/Child + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 117 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + i32.eqz + drop + global.get $~lib/memory/__stack_pointer + global.get $instanceof/childAsParent + local.tee $2 + i32.store $0 offset=8 + local.get $2 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $2 + call $~anyinstanceof|instanceof/Child + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 119 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + i32.eqz + drop + i32.const 0 + i32.eqz + drop + i32.const 0 + call $instanceof/Animal#constructor + global.set $instanceof/animal + i32.const 0 + call $instanceof/Cat#constructor + global.set $instanceof/cat + i32.const 0 + call $instanceof/BlackCat#constructor + global.set $instanceof/blackcat + i32.const 1 + drop + global.get $~lib/memory/__stack_pointer + global.get $instanceof/animal + local.tee $3 + i32.store $0 offset=12 + local.get $3 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $3 + call $~instanceof|instanceof/Cat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 134 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/animal + local.tee $4 + i32.store $0 offset=16 + local.get $4 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $4 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 135 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + global.get $~lib/memory/__stack_pointer + global.get $instanceof/cat + local.tee $5 + i32.store $0 offset=20 + local.get $5 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $5 + call $~instanceof|instanceof/Cat + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 138 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/cat + local.tee $6 + i32.store $0 offset=24 + local.get $6 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $6 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 139 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + global.get $~lib/memory/__stack_pointer + global.get $instanceof/blackcat + local.tee $7 + i32.store $0 offset=28 + local.get $7 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $7 + call $~instanceof|instanceof/Cat + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 142 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/blackcat + local.tee $8 + i32.store $0 offset=32 + local.get $8 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $8 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 143 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/Animal#constructor + global.set $instanceof/nullableAnimal + i32.const 0 + call $instanceof/Cat#constructor + global.set $instanceof/nullableCat + i32.const 0 + call $instanceof/BlackCat#constructor + global.set $instanceof/nullableBlackcat + global.get $instanceof/nullableAnimal + i32.const 0 + i32.ne + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 149 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableAnimal + local.tee $9 + i32.store $0 offset=36 + local.get $9 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $9 + call $~instanceof|instanceof/Cat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 150 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableAnimal + local.tee $10 + i32.store $0 offset=40 + local.get $10 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $10 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 151 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullableCat + i32.const 0 + i32.ne + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 153 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableCat + local.tee $11 + i32.store $0 offset=44 + local.get $11 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $11 + call $~instanceof|instanceof/Cat + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 154 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableCat + local.tee $12 + i32.store $0 offset=48 + local.get $12 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $12 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 155 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullableBlackcat + i32.const 0 + i32.ne + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 157 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableBlackcat + local.tee $13 + i32.store $0 offset=52 + local.get $13 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $13 + call $~instanceof|instanceof/Cat + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 158 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableBlackcat + local.tee $14 + i32.store $0 offset=56 + local.get $14 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $14 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 159 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullAnimal + i32.const 0 + i32.ne + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 165 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullAnimal + local.tee $15 + i32.store $0 offset=60 + local.get $15 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $15 + call $~instanceof|instanceof/Cat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 166 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullAnimal + local.tee $16 + i32.store $0 offset=64 + local.get $16 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $16 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 167 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullCat + i32.const 0 + i32.ne + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 169 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullCat + local.tee $17 + i32.store $0 offset=68 + local.get $17 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $17 + call $~instanceof|instanceof/Cat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 170 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullCat + local.tee $18 + i32.store $0 offset=72 + local.get $18 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $18 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 171 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullBlackcat + i32.const 0 + i32.ne + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 173 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullBlackcat + local.tee $19 + i32.store $0 offset=76 + local.get $19 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $19 + call $~instanceof|instanceof/Cat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 174 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullBlackcat + local.tee $20 + i32.store $0 offset=80 + local.get $20 + i32.eqz + if (result i32) + i32.const 0 + else + local.get $20 + call $~instanceof|instanceof/BlackCat + end + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 175 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/W#constructor + global.set $instanceof/w + i32.const 0 + call $instanceof/X#constructor + global.set $instanceof/x + i32.const 0 + call $instanceof/Y#constructor + global.set $instanceof/y + i32.const 0 + call $instanceof/Z#constructor + global.set $instanceof/z + global.get $instanceof/w + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/w + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/W> + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IA> + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IB> + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IA> + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IB> + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC> + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/ID> + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IA> + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IB> + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC> + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/ID> + global.get $instanceof/w + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/w + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/w + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/w + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/x + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/y + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertStaticFalse + global.get $instanceof/x + local.set $21 global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullAnimal - local.tee $15 - i32.store $0 offset=60 - local.get $15 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $15 - call $~instanceof|instanceof/Cat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 166 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/x + local.set $21 global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullAnimal - local.tee $16 - i32.store $0 offset=64 - local.get $16 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $16 - call $~instanceof|instanceof/BlackCat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 167 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullCat - i32.const 0 - i32.ne - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 169 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullCat - local.tee $17 - i32.store $0 offset=68 - local.get $17 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $17 - call $~instanceof|instanceof/Cat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 170 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y + local.set $21 global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullCat - local.tee $18 - i32.store $0 offset=72 - local.get $18 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $18 - call $~instanceof|instanceof/BlackCat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 171 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullBlackcat - i32.const 0 - i32.ne - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 173 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullBlackcat - local.tee $19 - i32.store $0 offset=76 - local.get $19 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $19 - call $~instanceof|instanceof/Cat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 174 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullBlackcat - local.tee $20 - i32.store $0 offset=80 - local.get $20 - i32.eqz - if (result i32) - i32.const 0 - else - local.get $20 - call $~instanceof|instanceof/BlackCat - end - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 432 - i32.const 175 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - call $instanceof/A_I1#constructor - global.set $instanceof/a_i1 - global.get $instanceof/a_i1 + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/y local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertStaticTrue - global.get $instanceof/a_i1 + call $instanceof/assertDynamicTrue + global.get $instanceof/y local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertStaticTrue - global.get $instanceof/a_i1 + call $instanceof/assertDynamicTrue + global.get $instanceof/y local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertStaticFalse - global.get $instanceof/a_i1 + call $instanceof/assertDynamicTrue + global.get $instanceof/y local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/I1> - i32.const 0 - call $instanceof/B_I1_I2#constructor - global.set $instanceof/b_i1_i2 - global.get $instanceof/b_i1_i2 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z + local.set $21 + global.get $~lib/memory/__stack_pointer + local.get $21 + i32.store $0 offset=84 + local.get $21 + call $instanceof/assertDynamicTrue + global.get $instanceof/z local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertStaticTrue - global.get $instanceof/b_i1_i2 + call $instanceof/assertDynamicTrue + global.get $instanceof/z local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertStaticTrue - global.get $instanceof/a_i1 + call $instanceof/assertDynamicTrue + global.get $instanceof/z local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertStaticFalse - global.get $instanceof/a_i1 + call $instanceof/assertDynamicTrue + global.get $instanceof/z local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertDynamicFalse - global.get $instanceof/b_i1_i2 + call $instanceof/assertDynamicTrue + global.get $instanceof/z local.set $21 global.get $~lib/memory/__stack_pointer local.get $21 i32.store $0 offset=84 local.get $21 - call $instanceof/assertDynamicTrue + call $instanceof/assertDynamicTrue global.get $~lib/memory/__stack_pointer i32.const 88 i32.add @@ -3978,7 +6175,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $instanceof/A_I1#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (func $instanceof/W#constructor (type $i32_=>_i32) (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -4011,7 +6208,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) - (func $instanceof/B_I1_I2#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (func $instanceof/X#constructor (type $i32_=>_i32) (param $this i32) (result i32) (local $1 i32) global.get $~lib/memory/__stack_pointer i32.const 4 @@ -4026,7 +6223,7 @@ if global.get $~lib/memory/__stack_pointer i32.const 0 - i32.const 17 + i32.const 15 call $~lib/rt/itcms/__new local.tee $this i32.store $0 @@ -4044,4 +6241,70 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $instanceof/Y#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (local $1 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 $0 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 18 + call $~lib/rt/itcms/__new + local.tee $this + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $this + call $instanceof/X#constructor + local.tee $this + i32.store $0 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $instanceof/Z#constructor (type $i32_=>_i32) (param $this i32) (result i32) + (local $1 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 $0 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 21 + call $~lib/rt/itcms/__new + local.tee $this + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $this + call $instanceof/Y#constructor + local.tee $this + i32.store $0 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) ) diff --git a/tests/compiler/instanceof.release.wat b/tests/compiler/instanceof.release.wat index baa63c5f28..25eebb2edc 100644 --- a/tests/compiler/instanceof.release.wat +++ b/tests/compiler/instanceof.release.wat @@ -1,7 +1,7 @@ (module + (type $i32_=>_none (func_subtype (param i32) func)) (type $i32_=>_i32 (func_subtype (param i32) (result i32) func)) (type $none_=>_none (func_subtype func)) - (type $i32_=>_none (func_subtype (param i32) func)) (type $i32_i32_=>_none (func_subtype (param i32 i32) func)) (type $none_=>_i32 (func_subtype (result i32) func)) (type $i32_i32_i32_i32_=>_none (func_subtype (param i32 i32 i32 i32) func)) @@ -28,9 +28,11 @@ (global $instanceof/nullableAnimal (mut i32) (i32.const 0)) (global $instanceof/nullableCat (mut i32) (i32.const 0)) (global $instanceof/nullableBlackcat (mut i32) (i32.const 0)) - (global $instanceof/a_i1 (mut i32) (i32.const 0)) - (global $instanceof/b_i1_i2 (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34332)) + (global $instanceof/w (mut i32) (i32.const 0)) + (global $instanceof/x (mut i32) (i32.const 0)) + (global $instanceof/y (mut i32) (i32.const 0)) + (global $instanceof/z (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34352)) (memory $0 1) (data (i32.const 1036) "<") (data (i32.const 1048) "\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") @@ -44,7 +46,7 @@ (data (i32.const 1384) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") (data (i32.const 1436) ",") (data (i32.const 1448) "\02\00\00\00\1a\00\00\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s") - (data (i32.const 1488) "\12\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 ") + (data (i32.const 1488) "\17\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\00 \00\00\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 (type $none_=>_none) @@ -116,13 +118,25 @@ local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end - global.get $instanceof/a_i1 + global.get $instanceof/w + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $instanceof/x + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $instanceof/y local.tee $0 if local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end - global.get $instanceof/b_i1_i2 + global.get $instanceof/z local.tee $0 if local.get $0 @@ -205,7 +219,7 @@ i32.load $0 offset=8 i32.eqz local.get $0 - i32.const 34332 + i32.const 34352 i32.lt_u i32.and i32.eqz @@ -833,10 +847,10 @@ if unreachable end - i32.const 34336 + i32.const 34352 i32.const 0 i32.store $0 - i32.const 35904 + i32.const 35920 i32.const 0 i32.store $0 loop $for-loop|0 @@ -847,7 +861,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 34336 + i32.const 34352 i32.add i32.const 0 i32.store $0 offset=4 @@ -865,7 +879,7 @@ i32.add i32.const 2 i32.shl - i32.const 34336 + i32.const 34352 i32.add i32.const 0 i32.store $0 offset=96 @@ -883,13 +897,13 @@ br $for-loop|0 end end - i32.const 34336 - i32.const 35908 + i32.const 34352 + i32.const 35924 memory.size $0 i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - i32.const 34336 + i32.const 34352 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (type $none_=>_i32) (result i32) @@ -974,7 +988,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 34332 + i32.const 34352 i32.lt_u if local.get $0 @@ -1074,7 +1088,7 @@ unreachable end local.get $0 - i32.const 34332 + i32.const 34352 i32.lt_u if local.get $0 @@ -1097,7 +1111,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 34332 + i32.const 34352 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1449,31 +1463,197 @@ memory.fill $0 local.get $0 ) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> (type $i32_=>_none) (param $0 i32) + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/X (result i32) + block $is_instance + block $tablify|0 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 15 + i32.sub + br_table $is_instance $tablify|0 $tablify|0 $is_instance $tablify|0 $tablify|0 $is_instance $tablify|0 + end + i32.const 0 + br $__inlined_func$~instanceof|instanceof/X + end + i32.const 1 + end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + ) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> (type $i32_=>_none) (param $0 i32) + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Y (result i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 18 + i32.eq + br_if $is_instance + local.get $0 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Y + end + i32.const 1 + end + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + ) + (func $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> (type $i32_=>_none) (param $0 i32) + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 21 + i32.eq + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $0 i32) + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Y (result i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 18 + i32.eq + br_if $is_instance + local.get $0 + i32.const 21 + i32.eq + br_if $is_instance + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Y + end + i32.const 1 + end + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + ) + (func $instanceof/assertDynamicFalse (type $i32_=>_none) (param $0 i32) + local.get $0 + if (result i32) + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 21 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 19 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + ) (func $~lib/rt/__visit_members (type $i32_=>_none) (param $0 i32) block $invalid - block $instanceof/B_I1_I2 - block $instanceof/I2 - block $instanceof/I1 - block $instanceof/A_I1 - block $instanceof/BlackCat - block $instanceof/Cat - block $instanceof/Animal - block $instanceof/SomethingElse - block $instanceof/Parent - block $instanceof/Child - block $instanceof/Parent - block $instanceof/Child - block $instanceof/B - block $instanceof/A - 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 $0 - br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/A_I1 $instanceof/I1 $instanceof/I2 $instanceof/B_I1_I2 $invalid + block $instanceof/IE + block $instanceof/Z + block $instanceof/IC + block $instanceof/ID + block $instanceof/Y + block $instanceof/IA + block $instanceof/IB + block $instanceof/X + block $instanceof/W + block $instanceof/BlackCat + block $instanceof/Cat + block $instanceof/Animal + block $instanceof/SomethingElse + block $instanceof/Parent + block $instanceof/Child + block $instanceof/Parent + block $instanceof/Child + block $instanceof/B + block $instanceof/A + 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 $0 + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $instanceof/A $instanceof/B $instanceof/Child $instanceof/Parent $instanceof/Child $instanceof/Parent $instanceof/SomethingElse $instanceof/Animal $instanceof/Cat $instanceof/BlackCat $instanceof/W $instanceof/X $instanceof/IB $instanceof/IA $instanceof/Y $instanceof/ID $instanceof/IC $instanceof/Z $instanceof/IE $invalid + end + return + end + return + end + return + end + local.get $0 + i32.load $0 + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + return + end + return end return end @@ -1481,13 +1661,6 @@ end return end - local.get $0 - i32.load $0 - local.tee $0 - if - local.get $0 - call $byn-split-outlined-A$~lib/rt/itcms/__visit - end return end return @@ -1526,877 +1699,1389 @@ (func $start:instanceof (type $none_=>_none) (local $0 i32) (local $1 i32) + (local $2 i32) + (local $3 i32) global.get $~lib/memory/__stack_pointer i32.const 88 i32.sub global.set $~lib/memory/__stack_pointer - block $folding-inner1 - block $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.const 88 - memory.fill $0 - memory.size $0 - i32.const 16 - i32.shl - i32.const 34332 + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 88 + memory.fill $0 + memory.size $0 + i32.const 16 + i32.shl + i32.const 34352 + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 1172 + i32.const 1168 + i32.store $0 + i32.const 1176 + i32.const 1168 + i32.store $0 + i32.const 1168 + global.set $~lib/rt/itcms/pinSpace + i32.const 1204 + i32.const 1200 + i32.store $0 + i32.const 1208 + i32.const 1200 + i32.store $0 + i32.const 1200 + global.set $~lib/rt/itcms/toSpace + i32.const 1348 + i32.const 1344 + i32.store $0 + i32.const 1352 + i32.const 1344 + i32.store $0 + i32.const 1344 + global.set $~lib/rt/itcms/fromSpace + i32.const 0 + call $instanceof/A#constructor + global.set $instanceof/a + 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 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $instanceof/A#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/b + global.get $~lib/memory/__stack_pointer + global.get $instanceof/a + local.tee $0 + i32.store $0 + local.get $0 + if (result i32) + local.get $0 + i32.const 8 i32.sub + i32.load $0 + i32.const 5 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 41 i32.const 1 - i32.shr_u - global.set $~lib/rt/itcms/threshold - i32.const 1172 - i32.const 1168 - i32.store $0 - i32.const 1176 - i32.const 1168 - i32.store $0 - i32.const 1168 - global.set $~lib/rt/itcms/pinSpace - i32.const 1204 - i32.const 1200 - i32.store $0 - i32.const 1208 - i32.const 1200 - i32.store $0 - i32.const 1200 - global.set $~lib/rt/itcms/toSpace - i32.const 1348 - i32.const 1344 - i32.store $0 - i32.const 1352 - i32.const 1344 - i32.store $0 - i32.const 1344 - global.set $~lib/rt/itcms/fromSpace + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/an + if i32.const 0 - call $instanceof/A#constructor - global.set $instanceof/a - 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 1564 - i32.lt_s - br_if $folding-inner0 + i32.const 1456 + i32.const 91 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + global.set $instanceof/an + 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 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 6 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.tee $1 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $0 + i32.eqz + if global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 5 + i32.const 7 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + local.get $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/child + 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 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 8 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.tee $1 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $0 + i32.eqz + if global.get $~lib/memory/__stack_pointer - local.get $0 - call $instanceof/A#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/b - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a - local.tee $0 - i32.store $0 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 5 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 41 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/an - if - i32.const 0 - i32.const 1456 - i32.const 91 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - global.set $instanceof/an - 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 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 - local.get $0 - i32.const 6 + i32.const 9 call $~lib/rt/itcms/__new local.tee $0 i32.store $0 - global.get $~lib/memory/__stack_pointer - local.tee $1 - i32.const 4 - i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store $0 - local.get $0 - i32.eqz - if - global.get $~lib/memory/__stack_pointer - i32.const 7 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - end - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $1 - local.get $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/child - 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 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 - i32.const 0 - i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + local.get $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/childAsParent + global.get $~lib/memory/__stack_pointer + global.get $instanceof/childAsParent + local.tee $0 + i32.store $0 offset=4 + local.get $0 + if (result i32) local.get $0 i32.const 8 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.tee $1 - i32.const 4 i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer + i32.load $0 + i32.const 8 + i32.eq + else i32.const 0 - i32.store $0 - local.get $0 - i32.eqz - if - global.get $~lib/memory/__stack_pointer - i32.const 9 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - end - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $1 - local.get $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/childAsParent - global.get $~lib/memory/__stack_pointer - global.get $instanceof/childAsParent - local.tee $0 - i32.store $0 offset=4 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 8 - i32.eq - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 117 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/childAsParent - local.tee $0 - i32.store $0 offset=8 - local.get $0 - if (result i32) - block $__inlined_func$~anyinstanceof|instanceof/Child (result i32) - block $is_instance2 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 6 - i32.eq - br_if $is_instance2 - local.get $0 - i32.const 8 - i32.eq - br_if $is_instance2 - i32.const 0 - br $__inlined_func$~anyinstanceof|instanceof/Child - end - i32.const 1 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 117 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/childAsParent + local.tee $0 + i32.store $0 offset=8 + local.get $0 + if (result i32) + block $__inlined_func$~anyinstanceof|instanceof/Child (result i32) + block $is_instance2 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 6 + i32.eq + br_if $is_instance2 + local.get $0 + i32.const 8 + i32.eq + br_if $is_instance2 + i32.const 0 + br $__inlined_func$~anyinstanceof|instanceof/Child end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 119 i32.const 1 - call $~lib/builtins/abort - unreachable end + else i32.const 0 - call $instanceof/Animal#constructor - global.set $instanceof/animal + end + i32.eqz + if i32.const 0 - call $instanceof/Cat#constructor - global.set $instanceof/cat - call $instanceof/BlackCat#constructor - global.set $instanceof/blackcat - global.get $~lib/memory/__stack_pointer - global.get $instanceof/animal - local.tee $0 - i32.store $0 offset=12 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat (result i32) - block $is_instance3 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance3 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance3 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat - end - i32.const 1 + i32.const 1456 + i32.const 119 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/Animal#constructor + global.set $instanceof/animal + i32.const 0 + call $instanceof/Cat#constructor + global.set $instanceof/cat + call $instanceof/BlackCat#constructor + global.set $instanceof/blackcat + global.get $~lib/memory/__stack_pointer + global.get $instanceof/animal + local.tee $0 + i32.store $0 offset=12 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat (result i32) + block $is_instance3 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance3 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance3 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat end - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 134 i32.const 1 - call $~lib/builtins/abort - unreachable end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/animal - local.tee $0 - i32.store $0 offset=16 + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 134 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/animal + local.tee $0 + i32.store $0 offset=16 + local.get $0 + if (result i32) local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 135 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/cat - local.tee $0 - i32.store $0 offset=20 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat5 (result i32) - block $is_instance6 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance6 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance6 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat5 - end - i32.const 1 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 135 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/cat + local.tee $0 + i32.store $0 offset=20 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat5 (result i32) + block $is_instance6 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance6 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance6 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat5 end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 138 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/cat - local.tee $0 - i32.store $0 offset=24 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 139 i32.const 1 - call $~lib/builtins/abort - unreachable end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/blackcat - local.tee $0 - i32.store $0 offset=28 + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 138 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/cat + local.tee $0 + i32.store $0 offset=24 + local.get $0 + if (result i32) local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat9 (result i32) - block $is_instance10 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance10 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance10 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat9 - end - i32.const 1 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 139 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/blackcat + local.tee $0 + i32.store $0 offset=28 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat9 (result i32) + block $is_instance10 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance10 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance10 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat9 end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 142 i32.const 1 - call $~lib/builtins/abort - unreachable end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/blackcat - local.tee $0 - i32.store $0 offset=32 + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 142 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/blackcat + local.tee $0 + i32.store $0 offset=32 + local.get $0 + if (result i32) local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 143 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + i32.eqz + if i32.const 0 - call $instanceof/Animal#constructor - global.set $instanceof/nullableAnimal + i32.const 1456 + i32.const 143 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + call $instanceof/Animal#constructor + global.set $instanceof/nullableAnimal + i32.const 0 + call $instanceof/Cat#constructor + global.set $instanceof/nullableCat + call $instanceof/BlackCat#constructor + global.set $instanceof/nullableBlackcat + global.get $instanceof/nullableAnimal + i32.eqz + if i32.const 0 - call $instanceof/Cat#constructor - global.set $instanceof/nullableCat - call $instanceof/BlackCat#constructor - global.set $instanceof/nullableBlackcat - global.get $instanceof/nullableAnimal - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 149 + i32.const 1456 + i32.const 149 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableAnimal + local.tee $0 + i32.store $0 offset=36 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat13 (result i32) + block $is_instance14 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance14 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance14 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat13 + end i32.const 1 - call $~lib/builtins/abort - unreachable end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableAnimal - local.tee $0 - i32.store $0 offset=36 + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 150 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableAnimal + local.tee $0 + i32.store $0 offset=40 + local.get $0 + if (result i32) local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat13 (result i32) - block $is_instance14 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance14 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance14 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat13 - end - i32.const 1 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else + i32.const 0 + end + if + i32.const 0 + i32.const 1456 + i32.const 151 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullableCat + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 153 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableCat + local.tee $0 + i32.store $0 offset=44 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat17 (result i32) + block $is_instance18 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance18 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance18 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat17 end - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 150 i32.const 1 - call $~lib/builtins/abort - unreachable end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableAnimal - local.tee $0 - i32.store $0 offset=40 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 151 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullableCat - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 153 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableCat - local.tee $0 - i32.store $0 offset=44 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat17 (result i32) - block $is_instance18 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance18 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance18 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat17 - end - i32.const 1 - end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 154 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableCat - local.tee $0 - i32.store $0 offset=48 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 155 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $instanceof/nullableBlackcat - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 157 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableBlackcat - local.tee $0 - i32.store $0 offset=52 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat21 (result i32) - block $is_instance22 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 12 - i32.eq - br_if $is_instance22 - local.get $0 - i32.const 13 - i32.eq - br_if $is_instance22 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat21 - end - i32.const 1 - end - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 158 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/nullableBlackcat - local.tee $0 - i32.store $0 offset=56 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 13 - i32.eq - else - i32.const 0 - end - i32.eqz - if - i32.const 0 - i32.const 1456 - i32.const 159 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - local.tee $0 + else i32.const 0 - i32.store $0 offset=60 - local.get $0 + end + i32.eqz + if i32.const 0 - i32.store $0 offset=64 + i32.const 1456 + i32.const 154 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableCat + local.tee $0 + i32.store $0 offset=48 + local.get $0 + if (result i32) local.get $0 + i32.const 8 + i32.sub + i32.load $0 + i32.const 13 + i32.eq + else i32.const 0 - i32.store $0 offset=68 - local.get $0 + end + if i32.const 0 - i32.store $0 offset=72 - local.get $0 + i32.const 1456 + i32.const 155 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $instanceof/nullableBlackcat + i32.eqz + if i32.const 0 - i32.store $0 offset=76 - local.get $0 + i32.const 1456 + i32.const 157 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableBlackcat + local.tee $0 + i32.store $0 offset=52 + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/Cat21 (result i32) + block $is_instance22 + local.get $0 + i32.const 8 + i32.sub + i32.load $0 + local.tee $0 + i32.const 12 + i32.eq + br_if $is_instance22 + local.get $0 + i32.const 13 + i32.eq + br_if $is_instance22 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Cat21 + end + i32.const 1 + end + else i32.const 0 - i32.store $0 offset=80 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 158 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/nullableBlackcat + local.tee $0 + i32.store $0 offset=56 + local.get $0 + if (result i32) local.get $0 - i32.const 4 + i32.const 8 i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 + i32.load $0 + i32.const 13 + i32.eq + else i32.const 0 - i32.store $0 - local.get $0 - i32.const 14 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/a_i1 - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a_i1 - local.tee $0 - i32.store $0 offset=84 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store $0 offset=84 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store $0 offset=84 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store $0 offset=84 - local.get $0 - if (result i32) - block $__inlined_func$~instanceof|instanceof/I1 (result i32) - block $is_instance13 - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - local.tee $0 - i32.const 14 - i32.eq - br_if $is_instance13 - local.get $0 - i32.const 17 - i32.eq - br_if $is_instance13 - i32.const 0 - br $__inlined_func$~instanceof|instanceof/I1 - end - i32.const 1 - end - else - i32.const 0 - end - i32.eqz - br_if $folding-inner1 - global.get $~lib/memory/__stack_pointer - i32.const 4 + end + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 159 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 offset=60 + local.get $0 + i32.const 0 + i32.store $0 offset=64 + local.get $0 + i32.const 0 + i32.store $0 offset=68 + local.get $0 + i32.const 0 + i32.store $0 offset=72 + local.get $0 + i32.const 0 + i32.store $0 offset=76 + local.get $0 + i32.const 0 + i32.store $0 offset=80 + local.get $0 + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 14 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/w + i32.const 0 + call $instanceof/X#constructor + global.set $instanceof/x + i32.const 0 + call $instanceof/Y#constructor + global.set $instanceof/y + 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 1584 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store $0 + local.get $0 + i32.const 21 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $instanceof/Y#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $instanceof/z + global.get $~lib/memory/__stack_pointer + global.get $instanceof/w + local.tee $2 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $3 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $1 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store $0 offset=84 + local.get $2 + if (result i32) + local.get $2 + i32.const 8 i32.sub - global.set $~lib/memory/__stack_pointer - global.get $~lib/memory/__stack_pointer - i32.const 1564 - i32.lt_s - br_if $folding-inner0 - global.get $~lib/memory/__stack_pointer - local.tee $0 + i32.load $0 + i32.const 14 + i32.eq + else i32.const 0 - i32.store $0 - local.get $0 - i32.const 17 - call $~lib/rt/itcms/__new - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - local.get $0 - call $~lib/object/Object#constructor - local.tee $0 - i32.store $0 - global.get $~lib/memory/__stack_pointer - i32.const 4 - i32.add - global.set $~lib/memory/__stack_pointer - local.get $0 - global.set $instanceof/b_i1_i2 - global.get $~lib/memory/__stack_pointer - global.get $instanceof/b_i1_i2 - local.tee $0 - i32.store $0 offset=84 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store $0 offset=84 - global.get $~lib/memory/__stack_pointer - global.get $instanceof/a_i1 - local.tee $0 - i32.store $0 offset=84 - global.get $~lib/memory/__stack_pointer - local.get $0 - i32.store $0 offset=84 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 17 - i32.eq - else - i32.const 0 - end - if - i32.const 0 - i32.const 1456 - i32.const 19 - i32.const 5 - call $~lib/builtins/abort - unreachable - end - global.get $~lib/memory/__stack_pointer - global.get $instanceof/b_i1_i2 - local.tee $0 - i32.store $0 offset=84 - local.get $0 - if (result i32) - local.get $0 - i32.const 8 - i32.sub - i32.load $0 - i32.const 17 - i32.eq - else - i32.const 0 - end - i32.eqz - br_if $folding-inner1 - global.get $~lib/memory/__stack_pointer - i32.const 88 - i32.add - global.set $~lib/memory/__stack_pointer - return end - i32.const 34352 - i32.const 34400 - i32.const 1 - i32.const 1 - call $~lib/builtins/abort - unreachable + i32.eqz + if + i32.const 0 + i32.const 1456 + i32.const 12 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/w + local.tee $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicFalse + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + i32.store $0 offset=84 + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/x + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/X> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/y + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $~lib/memory/__stack_pointer + global.get $instanceof/z + local.tee $0 + i32.store $0 offset=84 + local.get $0 + call $instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Z> + global.get $~lib/memory/__stack_pointer + i32.const 88 + i32.add + global.set $~lib/memory/__stack_pointer + return end - i32.const 0 - i32.const 1456 - i32.const 12 - i32.const 5 + i32.const 34384 + i32.const 34432 + i32.const 1 + i32.const 1 call $~lib/builtins/abort unreachable ) @@ -2406,11 +3091,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1584 i32.lt_s if - i32.const 34352 - i32.const 34400 + i32.const 34384 + i32.const 34432 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2440,11 +3125,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1584 i32.lt_s if - i32.const 34352 - i32.const 34400 + i32.const 34384 + i32.const 34432 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2479,11 +3164,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1584 i32.lt_s if - i32.const 34352 - i32.const 34400 + i32.const 34384 + i32.const 34432 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2518,11 +3203,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1584 i32.lt_s if - i32.const 34352 - i32.const 34400 + i32.const 34384 + i32.const 34432 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2558,11 +3243,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1564 + i32.const 1584 i32.lt_s if - i32.const 34352 - i32.const 34400 + i32.const 34384 + i32.const 34432 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2588,6 +3273,84 @@ global.set $~lib/memory/__stack_pointer local.get $0 ) + (func $instanceof/X#constructor (type $i32_=>_i32) (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 1584 + i32.lt_s + if + i32.const 34384 + i32.const 34432 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 15 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) + (func $instanceof/Y#constructor (type $i32_=>_i32) (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 1584 + i32.lt_s + if + i32.const 34384 + i32.const 34432 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store $0 + local.get $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 18 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store $0 + end + global.get $~lib/memory/__stack_pointer + local.get $0 + call $instanceof/X#constructor + local.tee $0 + i32.store $0 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) (func $byn-split-outlined-A$~lib/rt/itcms/__visit (type $i32_=>_none) (param $0 i32) global.get $~lib/rt/itcms/white local.get $0 diff --git a/tests/compiler/instanceof.ts b/tests/compiler/instanceof.ts index 3911cfe063..6c1c8db6aa 100644 --- a/tests/compiler/instanceof.ts +++ b/tests/compiler/instanceof.ts @@ -176,21 +176,188 @@ assert(!(nullBlackcat instanceof BlackCat)); // dynamic false // Interfaces -interface I1 {} -interface I2 {} -interface I3 extends I1 {} -class A_I1 implements I1 {} -class B_I1_I2 implements I1, I2 {} - -let a_i1 = new A_I1(); -assertStaticTrue(a_i1); -assertStaticTrue(a_i1); -assertStaticFalse(a_i1); -assertDynamicTrue(a_i1); - -let b_i1_i2 = new B_I1_I2(); -assertStaticTrue(b_i1_i2); -assertStaticTrue(b_i1_i2); -assertStaticFalse(a_i1); -assertDynamicFalse(a_i1); -assertDynamicTrue(b_i1_i2); +// IA W +// | +// IB IC IE +// | / +// X ID +// | / +// Y +// | +// Z +class W {} +interface IA {} +interface IB extends IA {} +class X implements IB {} +interface IC {} +interface ID extends IC {} +class Y extends X implements ID {} +class Z extends Y {} +interface IE {} + +let w = new W(); +let x = new X(); +let y = new Y(); +let z = new Z(); + +// instanceof Object + +assertStaticTrue(w); +assertStaticTrue(x); +assertStaticTrue(y); +assertStaticTrue(z); + +assertStaticTrue(x); +assertStaticTrue(x); +assertStaticTrue(y); +assertStaticTrue(y); +assertStaticTrue(y); +assertStaticTrue(y); +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticTrue(z); + +// Object instanceof + +assertDynamicTrue(w); +assertDynamicTrue(x); +assertDynamicTrue(y); +assertDynamicTrue(z); +assertDynamicTrue(y); +assertDynamicTrue(z); +assertDynamicTrue(z); + +assertDynamicTrue(x); +assertDynamicTrue(x); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); + +// instanceof + +assertStaticTrue(w); +assertStaticFalse(w); +assertStaticFalse(w); +assertStaticFalse(w); +assertStaticFalse(x); +assertStaticFalse(y); +assertStaticFalse(z); + +assertStaticTrue(x); +assertDynamicFalse(x); +assertDynamicFalse(x); +assertStaticTrue(y); +assertDynamicTrue(y); +assertDynamicFalse(y); +assertStaticTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); + +assertStaticTrue(y); +assertStaticTrue(y); +assertDynamicFalse(y); +assertStaticTrue(z); +assertStaticTrue(z); +assertDynamicTrue(z); + +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticTrue(z); + +// instanceof + +assertDynamicFalse(x); +assertDynamicFalse(x); +assertDynamicFalse(x); +assertDynamicFalse(x); +assertStaticFalse(x); +assertStaticFalse(x); + +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertStaticFalse(y); +assertStaticFalse(y); + +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertStaticFalse(z); +assertStaticFalse(z); + +// instanceof + +assertStaticTrue(x); +assertStaticTrue(x); +assertDynamicFalse(x); +assertDynamicFalse(x); +assertStaticFalse(x); +assertStaticTrue(y); +assertStaticTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertStaticFalse(y); +assertStaticTrue(z); +assertStaticTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertStaticFalse(z); + +assertStaticTrue(y); +assertStaticTrue(y); +assertStaticTrue(y); +assertStaticTrue(y); +assertStaticFalse(y); +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticFalse(z); + +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticTrue(z); +assertStaticFalse(z); + +// instanceof + +assertStaticFalse(x); +assertStaticFalse(x); +assertStaticFalse(y); +assertStaticFalse(y); +assertStaticFalse(y); +assertStaticFalse(y); +assertStaticFalse(z); +assertStaticFalse(z); +assertStaticFalse(z); +assertStaticFalse(z); + +assertDynamicTrue(x); +assertDynamicTrue(x); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(z); +assertDynamicTrue(z); + +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(y); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); + +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z); +assertDynamicTrue(z);