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 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