From f4e24e318cf269a67ae8621ae5698a86eed4b168 Mon Sep 17 00:00:00 2001 From: CountBleck Date: Tue, 20 Jun 2023 21:59:47 -0700 Subject: [PATCH 1/2] Add support for interfaces extending multiple interfaces This is a feature in TypeScript, and I didn't see much of a technical reason to disallow it. By changing interface extension such that implementsTypes and interfacePrototypes are used for base interfaces instead of extendsType and basePrototype in InterfacePrototype and Interface respectively, and by modifying the parser, existing code doesn't seem to break, and multiple base interfaces are possible (if not working already). There was also a small change to the instanceof helper generation, where arrays are now used instead of Sets, since I needed to filter for interfaces, and Set_values was used on the constructed Set regardless. However, the change also modified the order of instanceof checks as seen in instanceof.debug.wat. The instanceof.release.wat file underwent more drastic changes, but it still appears to work anyway. --- src/compiler.ts | 23 +- src/extra/ast.ts | 12 +- src/parser.ts | 44 ++-- src/program.ts | 143 ++++++++----- tests/compiler/class-implements.debug.wat | 8 +- tests/compiler/class-implements.release.wat | 10 +- tests/compiler/instanceof.debug.wat | 14 +- tests/compiler/instanceof.release.wat | 226 +++++++++++++++----- 8 files changed, 320 insertions(+), 160 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index bc15cd2143..651d488128 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -7696,23 +7696,26 @@ export class Compiler extends DiagnosticEmitter { ), false // managedness is irrelevant here, isn't interrupted ) ); - let allInstances: Set | null; + let allInstances: Class[] | null; if (instance.isInterface) { - allInstances = instance.implementers; + let implementers = instance.implementers; + // Ensure interfaces are filtered out, since their class IDs will never be + // seen in actual objects. + allInstances = implementers + ? Set_values(implementers).filter(implementer => implementer.kind == ElementKind.Class) + : null; } else { - allInstances = new Set(); - allInstances.add(instance); 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); - } + allInstances = Set_values(extenders); + allInstances.push(instance); + } else { + allInstances = [instance]; } } if (allInstances) { - for (let _values = Set_values(allInstances), i = 0, k = _values.length; i < k; ++i) { - let instance = _values[i]; + for (let i = 0, k = allInstances.length; i < k; ++i) { + let instance = unchecked(allInstances[i]); stmts.push( module.br("is_instance", module.binary(BinaryOp.EqI32, diff --git a/src/extra/ast.ts b/src/extra/ast.ts index ebe9217f90..5916aeb66c 100644 --- a/src/extra/ast.ts +++ b/src/extra/ast.ts @@ -1297,12 +1297,16 @@ export class ASTBuilder { } sb.push(">"); } - let extendsType = node.extendsType; - if (extendsType) { + let implementsTypes = node.implementsTypes; + if (implementsTypes && implementsTypes.length > 0) { sb.push(" extends "); - this.visitTypeNode(extendsType); + this.visitTypeNode(implementsTypes[0]); + for (let i = 1, k = implementsTypes.length; i < k; ++i) { + sb.push(", "); + this.visitTypeNode(implementsTypes[i]); + } } - // must not have implementsTypes + // must not have extendsType sb.push(" {\n"); let indentLevel = ++this.indentLevel; let members = node.members; diff --git a/src/parser.ts b/src/parser.ts index 58050e837e..6c9a283f18 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1708,20 +1708,40 @@ export class Parser extends DiagnosticEmitter { } let extendsType: NamedTypeNode | null = null; + let implementsTypes: NamedTypeNode[] | null = null; if (tn.skip(Token.Extends)) { - let type = this.parseType(tn); - if (!type) return null; - if (type.kind != NodeKind.NamedType) { - this.error( - DiagnosticCode.Identifier_expected, - type.range - ); - return null; + if (isInterface) { + do { + let type = this.parseType(tn); + if (!type) return null; + if (type.kind != NodeKind.NamedType) { + this.error( + DiagnosticCode.Identifier_expected, + type.range + ); + return null; + } + // Note: Even though the keyword is "extends", the base interfaces are stored in + // the implementsTypes field, as that's already an array that can be used. + // When an InterfacePrototype is created, the base InterfacePrototypes are + // stored in the interfacePrototypes field for the same reason. + if (!implementsTypes) implementsTypes = [type]; + else implementsTypes.push(type); + } while (tn.skip(Token.Comma)); + } else { + let type = this.parseType(tn); + if (!type) return null; + if (type.kind != NodeKind.NamedType) { + this.error( + DiagnosticCode.Identifier_expected, + type.range + ); + return null; + } + extendsType = type; } - extendsType = type; } - let implementsTypes: NamedTypeNode[] | null = null; if (tn.skip(Token.Implements)) { if (isInterface) { this.error( @@ -1757,14 +1777,14 @@ export class Parser extends DiagnosticEmitter { let members = new Array(); let declaration: ClassDeclaration; if (isInterface) { - assert(!implementsTypes); + assert(!extendsType); declaration = Node.createInterfaceDeclaration( identifier, decorators, flags, typeParameters, - extendsType, null, + implementsTypes, members, tn.range(startPos, tn.pos) ); diff --git a/src/program.ts b/src/program.ts index 3f9044e2d9..9575c6479b 100644 --- a/src/program.ts +++ b/src/program.ts @@ -1130,7 +1130,7 @@ export class Program extends DiagnosticEmitter { break; } case NodeKind.InterfaceDeclaration: { - this.initializeInterface(statement, file, queuedExtends); + this.initializeInterface(statement, file, queuedImplements); break; } case NodeKind.NamespaceDeclaration: { @@ -1303,64 +1303,45 @@ export class Program extends DiagnosticEmitter { } } - // resolve prototypes of extended classes or interfaces + // resolve prototypes of extended classes let resolver = this.resolver; for (let i = 0, k = queuedExtends.length; i < k; ++i) { let thisPrototype = queuedExtends[i]; + assert(thisPrototype.kind == ElementKind.ClassPrototype); let extendsNode = assert(thisPrototype.extendsNode); // must be present if in queuedExtends let baseElement = resolver.resolveTypeName(extendsNode.name, null, thisPrototype.parent); if (!baseElement) continue; - if (thisPrototype.kind == ElementKind.ClassPrototype) { - if (baseElement.kind == ElementKind.ClassPrototype) { - let basePrototype = baseElement; - if (basePrototype.hasDecorator(DecoratorFlags.Final)) { - this.error( - DiagnosticCode.Class_0_is_final_and_cannot_be_extended, - extendsNode.range, basePrototype.identifierNode.text - ); - } - if ( - basePrototype.hasDecorator(DecoratorFlags.Unmanaged) != - thisPrototype.hasDecorator(DecoratorFlags.Unmanaged) - ) { - this.error( - DiagnosticCode.Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa, - Range.join(thisPrototype.identifierNode.range, extendsNode.range) - ); - } - if (!thisPrototype.extends(basePrototype)) { - thisPrototype.basePrototype = basePrototype; - } else { - this.error( - DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, - basePrototype.identifierNode.range, - basePrototype.identifierNode.text, - ); - } - } else { + if (baseElement.kind == ElementKind.ClassPrototype) { + let basePrototype = baseElement; + if (basePrototype.hasDecorator(DecoratorFlags.Final)) { this.error( - DiagnosticCode.A_class_may_only_extend_another_class, - extendsNode.range + DiagnosticCode.Class_0_is_final_and_cannot_be_extended, + extendsNode.range, basePrototype.identifierNode.text ); } - } else if (thisPrototype.kind == ElementKind.InterfacePrototype) { - if (baseElement.kind == ElementKind.InterfacePrototype) { - const basePrototype = baseElement; - if (!thisPrototype.extends(basePrototype)) { - thisPrototype.basePrototype = basePrototype; - } else { - this.error( - DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, - basePrototype.identifierNode.range, - basePrototype.identifierNode.text, - ); - } + if ( + basePrototype.hasDecorator(DecoratorFlags.Unmanaged) != + thisPrototype.hasDecorator(DecoratorFlags.Unmanaged) + ) { + this.error( + DiagnosticCode.Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa, + Range.join(thisPrototype.identifierNode.range, extendsNode.range) + ); + } + if (!thisPrototype.extends(basePrototype)) { + thisPrototype.basePrototype = basePrototype; } else { this.error( - DiagnosticCode.An_interface_can_only_extend_an_interface, - extendsNode.range + DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, + basePrototype.identifierNode.range, + basePrototype.identifierNode.text, ); } + } else { + this.error( + DiagnosticCode.A_class_may_only_extend_another_class, + extendsNode.range + ); } } @@ -1399,7 +1380,7 @@ export class Program extends DiagnosticEmitter { } } - // resolve prototypes of implemented interfaces + // resolve prototypes of implemented/extended interfaces for (let i = 0, k = queuedImplements.length; i < k; ++i) { let thisPrototype = queuedImplements[i]; let implementsNodes = assert(thisPrototype.implementsNodes); // must be present if in queuedImplements @@ -1411,10 +1392,23 @@ export class Program extends DiagnosticEmitter { let interfacePrototype = interfaceElement; let interfacePrototypes = thisPrototype.interfacePrototypes; if (!interfacePrototypes) thisPrototype.interfacePrototypes = interfacePrototypes = new Array(); - interfacePrototypes.push(interfacePrototype); + if ( + thisPrototype.kind == ElementKind.Interface && + thisPrototype.implements(interfacePrototype) + ) { + this.error( + DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, + interfacePrototype.identifierNode.range, + interfacePrototype.identifierNode.text, + ); + } else { + interfacePrototypes.push(interfacePrototype); + } } else { this.error( - DiagnosticCode.A_class_can_only_implement_an_interface, + thisPrototype.kind == ElementKind.InterfacePrototype + ? DiagnosticCode.An_interface_can_only_extend_an_interface + : DiagnosticCode.A_class_can_only_implement_an_interface, implementsNode.range ); } @@ -2474,7 +2468,7 @@ export class Program extends DiagnosticEmitter { break; } case NodeKind.InterfaceDeclaration: { - element = this.initializeInterface(declaration, parent, queuedExtends); + element = this.initializeInterface(declaration, parent, queuedImplements); break; } case NodeKind.NamespaceDeclaration: { @@ -2625,7 +2619,7 @@ export class Program extends DiagnosticEmitter { /** Parent element, usually a file or namespace. */ parent: Element, /** So far queued `extends` clauses. */ - queuedExtends: ClassPrototype[], + queuedImplements: ClassPrototype[], ): InterfacePrototype | null { let name = declaration.name.text; let element = new InterfacePrototype( @@ -2638,8 +2632,8 @@ export class Program extends DiagnosticEmitter { ); if (!parent.add(name, element)) return null; - // remember interfaces that extend another interface - if (declaration.extendsType) queuedExtends.push(element); + // remember interfaces that extend other interfaces + if (declaration.implementsTypes) queuedImplements.push(element); let memberDeclarations = declaration.members; for (let i = 0, k = memberDeclarations.length; i < k; ++i) { @@ -2762,7 +2756,7 @@ export class Program extends DiagnosticEmitter { break; } case NodeKind.InterfaceDeclaration: { - this.initializeInterface(member, original, queuedExtends); + this.initializeInterface(member, original, queuedImplements); break; } case NodeKind.NamespaceDeclaration: { @@ -4298,6 +4292,24 @@ export class ClassPrototype extends DeclaredElement { return false; } + implements(other: InterfacePrototype, seen: Set | null = null): bool { + if (this.interfacePrototypes) { + if (!seen) seen = new Set(); + let interfacePrototypes = assert(this.interfacePrototypes); + + for (let i = 0, k = interfacePrototypes.length; i < k; ++i) { + let prototype = unchecked(interfacePrototypes[i]); + + if (prototype == other) return true; + if (seen.has(prototype)) continue; + seen.add(prototype); + + if (prototype.implements(other, seen)) return true; + } + } + return false; + } + /** Adds an element as an instance member of this one. Returns the previous element if a duplicate. */ addInstance(name: string, element: DeclaredElement): bool { let originalDeclaration = element.declaration; @@ -4557,9 +4569,11 @@ export class Class extends TypedElement { // 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; + // TODO: Maybe add a fast path when `iface` has no bases? + let ifaceStack = [iface]; let extenders = this.extenders; do { + let nextIface = assert(ifaceStack.pop()); let implementers = nextIface.implementers; if (!implementers) nextIface.implementers = implementers = new Set(); implementers.add(this); @@ -4569,8 +4583,19 @@ export class Class extends TypedElement { implementers.add(extender); } } - nextIface = nextIface.base; - } while (nextIface); + + let nextIfaces = nextIface.interfaces; + if (!nextIfaces) continue; + + let stackIndex = ifaceStack.length; + + // Calls the internal ensureCapacity() when run in the bootstrapped compiler: + ifaceStack.length = stackIndex + nextIfaces.size; + + for (let _values = Set_values(nextIfaces), i = 0, k = _values.length; i < k; ++i) { + ifaceStack[stackIndex++] = unchecked(_values[i]); + } + } while (ifaceStack.length); } /** Adds an interface. */ @@ -4589,7 +4614,7 @@ export class Class extends TypedElement { if (target.isInterface) { if (this.isInterface) { // targetInterface = thisInterface - return this == target || this.extends(target); + return this == target || this.implements(target); } else { // targetInterface = thisClass return this.implements(target); @@ -4863,7 +4888,7 @@ export class Class extends TypedElement { return true; } - /** Tests if this class or interface extends the given class or interface. */ + /** Tests if this class extends the given class. */ extends(other: Class): bool { return other.hasExtender(this); } diff --git a/tests/compiler/class-implements.debug.wat b/tests/compiler/class-implements.debug.wat index e967a93f72..788764ace7 100644 --- a/tests/compiler/class-implements.debug.wat +++ b/tests/compiler/class-implements.debug.wat @@ -2425,11 +2425,11 @@ i32.load local.set $1 local.get $1 - i32.const 13 + i32.const 11 i32.eq br_if $case0 local.get $1 - i32.const 11 + i32.const 13 i32.eq br_if $case1 local.get $1 @@ -2447,11 +2447,11 @@ br $default end local.get $0 - call $class-implements/K#foo + call $class-implements/F#foo return end local.get $0 - call $class-implements/F#foo + call $class-implements/K#foo return end local.get $0 diff --git a/tests/compiler/class-implements.release.wat b/tests/compiler/class-implements.release.wat index a8a05184e7..c82a4ff080 100644 --- a/tests/compiler/class-implements.release.wat +++ b/tests/compiler/class-implements.release.wat @@ -2392,13 +2392,13 @@ i32.load i32.const 8 i32.sub - br_table $case25 $default3 $case25 $case16 $case34 $case07 $default3 + br_table $case25 $default3 $case25 $case07 $case34 $case16 $default3 end - unreachable + i32.const 4 + local.set $0 + br $__inlined_func$class-implements/J#foo@override$169 end - i32.const 4 - local.set $0 - br $__inlined_func$class-implements/J#foo@override$169 + unreachable end i32.const 3 local.set $0 diff --git a/tests/compiler/instanceof.debug.wat b/tests/compiler/instanceof.debug.wat index 79d6b3b7cb..4443240c8a 100644 --- a/tests/compiler/instanceof.debug.wat +++ b/tests/compiler/instanceof.debug.wat @@ -4232,11 +4232,11 @@ i32.load local.set $1 local.get $1 - i32.const 13 + i32.const 14 i32.eq br_if $is_instance local.get $1 - i32.const 14 + i32.const 13 i32.eq br_if $is_instance i32.const 0 @@ -4287,15 +4287,15 @@ i32.load local.set $1 local.get $1 - i32.const 16 + i32.const 19 i32.eq br_if $is_instance local.get $1 - i32.const 19 + i32.const 22 i32.eq br_if $is_instance local.get $1 - i32.const 22 + i32.const 16 i32.eq br_if $is_instance i32.const 0 @@ -4312,11 +4312,11 @@ i32.load local.set $1 local.get $1 - i32.const 19 + i32.const 22 i32.eq br_if $is_instance local.get $1 - i32.const 22 + i32.const 19 i32.eq br_if $is_instance i32.const 0 diff --git a/tests/compiler/instanceof.release.wat b/tests/compiler/instanceof.release.wat index 17c9936fff..ef18665cda 100644 --- a/tests/compiler/instanceof.release.wat +++ b/tests/compiler/instanceof.release.wat @@ -1,6 +1,6 @@ (module - (type $0 (func (param i32) (result i32))) - (type $1 (func (param i32))) + (type $0 (func (param i32))) + (type $1 (func (param i32) (result i32))) (type $2 (func)) (type $3 (func (param i32 i32))) (type $4 (func (result i32))) @@ -222,7 +222,7 @@ local.get $0 global.set $~lib/rt/itcms/iter end - block $__inlined_func$~lib/rt/itcms/Object#unlink$241 + block $__inlined_func$~lib/rt/itcms/Object#unlink$248 local.get $1 i32.load offset=4 i32.const -4 @@ -246,7 +246,7 @@ call $~lib/builtins/abort unreachable end - br $__inlined_func$~lib/rt/itcms/Object#unlink$241 + br $__inlined_func$~lib/rt/itcms/Object#unlink$248 end local.get $1 i32.load offset=8 @@ -1562,11 +1562,11 @@ i32.sub i32.load local.tee $0 - i32.const 19 + i32.const 22 i32.eq br_if $is_instance local.get $0 - i32.const 22 + i32.const 19 i32.eq br_if $is_instance i32.const 0 @@ -1638,7 +1638,7 @@ i32.add global.set $~lib/memory/__stack_pointer ) - (func $"instanceof/assertDynamicFalse" (param $0 i32) + (func $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" (param $0 i32) global.get $~lib/memory/__stack_pointer i32.const 4 i32.sub @@ -1662,7 +1662,7 @@ i32.store local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/Y$82 (result i32) + block $__inlined_func$~instanceof|instanceof/IC$84 (result i32) block $is_instance local.get $0 i32.const 8 @@ -1677,17 +1677,18 @@ i32.eq br_if $is_instance i32.const 0 - br $__inlined_func$~instanceof|instanceof/Y$82 + br $__inlined_func$~instanceof|instanceof/IC$84 end i32.const 1 end else i32.const 0 end + i32.eqz if i32.const 0 i32.const 1456 - i32.const 19 + i32.const 12 i32.const 5 call $~lib/builtins/abort unreachable @@ -1743,6 +1744,65 @@ i32.add global.set $~lib/memory/__stack_pointer ) + (func $"instanceof/assertDynamicFalse" (param $0 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 1588 + 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 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + if (result i32) + block $__inlined_func$~instanceof|instanceof/IC$90 (result i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load + local.tee $0 + i32.const 19 + i32.eq + br_if $is_instance + local.get $0 + i32.const 22 + i32.eq + br_if $is_instance + i32.const 0 + br $__inlined_func$~instanceof|instanceof/IC$90 + 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 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) (func $~lib/rt/__visit_members (param $0 i32) block $invalid block $instanceof/IE @@ -2419,7 +2479,7 @@ i32.store offset=12 local.get $0 if (result i32) - block $__inlined_func$~anyinstanceof|instanceof/Child$110 (result i32) + block $__inlined_func$~anyinstanceof|instanceof/Child$116 (result i32) block $is_instance1 local.get $0 i32.const 8 @@ -2434,7 +2494,7 @@ i32.eq br_if $is_instance1 i32.const 0 - br $__inlined_func$~anyinstanceof|instanceof/Child$110 + br $__inlined_func$~anyinstanceof|instanceof/Child$116 end i32.const 1 end @@ -2464,22 +2524,22 @@ i32.store offset=16 local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat$111 (result i32) + block $__inlined_func$~instanceof|instanceof/Cat$117 (result i32) block $is_instance2 local.get $0 i32.const 8 i32.sub i32.load local.tee $0 - i32.const 13 + i32.const 14 i32.eq br_if $is_instance2 local.get $0 - i32.const 14 + i32.const 13 i32.eq br_if $is_instance2 i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat$111 + br $__inlined_func$~instanceof|instanceof/Cat$117 end i32.const 1 end @@ -2523,22 +2583,22 @@ i32.store offset=24 local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat$113 (result i32) + block $__inlined_func$~instanceof|instanceof/Cat$119 (result i32) block $is_instance4 local.get $0 i32.const 8 i32.sub i32.load local.tee $0 - i32.const 13 + i32.const 14 i32.eq br_if $is_instance4 local.get $0 - i32.const 14 + i32.const 13 i32.eq br_if $is_instance4 i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat$113 + br $__inlined_func$~instanceof|instanceof/Cat$119 end i32.const 1 end @@ -2583,22 +2643,22 @@ i32.store offset=32 local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat$115 (result i32) + block $__inlined_func$~instanceof|instanceof/Cat$121 (result i32) block $is_instance6 local.get $0 i32.const 8 i32.sub i32.load local.tee $0 - i32.const 13 + i32.const 14 i32.eq br_if $is_instance6 local.get $0 - i32.const 14 + i32.const 13 i32.eq br_if $is_instance6 i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat$115 + br $__inlined_func$~instanceof|instanceof/Cat$121 end i32.const 1 end @@ -2662,22 +2722,22 @@ i32.store offset=40 local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat$117 (result i32) + block $__inlined_func$~instanceof|instanceof/Cat$123 (result i32) block $is_instance8 local.get $0 i32.const 8 i32.sub i32.load local.tee $0 - i32.const 13 + i32.const 14 i32.eq br_if $is_instance8 local.get $0 - i32.const 14 + i32.const 13 i32.eq br_if $is_instance8 i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat$117 + br $__inlined_func$~instanceof|instanceof/Cat$123 end i32.const 1 end @@ -2731,22 +2791,22 @@ i32.store offset=48 local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat$119 (result i32) + block $__inlined_func$~instanceof|instanceof/Cat$125 (result i32) block $is_instance10 local.get $0 i32.const 8 i32.sub i32.load local.tee $0 - i32.const 13 + i32.const 14 i32.eq br_if $is_instance10 local.get $0 - i32.const 14 + i32.const 13 i32.eq br_if $is_instance10 i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat$119 + br $__inlined_func$~instanceof|instanceof/Cat$125 end i32.const 1 end @@ -2801,22 +2861,22 @@ i32.store offset=56 local.get $0 if (result i32) - block $__inlined_func$~instanceof|instanceof/Cat$121 (result i32) + block $__inlined_func$~instanceof|instanceof/Cat$127 (result i32) block $is_instance12 local.get $0 i32.const 8 i32.sub i32.load local.tee $0 - i32.const 13 + i32.const 14 i32.eq br_if $is_instance12 local.get $0 - i32.const 14 + i32.const 13 i32.eq br_if $is_instance12 i32.const 0 - br $__inlined_func$~instanceof|instanceof/Cat$121 + br $__inlined_func$~instanceof|instanceof/Cat$127 end i32.const 1 end @@ -3089,13 +3149,13 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/y local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z local.tee $0 @@ -3113,13 +3173,13 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/w i32.store @@ -3148,8 +3208,56 @@ global.get $instanceof/x local.tee $0 i32.store + 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 1588 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store local.get $0 - call $"instanceof/assertDynamicFalse" + if (result i32) + block $__inlined_func$~instanceof|instanceof/Y$86 (result i32) + block $is_instance21 + local.get $0 + i32.const 8 + i32.sub + i32.load + local.tee $0 + i32.const 22 + i32.eq + br_if $is_instance21 + local.get $0 + i32.const 19 + i32.eq + br_if $is_instance21 + i32.const 0 + br $__inlined_func$~instanceof|instanceof/Y$86 + 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 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer global.get $instanceof/x local.tee $0 @@ -3224,25 +3332,25 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicFalse" + call $"instanceof/assertDynamicFalse" global.get $~lib/memory/__stack_pointer global.get $instanceof/x local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicFalse" + call $"instanceof/assertDynamicFalse" global.get $~lib/memory/__stack_pointer global.get $instanceof/x local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicFalse" + call $"instanceof/assertDynamicFalse" global.get $~lib/memory/__stack_pointer global.get $instanceof/x local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicFalse" + call $"instanceof/assertDynamicFalse" global.get $~lib/memory/__stack_pointer global.get $instanceof/x i32.store @@ -3254,25 +3362,25 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/y local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/y local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/y local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/y i32.store @@ -3284,25 +3392,25 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z i32.store @@ -3320,13 +3428,13 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicFalse" + call $"instanceof/assertDynamicFalse" global.get $~lib/memory/__stack_pointer global.get $instanceof/x local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicFalse" + call $"instanceof/assertDynamicFalse" global.get $~lib/memory/__stack_pointer global.get $instanceof/x i32.store @@ -3341,13 +3449,13 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/y local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/y i32.store @@ -3362,13 +3470,13 @@ local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z local.tee $0 i32.store local.get $0 - call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/Y>" + call $"instanceof/assertDynamicTrue<~lib/object/Object,instanceof/IC>" global.get $~lib/memory/__stack_pointer global.get $instanceof/z i32.store From 5abcad823bdecf49e75efdeac2d4983f65de0edd Mon Sep 17 00:00:00 2001 From: CountBleck Date: Tue, 20 Jun 2023 22:37:08 -0700 Subject: [PATCH 2/2] Add a proper test for multiple interfaces Without inspecting the resulting WAT, and instead concluding based on the test compiling successfully and executing without any errors, everything seems to work properly. --- tests/compiler/multiple-interfaces.debug.wat | 2800 +++++++++++++++++ tests/compiler/multiple-interfaces.js | 0 tests/compiler/multiple-interfaces.json | 1 + .../compiler/multiple-interfaces.release.wat | 1817 +++++++++++ tests/compiler/multiple-interfaces.ts | 63 + 5 files changed, 4681 insertions(+) create mode 100644 tests/compiler/multiple-interfaces.debug.wat create mode 100644 tests/compiler/multiple-interfaces.js create mode 100644 tests/compiler/multiple-interfaces.json create mode 100644 tests/compiler/multiple-interfaces.release.wat create mode 100644 tests/compiler/multiple-interfaces.ts diff --git a/tests/compiler/multiple-interfaces.debug.wat b/tests/compiler/multiple-interfaces.debug.wat new file mode 100644 index 0000000000..d03178ead0 --- /dev/null +++ b/tests/compiler/multiple-interfaces.debug.wat @@ -0,0 +1,2800 @@ +(module + (type $0 (func (param i32) (result i32))) + (type $1 (func (param i32 i32))) + (type $2 (func (param i32) (result f64))) + (type $3 (func (param i32))) + (type $4 (func)) + (type $5 (func (param i32 f64))) + (type $6 (func (param i32 i32) (result i32))) + (type $7 (func (param i32 i32 i32))) + (type $8 (func (param i32 i32 i32 i32))) + (type $9 (func (param i32 i32 i64) (result i32))) + (type $10 (func (result i32))) + (type $11 (func (param i32 f64 f64 f64 f64) (result i32))) + (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (global $~lib/rt/itcms/total (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/threshold (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/state (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/visitCount (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/pinSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/iter (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/toSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/white (mut i32) (i32.const 0)) + (global $~lib/shared/runtime/Runtime.Stub i32 (i32.const 0)) + (global $~lib/shared/runtime/Runtime.Minimal i32 (i32.const 1)) + (global $~lib/shared/runtime/Runtime.Incremental i32 (i32.const 2)) + (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) + (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) + (global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) + (global $multiple-interfaces/vec4 (mut i32) (i32.const 0)) + (global $multiple-interfaces/anotherVec4 (mut i32) (i32.const 0)) + (global $multiple-interfaces/y (mut i32) (i32.const 0)) + (global $multiple-interfaces/yz (mut i32) (i32.const 0)) + (global $multiple-interfaces/vec3 (mut i32) (i32.const 0)) + (global $multiple-interfaces/x (mut i32) (i32.const 0)) + (global $multiple-interfaces/wx (mut i32) (i32.const 0)) + (global $~lib/rt/__rtti_base i32 (i32.const 544)) + (global $~lib/memory/__data_end i32 (i32.const 608)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 33376)) + (global $~lib/memory/__heap_base i32 (i32.const 33376)) + (memory $0 1) + (data $0 (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 $1 (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") + (data $2 (i32.const 144) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $3 (i32.const 176) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $4 (i32.const 204) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e\00\00\00\00\00\00\00\00\00") + (data $5 (i32.const 268) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00\00\00\00\00\00\00\00\00") + (data $6 (i32.const 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $7 (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 $8 (i32.const 412) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00,\00\00\00m\00u\00l\00t\00i\00p\00l\00e\00-\00i\00n\00t\00e\00r\00f\00a\00c\00e\00s\00.\00t\00s\00") + (data $9 (i32.const 476) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00 \00\00\00i\00n\00v\00a\00l\00i\00d\00 \00d\00o\00w\00n\00c\00a\00s\00t\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $10 (i32.const 544) "\0f\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \00\00\00 \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)) + (start $~start) + (func $~lib/rt/itcms/Object#set:nextWithColor (param $this i32) (param $nextWithColor i32) + local.get $this + local.get $nextWithColor + i32.store offset=4 + ) + (func $~lib/rt/itcms/Object#set:prev (param $this i32) (param $prev i32) + local.get $this + local.get $prev + i32.store offset=8 + ) + (func $~lib/rt/itcms/initLazy (param $space i32) (result i32) + local.get $space + local.get $space + call $~lib/rt/itcms/Object#set:nextWithColor + local.get $space + local.get $space + call $~lib/rt/itcms/Object#set:prev + local.get $space + return + ) + (func $~lib/rt/itcms/Object#get:nextWithColor (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/rt/itcms/Object#get:next (param $this i32) (result i32) + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.const -1 + i32.xor + i32.and + return + ) + (func $~lib/rt/itcms/Object#get:color (param $this i32) (result i32) + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.and + return + ) + (func $~lib/rt/itcms/visitRoots (param $cookie i32) + (local $pn i32) + (local $iter i32) + local.get $cookie + call $~lib/rt/__visit_globals + global.get $~lib/rt/itcms/pinSpace + local.set $pn + local.get $pn + call $~lib/rt/itcms/Object#get:next + local.set $iter + loop $while-continue|0 + local.get $iter + local.get $pn + i32.ne + if + i32.const 1 + drop + local.get $iter + call $~lib/rt/itcms/Object#get:color + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 160 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $iter + i32.const 20 + i32.add + local.get $cookie + call $~lib/rt/__visit_members + local.get $iter + call $~lib/rt/itcms/Object#get:next + local.set $iter + br $while-continue|0 + end + end + ) + (func $~lib/rt/itcms/Object#set:color (param $this i32) (param $color i32) + local.get $this + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $color + i32.or + call $~lib/rt/itcms/Object#set:nextWithColor + ) + (func $~lib/rt/itcms/Object#get:prev (param $this i32) (result i32) + local.get $this + i32.load offset=8 + ) + (func $~lib/rt/itcms/Object#set:next (param $this i32) (param $obj i32) + local.get $this + local.get $obj + local.get $this + call $~lib/rt/itcms/Object#get:nextWithColor + i32.const 3 + i32.and + i32.or + call $~lib/rt/itcms/Object#set:nextWithColor + ) + (func $~lib/rt/itcms/Object#unlink (param $this i32) + (local $next i32) + (local $prev i32) + local.get $this + call $~lib/rt/itcms/Object#get:next + local.set $next + local.get $next + i32.const 0 + i32.eq + if + i32.const 1 + drop + local.get $this + call $~lib/rt/itcms/Object#get:prev + i32.const 0 + i32.eq + if (result i32) + local.get $this + global.get $~lib/memory/__heap_base + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 128 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + return + end + local.get $this + call $~lib/rt/itcms/Object#get:prev + local.set $prev + i32.const 1 + drop + local.get $prev + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 132 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $next + local.get $prev + call $~lib/rt/itcms/Object#set:prev + local.get $prev + local.get $next + call $~lib/rt/itcms/Object#set:next + ) + (func $~lib/rt/itcms/Object#get:rtId (param $this i32) (result i32) + local.get $this + i32.load offset=12 + ) + (func $~lib/shared/typeinfo/Typeinfo#get:flags (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/__typeinfo (param $id i32) (result i32) + (local $ptr i32) + global.get $~lib/rt/__rtti_base + local.set $ptr + local.get $id + local.get $ptr + i32.load + i32.gt_u + if + i32.const 224 + i32.const 288 + i32.const 21 + i32.const 28 + call $~lib/builtins/abort + unreachable + end + local.get $ptr + i32.const 4 + i32.add + local.get $id + i32.const 4 + i32.mul + i32.add + call $~lib/shared/typeinfo/Typeinfo#get:flags + return + ) + (func $~lib/rt/itcms/Object#get:isPointerfree (param $this i32) (result i32) + (local $rtId i32) + local.get $this + call $~lib/rt/itcms/Object#get:rtId + local.set $rtId + local.get $rtId + i32.const 2 + i32.le_u + if (result i32) + i32.const 1 + else + local.get $rtId + call $~lib/rt/__typeinfo + i32.const 32 + i32.and + i32.const 0 + i32.ne + end + return + ) + (func $~lib/rt/itcms/Object#linkTo (param $this i32) (param $list i32) (param $withColor i32) + (local $prev i32) + local.get $list + call $~lib/rt/itcms/Object#get:prev + local.set $prev + local.get $this + local.get $list + local.get $withColor + i32.or + call $~lib/rt/itcms/Object#set:nextWithColor + local.get $this + local.get $prev + call $~lib/rt/itcms/Object#set:prev + local.get $prev + local.get $this + call $~lib/rt/itcms/Object#set:next + local.get $list + local.get $this + call $~lib/rt/itcms/Object#set:prev + ) + (func $~lib/rt/itcms/Object#makeGray (param $this i32) + (local $1 i32) + local.get $this + global.get $~lib/rt/itcms/iter + i32.eq + if + local.get $this + call $~lib/rt/itcms/Object#get:prev + local.tee $1 + i32.eqz + if (result i32) + i32.const 0 + i32.const 96 + i32.const 148 + i32.const 30 + call $~lib/builtins/abort + unreachable + else + local.get $1 + end + global.set $~lib/rt/itcms/iter + end + local.get $this + call $~lib/rt/itcms/Object#unlink + local.get $this + global.get $~lib/rt/itcms/toSpace + local.get $this + call $~lib/rt/itcms/Object#get:isPointerfree + if (result i32) + global.get $~lib/rt/itcms/white + i32.eqz + else + i32.const 2 + end + call $~lib/rt/itcms/Object#linkTo + ) + (func $~lib/rt/itcms/__visit (param $ptr i32) (param $cookie i32) + (local $obj i32) + local.get $ptr + i32.eqz + if + return + end + local.get $ptr + i32.const 20 + i32.sub + local.set $obj + i32.const 0 + drop + local.get $obj + call $~lib/rt/itcms/Object#get:color + global.get $~lib/rt/itcms/white + i32.eq + if + local.get $obj + call $~lib/rt/itcms/Object#makeGray + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.add + global.set $~lib/rt/itcms/visitCount + end + ) + (func $~lib/rt/itcms/visitStack (param $cookie i32) + (local $ptr i32) + global.get $~lib/memory/__stack_pointer + local.set $ptr + loop $while-continue|0 + local.get $ptr + global.get $~lib/memory/__heap_base + i32.lt_u + if + local.get $ptr + i32.load + local.get $cookie + call $~lib/rt/itcms/__visit + local.get $ptr + i32.const 4 + i32.add + local.set $ptr + br $while-continue|0 + end + end + ) + (func $~lib/rt/common/BLOCK#get:mmInfo (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/itcms/Object#get:size (param $this i32) (result i32) + i32.const 4 + local.get $this + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + return + ) + (func $~lib/rt/tlsf/Root#set:flMap (param $this i32) (param $flMap i32) + local.get $this + local.get $flMap + i32.store + ) + (func $~lib/rt/common/BLOCK#set:mmInfo (param $this i32) (param $mmInfo i32) + local.get $this + local.get $mmInfo + i32.store + ) + (func $~lib/rt/tlsf/Block#set:prev (param $this i32) (param $prev i32) + local.get $this + local.get $prev + i32.store offset=4 + ) + (func $~lib/rt/tlsf/Block#set:next (param $this i32) (param $next i32) + local.get $this + local.get $next + i32.store offset=8 + ) + (func $~lib/rt/tlsf/Block#get:prev (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/rt/tlsf/Block#get:next (param $this i32) (result i32) + local.get $this + i32.load offset=8 + ) + (func $~lib/rt/tlsf/Root#get:flMap (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/tlsf/removeBlock (param $root i32) (param $block i32) + (local $blockInfo i32) + (local $size i32) + (local $fl i32) + (local $sl i32) + (local $6 i32) + (local $7 i32) + (local $boundedSize i32) + (local $prev i32) + (local $next i32) + (local $root|11 i32) + (local $fl|12 i32) + (local $sl|13 i32) + (local $root|14 i32) + (local $fl|15 i32) + (local $sl|16 i32) + (local $head i32) + (local $root|18 i32) + (local $fl|19 i32) + (local $slMap i32) + (local $root|21 i32) + (local $fl|22 i32) + (local $slMap|23 i32) + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $blockInfo + i32.const 1 + drop + local.get $blockInfo + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 268 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.set $size + i32.const 1 + drop + local.get $size + i32.const 12 + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 270 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $size + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $fl + local.get $size + i32.const 4 + i32.shr_u + local.set $sl + else + local.get $size + local.tee $6 + i32.const 1073741820 + local.tee $7 + local.get $6 + local.get $7 + i32.lt_u + select + local.set $boundedSize + i32.const 31 + local.get $boundedSize + i32.clz + i32.sub + local.set $fl + local.get $boundedSize + local.get $fl + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $sl + local.get $fl + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $fl + end + i32.const 1 + drop + local.get $fl + i32.const 23 + i32.lt_u + if (result i32) + local.get $sl + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 284 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $block + call $~lib/rt/tlsf/Block#get:prev + local.set $prev + local.get $block + call $~lib/rt/tlsf/Block#get:next + local.set $next + local.get $prev + if + local.get $prev + local.get $next + call $~lib/rt/tlsf/Block#set:next + end + local.get $next + if + local.get $next + local.get $prev + call $~lib/rt/tlsf/Block#set:prev + end + local.get $block + block $~lib/rt/tlsf/GETHEAD|inlined.0 (result i32) + local.get $root + local.set $root|11 + local.get $fl + local.set $fl|12 + local.get $sl + local.set $sl|13 + local.get $root|11 + local.get $fl|12 + i32.const 4 + i32.shl + local.get $sl|13 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.0 + end + i32.eq + if + local.get $root + local.set $root|14 + local.get $fl + local.set $fl|15 + local.get $sl + local.set $sl|16 + local.get $next + local.set $head + local.get $root|14 + local.get $fl|15 + i32.const 4 + i32.shl + local.get $sl|16 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $head + i32.store offset=96 + local.get $next + i32.eqz + if + block $~lib/rt/tlsf/GETSL|inlined.0 (result i32) + local.get $root + local.set $root|18 + local.get $fl + local.set $fl|19 + local.get $root|18 + local.get $fl|19 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.0 + end + local.set $slMap + local.get $root + local.set $root|21 + local.get $fl + local.set $fl|22 + local.get $slMap + i32.const 1 + local.get $sl + i32.shl + i32.const -1 + i32.xor + i32.and + local.tee $slMap + local.set $slMap|23 + local.get $root|21 + local.get $fl|22 + i32.const 2 + i32.shl + i32.add + local.get $slMap|23 + i32.store offset=4 + local.get $slMap + i32.eqz + if + local.get $root + local.get $root + call $~lib/rt/tlsf/Root#get:flMap + i32.const 1 + local.get $fl + i32.shl + i32.const -1 + i32.xor + i32.and + call $~lib/rt/tlsf/Root#set:flMap + end + end + end + ) + (func $~lib/rt/tlsf/insertBlock (param $root i32) (param $block i32) + (local $blockInfo i32) + (local $block|3 i32) + (local $right i32) + (local $rightInfo i32) + (local $block|6 i32) + (local $block|7 i32) + (local $left i32) + (local $leftInfo i32) + (local $size i32) + (local $fl i32) + (local $sl i32) + (local $13 i32) + (local $14 i32) + (local $boundedSize i32) + (local $root|16 i32) + (local $fl|17 i32) + (local $sl|18 i32) + (local $head i32) + (local $root|20 i32) + (local $fl|21 i32) + (local $sl|22 i32) + (local $head|23 i32) + (local $root|24 i32) + (local $fl|25 i32) + (local $root|26 i32) + (local $fl|27 i32) + (local $slMap i32) + i32.const 1 + drop + local.get $block + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 201 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $blockInfo + i32.const 1 + drop + local.get $blockInfo + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 203 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETRIGHT|inlined.0 (result i32) + local.get $block + local.set $block|3 + local.get $block|3 + i32.const 4 + i32.add + local.get $block|3 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.0 + end + local.set $right + local.get $right + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $rightInfo + local.get $rightInfo + i32.const 1 + i32.and + if + local.get $root + local.get $right + call $~lib/rt/tlsf/removeBlock + local.get $block + local.get $blockInfo + i32.const 4 + i32.add + local.get $rightInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.tee $blockInfo + call $~lib/rt/common/BLOCK#set:mmInfo + block $~lib/rt/tlsf/GETRIGHT|inlined.1 (result i32) + local.get $block + local.set $block|6 + local.get $block|6 + i32.const 4 + i32.add + local.get $block|6 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.1 + end + local.set $right + local.get $right + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $rightInfo + end + local.get $blockInfo + i32.const 2 + i32.and + if + block $~lib/rt/tlsf/GETFREELEFT|inlined.0 (result i32) + local.get $block + local.set $block|7 + local.get $block|7 + i32.const 4 + i32.sub + i32.load + br $~lib/rt/tlsf/GETFREELEFT|inlined.0 + end + local.set $left + local.get $left + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $leftInfo + i32.const 1 + drop + local.get $leftInfo + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 221 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $root + local.get $left + call $~lib/rt/tlsf/removeBlock + local.get $left + local.set $block + local.get $block + local.get $leftInfo + i32.const 4 + i32.add + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.tee $blockInfo + call $~lib/rt/common/BLOCK#set:mmInfo + end + local.get $right + local.get $rightInfo + i32.const 2 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.set $size + i32.const 1 + drop + local.get $size + i32.const 12 + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 233 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + drop + local.get $block + i32.const 4 + i32.add + local.get $size + i32.add + local.get $right + i32.eq + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 234 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $right + i32.const 4 + i32.sub + local.get $block + i32.store + local.get $size + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $fl + local.get $size + i32.const 4 + i32.shr_u + local.set $sl + else + local.get $size + local.tee $13 + i32.const 1073741820 + local.tee $14 + local.get $13 + local.get $14 + i32.lt_u + select + local.set $boundedSize + i32.const 31 + local.get $boundedSize + i32.clz + i32.sub + local.set $fl + local.get $boundedSize + local.get $fl + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $sl + local.get $fl + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $fl + end + i32.const 1 + drop + local.get $fl + i32.const 23 + i32.lt_u + if (result i32) + local.get $sl + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 251 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETHEAD|inlined.1 (result i32) + local.get $root + local.set $root|16 + local.get $fl + local.set $fl|17 + local.get $sl + local.set $sl|18 + local.get $root|16 + local.get $fl|17 + i32.const 4 + i32.shl + local.get $sl|18 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.1 + end + local.set $head + local.get $block + i32.const 0 + call $~lib/rt/tlsf/Block#set:prev + local.get $block + local.get $head + call $~lib/rt/tlsf/Block#set:next + local.get $head + if + local.get $head + local.get $block + call $~lib/rt/tlsf/Block#set:prev + end + local.get $root + local.set $root|20 + local.get $fl + local.set $fl|21 + local.get $sl + local.set $sl|22 + local.get $block + local.set $head|23 + local.get $root|20 + local.get $fl|21 + i32.const 4 + i32.shl + local.get $sl|22 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $head|23 + i32.store offset=96 + local.get $root + local.get $root + call $~lib/rt/tlsf/Root#get:flMap + i32.const 1 + local.get $fl + i32.shl + i32.or + call $~lib/rt/tlsf/Root#set:flMap + local.get $root + local.set $root|26 + local.get $fl + local.set $fl|27 + block $~lib/rt/tlsf/GETSL|inlined.1 (result i32) + local.get $root + local.set $root|24 + local.get $fl + local.set $fl|25 + local.get $root|24 + local.get $fl|25 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.1 + end + i32.const 1 + local.get $sl + i32.shl + i32.or + local.set $slMap + local.get $root|26 + local.get $fl|27 + i32.const 2 + i32.shl + i32.add + local.get $slMap + i32.store offset=4 + ) + (func $~lib/rt/tlsf/addMemory (param $root i32) (param $start i32) (param $endU64 i64) (result i32) + (local $end i32) + (local $root|4 i32) + (local $tail i32) + (local $tailInfo i32) + (local $size i32) + (local $leftSize i32) + (local $left i32) + (local $root|10 i32) + (local $tail|11 i32) + local.get $endU64 + i32.wrap_i64 + local.set $end + i32.const 1 + drop + local.get $start + i64.extend_i32_u + local.get $endU64 + i64.le_u + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 382 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $start + i32.const 4 + i32.add + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + i32.const 4 + i32.sub + local.set $start + local.get $end + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.set $end + block $~lib/rt/tlsf/GETTAIL|inlined.0 (result i32) + local.get $root + local.set $root|4 + local.get $root|4 + i32.load offset=1568 + br $~lib/rt/tlsf/GETTAIL|inlined.0 + end + local.set $tail + i32.const 0 + local.set $tailInfo + local.get $tail + if + i32.const 1 + drop + local.get $start + local.get $tail + i32.const 4 + i32.add + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 389 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $start + i32.const 16 + i32.sub + local.get $tail + i32.eq + if + local.get $start + i32.const 16 + i32.sub + local.set $start + local.get $tail + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $tailInfo + else + end + else + i32.const 1 + drop + local.get $start + local.get $root + i32.const 1572 + i32.add + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 402 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + local.get $end + local.get $start + i32.sub + local.set $size + local.get $size + i32.const 4 + i32.const 12 + i32.add + i32.const 4 + i32.add + i32.lt_u + if + i32.const 0 + return + end + local.get $size + i32.const 2 + i32.const 4 + i32.mul + i32.sub + local.set $leftSize + local.get $start + local.set $left + local.get $left + local.get $leftSize + i32.const 1 + i32.or + local.get $tailInfo + i32.const 2 + i32.and + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $left + i32.const 0 + call $~lib/rt/tlsf/Block#set:prev + local.get $left + i32.const 0 + call $~lib/rt/tlsf/Block#set:next + local.get $start + i32.const 4 + i32.add + local.get $leftSize + i32.add + local.set $tail + local.get $tail + i32.const 0 + i32.const 2 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $root + local.set $root|10 + local.get $tail + local.set $tail|11 + local.get $root|10 + local.get $tail|11 + i32.store offset=1568 + local.get $root + local.get $left + call $~lib/rt/tlsf/insertBlock + i32.const 1 + return + ) + (func $~lib/rt/tlsf/initialize + (local $rootOffset i32) + (local $pagesBefore i32) + (local $pagesNeeded i32) + (local $root i32) + (local $root|4 i32) + (local $tail i32) + (local $fl i32) + (local $root|7 i32) + (local $fl|8 i32) + (local $slMap i32) + (local $sl i32) + (local $root|11 i32) + (local $fl|12 i32) + (local $sl|13 i32) + (local $head i32) + (local $memStart i32) + i32.const 0 + drop + global.get $~lib/memory/__heap_base + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.set $rootOffset + memory.size + local.set $pagesBefore + local.get $rootOffset + i32.const 1572 + i32.add + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $pagesNeeded + local.get $pagesNeeded + local.get $pagesBefore + i32.gt_s + if (result i32) + local.get $pagesNeeded + local.get $pagesBefore + i32.sub + memory.grow + i32.const 0 + i32.lt_s + else + i32.const 0 + end + if + unreachable + end + local.get $rootOffset + local.set $root + local.get $root + i32.const 0 + call $~lib/rt/tlsf/Root#set:flMap + local.get $root + local.set $root|4 + i32.const 0 + local.set $tail + local.get $root|4 + local.get $tail + i32.store offset=1568 + i32.const 0 + local.set $fl + loop $for-loop|0 + local.get $fl + i32.const 23 + i32.lt_u + if + local.get $root + local.set $root|7 + local.get $fl + local.set $fl|8 + i32.const 0 + local.set $slMap + local.get $root|7 + local.get $fl|8 + i32.const 2 + i32.shl + i32.add + local.get $slMap + i32.store offset=4 + i32.const 0 + local.set $sl + loop $for-loop|1 + local.get $sl + i32.const 16 + i32.lt_u + if + local.get $root + local.set $root|11 + local.get $fl + local.set $fl|12 + local.get $sl + local.set $sl|13 + i32.const 0 + local.set $head + local.get $root|11 + local.get $fl|12 + i32.const 4 + i32.shl + local.get $sl|13 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $head + i32.store offset=96 + local.get $sl + i32.const 1 + i32.add + local.set $sl + br $for-loop|1 + end + end + local.get $fl + i32.const 1 + i32.add + local.set $fl + br $for-loop|0 + end + end + local.get $rootOffset + i32.const 1572 + i32.add + local.set $memStart + i32.const 0 + drop + local.get $root + local.get $memStart + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + drop + local.get $root + global.set $~lib/rt/tlsf/ROOT + ) + (func $~lib/rt/tlsf/checkUsedBlock (param $ptr i32) (result i32) + (local $block i32) + local.get $ptr + i32.const 4 + i32.sub + local.set $block + local.get $ptr + i32.const 0 + i32.ne + if (result i32) + local.get $ptr + i32.const 15 + i32.and + i32.eqz + else + i32.const 0 + end + if (result i32) + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 1 + i32.and + i32.eqz + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 562 + i32.const 3 + call $~lib/builtins/abort + unreachable + end + local.get $block + return + ) + (func $~lib/rt/tlsf/freeBlock (param $root i32) (param $block i32) + i32.const 0 + drop + local.get $block + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 1 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $root + local.get $block + call $~lib/rt/tlsf/insertBlock + ) + (func $~lib/rt/tlsf/__free (param $ptr i32) + local.get $ptr + global.get $~lib/memory/__heap_base + i32.lt_u + if + return + end + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.get $ptr + call $~lib/rt/tlsf/checkUsedBlock + call $~lib/rt/tlsf/freeBlock + ) + (func $~lib/rt/itcms/free (param $obj i32) + local.get $obj + global.get $~lib/memory/__heap_base + i32.lt_u + if + local.get $obj + i32.const 0 + call $~lib/rt/itcms/Object#set:nextWithColor + local.get $obj + i32.const 0 + call $~lib/rt/itcms/Object#set:prev + else + global.get $~lib/rt/itcms/total + local.get $obj + call $~lib/rt/itcms/Object#get:size + i32.sub + global.set $~lib/rt/itcms/total + i32.const 0 + drop + local.get $obj + i32.const 4 + i32.add + call $~lib/rt/tlsf/__free + end + ) + (func $~lib/rt/itcms/step (result i32) + (local $obj i32) + (local $1 i32) + (local $black i32) + (local $from i32) + block $break|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/rt/itcms/state + local.set $1 + local.get $1 + i32.const 0 + i32.eq + br_if $case0|0 + local.get $1 + i32.const 1 + i32.eq + br_if $case1|0 + local.get $1 + i32.const 2 + i32.eq + br_if $case2|0 + br $break|0 + end + i32.const 1 + global.set $~lib/rt/itcms/state + i32.const 0 + global.set $~lib/rt/itcms/visitCount + i32.const 0 + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/iter + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.mul + return + end + global.get $~lib/rt/itcms/white + i32.eqz + local.set $black + global.get $~lib/rt/itcms/iter + call $~lib/rt/itcms/Object#get:next + local.set $obj + loop $while-continue|1 + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $obj + global.set $~lib/rt/itcms/iter + local.get $obj + call $~lib/rt/itcms/Object#get:color + local.get $black + i32.ne + if + local.get $obj + local.get $black + call $~lib/rt/itcms/Object#set:color + i32.const 0 + global.set $~lib/rt/itcms/visitCount + local.get $obj + i32.const 20 + i32.add + i32.const 0 + call $~lib/rt/__visit_members + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.mul + return + end + local.get $obj + call $~lib/rt/itcms/Object#get:next + local.set $obj + br $while-continue|1 + end + end + i32.const 0 + global.set $~lib/rt/itcms/visitCount + i32.const 0 + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/iter + call $~lib/rt/itcms/Object#get:next + local.set $obj + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.eq + if + i32.const 0 + call $~lib/rt/itcms/visitStack + global.get $~lib/rt/itcms/iter + call $~lib/rt/itcms/Object#get:next + local.set $obj + loop $while-continue|2 + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $obj + call $~lib/rt/itcms/Object#get:color + local.get $black + i32.ne + if + local.get $obj + local.get $black + call $~lib/rt/itcms/Object#set:color + local.get $obj + i32.const 20 + i32.add + i32.const 0 + call $~lib/rt/__visit_members + end + local.get $obj + call $~lib/rt/itcms/Object#get:next + local.set $obj + br $while-continue|2 + end + end + global.get $~lib/rt/itcms/fromSpace + local.set $from + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/fromSpace + local.get $from + global.set $~lib/rt/itcms/toSpace + local.get $black + global.set $~lib/rt/itcms/white + local.get $from + call $~lib/rt/itcms/Object#get:next + global.set $~lib/rt/itcms/iter + i32.const 2 + global.set $~lib/rt/itcms/state + end + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.mul + return + end + global.get $~lib/rt/itcms/iter + local.set $obj + local.get $obj + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $obj + call $~lib/rt/itcms/Object#get:next + global.set $~lib/rt/itcms/iter + i32.const 1 + drop + local.get $obj + call $~lib/rt/itcms/Object#get:color + global.get $~lib/rt/itcms/white + i32.eqz + i32.eq + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 229 + i32.const 20 + call $~lib/builtins/abort + unreachable + end + local.get $obj + call $~lib/rt/itcms/free + i32.const 10 + return + end + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + call $~lib/rt/itcms/Object#set:nextWithColor + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + call $~lib/rt/itcms/Object#set:prev + i32.const 0 + global.set $~lib/rt/itcms/state + br $break|0 + end + i32.const 0 + return + ) + (func $~lib/rt/itcms/interrupt + (local $budget i32) + i32.const 0 + drop + i32.const 0 + drop + i32.const 1024 + i32.const 200 + i32.mul + i32.const 100 + i32.div_u + local.set $budget + loop $do-loop|0 + local.get $budget + call $~lib/rt/itcms/step + i32.sub + local.set $budget + global.get $~lib/rt/itcms/state + i32.const 0 + i32.eq + if + i32.const 0 + drop + global.get $~lib/rt/itcms/total + i64.extend_i32_u + i32.const 200 + i64.extend_i32_u + i64.mul + i64.const 100 + i64.div_u + i32.wrap_i64 + i32.const 1024 + i32.add + global.set $~lib/rt/itcms/threshold + i32.const 0 + drop + return + end + local.get $budget + i32.const 0 + i32.gt_s + br_if $do-loop|0 + end + i32.const 0 + drop + global.get $~lib/rt/itcms/total + i32.const 1024 + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.sub + i32.const 1024 + i32.lt_u + i32.mul + i32.add + global.set $~lib/rt/itcms/threshold + i32.const 0 + drop + ) + (func $~lib/rt/tlsf/computeSize (param $size i32) (result i32) + local.get $size + i32.const 12 + i32.le_u + if (result i32) + i32.const 12 + else + local.get $size + i32.const 4 + i32.add + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + i32.const 4 + i32.sub + end + return + ) + (func $~lib/rt/tlsf/prepareSize (param $size i32) (result i32) + local.get $size + i32.const 1073741820 + i32.gt_u + if + i32.const 32 + i32.const 368 + i32.const 461 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $size + call $~lib/rt/tlsf/computeSize + return + ) + (func $~lib/rt/tlsf/roundSize (param $size i32) (result i32) + local.get $size + i32.const 536870910 + i32.lt_u + if (result i32) + local.get $size + i32.const 1 + i32.const 27 + local.get $size + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + else + local.get $size + end + return + ) + (func $~lib/rt/tlsf/searchBlock (param $root i32) (param $size i32) (result i32) + (local $fl i32) + (local $sl i32) + (local $requestSize i32) + (local $root|5 i32) + (local $fl|6 i32) + (local $slMap i32) + (local $head i32) + (local $flMap i32) + (local $root|10 i32) + (local $fl|11 i32) + (local $root|12 i32) + (local $fl|13 i32) + (local $sl|14 i32) + (local $root|15 i32) + (local $fl|16 i32) + (local $sl|17 i32) + local.get $size + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $fl + local.get $size + i32.const 4 + i32.shr_u + local.set $sl + else + local.get $size + call $~lib/rt/tlsf/roundSize + local.set $requestSize + i32.const 4 + i32.const 8 + i32.mul + i32.const 1 + i32.sub + local.get $requestSize + i32.clz + i32.sub + local.set $fl + local.get $requestSize + local.get $fl + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $sl + local.get $fl + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $fl + end + i32.const 1 + drop + local.get $fl + i32.const 23 + i32.lt_u + if (result i32) + local.get $sl + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 334 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETSL|inlined.2 (result i32) + local.get $root + local.set $root|5 + local.get $fl + local.set $fl|6 + local.get $root|5 + local.get $fl|6 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.2 + end + i32.const 0 + i32.const -1 + i32.xor + local.get $sl + i32.shl + i32.and + local.set $slMap + i32.const 0 + local.set $head + local.get $slMap + i32.eqz + if + local.get $root + call $~lib/rt/tlsf/Root#get:flMap + i32.const 0 + i32.const -1 + i32.xor + local.get $fl + i32.const 1 + i32.add + i32.shl + i32.and + local.set $flMap + local.get $flMap + i32.eqz + if + i32.const 0 + local.set $head + else + local.get $flMap + i32.ctz + local.set $fl + block $~lib/rt/tlsf/GETSL|inlined.3 (result i32) + local.get $root + local.set $root|10 + local.get $fl + local.set $fl|11 + local.get $root|10 + local.get $fl|11 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + br $~lib/rt/tlsf/GETSL|inlined.3 + end + local.set $slMap + i32.const 1 + drop + local.get $slMap + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 347 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + block $~lib/rt/tlsf/GETHEAD|inlined.2 (result i32) + local.get $root + local.set $root|12 + local.get $fl + local.set $fl|13 + local.get $slMap + i32.ctz + local.set $sl|14 + local.get $root|12 + local.get $fl|13 + i32.const 4 + i32.shl + local.get $sl|14 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.2 + end + local.set $head + end + else + block $~lib/rt/tlsf/GETHEAD|inlined.3 (result i32) + local.get $root + local.set $root|15 + local.get $fl + local.set $fl|16 + local.get $slMap + i32.ctz + local.set $sl|17 + local.get $root|15 + local.get $fl|16 + i32.const 4 + i32.shl + local.get $sl|17 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + br $~lib/rt/tlsf/GETHEAD|inlined.3 + end + local.set $head + end + local.get $head + return + ) + (func $~lib/rt/tlsf/growMemory (param $root i32) (param $size i32) + (local $pagesBefore i32) + (local $root|3 i32) + (local $pagesNeeded i32) + (local $5 i32) + (local $6 i32) + (local $pagesWanted i32) + (local $pagesAfter i32) + i32.const 0 + drop + local.get $size + i32.const 256 + i32.ge_u + if + local.get $size + call $~lib/rt/tlsf/roundSize + local.set $size + end + memory.size + local.set $pagesBefore + local.get $size + i32.const 4 + local.get $pagesBefore + i32.const 16 + i32.shl + i32.const 4 + i32.sub + block $~lib/rt/tlsf/GETTAIL|inlined.1 (result i32) + local.get $root + local.set $root|3 + local.get $root|3 + i32.load offset=1568 + br $~lib/rt/tlsf/GETTAIL|inlined.1 + end + i32.ne + i32.shl + i32.add + local.set $size + local.get $size + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $pagesNeeded + local.get $pagesBefore + local.tee $5 + local.get $pagesNeeded + local.tee $6 + local.get $5 + local.get $6 + i32.gt_s + select + local.set $pagesWanted + local.get $pagesWanted + memory.grow + i32.const 0 + i32.lt_s + if + local.get $pagesNeeded + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + memory.size + local.set $pagesAfter + local.get $root + local.get $pagesBefore + i32.const 16 + i32.shl + local.get $pagesAfter + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + drop + ) + (func $~lib/rt/tlsf/prepareBlock (param $root i32) (param $block i32) (param $size i32) + (local $blockInfo i32) + (local $remaining i32) + (local $spare i32) + (local $block|6 i32) + (local $block|7 i32) + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + local.set $blockInfo + i32.const 1 + drop + local.get $size + i32.const 4 + i32.add + i32.const 15 + i32.and + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 361 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $blockInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $size + i32.sub + local.set $remaining + local.get $remaining + i32.const 4 + i32.const 12 + i32.add + i32.ge_u + if + local.get $block + local.get $size + local.get $blockInfo + i32.const 2 + i32.and + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $block + i32.const 4 + i32.add + local.get $size + i32.add + local.set $spare + local.get $spare + local.get $remaining + i32.const 4 + i32.sub + i32.const 1 + i32.or + call $~lib/rt/common/BLOCK#set:mmInfo + local.get $root + local.get $spare + call $~lib/rt/tlsf/insertBlock + else + local.get $block + local.get $blockInfo + i32.const 1 + i32.const -1 + i32.xor + i32.and + call $~lib/rt/common/BLOCK#set:mmInfo + block $~lib/rt/tlsf/GETRIGHT|inlined.3 (result i32) + local.get $block + local.set $block|7 + local.get $block|7 + i32.const 4 + i32.add + local.get $block|7 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.3 + end + block $~lib/rt/tlsf/GETRIGHT|inlined.2 (result i32) + local.get $block + local.set $block|6 + local.get $block|6 + i32.const 4 + i32.add + local.get $block|6 + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + br $~lib/rt/tlsf/GETRIGHT|inlined.2 + end + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 2 + i32.const -1 + i32.xor + i32.and + call $~lib/rt/common/BLOCK#set:mmInfo + end + ) + (func $~lib/rt/tlsf/allocateBlock (param $root i32) (param $size i32) (result i32) + (local $payloadSize i32) + (local $block i32) + local.get $size + call $~lib/rt/tlsf/prepareSize + local.set $payloadSize + local.get $root + local.get $payloadSize + call $~lib/rt/tlsf/searchBlock + local.set $block + local.get $block + i32.eqz + if + local.get $root + local.get $payloadSize + call $~lib/rt/tlsf/growMemory + local.get $root + local.get $payloadSize + call $~lib/rt/tlsf/searchBlock + local.set $block + i32.const 1 + drop + local.get $block + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 499 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + end + i32.const 1 + drop + local.get $block + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $payloadSize + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 368 + i32.const 501 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $root + local.get $block + call $~lib/rt/tlsf/removeBlock + local.get $root + local.get $block + local.get $payloadSize + call $~lib/rt/tlsf/prepareBlock + i32.const 0 + drop + local.get $block + return + ) + (func $~lib/rt/tlsf/__alloc (param $size i32) (result i32) + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.get $size + call $~lib/rt/tlsf/allocateBlock + i32.const 4 + i32.add + return + ) + (func $~lib/rt/itcms/Object#set:rtId (param $this i32) (param $rtId i32) + local.get $this + local.get $rtId + i32.store offset=12 + ) + (func $~lib/rt/itcms/Object#set:rtSize (param $this i32) (param $rtSize i32) + local.get $this + local.get $rtSize + i32.store offset=16 + ) + (func $~lib/rt/itcms/__new (param $size i32) (param $id i32) (result i32) + (local $obj i32) + (local $ptr i32) + local.get $size + i32.const 1073741804 + i32.ge_u + if + i32.const 32 + i32.const 96 + i32.const 261 + i32.const 31 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.ge_u + if + call $~lib/rt/itcms/interrupt + end + i32.const 16 + local.get $size + i32.add + call $~lib/rt/tlsf/__alloc + i32.const 4 + i32.sub + local.set $obj + local.get $obj + local.get $id + call $~lib/rt/itcms/Object#set:rtId + local.get $obj + local.get $size + call $~lib/rt/itcms/Object#set:rtSize + local.get $obj + global.get $~lib/rt/itcms/fromSpace + global.get $~lib/rt/itcms/white + call $~lib/rt/itcms/Object#linkTo + global.get $~lib/rt/itcms/total + local.get $obj + call $~lib/rt/itcms/Object#get:size + i32.add + global.set $~lib/rt/itcms/total + local.get $obj + i32.const 20 + i32.add + local.set $ptr + local.get $ptr + i32.const 0 + local.get $size + memory.fill + local.get $ptr + return + ) + (func $multiple-interfaces/Vec4TheClass#set:w (param $this i32) (param $w f64) + local.get $this + local.get $w + f64.store + ) + (func $multiple-interfaces/Vec4TheClass#set:x (param $this i32) (param $x f64) + local.get $this + local.get $x + f64.store offset=8 + ) + (func $multiple-interfaces/Vec4TheClass#set:y (param $this i32) (param $y f64) + local.get $this + local.get $y + f64.store offset=16 + ) + (func $multiple-interfaces/Vec4TheClass#set:z (param $this i32) (param $z f64) + local.get $this + local.get $z + f64.store offset=24 + ) + (func $multiple-interfaces/W#get:w (param $this i32) (result f64) + unreachable + ) + (func $multiple-interfaces/Vec4TheClass#get:w (param $this i32) (result f64) + local.get $this + f64.load + ) + (func $multiple-interfaces/Y#get:y (param $this i32) (result f64) + unreachable + ) + (func $multiple-interfaces/Vec4TheClass#get:y (param $this i32) (result f64) + local.get $this + f64.load offset=16 + ) + (func $multiple-interfaces/Z#get:z (param $this i32) (result f64) + unreachable + ) + (func $multiple-interfaces/Vec4TheClass#get:z (param $this i32) (result f64) + local.get $this + f64.load offset=24 + ) + (func $multiple-interfaces/X#get:x (param $this i32) (result f64) + unreachable + ) + (func $multiple-interfaces/Vec4TheClass#get:x (param $this i32) (result f64) + local.get $this + f64.load offset=8 + ) + (func $multiple-interfaces/W#get:w@override (param $0 i32) (result f64) + (local $1 i32) + block $default + block $case0 + local.get $0 + i32.const 8 + i32.sub + i32.load + local.set $1 + local.get $1 + i32.const 4 + i32.eq + br_if $case0 + br $default + end + local.get $0 + call $multiple-interfaces/Vec4TheClass#get:w + return + end + unreachable + ) + (func $multiple-interfaces/Y#get:y@override (param $0 i32) (result f64) + (local $1 i32) + block $default + block $case0 + local.get $0 + i32.const 8 + i32.sub + i32.load + local.set $1 + local.get $1 + i32.const 4 + i32.eq + br_if $case0 + br $default + end + local.get $0 + call $multiple-interfaces/Vec4TheClass#get:y + return + end + unreachable + ) + (func $multiple-interfaces/Z#get:z@override (param $0 i32) (result f64) + (local $1 i32) + block $default + block $case0 + local.get $0 + i32.const 8 + i32.sub + i32.load + local.set $1 + local.get $1 + i32.const 4 + i32.eq + br_if $case0 + br $default + end + local.get $0 + call $multiple-interfaces/Vec4TheClass#get:z + return + end + unreachable + ) + (func $multiple-interfaces/X#get:x@override (param $0 i32) (result f64) + (local $1 i32) + block $default + block $case0 + local.get $0 + i32.const 8 + i32.sub + i32.load + local.set $1 + local.get $1 + i32.const 4 + i32.eq + br_if $case0 + br $default + end + local.get $0 + call $multiple-interfaces/Vec4TheClass#get:x + return + end + unreachable + ) + (func $~instanceof|multiple-interfaces/Vec4 (param $0 i32) (result i32) + (local $1 i32) + block $is_instance + local.get $0 + i32.const 8 + i32.sub + i32.load + local.set $1 + local.get $1 + i32.const 4 + i32.eq + br_if $is_instance + i32.const 0 + return + end + i32.const 1 + ) + (func $~lib/rt/__visit_globals (param $0 i32) + (local $1 i32) + global.get $multiple-interfaces/vec4 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/anotherVec4 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/y + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/yz + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/vec3 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/x + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/wx + 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 (param $0 i32) (param $1 i32) + (local $2 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + i32.load + local.tee $2 + if + local.get $2 + local.get $1 + call $~lib/rt/itcms/__visit + end + ) + (func $~lib/object/Object~visit (param $0 i32) (param $1 i32) + ) + (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) + block $invalid + block $multiple-interfaces/YZ + block $multiple-interfaces/Z + block $multiple-interfaces/XZ + block $multiple-interfaces/Y + block $multiple-interfaces/XY + block $multiple-interfaces/Vec3 + block $multiple-interfaces/X + block $multiple-interfaces/W + block $multiple-interfaces/WX + block $multiple-interfaces/Vec4 + block $multiple-interfaces/Vec4TheClass + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $multiple-interfaces/Vec4TheClass $multiple-interfaces/Vec4 $multiple-interfaces/WX $multiple-interfaces/W $multiple-interfaces/X $multiple-interfaces/Vec3 $multiple-interfaces/XY $multiple-interfaces/Y $multiple-interfaces/XZ $multiple-interfaces/Z $multiple-interfaces/YZ $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 + unreachable + ) + (func $~start + call $start:multiple-interfaces + ) + (func $~stack_check + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__data_end + i32.lt_s + if + i32.const 33408 + i32.const 33456 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $multiple-interfaces/Vec4TheClass#constructor (param $this i32) (param $w f64) (param $x f64) (param $y f64) (param $z f64) (result i32) + (local $5 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 32 + i32.const 4 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=4 + local.get $5 + local.get $w + call $multiple-interfaces/Vec4TheClass#set:w + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=4 + local.get $5 + local.get $x + call $multiple-interfaces/Vec4TheClass#set:x + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=4 + local.get $5 + local.get $y + call $multiple-interfaces/Vec4TheClass#set:y + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=4 + local.get $5 + local.get $z + call $multiple-interfaces/Vec4TheClass#set:z + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $5 + ) + (func $start:multiple-interfaces + (local $0 i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + memory.size + i32.const 16 + i32.shl + global.get $~lib/memory/__heap_base + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 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 + f64.const 1 + f64.const 2 + f64.const 3 + f64.const 4 + call $multiple-interfaces/Vec4TheClass#constructor + global.set $multiple-interfaces/vec4 + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/anotherVec4 + global.get $multiple-interfaces/anotherVec4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/W#get:w@override + global.get $multiple-interfaces/vec4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/Vec4TheClass#get:w + f64.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 49 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/y + global.get $multiple-interfaces/y + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/Y#get:y@override + global.get $multiple-interfaces/vec4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/Vec4TheClass#get:y + f64.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 52 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/yz + global.get $multiple-interfaces/yz + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/Z#get:z@override + global.get $multiple-interfaces/vec4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/Vec4TheClass#get:z + f64.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 55 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/vec3 + global.get $multiple-interfaces/vec3 + global.set $multiple-interfaces/x + global.get $multiple-interfaces/vec3 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/X#get:x@override + global.get $multiple-interfaces/x + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/X#get:x@override + f64.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 59 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/vec3 + local.tee $0 + i32.store offset=4 + local.get $0 + call $~instanceof|multiple-interfaces/Vec4 + if (result i32) + local.get $0 + else + i32.const 496 + i32.const 432 + i32.const 62 + i32.const 12 + call $~lib/builtins/abort + unreachable + end + global.set $multiple-interfaces/wx + global.get $multiple-interfaces/wx + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/W#get:w@override + global.get $multiple-interfaces/vec4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $multiple-interfaces/Vec4TheClass#get:w + f64.eq + i32.eqz + if + i32.const 0 + i32.const 432 + i32.const 63 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + ) +) diff --git a/tests/compiler/multiple-interfaces.js b/tests/compiler/multiple-interfaces.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/compiler/multiple-interfaces.json b/tests/compiler/multiple-interfaces.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/tests/compiler/multiple-interfaces.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/compiler/multiple-interfaces.release.wat b/tests/compiler/multiple-interfaces.release.wat new file mode 100644 index 0000000000..84591d59ca --- /dev/null +++ b/tests/compiler/multiple-interfaces.release.wat @@ -0,0 +1,1817 @@ +(module + (type $0 (func)) + (type $1 (func (param i32))) + (type $2 (func (param i32 i32))) + (type $3 (func (result i32))) + (type $4 (func (param i32 i32 i32 i32))) + (type $5 (func (param i32 i32 i64))) + (type $6 (func (param i32) (result i32))) + (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (global $~lib/rt/itcms/total (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/threshold (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/state (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/visitCount (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/pinSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/iter (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/toSpace (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/white (mut i32) (i32.const 0)) + (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) + (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) + (global $multiple-interfaces/vec4 (mut i32) (i32.const 0)) + (global $multiple-interfaces/anotherVec4 (mut i32) (i32.const 0)) + (global $multiple-interfaces/y (mut i32) (i32.const 0)) + (global $multiple-interfaces/yz (mut i32) (i32.const 0)) + (global $multiple-interfaces/vec3 (mut i32) (i32.const 0)) + (global $multiple-interfaces/x (mut i32) (i32.const 0)) + (global $multiple-interfaces/wx (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34400)) + (memory $0 1) + (data $0 (i32.const 1036) "<") + (data $0.1 (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") + (data $1 (i32.const 1100) "<") + (data $1.1 (i32.const 1112) "\02\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s") + (data $4 (i32.const 1228) "<") + (data $4.1 (i32.const 1240) "\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e") + (data $5 (i32.const 1292) ",") + (data $5.1 (i32.const 1304) "\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s") + (data $7 (i32.const 1372) "<") + (data $7.1 (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 $8 (i32.const 1436) "<") + (data $8.1 (i32.const 1448) "\02\00\00\00,\00\00\00m\00u\00l\00t\00i\00p\00l\00e\00-\00i\00n\00t\00e\00r\00f\00a\00c\00e\00s\00.\00t\00s") + (data $9 (i32.const 1500) "<") + (data $9.1 (i32.const 1512) "\02\00\00\00 \00\00\00i\00n\00v\00a\00l\00i\00d\00 \00d\00o\00w\00n\00c\00a\00s\00t") + (data $10 (i32.const 1568) "\0f\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00 \00\00\00 \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 + (local $0 i32) + (local $1 i32) + global.get $multiple-interfaces/vec4 + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/anotherVec4 + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/y + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/yz + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/vec3 + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/x + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $multiple-interfaces/wx + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + i32.const 1248 + call $~lib/rt/itcms/__visit + i32.const 1056 + call $~lib/rt/itcms/__visit + global.get $~lib/rt/itcms/pinSpace + local.tee $1 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + loop $while-continue|0 + local.get $0 + local.get $1 + i32.ne + if + local.get $0 + i32.load offset=4 + i32.const 3 + i32.and + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1120 + i32.const 160 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 20 + i32.add + call $~lib/rt/__visit_members + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + br $while-continue|0 + end + end + ) + (func $~lib/rt/itcms/__visit (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + local.get $0 + i32.eqz + if + return + end + global.get $~lib/rt/itcms/white + local.get $0 + i32.const 20 + i32.sub + local.tee $1 + i32.load offset=4 + i32.const 3 + i32.and + i32.eq + if + local.get $1 + global.get $~lib/rt/itcms/iter + i32.eq + if + local.get $1 + i32.load offset=8 + local.tee $0 + i32.eqz + if + i32.const 0 + i32.const 1120 + i32.const 148 + i32.const 30 + call $~lib/builtins/abort + unreachable + end + local.get $0 + global.set $~lib/rt/itcms/iter + end + block $__inlined_func$~lib/rt/itcms/Object#unlink$129 + local.get $1 + i32.load offset=4 + i32.const -4 + i32.and + local.tee $0 + i32.eqz + if + local.get $1 + i32.load offset=8 + i32.eqz + local.get $1 + i32.const 34400 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1120 + i32.const 128 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + br $__inlined_func$~lib/rt/itcms/Object#unlink$129 + end + local.get $1 + i32.load offset=8 + local.tee $2 + i32.eqz + if + i32.const 0 + i32.const 1120 + i32.const 132 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $2 + i32.store offset=8 + local.get $2 + local.get $0 + local.get $2 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + end + global.get $~lib/rt/itcms/toSpace + local.set $2 + local.get $1 + i32.load offset=12 + local.tee $0 + i32.const 2 + i32.le_u + if (result i32) + i32.const 1 + else + local.get $0 + i32.const 1568 + i32.load + i32.gt_u + if + i32.const 1248 + i32.const 1312 + i32.const 21 + i32.const 28 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 2 + i32.shl + i32.const 1572 + i32.add + i32.load + i32.const 32 + i32.and + end + local.set $3 + local.get $2 + i32.load offset=8 + local.set $0 + local.get $1 + global.get $~lib/rt/itcms/white + i32.eqz + i32.const 2 + local.get $3 + select + local.get $2 + i32.or + i32.store offset=4 + local.get $1 + local.get $0 + i32.store offset=8 + local.get $0 + local.get $1 + local.get $0 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + local.get $2 + local.get $1 + i32.store offset=8 + global.get $~lib/rt/itcms/visitCount + i32.const 1 + i32.add + global.set $~lib/rt/itcms/visitCount + end + ) + (func $~lib/rt/tlsf/removeBlock (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + local.get $1 + i32.load + local.tee $3 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 268 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const -4 + i32.and + local.tee $3 + i32.const 12 + i32.lt_u + if + i32.const 0 + i32.const 1392 + i32.const 270 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const 256 + i32.lt_u + if (result i32) + local.get $3 + i32.const 4 + i32.shr_u + else + i32.const 31 + i32.const 1073741820 + local.get $3 + local.get $3 + i32.const 1073741820 + i32.ge_u + select + local.tee $3 + i32.clz + i32.sub + local.tee $4 + i32.const 7 + i32.sub + local.set $2 + local.get $3 + local.get $4 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + end + local.tee $3 + i32.const 16 + i32.lt_u + local.get $2 + i32.const 23 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 284 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load offset=8 + local.set $5 + local.get $1 + i32.load offset=4 + local.tee $4 + if + local.get $4 + local.get $5 + i32.store offset=8 + end + local.get $5 + if + local.get $5 + local.get $4 + i32.store offset=4 + end + local.get $1 + local.get $0 + local.get $2 + i32.const 4 + i32.shl + local.get $3 + i32.add + i32.const 2 + i32.shl + i32.add + local.tee $1 + i32.load offset=96 + i32.eq + if + local.get $1 + local.get $5 + i32.store offset=96 + local.get $5 + i32.eqz + if + local.get $0 + local.get $2 + i32.const 2 + i32.shl + i32.add + local.tee $1 + i32.load offset=4 + i32.const -2 + local.get $3 + i32.rotl + i32.and + local.set $3 + local.get $1 + local.get $3 + i32.store offset=4 + local.get $3 + i32.eqz + if + local.get $0 + local.get $0 + i32.load + i32.const -2 + local.get $2 + i32.rotl + i32.and + i32.store + end + end + end + ) + (func $~lib/rt/tlsf/insertBlock (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + local.get $1 + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 201 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load + local.tee $3 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 203 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 4 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $4 + i32.load + local.tee $2 + i32.const 1 + i32.and + if + local.get $0 + local.get $4 + call $~lib/rt/tlsf/removeBlock + local.get $1 + local.get $3 + i32.const 4 + i32.add + local.get $2 + i32.const -4 + i32.and + i32.add + local.tee $3 + i32.store + local.get $1 + i32.const 4 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $4 + i32.load + local.set $2 + end + local.get $3 + i32.const 2 + i32.and + if + local.get $1 + i32.const 4 + i32.sub + i32.load + local.tee $1 + i32.load + local.tee $6 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 221 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $1 + call $~lib/rt/tlsf/removeBlock + local.get $1 + local.get $6 + i32.const 4 + i32.add + local.get $3 + i32.const -4 + i32.and + i32.add + local.tee $3 + i32.store + end + local.get $4 + local.get $2 + i32.const 2 + i32.or + i32.store + local.get $3 + i32.const -4 + i32.and + local.tee $2 + i32.const 12 + i32.lt_u + if + i32.const 0 + i32.const 1392 + i32.const 233 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + local.get $1 + i32.const 4 + i32.add + local.get $2 + i32.add + i32.ne + if + i32.const 0 + i32.const 1392 + i32.const 234 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + i32.const 4 + i32.sub + local.get $1 + i32.store + local.get $2 + i32.const 256 + i32.lt_u + if (result i32) + local.get $2 + i32.const 4 + i32.shr_u + else + i32.const 31 + i32.const 1073741820 + local.get $2 + local.get $2 + i32.const 1073741820 + i32.ge_u + select + local.tee $2 + i32.clz + i32.sub + local.tee $3 + i32.const 7 + i32.sub + local.set $5 + local.get $2 + local.get $3 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + end + local.tee $2 + i32.const 16 + i32.lt_u + local.get $5 + i32.const 23 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 251 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $5 + i32.const 4 + i32.shl + local.get $2 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + local.set $3 + local.get $1 + i32.const 0 + i32.store offset=4 + local.get $1 + local.get $3 + i32.store offset=8 + local.get $3 + if + local.get $3 + local.get $1 + i32.store offset=4 + end + local.get $0 + local.get $5 + i32.const 4 + i32.shl + local.get $2 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $1 + i32.store offset=96 + local.get $0 + local.get $0 + i32.load + i32.const 1 + local.get $5 + i32.shl + i32.or + i32.store + local.get $0 + local.get $5 + i32.const 2 + i32.shl + i32.add + local.tee $0 + local.get $0 + i32.load offset=4 + i32.const 1 + local.get $2 + i32.shl + i32.or + i32.store offset=4 + ) + (func $~lib/rt/tlsf/addMemory (param $0 i32) (param $1 i32) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + local.get $2 + local.get $1 + i64.extend_i32_u + i64.lt_u + if + i32.const 0 + i32.const 1392 + i32.const 382 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 19 + i32.add + i32.const -16 + i32.and + i32.const 4 + i32.sub + local.set $1 + local.get $0 + i32.load offset=1568 + local.tee $3 + if + local.get $3 + i32.const 4 + i32.add + local.get $1 + i32.gt_u + if + i32.const 0 + i32.const 1392 + i32.const 389 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $3 + local.get $1 + i32.const 16 + i32.sub + local.tee $5 + i32.eq + if + local.get $3 + i32.load + local.set $4 + local.get $5 + local.set $1 + end + else + local.get $0 + i32.const 1572 + i32.add + local.get $1 + i32.gt_u + if + i32.const 0 + i32.const 1392 + i32.const 402 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + local.get $2 + i32.wrap_i64 + i32.const -16 + i32.and + local.get $1 + i32.sub + local.tee $3 + i32.const 20 + i32.lt_u + if + return + end + local.get $1 + local.get $4 + i32.const 2 + i32.and + local.get $3 + i32.const 8 + i32.sub + local.tee $3 + i32.const 1 + i32.or + i32.or + i32.store + local.get $1 + i32.const 0 + i32.store offset=4 + local.get $1 + i32.const 0 + i32.store offset=8 + local.get $1 + i32.const 4 + i32.add + local.get $3 + i32.add + local.tee $3 + i32.const 2 + i32.store + local.get $0 + local.get $3 + i32.store offset=1568 + local.get $0 + local.get $1 + call $~lib/rt/tlsf/insertBlock + ) + (func $~lib/rt/tlsf/initialize + (local $0 i32) + (local $1 i32) + memory.size + local.tee $1 + i32.const 0 + i32.le_s + if (result i32) + i32.const 1 + local.get $1 + i32.sub + memory.grow + i32.const 0 + i32.lt_s + else + i32.const 0 + end + if + unreachable + end + i32.const 34400 + i32.const 0 + i32.store + i32.const 35968 + i32.const 0 + i32.store + loop $for-loop|0 + local.get $0 + i32.const 23 + i32.lt_u + if + local.get $0 + i32.const 2 + i32.shl + i32.const 34400 + i32.add + i32.const 0 + i32.store offset=4 + i32.const 0 + local.set $1 + loop $for-loop|1 + local.get $1 + i32.const 16 + i32.lt_u + if + local.get $0 + i32.const 4 + i32.shl + local.get $1 + i32.add + i32.const 2 + i32.shl + i32.const 34400 + i32.add + i32.const 0 + i32.store offset=96 + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $for-loop|1 + end + end + local.get $0 + i32.const 1 + i32.add + local.set $0 + br $for-loop|0 + end + end + i32.const 34400 + i32.const 35972 + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + i32.const 34400 + global.set $~lib/rt/tlsf/ROOT + ) + (func $~lib/rt/itcms/step (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + block $break|0 + block $case2|0 + block $case1|0 + block $case0|0 + global.get $~lib/rt/itcms/state + br_table $case0|0 $case1|0 $case2|0 $break|0 + end + i32.const 1 + global.set $~lib/rt/itcms/state + i32.const 0 + global.set $~lib/rt/itcms/visitCount + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/iter + global.get $~lib/rt/itcms/visitCount + return + end + global.get $~lib/rt/itcms/white + i32.eqz + local.set $1 + global.get $~lib/rt/itcms/iter + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + loop $while-continue|1 + local.get $0 + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $0 + global.set $~lib/rt/itcms/iter + local.get $1 + local.get $0 + i32.load offset=4 + local.tee $2 + i32.const 3 + i32.and + i32.ne + if + local.get $0 + local.get $2 + i32.const -4 + i32.and + local.get $1 + i32.or + i32.store offset=4 + i32.const 0 + global.set $~lib/rt/itcms/visitCount + local.get $0 + i32.const 20 + i32.add + call $~lib/rt/__visit_members + global.get $~lib/rt/itcms/visitCount + return + end + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + br $while-continue|1 + end + end + i32.const 0 + global.set $~lib/rt/itcms/visitCount + call $~lib/rt/itcms/visitRoots + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/iter + i32.load offset=4 + i32.const -4 + i32.and + i32.eq + if + global.get $~lib/memory/__stack_pointer + local.set $0 + loop $while-continue|0 + local.get $0 + i32.const 34400 + i32.lt_u + if + local.get $0 + i32.load + call $~lib/rt/itcms/__visit + local.get $0 + i32.const 4 + i32.add + local.set $0 + br $while-continue|0 + end + end + global.get $~lib/rt/itcms/iter + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + loop $while-continue|2 + local.get $0 + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $1 + local.get $0 + i32.load offset=4 + local.tee $2 + i32.const 3 + i32.and + i32.ne + if + local.get $0 + local.get $2 + i32.const -4 + i32.and + local.get $1 + i32.or + i32.store offset=4 + local.get $0 + i32.const 20 + i32.add + call $~lib/rt/__visit_members + end + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + local.set $0 + br $while-continue|2 + end + end + global.get $~lib/rt/itcms/fromSpace + local.set $0 + global.get $~lib/rt/itcms/toSpace + global.set $~lib/rt/itcms/fromSpace + local.get $0 + global.set $~lib/rt/itcms/toSpace + local.get $1 + global.set $~lib/rt/itcms/white + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + global.set $~lib/rt/itcms/iter + i32.const 2 + global.set $~lib/rt/itcms/state + end + global.get $~lib/rt/itcms/visitCount + return + end + global.get $~lib/rt/itcms/iter + local.tee $0 + global.get $~lib/rt/itcms/toSpace + i32.ne + if + local.get $0 + i32.load offset=4 + local.tee $1 + i32.const -4 + i32.and + global.set $~lib/rt/itcms/iter + global.get $~lib/rt/itcms/white + i32.eqz + local.get $1 + i32.const 3 + i32.and + i32.ne + if + i32.const 0 + i32.const 1120 + i32.const 229 + i32.const 20 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 34400 + i32.lt_u + if + local.get $0 + i32.const 0 + i32.store offset=4 + local.get $0 + i32.const 0 + i32.store offset=8 + else + global.get $~lib/rt/itcms/total + local.get $0 + i32.load + i32.const -4 + i32.and + i32.const 4 + i32.add + i32.sub + global.set $~lib/rt/itcms/total + local.get $0 + i32.const 4 + i32.add + local.tee $0 + i32.const 34400 + i32.ge_u + if + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.set $1 + local.get $0 + i32.const 4 + i32.sub + local.set $2 + local.get $0 + i32.const 15 + i32.and + i32.const 1 + local.get $0 + select + if (result i32) + i32.const 1 + else + local.get $2 + i32.load + i32.const 1 + i32.and + end + if + i32.const 0 + i32.const 1392 + i32.const 562 + i32.const 3 + call $~lib/builtins/abort + unreachable + end + local.get $2 + local.get $2 + i32.load + i32.const 1 + i32.or + i32.store + local.get $1 + local.get $2 + call $~lib/rt/tlsf/insertBlock + end + end + i32.const 10 + return + end + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + i32.store offset=4 + global.get $~lib/rt/itcms/toSpace + global.get $~lib/rt/itcms/toSpace + i32.store offset=8 + i32.const 0 + global.set $~lib/rt/itcms/state + end + i32.const 0 + ) + (func $~lib/rt/tlsf/searchBlock (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + local.get $0 + i32.load offset=4 + i32.const -8 + i32.and + local.tee $1 + if (result i32) + local.get $0 + local.get $1 + i32.ctz + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + else + local.get $0 + i32.load + i32.const -2 + i32.and + local.tee $1 + if (result i32) + local.get $0 + local.get $1 + i32.ctz + local.tee $2 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + local.tee $1 + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 347 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $1 + i32.ctz + local.get $2 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + else + i32.const 0 + end + end + ) + (func $~lib/rt/itcms/__new (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.ge_u + if + block $__inlined_func$~lib/rt/itcms/interrupt$69 + i32.const 2048 + local.set $0 + loop $do-loop|0 + local.get $0 + call $~lib/rt/itcms/step + i32.sub + local.set $0 + global.get $~lib/rt/itcms/state + i32.eqz + if + global.get $~lib/rt/itcms/total + i64.extend_i32_u + i64.const 200 + i64.mul + i64.const 100 + i64.div_u + i32.wrap_i64 + i32.const 1024 + i32.add + global.set $~lib/rt/itcms/threshold + br $__inlined_func$~lib/rt/itcms/interrupt$69 + end + local.get $0 + i32.const 0 + i32.gt_s + br_if $do-loop|0 + end + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.sub + i32.const 1024 + i32.lt_u + i32.const 10 + i32.shl + i32.add + global.set $~lib/rt/itcms/threshold + end + end + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + local.tee $1 + call $~lib/rt/tlsf/searchBlock + local.tee $0 + i32.eqz + if + memory.size + local.tee $0 + i32.const 4 + local.get $1 + i32.load offset=1568 + local.get $0 + i32.const 16 + i32.shl + i32.const 4 + i32.sub + i32.ne + i32.shl + i32.const 65595 + i32.add + i32.const -65536 + i32.and + i32.const 16 + i32.shr_u + local.tee $2 + local.get $0 + local.get $2 + i32.gt_s + select + memory.grow + i32.const 0 + i32.lt_s + if + local.get $2 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + local.get $1 + local.get $0 + i32.const 16 + i32.shl + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + local.get $1 + call $~lib/rt/tlsf/searchBlock + local.tee $0 + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 499 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + end + local.get $0 + i32.load + i32.const -4 + i32.and + i32.const 60 + i32.lt_u + if + i32.const 0 + i32.const 1392 + i32.const 501 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + local.get $0 + call $~lib/rt/tlsf/removeBlock + local.get $0 + i32.load + local.tee $2 + i32.const -4 + i32.and + i32.const 60 + i32.sub + local.tee $3 + i32.const 16 + i32.ge_u + if + local.get $0 + local.get $2 + i32.const 2 + i32.and + i32.const 60 + i32.or + i32.store + local.get $0 + i32.const -64 + i32.sub + local.tee $2 + local.get $3 + i32.const 4 + i32.sub + i32.const 1 + i32.or + i32.store + local.get $1 + local.get $2 + call $~lib/rt/tlsf/insertBlock + else + local.get $0 + local.get $2 + i32.const -2 + i32.and + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $0 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $1 + local.get $1 + i32.load + i32.const -3 + i32.and + i32.store + end + local.get $0 + i32.const 4 + i32.store offset=12 + local.get $0 + i32.const 32 + i32.store offset=16 + global.get $~lib/rt/itcms/fromSpace + local.tee $1 + i32.load offset=8 + local.set $2 + local.get $0 + local.get $1 + global.get $~lib/rt/itcms/white + i32.or + i32.store offset=4 + local.get $0 + local.get $2 + i32.store offset=8 + local.get $2 + local.get $0 + local.get $2 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + local.get $1 + local.get $0 + i32.store offset=8 + global.get $~lib/rt/itcms/total + local.get $0 + i32.load + i32.const -4 + i32.and + i32.const 4 + i32.add + i32.add + global.set $~lib/rt/itcms/total + local.get $0 + i32.const 20 + i32.add + local.tee $0 + i32.const 0 + i32.const 32 + memory.fill + local.get $0 + ) + (func $~lib/rt/__visit_members (param $0 i32) + block $invalid + block $multiple-interfaces/YZ + block $multiple-interfaces/Z + block $multiple-interfaces/XZ + block $multiple-interfaces/Y + block $multiple-interfaces/XY + block $multiple-interfaces/Vec3 + block $multiple-interfaces/X + block $multiple-interfaces/W + block $multiple-interfaces/WX + block $multiple-interfaces/Vec4 + block $multiple-interfaces/Vec4TheClass + block $~lib/arraybuffer/ArrayBufferView + block $~lib/string/String + block $~lib/arraybuffer/ArrayBuffer + block $~lib/object/Object + local.get $0 + i32.const 8 + i32.sub + i32.load + br_table $~lib/object/Object $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $multiple-interfaces/Vec4TheClass $multiple-interfaces/Vec4 $multiple-interfaces/WX $multiple-interfaces/W $multiple-interfaces/X $multiple-interfaces/Vec3 $multiple-interfaces/XY $multiple-interfaces/Y $multiple-interfaces/XZ $multiple-interfaces/Z $multiple-interfaces/YZ $invalid + end + return + end + return + end + return + end + local.get $0 + i32.load + local.tee $0 + if + local.get $0 + call $~lib/rt/itcms/__visit + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + return + end + unreachable + ) + (func $~start + (local $0 i32) + (local $1 f64) + (local $2 f64) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 1632 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + memory.size + i32.const 16 + i32.shl + i32.const 34400 + i32.sub + i32.const 1 + i32.shr_u + global.set $~lib/rt/itcms/threshold + i32.const 1172 + i32.const 1168 + i32.store + i32.const 1176 + i32.const 1168 + i32.store + i32.const 1168 + global.set $~lib/rt/itcms/pinSpace + i32.const 1204 + i32.const 1200 + i32.store + i32.const 1208 + i32.const 1200 + i32.store + i32.const 1200 + global.set $~lib/rt/itcms/toSpace + i32.const 1348 + i32.const 1344 + i32.store + i32.const 1352 + i32.const 1344 + i32.store + i32.const 1344 + global.set $~lib/rt/itcms/fromSpace + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1632 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + f64.const 1 + f64.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + f64.const 2 + f64.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + f64.const 3 + f64.store offset=16 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + f64.const 4 + f64.store offset=24 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $multiple-interfaces/vec4 + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/anotherVec4 + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/anotherVec4 + local.tee $0 + i32.store + block $__inlined_func$multiple-interfaces/W#get:w@override$118 + local.get $0 + i32.const 8 + i32.sub + i32.load + i32.const 4 + i32.eq + if + local.get $0 + f64.load + local.set $1 + br $__inlined_func$multiple-interfaces/W#get:w@override$118 + end + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/vec4 + local.tee $0 + i32.store + local.get $1 + local.get $0 + f64.load + f64.ne + if + i32.const 0 + i32.const 1456 + i32.const 49 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/y + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/y + local.tee $0 + i32.store + block $__inlined_func$multiple-interfaces/Y#get:y@override$120 + local.get $0 + i32.const 8 + i32.sub + i32.load + i32.const 4 + i32.eq + if + local.get $0 + f64.load offset=16 + local.set $1 + br $__inlined_func$multiple-interfaces/Y#get:y@override$120 + end + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/vec4 + local.tee $0 + i32.store + local.get $1 + local.get $0 + f64.load offset=16 + f64.ne + if + i32.const 0 + i32.const 1456 + i32.const 52 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/yz + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/yz + local.tee $0 + i32.store + block $__inlined_func$multiple-interfaces/Z#get:z@override$122 + local.get $0 + i32.const 8 + i32.sub + i32.load + i32.const 4 + i32.eq + if + local.get $0 + f64.load offset=24 + local.set $1 + br $__inlined_func$multiple-interfaces/Z#get:z@override$122 + end + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/vec4 + local.tee $0 + i32.store + local.get $1 + local.get $0 + f64.load offset=24 + f64.ne + if + i32.const 0 + i32.const 1456 + i32.const 55 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $multiple-interfaces/vec4 + global.set $multiple-interfaces/vec3 + global.get $multiple-interfaces/vec3 + global.set $multiple-interfaces/x + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/vec3 + local.tee $0 + i32.store + block $__inlined_func$multiple-interfaces/X#get:x@override$124 + local.get $0 + i32.const 8 + i32.sub + i32.load + i32.const 4 + i32.eq + if + local.get $0 + f64.load offset=8 + local.set $1 + br $__inlined_func$multiple-interfaces/X#get:x@override$124 + end + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/x + local.tee $0 + i32.store + block $__inlined_func$multiple-interfaces/X#get:x@override$125 + local.get $0 + i32.const 8 + i32.sub + i32.load + i32.const 4 + i32.eq + if + local.get $0 + f64.load offset=8 + local.set $2 + br $__inlined_func$multiple-interfaces/X#get:x@override$125 + end + unreachable + end + local.get $1 + local.get $2 + f64.ne + if + i32.const 0 + i32.const 1456 + i32.const 59 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + block $__inlined_func$~instanceof|multiple-interfaces/Vec4$126 (result i32) + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/vec3 + local.tee $0 + i32.store offset=4 + i32.const 0 + local.get $0 + i32.const 8 + i32.sub + i32.load + i32.const 4 + i32.ne + br_if $__inlined_func$~instanceof|multiple-interfaces/Vec4$126 + drop + i32.const 1 + end + i32.eqz + if + i32.const 1520 + i32.const 1456 + i32.const 62 + i32.const 12 + call $~lib/builtins/abort + unreachable + end + local.get $0 + global.set $multiple-interfaces/wx + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/wx + local.tee $0 + i32.store + block $__inlined_func$multiple-interfaces/W#get:w@override$127 + local.get $0 + i32.const 8 + i32.sub + i32.load + i32.const 4 + i32.eq + if + local.get $0 + f64.load + local.set $1 + br $__inlined_func$multiple-interfaces/W#get:w@override$127 + end + unreachable + end + global.get $~lib/memory/__stack_pointer + global.get $multiple-interfaces/vec4 + local.tee $0 + i32.store + local.get $1 + local.get $0 + f64.load + f64.ne + if + i32.const 0 + i32.const 1456 + i32.const 63 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + return + end + i32.const 34432 + i32.const 34480 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + ) +) diff --git a/tests/compiler/multiple-interfaces.ts b/tests/compiler/multiple-interfaces.ts new file mode 100644 index 0000000000..2aa95dbad0 --- /dev/null +++ b/tests/compiler/multiple-interfaces.ts @@ -0,0 +1,63 @@ +interface W { + w: f64 +} + +interface X { + x: f64 +} + +interface Y { + y: f64 +} + +interface Z { + z: f64 +} + +// WX XY XZ YZ +// | \__|__/ +// | | +// | Vec3 +// \_____| +// Vec4 + +interface WX extends W, X {} +interface XY extends X, Y {} +interface XZ extends X, Z {} +interface YZ extends Y, Z {} + +interface Vec3 extends XY, XZ, YZ {} + +/** + * Who needs a regular old Vec3, when you can have a Vec4? + * Vec3 is overused anyway :^) + */ +interface Vec4 extends WX, Vec3 {} + +class Vec4TheClass implements Vec4 { + constructor( + public w: f64, + public x: f64, + public y: f64, + public z: f64 + ) {} +} + +const vec4 = new Vec4TheClass(1, 2, 3, 4); + +const anotherVec4: Vec4 = vec4; +assert(anotherVec4.w == vec4.w); + +const y: Y = vec4; +assert(y.y == vec4.y); + +const yz: YZ = vec4; +assert(yz.z == vec4.z); + +const vec3: Vec3 = vec4; +const x: X = vec3; +assert(vec3.x == x.x); + +// Up-cast, down-cast, left-cast, right-cast +const wx = vec3 as Vec4 as WX; +assert(wx.w == vec4.w); \ No newline at end of file