From f6683d6897cad33eca315c4d19260842a58dbc96 Mon Sep 17 00:00:00 2001 From: BlobMaster41 <96896824+BlobMaster41@users.noreply.github.com> Date: Fri, 12 Dec 2025 02:10:26 -0500 Subject: [PATCH] Refactor closure capture analysis and recompilation logic Replaces the pre-scan approach for closure variable capture with a single-pass, on-demand capture analysis that supports late discovery and recompilation of function bodies when captures are detected after initial compilation. This change simplifies closure handling, ensures correct environment slot assignment, and improves support for complex nested closure scenarios. Updates related logic for local variable tracking, anonymous function naming, and closure environment allocation. --- src/compiler.ts | 1136 ++-- src/program.ts | 7 +- tests/compiler/closure-class.debug.wat | 68 +- tests/compiler/closure-class.release.wat | 54 +- tests/compiler/closure-complex.debug.wat | 5800 ++++++++++++++++++++ tests/compiler/closure-complex.json | 5 + tests/compiler/closure-complex.release.wat | 4360 +++++++++++++++ tests/compiler/closure-complex.ts | 279 + tests/compiler/closure-stress.debug.wat | 128 +- tests/compiler/closure-stress.release.wat | 128 +- tests/compiler/closure.debug.wat | 141 +- tests/compiler/closure.release.wat | 212 +- 12 files changed, 11138 insertions(+), 1180 deletions(-) create mode 100644 tests/compiler/closure-complex.debug.wat create mode 100644 tests/compiler/closure-complex.json create mode 100644 tests/compiler/closure-complex.release.wat create mode 100644 tests/compiler/closure-complex.ts diff --git a/src/compiler.ts b/src/compiler.ts index 0e2742e33f..bf2f2c2d3e 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1774,78 +1774,11 @@ export class Compiler extends DiagnosticEmitter { : null; let bodyStartIndex = stmts.length; - // Pre-scan the body to identify captured variables before compiling - // This ensures we know which locals need to be stored in the environment - this.prescanForClosures(bodyNode, instance, flow); - - // Mark captured parameters and set up environment if needed - let preCapturedNames = instance.preCapturedNames; - if (preCapturedNames && preCapturedNames.size > 0) { - // Check if any parameters are captured - for (let i = 0, k = instance.signature.parameterTypes.length; i < k; i++) { - let paramName = instance.getParameterName(i); - if (preCapturedNames.has(paramName)) { - let local = flow.lookupLocal(paramName); - if (local && !local.isCaptured) { - local.isCaptured = true; - // Ensure environment structures are set up - let capturedLocals = instance.capturedLocals; - if (!capturedLocals) { - capturedLocals = new Map(); - instance.capturedLocals = capturedLocals; - } - if (!capturedLocals.has(local)) { - // Calculate proper byte offset with alignment - // Reserve slot 0 for parent environment pointer (4 or 8 bytes depending on wasm32/64) - let currentOffset = this.options.usizeType.byteSize; // Start after parent pointer slot - for (let _keys = Map_keys(capturedLocals), j = 0, m = _keys.length; j < m; ++j) { - let existingLocal = _keys[j]; - let endOfSlot = existingLocal.envSlotIndex + existingLocal.type.byteSize; - if (endOfSlot > currentOffset) currentOffset = endOfSlot; - } - // Align to the type's natural alignment - let align = local.type.byteSize; - currentOffset = (currentOffset + align - 1) & ~(align - 1); - local.envSlotIndex = currentOffset; - local.envOwner = instance; // Track which function owns this capture - capturedLocals.set(local, local.envSlotIndex); - } - if (!instance.envLocal) { - instance.envLocal = flow.addScopedLocal("$env", this.options.usizeType); - } - } - } - } + // Track locals before body compilation for potential recompilation + let numLocalsBeforeBody = instance.localsByIndex.length; - // Also check if 'this' is captured (for methods) - if (preCapturedNames.has(CommonNames.this_)) { - let thisLocal = flow.lookupLocal(CommonNames.this_); - if (thisLocal && !thisLocal.isCaptured) { - thisLocal.isCaptured = true; - let capturedLocals = instance.capturedLocals; - if (!capturedLocals) { - capturedLocals = new Map(); - instance.capturedLocals = capturedLocals; - } - if (!capturedLocals.has(thisLocal)) { - let currentOffset = this.options.usizeType.byteSize; - for (let _keys = Map_keys(capturedLocals), j = 0, m = _keys.length; j < m; ++j) { - let existingLocal = _keys[j]; - let endOfSlot = existingLocal.envSlotIndex + existingLocal.type.byteSize; - if (endOfSlot > currentOffset) currentOffset = endOfSlot; - } - let align = thisLocal.type.byteSize; - currentOffset = (currentOffset + align - 1) & ~(align - 1); - thisLocal.envSlotIndex = currentOffset; - thisLocal.envOwner = instance; - capturedLocals.set(thisLocal, thisLocal.envSlotIndex); - } - if (!instance.envLocal) { - instance.envLocal = flow.addScopedLocal("$env", this.options.usizeType); - } - } - } - } + // Track anonymous function counter for potential recompilation + let nextAnonymousIdBeforeBody = instance.nextAnonymousId; // For closures (functions that capture from outer scope), create a local to cache // the environment pointer. This is needed because indirect calls to other closures @@ -1854,6 +1787,33 @@ export class Compiler extends DiagnosticEmitter { instance.closureEnvLocal = flow.addScopedLocal("$closureEnv", this.options.usizeType); } + // On recompilation, mark parameters that are known to be captured from previous pass + let capturedLocals = instance.capturedLocals; + if (capturedLocals && capturedLocals.size > 0) { + // Mark captured parameters and 'this' - they exist before body compilation + let hasOwnCapturedLocals = false; + for (let _keys = Map_keys(capturedLocals), i = 0, k = _keys.length; i < k; i++) { + let capturedLocal = _keys[i]; + // Only handle parameters/this (they belong to this function) + if (capturedLocal.parent == instance) { + let localInFlow = flow.lookupLocal(capturedLocal.name); + if (localInFlow && !localInFlow.isCaptured) { + localInFlow.isCaptured = true; + localInFlow.envSlotIndex = capturedLocal.envSlotIndex; + localInFlow.envOwner = capturedLocal.envOwner; + } + } + // Check if this instance owns any captured variables (needs envLocal) + if (capturedLocal.envOwner == instance) { + hasOwnCapturedLocals = true; + } + } + // Only create envLocal if this function owns some captured variables + if (hasOwnCapturedLocals && !instance.envLocal) { + instance.envLocal = flow.addScopedLocal("$env", this.options.usizeType); + } + } + // compile statements if (bodyNode.kind == NodeKind.Block) { stmts = this.compileStatements((bodyNode).statements, stmts); @@ -1881,9 +1841,97 @@ export class Compiler extends DiagnosticEmitter { } } + // Check if recompilation is needed due to late capture discovery + if (instance.needsCaptureRecompile) { + // Reset state for recompilation + instance.needsCaptureRecompile = false; + + // Reset stmts to before body compilation + stmts.length = bodyStartIndex; + + // Reset locals to before body compilation + let localsByIndex = instance.localsByIndex; + for (let i = numLocalsBeforeBody, k = localsByIndex.length; i < k; i++) { + localsByIndex[i].wasAccessedAsLocal = false; + } + localsByIndex.length = numLocalsBeforeBody; + + // Reset flow flags + flow.localFlags.length = numLocalsBeforeBody; + flow.unset( + FlowFlags.Returns | + FlowFlags.ReturnsWrapped | + FlowFlags.ReturnsNonNull | + FlowFlags.Terminates | + FlowFlags.Breaks | + FlowFlags.Continues | + FlowFlags.AccessesThis | + FlowFlags.ConditionallyAccessesThis | + FlowFlags.CallsSuper | + FlowFlags.MayReturnNonThis + ); + + // Clear scoped locals added during body compilation + // Keep only parameters and 'this' which exist before body compilation + let scopedLocals = flow.scopedLocals; + if (scopedLocals) { + let signature = instance.signature; + let numParams = signature.parameterTypes.length; + let hasThis = signature.thisType != null; + let keysToDelete = new Array(); + for (let _keys = Map_keys(scopedLocals), i = 0, k = _keys.length; i < k; i++) { + let name = _keys[i]; + let local = assert(scopedLocals.get(name)); + // Keep parameters and 'this', but remove body-scoped locals + let isParam = local.index >= (hasThis ? 1 : 0) && local.index < numParams + (hasThis ? 1 : 0); + let isThis = hasThis && local.index == 0; + let isEnvLocal = local == instance.envLocal || local == instance.closureEnvLocal; + if (!isParam && !isThis && !isEnvLocal) { + keysToDelete.push(name); + } + } + for (let i = 0, k = keysToDelete.length; i < k; i++) { + scopedLocals.delete(keysToDelete[i]); + } + } + + // Clear envLocal so it gets recreated with a valid index + // The old envLocal's index is invalid after localsByIndex truncation + if (instance.envLocal) { + let scopedLocals = flow.scopedLocals; + if (scopedLocals && scopedLocals.has("$env")) { + scopedLocals.delete("$env"); + } + instance.envLocal = null; + } + + // Also clear closureEnvLocal so it gets recreated with a valid index + if (instance.closureEnvLocal) { + let scopedLocals = flow.scopedLocals; + if (scopedLocals && scopedLocals.has("$closureEnv")) { + scopedLocals.delete("$closureEnv"); + } + instance.closureEnvLocal = null; + } + + // Clear wasAccessedAsLocal on parameters that will be marked captured + capturedLocals = instance.capturedLocals; + if (capturedLocals) { + for (let _keys = Map_keys(capturedLocals), i = 0, k = _keys.length; i < k; i++) { + _keys[i].wasAccessedAsLocal = false; + } + } + + // Reset anonymous ID counter so inner functions get the same IDs + instance.nextAnonymousId = nextAnonymousIdBeforeBody; + + // Recursively recompile - captures are now known + return this.compileFunctionBody(instance, stmts); + } + // Allocate closure environment if this function has captured variables // This is done after compiling the body because we discover captures during body compilation - let capturedLocals = instance.capturedLocals; + capturedLocals = instance.capturedLocals; if (instance.envLocal && capturedLocals && capturedLocals.size > 0) { let envAlloc = this.compileClosureEnvironmentAllocation(instance); // Insert at the beginning of the body @@ -3322,39 +3370,25 @@ export class Compiler extends DiagnosticEmitter { if (isConst) flow.setLocalFlag(local.index, LocalFlags.Constant); } - // Check if this local is pre-marked as captured by a closure + // On recompilation, check if this local matches a known captured variable + // (captures are discovered during first pass when compiling inner functions) let sourceFunc = flow.sourceFunction; - let preCapturedNames = sourceFunc.preCapturedNames; - if (preCapturedNames && preCapturedNames.has(name)) { - local.isCaptured = true; - // Ensure we have a closure environment for this function - let capturedLocals = sourceFunc.capturedLocals; - if (!capturedLocals) { - capturedLocals = new Map(); - sourceFunc.capturedLocals = capturedLocals; - } - if (!capturedLocals.has(local)) { - // Calculate proper byte offset based on current environment size with alignment - // Reserve slot 0 for parent environment pointer (4 or 8 bytes depending on wasm32/64) - let ptrSize = this.options.usizeType.byteSize; - let currentOffset = ptrSize; // Start after parent pointer slot - for (let _keys = Map_keys(capturedLocals), i = 0, k = _keys.length; i < k; ++i) { - let existingLocal = _keys[i]; - let endOfSlot = existingLocal.envSlotIndex + existingLocal.type.byteSize; - if (endOfSlot > currentOffset) currentOffset = endOfSlot; + let capturedLocals = sourceFunc.capturedLocals; + if (capturedLocals) { + // Look for a captured local with matching name and parent + for (let _keys = Map_keys(capturedLocals), i = 0, k = _keys.length; i < k; ++i) { + let capturedLocal = _keys[i]; + if (capturedLocal.name == name && capturedLocal.parent == sourceFunc) { + // Found a match - copy capture info to the new local + local.isCaptured = true; + local.envSlotIndex = capturedLocal.envSlotIndex; + local.envOwner = capturedLocal.envOwner; + // Replace the old local in capturedLocals with the new one + let slotIndex = capturedLocals.get(capturedLocal) as i32; + capturedLocals.delete(capturedLocal); + capturedLocals.set(local, slotIndex); + break; } - // Align to the type's natural alignment - let typeSize = local.type.byteSize; - let align = typeSize; - currentOffset = (currentOffset + align - 1) & ~(align - 1); - local.envSlotIndex = currentOffset; - local.envOwner = sourceFunc; // Track which function owns this capture - capturedLocals.set(local, local.envSlotIndex); - } - // Ensure we have an environment local - if (!sourceFunc.envLocal) { - let envLocal = flow.addScopedLocal("$env", this.options.usizeType); - sourceFunc.envLocal = envLocal; } } @@ -6198,6 +6232,11 @@ export class Compiler extends DiagnosticEmitter { if (!flow.canOverflow(valueExpr, type)) flow.setLocalFlag(localIndex, LocalFlags.Wrapped); else flow.unsetLocalFlag(localIndex, LocalFlags.Wrapped); } + + // Track that we accessed this as a regular local (for closure recompilation detection) + // Only set if not already captured (to avoid infinite recompilation loops) + if (!local.isCaptured) local.wasAccessedAsLocal = true; + if (tee) { // local = value this.currentType = type; return module.local_tee(localIndex, valueExpr, type.isManaged); @@ -7431,14 +7470,45 @@ export class Compiler extends DiagnosticEmitter { let sourceFunction = flow.sourceFunction; let isNamed = declaration.name.text.length > 0; let isSemanticallyAnonymous = !isNamed || contextualType != Type.void; - let prototype = new FunctionPrototype( - isSemanticallyAnonymous - ? `${isNamed ? declaration.name.text : "anonymous"}|${sourceFunction.nextAnonymousId++}` - : declaration.name.text, - sourceFunction, - declaration, - DecoratorFlags.None - ); + + // Generate the name for this anonymous/named function + let functionName = isSemanticallyAnonymous + ? `${isNamed ? declaration.name.text : "anonymous"}|${sourceFunction.nextAnonymousId++}` + : declaration.name.text; + + // During recompilation, check if this function already exists + // Check in program.instancesByName using the internal name that would be generated + let expectedInternalName = mangleInternalName(functionName, sourceFunction, false); + let existingInstance = this.program.instancesByName.get(expectedInternalName); + if (existingInstance && existingInstance.kind == ElementKind.Function) { + let existingFunc = existingInstance; + if (existingFunc.is(CommonFlags.Compiled)) { + // Already compiled - just return a reference to it + let offset = this.ensureRuntimeFunction(existingFunc); + let capturedLocals = existingFunc.capturedLocals; + if (capturedLocals && capturedLocals.size > 0) { + return this.compileClosureFunctionCreation(existingFunc, sourceFunction); + } + this.currentType = existingFunc.signature.type; + let expr = this.options.isWasm64 + ? this.module.i64(i64_low(offset), i64_high(offset)) + : this.module.i32(i64_low(offset)); + return expr; + } + } + + // Reuse existing prototype if available (during recompilation), otherwise create new + let prototype: FunctionPrototype; + if (existingInstance && existingInstance.kind == ElementKind.Function) { + prototype = (existingInstance).prototype; + } else { + prototype = new FunctionPrototype( + functionName, + sourceFunction, + declaration, + DecoratorFlags.None + ); + } let instance: Function | null; let contextualTypeArguments = cloneMap(flow.contextualTypeArguments); let module = this.module; @@ -7554,7 +7624,7 @@ export class Compiler extends DiagnosticEmitter { } instance.capturedLocals = captures; instance.outerFunction = sourceFunction; - this.ensureClosureEnvironment(sourceFunction, captures, flow); + this.ensureClosureEnvironmentsForCaptures(captures, flow); } let worked = this.compileFunction(instance); @@ -7580,7 +7650,7 @@ export class Compiler extends DiagnosticEmitter { } instance.capturedLocals = captures; instance.outerFunction = sourceFunction; - this.ensureClosureEnvironment(sourceFunction, captures, flow); + this.ensureClosureEnvironmentsForCaptures(captures, flow); } let worked = this.compileFunction(instance); @@ -7633,21 +7703,12 @@ export class Compiler extends DiagnosticEmitter { // === Closure Support ========================================================================== /** Scans a node and its children for captured variables from outer scopes. - * - * This function supports two modes: - * 1. Local mode (captures provided): Resolves names to Local objects and calculates slot indices. - * Used when compiling function expressions where outer function's locals already exist. - * 2. Name mode (capturedNames provided): Collects just variable names for later resolution. - * Used during prescan when the function body hasn't been compiled yet. - * In this mode, declaredVars contains pre-scanned variable names from the outer function. - */ + * Resolves names to Local objects and calculates slot indices. */ private scanNodeForCaptures( node: Node, outerFlow: Flow, innerFunctionNames: Set, - captures: Map | null, - capturedNames: Set | null = null, - declaredVars: Map | null = null + captures: Map ): void { switch (node.kind) { case NodeKind.Identifier: { @@ -7656,40 +7717,55 @@ export class Compiler extends DiagnosticEmitter { // Skip identifiers that are parameters/locals of inner functions if (innerFunctionNames.has(name)) break; - if (captures) { - // Local mode: resolve to Local and calculate slot index - let local = outerFlow.lookupLocal(name); - if (!local) { - local = outerFlow.lookupLocalInOuter(name); + // Resolve to Local and calculate slot index + let local = outerFlow.lookupLocal(name); + if (!local) { + local = outerFlow.lookupLocalInOuter(name); + } + if (local && !captures.has(local)) { + local.isCaptured = true; + if (!local.envOwner) { + local.envOwner = local.parent; } - if (local && !captures.has(local)) { - local.isCaptured = true; - if (!local.envOwner) { - local.envOwner = local.parent; - } - if (local.envSlotIndex >= 0) { - captures.set(local, local.envSlotIndex); - } else { - // Calculate proper byte offset with alignment - let ptrSize = this.options.usizeType.byteSize; - let currentOffset = ptrSize; - for (let _keys = Map_keys(captures), idx = 0, cnt = _keys.length; idx < cnt; ++idx) { + // Check if local was accessed before capture was discovered - need recompilation + if (local.wasAccessedAsLocal) { + let ownerFunc = local.parent; + ownerFunc.needsCaptureRecompile = true; + } + if (local.envSlotIndex >= 0) { + captures.set(local, local.envSlotIndex); + } else { + // Calculate proper byte offset with alignment + // Consider both current captures AND the outer function's existing captures + let ptrSize = this.options.usizeType.byteSize; + let currentOffset = ptrSize; + // First check existing captured locals on the outer function + // Only consider locals that belong to the SAME envOwner + let envOwner = local.envOwner; + if (envOwner && envOwner.capturedLocals) { + let existingCaptures = changetype>(envOwner.capturedLocals); + for (let _keys = Map_keys(existingCaptures), idx = 0, cnt = _keys.length; idx < cnt; ++idx) { let existingLocal = _keys[idx]; + // Only consider locals owned by the same function + if (existingLocal.envOwner == envOwner && existingLocal.envSlotIndex >= 0) { + let endOfSlot = existingLocal.envSlotIndex + existingLocal.type.byteSize; + if (endOfSlot > currentOffset) currentOffset = endOfSlot; + } + } + } + // Then check locals in current captures map that belong to the same envOwner + for (let _keys = Map_keys(captures), idx = 0, cnt = _keys.length; idx < cnt; ++idx) { + let existingLocal = _keys[idx]; + if (existingLocal.envOwner == envOwner && existingLocal.envSlotIndex >= 0) { let endOfSlot = existingLocal.envSlotIndex + existingLocal.type.byteSize; if (endOfSlot > currentOffset) currentOffset = endOfSlot; } - let typeSize = local.type.byteSize; - let align = typeSize; - currentOffset = (currentOffset + align - 1) & ~(align - 1); - local.envSlotIndex = currentOffset; - captures.set(local, local.envSlotIndex); } - } - } else if (capturedNames) { - // Name mode: collect name if it's from outer scope - let isFromOuter = (declaredVars != null && declaredVars.has(name)) || outerFlow.lookupLocal(name) != null; - if (isFromOuter) { - capturedNames.add(name); + let typeSize = local.type.byteSize; + let align = typeSize; + currentOffset = (currentOffset + align - 1) & ~(align - 1); + local.envSlotIndex = currentOffset; + captures.set(local, local.envSlotIndex); } } break; @@ -7700,34 +7776,50 @@ export class Compiler extends DiagnosticEmitter { if (!local) { local = outerFlow.lookupLocalInOuter(CommonNames.this_); } - if (captures) { - // Local mode - if (local && !captures.has(local)) { - local.isCaptured = true; - if (!local.envOwner) { - local.envOwner = local.parent; - } - if (local.envSlotIndex >= 0) { - captures.set(local, local.envSlotIndex); - } else { - let ptrSize = this.options.usizeType.byteSize; - let currentOffset = ptrSize; - for (let _keys = Map_keys(captures), idx = 0, cnt = _keys.length; idx < cnt; ++idx) { + if (local && !captures.has(local)) { + local.isCaptured = true; + if (!local.envOwner) { + local.envOwner = local.parent; + } + // Check if local was accessed before capture was discovered - need recompilation + if (local.wasAccessedAsLocal) { + let ownerFunc = local.parent; + ownerFunc.needsCaptureRecompile = true; + } + if (local.envSlotIndex >= 0) { + captures.set(local, local.envSlotIndex); + } else { + // Calculate proper byte offset with alignment + // Consider both current captures AND the outer function's existing captures + let ptrSize = this.options.usizeType.byteSize; + let currentOffset = ptrSize; + // First check existing captured locals on the outer function + // Only consider locals that belong to the SAME envOwner + let envOwner = local.envOwner; + if (envOwner && envOwner.capturedLocals) { + let existingCaptures = changetype>(envOwner.capturedLocals); + for (let _keys = Map_keys(existingCaptures), idx = 0, cnt = _keys.length; idx < cnt; ++idx) { let existingLocal = _keys[idx]; + // Only consider locals owned by the same function + if (existingLocal.envOwner == envOwner && existingLocal.envSlotIndex >= 0) { + let endOfSlot = existingLocal.envSlotIndex + existingLocal.type.byteSize; + if (endOfSlot > currentOffset) currentOffset = endOfSlot; + } + } + } + // Then check locals in current captures map that belong to the same envOwner + for (let _keys = Map_keys(captures), idx = 0, cnt = _keys.length; idx < cnt; ++idx) { + let existingLocal = _keys[idx]; + if (existingLocal.envOwner == envOwner && existingLocal.envSlotIndex >= 0) { let endOfSlot = existingLocal.envSlotIndex + existingLocal.type.byteSize; if (endOfSlot > currentOffset) currentOffset = endOfSlot; } - let typeSize = local.type.byteSize; - let align = typeSize; - currentOffset = (currentOffset + align - 1) & ~(align - 1); - local.envSlotIndex = currentOffset; - captures.set(local, local.envSlotIndex); } - } - } else if (capturedNames) { - // Name mode - if (local) { - capturedNames.add(CommonNames.this_); + let typeSize = local.type.byteSize; + let align = typeSize; + currentOffset = (currentOffset + align - 1) & ~(align - 1); + local.envSlotIndex = currentOffset; + captures.set(local, local.envSlotIndex); } } break; @@ -7741,7 +7833,7 @@ export class Compiler extends DiagnosticEmitter { for (let i = 0, k = params.length; i < k; i++) { let paramInit = params[i].initializer; if (paramInit) { - this.scanNodeForCaptures(paramInit, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(paramInit, outerFlow, innerFunctionNames, captures); } } for (let i = 0, k = params.length; i < k; i++) { @@ -7749,7 +7841,7 @@ export class Compiler extends DiagnosticEmitter { } let declBody = decl.body; if (declBody) { - this.scanNodeForCaptures(declBody, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(declBody, outerFlow, innerFunctionNames, captures); } for (let i = 0, k = params.length; i < k; i++) { innerFunctionNames.delete(params[i].name.text); @@ -7759,21 +7851,21 @@ export class Compiler extends DiagnosticEmitter { // Expression nodes case NodeKind.Assertion: { let expr = node; - this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Binary: { let expr = node; - this.scanNodeForCaptures(expr.left, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(expr.right, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.left, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(expr.right, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Call: { let expr = node; - this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures); let args = expr.args; for (let i = 0, k = args.length; i < k; i++) { - this.scanNodeForCaptures(args[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(args[i], outerFlow, innerFunctionNames, captures); } break; } @@ -7781,7 +7873,7 @@ export class Compiler extends DiagnosticEmitter { let expr = node; let expressions = expr.expressions; for (let i = 0, k = expressions.length; i < k; i++) { - this.scanNodeForCaptures(expressions[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expressions[i], outerFlow, innerFunctionNames, captures); } break; } @@ -7793,20 +7885,20 @@ export class Compiler extends DiagnosticEmitter { for (let i = 0, k = elements.length; i < k; i++) { let elem = elements[i]; if (elem) { - this.scanNodeForCaptures(elem, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(elem, outerFlow, innerFunctionNames, captures); } } } else if (literal.literalKind == LiteralKind.Object) { let objLiteral = literal; let values = objLiteral.values; for (let i = 0, k = values.length; i < k; i++) { - this.scanNodeForCaptures(values[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(values[i], outerFlow, innerFunctionNames, captures); } } else if (literal.literalKind == LiteralKind.Template) { let tmplLiteral = literal; let expressions = tmplLiteral.expressions; for (let i = 0, k = expressions.length; i < k; i++) { - this.scanNodeForCaptures(expressions[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expressions[i], outerFlow, innerFunctionNames, captures); } } // Other literal kinds (Integer, Float, String, RegExp) have no variable refs @@ -7814,49 +7906,49 @@ export class Compiler extends DiagnosticEmitter { } case NodeKind.ElementAccess: { let expr = node; - this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(expr.elementExpression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(expr.elementExpression, outerFlow, innerFunctionNames, captures); break; } case NodeKind.New: { let expr = node; - this.scanNodeForCaptures(expr.typeName, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.typeName, outerFlow, innerFunctionNames, captures); let args = expr.args; for (let i = 0, k = args.length; i < k; i++) { - this.scanNodeForCaptures(args[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(args[i], outerFlow, innerFunctionNames, captures); } break; } case NodeKind.Parenthesized: { let expr = node; - this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures); break; } case NodeKind.PropertyAccess: { let expr = node; - this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Ternary: { let expr = node; - this.scanNodeForCaptures(expr.condition, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(expr.ifThen, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(expr.ifElse, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.condition, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(expr.ifThen, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(expr.ifElse, outerFlow, innerFunctionNames, captures); break; } case NodeKind.UnaryPostfix: { let expr = node; - this.scanNodeForCaptures(expr.operand, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.operand, outerFlow, innerFunctionNames, captures); break; } case NodeKind.UnaryPrefix: { let expr = node; - this.scanNodeForCaptures(expr.operand, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.operand, outerFlow, innerFunctionNames, captures); break; } case NodeKind.InstanceOf: { let expr = node; - this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(expr.expression, outerFlow, innerFunctionNames, captures); break; } // Statement nodes @@ -7864,19 +7956,19 @@ export class Compiler extends DiagnosticEmitter { let stmt = node; let statements = stmt.statements; for (let i = 0, k = statements.length; i < k; i++) { - this.scanNodeForCaptures(statements[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(statements[i], outerFlow, innerFunctionNames, captures); } break; } case NodeKind.Do: { let stmt = node; - this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Expression: { let stmt = node; - this.scanNodeForCaptures(stmt.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.expression, outerFlow, innerFunctionNames, captures); break; } case NodeKind.For: { @@ -7884,69 +7976,69 @@ export class Compiler extends DiagnosticEmitter { let forInit = stmt.initializer; let forCond = stmt.condition; let forIncr = stmt.incrementor; - if (forInit) this.scanNodeForCaptures(forInit, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - if (forCond) this.scanNodeForCaptures(forCond, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - if (forIncr) this.scanNodeForCaptures(forIncr, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + if (forInit) this.scanNodeForCaptures(forInit, outerFlow, innerFunctionNames, captures); + if (forCond) this.scanNodeForCaptures(forCond, outerFlow, innerFunctionNames, captures); + if (forIncr) this.scanNodeForCaptures(forIncr, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures); break; } case NodeKind.ForOf: { let stmt = node; - this.scanNodeForCaptures(stmt.variable, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(stmt.iterable, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.variable, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(stmt.iterable, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures); break; } case NodeKind.If: { let stmt = node; - this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(stmt.ifTrue, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(stmt.ifTrue, outerFlow, innerFunctionNames, captures); let ifFalse = stmt.ifFalse; - if (ifFalse) this.scanNodeForCaptures(ifFalse, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + if (ifFalse) this.scanNodeForCaptures(ifFalse, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Return: { let stmt = node; let retValue = stmt.value; - if (retValue) this.scanNodeForCaptures(retValue, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + if (retValue) this.scanNodeForCaptures(retValue, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Switch: { let stmt = node; - this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures); let cases = stmt.cases; for (let i = 0, k = cases.length; i < k; i++) { let case_ = cases[i]; let caseLabel = case_.label; - if (caseLabel) this.scanNodeForCaptures(caseLabel, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + if (caseLabel) this.scanNodeForCaptures(caseLabel, outerFlow, innerFunctionNames, captures); let stmts = case_.statements; for (let j = 0, l = stmts.length; j < l; j++) { - this.scanNodeForCaptures(stmts[j], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmts[j], outerFlow, innerFunctionNames, captures); } } break; } case NodeKind.Throw: { let stmt = node; - this.scanNodeForCaptures(stmt.value, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.value, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Try: { let stmt = node; let bodyStmts = stmt.bodyStatements; for (let i = 0, k = bodyStmts.length; i < k; i++) { - this.scanNodeForCaptures(bodyStmts[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(bodyStmts[i], outerFlow, innerFunctionNames, captures); } let catchStmts = stmt.catchStatements; if (catchStmts) { for (let i = 0, k = catchStmts.length; i < k; i++) { - this.scanNodeForCaptures(catchStmts[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(catchStmts[i], outerFlow, innerFunctionNames, captures); } } let finallyStmts = stmt.finallyStatements; if (finallyStmts) { for (let i = 0, k = finallyStmts.length; i < k; i++) { - this.scanNodeForCaptures(finallyStmts[i], outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(finallyStmts[i], outerFlow, innerFunctionNames, captures); } } break; @@ -7960,20 +8052,20 @@ export class Compiler extends DiagnosticEmitter { innerFunctionNames.add(decl.name.text); let declInit = decl.initializer; if (declInit) { - this.scanNodeForCaptures(declInit, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(declInit, outerFlow, innerFunctionNames, captures); } } break; } case NodeKind.While: { let stmt = node; - this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); - this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.condition, outerFlow, innerFunctionNames, captures); + this.scanNodeForCaptures(stmt.body, outerFlow, innerFunctionNames, captures); break; } case NodeKind.Void: { let stmt = node; - this.scanNodeForCaptures(stmt.expression, outerFlow, innerFunctionNames, captures, capturedNames, declaredVars); + this.scanNodeForCaptures(stmt.expression, outerFlow, innerFunctionNames, captures); break; } @@ -8063,558 +8155,6 @@ export class Compiler extends DiagnosticEmitter { return captures; } - /** Pre-scans a function body to identify all closures and their captured variables. - * This must be done before compiling the body so that local variables know they're captured. */ - private prescanForClosures( - bodyNode: Statement, - instance: Function, - flow: Flow - ): void { - // Collect all variable names declared in this function body - let declaredVars = new Map(); - this.collectDeclaredVariables(bodyNode, declaredVars); - - // Scan for function expressions in the body - this.prescanNodeForFunctionExpressions(bodyNode, instance, flow, declaredVars); - } - - /** Collects all variable declarations in a node (for prescan). */ - private collectDeclaredVariables(node: Node, vars: Map): void { - switch (node.kind) { - // Statements that contain other statements - case NodeKind.Block: { - let block = node; - for (let i = 0, k = block.statements.length; i < k; i++) { - this.collectDeclaredVariables(block.statements[i], vars); - } - break; - } - case NodeKind.If: { - let ifStmt = node; - this.collectDeclaredVariables(ifStmt.ifTrue, vars); - let ifFalse = ifStmt.ifFalse; - if (ifFalse) { - this.collectDeclaredVariables(ifFalse, vars); - } - break; - } - case NodeKind.While: { - let whileStmt = node; - this.collectDeclaredVariables(whileStmt.body, vars); - break; - } - case NodeKind.Do: { - let doStmt = node; - this.collectDeclaredVariables(doStmt.body, vars); - break; - } - case NodeKind.For: { - let forStmt = node; - let initializer = forStmt.initializer; - if (initializer) this.collectDeclaredVariables(initializer, vars); - this.collectDeclaredVariables(forStmt.body, vars); - break; - } - case NodeKind.ForOf: { - let forOfStmt = node; - if (forOfStmt.variable.kind == NodeKind.Variable) { - this.collectDeclaredVariables(forOfStmt.variable, vars); - } - this.collectDeclaredVariables(forOfStmt.body, vars); - break; - } - case NodeKind.Switch: { - let switchStmt = node; - let cases = switchStmt.cases; - for (let i = 0, k = cases.length; i < k; i++) { - let statements = cases[i].statements; - for (let j = 0, l = statements.length; j < l; j++) { - this.collectDeclaredVariables(statements[j], vars); - } - } - break; - } - case NodeKind.Try: { - let tryStmt = node; - let bodyStatements = tryStmt.bodyStatements; - for (let i = 0, k = bodyStatements.length; i < k; i++) { - this.collectDeclaredVariables(bodyStatements[i], vars); - } - let catchStatements = tryStmt.catchStatements; - if (catchStatements) { - let catchVariable = tryStmt.catchVariable; - if (catchVariable) { - vars.set(catchVariable.text, null); - } - for (let i = 0, k = catchStatements.length; i < k; i++) { - this.collectDeclaredVariables(catchStatements[i], vars); - } - } - let finallyStatements = tryStmt.finallyStatements; - if (finallyStatements) { - for (let i = 0, k = finallyStatements.length; i < k; i++) { - this.collectDeclaredVariables(finallyStatements[i], vars); - } - } - break; - } - - // Variable declarations - case NodeKind.Variable: { - let varStmt = node; - for (let i = 0, k = varStmt.declarations.length; i < k; i++) { - let decl = varStmt.declarations[i]; - vars.set(decl.name.text, null); - } - break; - } - - // Function scopes - don't leak variables - case NodeKind.FunctionDeclaration: - case NodeKind.Function: - break; - - // Statements without variable declarations - case NodeKind.Expression: - case NodeKind.Return: - case NodeKind.Break: - case NodeKind.Continue: - case NodeKind.Throw: - case NodeKind.Empty: - case NodeKind.Void: - break; - - // Module-level declarations (shouldn't appear in function bodies normally) - case NodeKind.Export: - case NodeKind.ExportDefault: - case NodeKind.ExportImport: - case NodeKind.Import: - case NodeKind.Module: - case NodeKind.ClassDeclaration: - case NodeKind.EnumDeclaration: - case NodeKind.InterfaceDeclaration: - case NodeKind.NamespaceDeclaration: - case NodeKind.TypeDeclaration: - break; - - // Expression nodes (shouldn't be passed to this function normally) - case NodeKind.Identifier: - case NodeKind.Assertion: - case NodeKind.Binary: - case NodeKind.Call: - case NodeKind.Class: - case NodeKind.Comma: - case NodeKind.ElementAccess: - case NodeKind.False: - case NodeKind.InstanceOf: - case NodeKind.Literal: - case NodeKind.New: - case NodeKind.Null: - case NodeKind.Omitted: - case NodeKind.Parenthesized: - case NodeKind.PropertyAccess: - case NodeKind.Ternary: - case NodeKind.Super: - case NodeKind.This: - case NodeKind.True: - case NodeKind.Constructor: - case NodeKind.UnaryPostfix: - case NodeKind.UnaryPrefix: - case NodeKind.Compiled: - break; - - // Type nodes - case NodeKind.NamedType: - case NodeKind.FunctionType: - case NodeKind.TypeName: - case NodeKind.TypeParameter: - case NodeKind.Parameter: - break; - - // Special nodes - case NodeKind.Source: - case NodeKind.Decorator: - case NodeKind.ExportMember: - case NodeKind.SwitchCase: - case NodeKind.IndexSignature: - case NodeKind.Comment: - case NodeKind.EnumValueDeclaration: - case NodeKind.FieldDeclaration: - case NodeKind.ImportDeclaration: - case NodeKind.MethodDeclaration: - case NodeKind.VariableDeclaration: - break; - - default: - assert(false, "collectDeclaredVariables: unhandled node kind: " + (node.kind as i32).toString()); - } - } - - /** Iteratively scans a node for function expressions and sets up their captures. - * Uses an explicit stack to avoid stack overflow on deeply nested code. */ - private prescanNodeForFunctionExpressions( - node: Node, - instance: Function, - flow: Flow, - declaredVars: Map - ): void { - // Use an explicit stack to avoid recursion stack overflow - let stack = new Array(); - stack.push(node); - - while (stack.length > 0) { - let current = assert(stack.pop()); - switch (current.kind) { - case NodeKind.Block: { - let block = current; - let statements = block.statements; - for (let i = statements.length - 1; i >= 0; i--) { - stack.push(statements[i]); - } - break; - } - case NodeKind.Expression: { - let exprStmt = current; - stack.push(exprStmt.expression); - break; - } - case NodeKind.Return: { - let ret = current; - let retValue = ret.value; - if (retValue) { - stack.push(retValue); - } - break; - } - case NodeKind.Variable: { - let varStmt = current; - let declarations = varStmt.declarations; - for (let i = declarations.length - 1; i >= 0; i--) { - let declInit = declarations[i].initializer; - if (declInit) { - stack.push(declInit); - } - } - break; - } - case NodeKind.If: { - let ifStmt = current; - let ifFalse = ifStmt.ifFalse; - if (ifFalse) { - stack.push(ifFalse); - } - stack.push(ifStmt.ifTrue); - stack.push(ifStmt.condition); - break; - } - case NodeKind.While: { - let whileStmt = current; - stack.push(whileStmt.body); - stack.push(whileStmt.condition); - break; - } - case NodeKind.Do: { - let doStmt = current; - stack.push(doStmt.body); - stack.push(doStmt.condition); - break; - } - case NodeKind.For: { - let forStmt = current; - stack.push(forStmt.body); - let forIncr = forStmt.incrementor; - if (forIncr) stack.push(forIncr); - let forCond = forStmt.condition; - if (forCond) stack.push(forCond); - let forInit = forStmt.initializer; - if (forInit) stack.push(forInit); - break; - } - case NodeKind.Function: { - // Found a function expression - analyze its captures - let funcExpr = current; - let capturedNames = this.analyzeCapturedVariablesWithDeclared(funcExpr.declaration, flow, declaredVars); - if (capturedNames.size > 0) { - // Check if closures feature is enabled - if (!this.options.hasFeature(Feature.Closures)) { - this.error( - DiagnosticCode.Feature_0_is_not_enabled, - funcExpr.range, "closures" - ); - break; - } - // Store captured names for later use when compiling variable declarations - let existingNames = instance.preCapturedNames; - if (!existingNames) { - existingNames = new Set(); - instance.preCapturedNames = existingNames; - } - for (let _values = Set_values(capturedNames), i = 0, k = _values.length; i < k; i++) { - existingNames.add(_values[i]); - } - } - // We don't recurse into nested function bodies here - that happens when the inner function is compiled - break; - } - case NodeKind.Binary: { - let binary = current; - stack.push(binary.right); - stack.push(binary.left); - break; - } - case NodeKind.UnaryPrefix: { - let unary = current; - stack.push(unary.operand); - break; - } - case NodeKind.UnaryPostfix: { - let unary = current; - stack.push(unary.operand); - break; - } - case NodeKind.Call: { - let call = current; - let args = call.args; - for (let i = args.length - 1; i >= 0; i--) { - stack.push(args[i]); - } - stack.push(call.expression); - break; - } - case NodeKind.New: { - let newExpr = current; - let args = newExpr.args; - for (let i = args.length - 1; i >= 0; i--) { - stack.push(args[i]); - } - break; - } - case NodeKind.Parenthesized: { - let paren = current; - stack.push(paren.expression); - break; - } - case NodeKind.Ternary: { - let ternary = current; - stack.push(ternary.ifElse); - stack.push(ternary.ifThen); - stack.push(ternary.condition); - break; - } - case NodeKind.Comma: { - let comma = current; - let expressions = comma.expressions; - for (let i = expressions.length - 1; i >= 0; i--) { - stack.push(expressions[i]); - } - break; - } - case NodeKind.Literal: { - let literal = current; - if (literal.literalKind == LiteralKind.Array) { - let arrLiteral = literal; - let elements = arrLiteral.elementExpressions; - for (let i = elements.length - 1; i >= 0; i--) { - let elem = elements[i]; - if (elem) { - stack.push(elem); - } - } - } else if (literal.literalKind == LiteralKind.Object) { - let objLiteral = literal; - let values = objLiteral.values; - for (let i = values.length - 1; i >= 0; i--) { - stack.push(values[i]); - } - } else if (literal.literalKind == LiteralKind.Template) { - let tmplLiteral = literal; - let expressions = tmplLiteral.expressions; - for (let i = expressions.length - 1; i >= 0; i--) { - stack.push(expressions[i]); - } - } - break; - } - case NodeKind.ElementAccess: { - let elemAccess = current; - stack.push(elemAccess.elementExpression); - stack.push(elemAccess.expression); - break; - } - case NodeKind.PropertyAccess: { - let propAccess = current; - stack.push(propAccess.expression); - break; - } - case NodeKind.Assertion: { - let assertion = current; - stack.push(assertion.expression); - break; - } - case NodeKind.InstanceOf: { - let instanceOfExpr = current; - stack.push(instanceOfExpr.expression); - break; - } - case NodeKind.Switch: { - let switchStmt = current; - let cases = switchStmt.cases; - for (let i = cases.length - 1; i >= 0; i--) { - let switchCase = cases[i]; - let statements = switchCase.statements; - for (let j = statements.length - 1; j >= 0; j--) { - stack.push(statements[j]); - } - let caseLabel = switchCase.label; - if (caseLabel) { - stack.push(caseLabel); - } - } - stack.push(switchStmt.condition); - break; - } - case NodeKind.ForOf: { - let forOfStmt = current; - stack.push(forOfStmt.body); - if (forOfStmt.variable.kind == NodeKind.Variable) { - stack.push(forOfStmt.variable); - } - stack.push(forOfStmt.iterable); - break; - } - case NodeKind.Try: { - let tryStmt = current; - let finallyStatements = tryStmt.finallyStatements; - if (finallyStatements) { - for (let i = finallyStatements.length - 1; i >= 0; i--) { - stack.push(finallyStatements[i]); - } - } - let catchStatements = tryStmt.catchStatements; - if (catchStatements) { - for (let i = catchStatements.length - 1; i >= 0; i--) { - stack.push(catchStatements[i]); - } - } - let bodyStatements = tryStmt.bodyStatements; - for (let i = bodyStatements.length - 1; i >= 0; i--) { - stack.push(bodyStatements[i]); - } - break; - } - case NodeKind.Throw: { - let throwStmt = current; - stack.push(throwStmt.value); - break; - } - case NodeKind.Void: { - let voidStmt = current; - stack.push(voidStmt.expression); - break; - } - - // Leaf expressions - no children to scan - case NodeKind.Identifier: - case NodeKind.True: - case NodeKind.False: - case NodeKind.Null: - case NodeKind.Super: - case NodeKind.This: - case NodeKind.Omitted: - case NodeKind.Compiled: - break; - - // Statements without expressions - case NodeKind.Break: - case NodeKind.Continue: - case NodeKind.Empty: - break; - - // Class expressions are not supported (will error during compilation) - case NodeKind.Class: - // Constructor keyword - not a capturable expression - case NodeKind.Constructor: - break; - - // Module-level declarations (shouldn't appear in function bodies normally) - case NodeKind.Export: - case NodeKind.ExportDefault: - case NodeKind.ExportImport: - case NodeKind.Import: - case NodeKind.Module: - case NodeKind.ClassDeclaration: - case NodeKind.EnumDeclaration: - case NodeKind.InterfaceDeclaration: - case NodeKind.NamespaceDeclaration: - case NodeKind.TypeDeclaration: - case NodeKind.FunctionDeclaration: - break; - - // Type nodes - no runtime expressions - case NodeKind.NamedType: - case NodeKind.FunctionType: - case NodeKind.TypeName: - case NodeKind.TypeParameter: - case NodeKind.Parameter: - break; - - // Special nodes - case NodeKind.Source: - case NodeKind.Decorator: - case NodeKind.ExportMember: - case NodeKind.SwitchCase: - case NodeKind.IndexSignature: - case NodeKind.Comment: - case NodeKind.EnumValueDeclaration: - case NodeKind.FieldDeclaration: - case NodeKind.ImportDeclaration: - case NodeKind.MethodDeclaration: - case NodeKind.VariableDeclaration: - break; - - default: - assert(false, "prescanNodeForFunctionExpressions: unhandled node kind: " + (current.kind as i32).toString()); - } - } - } - - /** Analyzes captured variables using both flow and pre-collected variable names. - * Uses name mode since Locals may not exist yet during prescan. */ - private analyzeCapturedVariablesWithDeclared( - declaration: FunctionDeclaration, - outerFlow: Flow, - declaredVars: Map - ): Set { - // For prescan, we just collect variable NAMES that are captured - // We'll create the actual captures with proper Local references later - let capturedNames = new Set(); - let innerFunctionNames = new Set(); - - // Scan parameter default values for captures (before adding params to inner names) - let params = declaration.signature.parameters; - for (let i = 0, k = params.length; i < k; i++) { - let paramInit = params[i].initializer; - if (paramInit) { - // Use name mode (null captures, with capturedNames and declaredVars) - this.scanNodeForCaptures(paramInit, outerFlow, innerFunctionNames, null, capturedNames, declaredVars); - } - } - - // Add the function's own parameters to the inner names set - for (let i = 0, k = params.length; i < k; i++) { - innerFunctionNames.add(params[i].name.text); - } - - // Scan the function body for identifier usages - let body = declaration.body; - if (body) { - // Use name mode (null captures, with capturedNames and declaredVars) - this.scanNodeForCaptures(body, outerFlow, innerFunctionNames, null, capturedNames, declaredVars); - } - - return capturedNames; - } - /** Computes the total size needed for a closure environment. */ private computeEnvironmentSize(captures: Map): i32 { // Calculate the total size based on already-assigned slot indices @@ -8631,6 +8171,30 @@ export class Compiler extends DiagnosticEmitter { return (maxEnd + usizeSize - 1) & ~(usizeSize - 1); } + /** Ensures closure environments are set up for all functions that own captured variables. */ + private ensureClosureEnvironmentsForCaptures( + captures: Map, + flow: Flow + ): void { + // Group captures by owner since variables may come from different nesting levels + let envOwners = new Map>(); + for (let _keys = Map_keys(captures), i = 0, k = _keys.length; i < k; i++) { + let local = _keys[i]; + let owner = assert(local.envOwner); + let ownerCaptures = envOwners.get(owner); + if (!ownerCaptures) { + ownerCaptures = new Map(); + envOwners.set(owner, ownerCaptures); + } + ownerCaptures.set(local, captures.get(local) as i32); + } + for (let _keys = Map_keys(envOwners), i = 0, k = _keys.length; i < k; i++) { + let owner = _keys[i]; + let ownerCaptures = assert(envOwners.get(owner)); + this.ensureClosureEnvironment(owner, ownerCaptures, flow); + } + } + /** Ensures a closure environment is set up for the outer function. */ private ensureClosureEnvironment( outerFunc: Function, @@ -8654,7 +8218,7 @@ export class Compiler extends DiagnosticEmitter { // Create a new environment local for the outer function let usizeType = this.options.usizeType; - outerFunc.envLocal = flow.addScopedLocal("$env", usizeType);; + outerFunc.envLocal = flow.addScopedLocal("$env", usizeType); outerFunc.capturedLocals = captures; // Compute the environment size @@ -8700,10 +8264,17 @@ export class Compiler extends DiagnosticEmitter { flow.setLocalFlag(funcPtrLocal.index, LocalFlags.Wrapped); // Get the environment pointer from the outer function + // For nested closures, the outer function might not own the environment + // - it might be using closureEnvLocal (a cached copy from an even outer function) let envPtrExpr: ExpressionRef; let outerEnvLocal = outerFunc.envLocal; + let outerClosureEnvLocal = outerFunc.closureEnvLocal; if (outerEnvLocal) { + // Outer function owns an environment - use it envPtrExpr = module.local_get(outerEnvLocal.index, sizeTypeRef); + } else if (outerClosureEnvLocal) { + // Outer function is a closure - use its cached environment from the outer scope + envPtrExpr = module.local_get(outerClosureEnvLocal.index, sizeTypeRef); } else { envPtrExpr = options.isWasm64 ? module.i64(0) : module.i32(0); } @@ -8776,10 +8347,15 @@ export class Compiler extends DiagnosticEmitter { // Count how many levels up we need to go // Start from current function's outer function and walk up to find envOwner + // Only count functions that have their own environment (envLocal set) let func: Function | null = currentFunc.outerFunction; let depth = 0; while (func && func != envOwner) { - depth++; + // Only increment depth if this function has its own environment + // Functions without envLocal just pass through their parent's environment + if (func.envLocal) { + depth++; + } func = func.outerFunction; } @@ -9151,6 +8727,10 @@ export class Compiler extends DiagnosticEmitter { this.currentType = localType; } + // Track that we accessed this as a regular local (for closure recompilation detection) + // Only set if not already captured (to avoid infinite recompilation loops) + if (!local.isCaptured) local.wasAccessedAsLocal = true; + let expr = module.local_get(localIndex, localType.toRef()); if (isNonNull && localType.isNullableExternalReference && this.options.hasFeature(Feature.GC)) { // If the local's type is nullable, but its value is known to be non-null, propagate diff --git a/src/program.ts b/src/program.ts index 3416db46ea..90d43b7649 100644 --- a/src/program.ts +++ b/src/program.ts @@ -3639,6 +3639,9 @@ export class Local extends VariableLikeElement { /** The function whose environment this local is stored in. Set when captured. */ envOwner: Function | null = null; + /** Whether this local was accessed as a regular wasm local (before capture was discovered). */ + wasAccessedAsLocal: bool = false; + /** Constructs a new local variable. */ constructor( /** Simple name. */ @@ -3814,8 +3817,8 @@ export class Function extends TypedElement { * This is needed because indirect calls can overwrite the global. */ closureEnvLocal: Local | null = null; - /** Pre-scanned names of captured variables (set before compilation, used to mark locals). */ - preCapturedNames: Set | null = null; + /** Whether this function needs recompilation due to late capture discovery. */ + needsCaptureRecompile: bool = false; /** Whether this function requires an environment (is a closure). */ get needsEnvironment(): bool { diff --git a/tests/compiler/closure-class.debug.wat b/tests/compiler/closure-class.debug.wat index 9ea83bc205..60a89d3d3b 100644 --- a/tests/compiler/closure-class.debug.wat +++ b/tests/compiler/closure-class.debug.wat @@ -2511,13 +2511,13 @@ i32.const 0 i32.store local.get $$env - local.get $operand + local.get $operation i32.store offset=4 local.get $$env - local.get $operation + local.get $this i32.store offset=8 local.get $$env - local.get $this + local.get $operand i32.store offset=12 i32.const 8 i32.const 6 @@ -3654,10 +3654,10 @@ i32.const 0 i32.store local.get $$env - local.get $amount + local.get $this i32.store offset=4 local.get $$env - local.get $this + local.get $amount i32.store offset=8 i32.const 8 i32.const 34 @@ -3682,10 +3682,10 @@ i32.const 0 i32.store local.get $$env - local.get $factor + local.get $this i32.store offset=4 local.get $$env - local.get $this + local.get $factor i32.store offset=8 i32.const 8 i32.const 34 @@ -5898,19 +5898,19 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 i32.const 0 i32.eq if local.get $$closureEnv - i32.load offset=12 + i32.load offset=8 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 i32.store local.get $1 local.get $$closureEnv - i32.load offset=12 + i32.load offset=8 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 @@ -5918,24 +5918,24 @@ local.get $1 call $closure-class/Calculator#get:result local.get $$closureEnv - i32.load offset=4 + i32.load offset=12 i32.add call $closure-class/Calculator#set:result else local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 i32.const 1 i32.eq if local.get $$closureEnv - i32.load offset=12 + i32.load offset=8 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 i32.store local.get $1 local.get $$closureEnv - i32.load offset=12 + i32.load offset=8 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 @@ -5943,24 +5943,24 @@ local.get $1 call $closure-class/Calculator#get:result local.get $$closureEnv - i32.load offset=4 + i32.load offset=12 i32.sub call $closure-class/Calculator#set:result else local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 i32.const 2 i32.eq if local.get $$closureEnv - i32.load offset=12 + i32.load offset=8 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 i32.store local.get $1 local.get $$closureEnv - i32.load offset=12 + i32.load offset=8 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 @@ -5968,14 +5968,14 @@ local.get $1 call $closure-class/Calculator#get:result local.get $$closureEnv - i32.load offset=4 + i32.load offset=12 i32.mul call $closure-class/Calculator#set:result end end end local.get $$closureEnv - i32.load offset=12 + i32.load offset=8 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 @@ -10358,14 +10358,14 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 i32.store local.get $1 local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 @@ -10373,11 +10373,11 @@ local.get $1 call $closure-class/ChainableCounter#get:count local.get $$closureEnv - i32.load offset=4 + i32.load offset=8 i32.add call $closure-class/ChainableCounter#set:count local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $1 global.get $~lib/memory/__stack_pointer i32.const 8 @@ -10400,14 +10400,14 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 i32.store local.get $1 local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $1 global.get $~lib/memory/__stack_pointer local.get $1 @@ -10415,11 +10415,11 @@ local.get $1 call $closure-class/ChainableCounter#get:count local.get $$closureEnv - i32.load offset=4 + i32.load offset=8 i32.mul call $closure-class/ChainableCounter#set:count local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $1 global.get $~lib/memory/__stack_pointer i32.const 8 @@ -10819,11 +10819,11 @@ return ) (func $closure-class/testTaskCallbacks (result i32) + (local $$env i32) (local $task i32) (local $then i32) (local $complete i32) (local $receivedValue i32) - (local $$env i32) (local $5 i32) (local $6 i32) (local $7 i32) @@ -10969,12 +10969,12 @@ return ) (func $closure-class/testTaskCallbackAfterComplete (result i32) + (local $$env i32) (local $task i32) (local $then i32) (local $complete i32) - (local $3 i32) + (local $4 i32) (local $receivedValue i32) - (local $$env i32) (local $6 i32) (local $7 i32) (local $8 i32) @@ -11023,12 +11023,12 @@ i32.const 1 global.set $~argumentsLength local.get $complete - local.tee $3 + local.tee $4 i32.store offset=16 - local.get $3 + local.get $4 i32.load offset=4 global.set $~lib/__closure_env - local.get $3 + local.get $4 i32.load call_indirect (type $3) local.get $$env diff --git a/tests/compiler/closure-class.release.wat b/tests/compiler/closure-class.release.wat index 561f6453b5..645f9da8fe 100644 --- a/tests/compiler/closure-class.release.wat +++ b/tests/compiler/closure-class.release.wat @@ -1759,13 +1759,13 @@ i32.const 0 i32.store local.get $4 - local.get $1 + local.get $2 i32.store offset=8 local.get $4 - local.get $2 + local.get $0 i32.store offset=12 local.get $4 - local.get $0 + local.get $1 i32.store offset=16 i32.const 8 i32.const 6 @@ -1907,10 +1907,10 @@ i32.const 0 i32.store local.get $3 - local.get $1 + local.get $0 i32.store offset=8 local.get $3 - local.get $0 + local.get $1 i32.store offset=12 i32.const 8 i32.const 34 @@ -3689,10 +3689,10 @@ i32.const 0 i32.store offset=4 local.get $4 - i32.const 2 + local.get $1 i32.store offset=8 local.get $4 - local.get $1 + i32.const 2 i32.store offset=12 i32.const 8 i32.const 34 @@ -5248,7 +5248,7 @@ i64.store global.get $~lib/__closure_env local.tee $0 - i32.load offset=8 + i32.load offset=4 local.tee $1 if local.get $1 @@ -5257,42 +5257,42 @@ if global.get $~lib/memory/__stack_pointer local.get $0 - i32.load offset=12 + i32.load offset=8 local.tee $1 i32.store global.get $~lib/memory/__stack_pointer local.get $0 - i32.load offset=12 + i32.load offset=8 local.tee $2 i32.store offset=4 local.get $1 local.get $2 i32.load local.get $0 - i32.load offset=4 + i32.load offset=12 i32.sub i32.store else local.get $0 - i32.load offset=8 + i32.load offset=4 i32.const 2 i32.eq if global.get $~lib/memory/__stack_pointer local.get $0 - i32.load offset=12 + i32.load offset=8 local.tee $1 i32.store global.get $~lib/memory/__stack_pointer local.get $0 - i32.load offset=12 + i32.load offset=8 local.tee $2 i32.store offset=4 local.get $1 local.get $2 i32.load local.get $0 - i32.load offset=4 + i32.load offset=12 i32.mul i32.store end @@ -5300,25 +5300,25 @@ else global.get $~lib/memory/__stack_pointer local.get $0 - i32.load offset=12 + i32.load offset=8 local.tee $1 i32.store global.get $~lib/memory/__stack_pointer local.get $0 - i32.load offset=12 + i32.load offset=8 local.tee $2 i32.store offset=4 local.get $1 local.get $2 i32.load local.get $0 - i32.load offset=4 + i32.load offset=12 i32.add i32.store end global.get $~lib/memory/__stack_pointer local.get $0 - i32.load offset=12 + i32.load offset=8 local.tee $0 i32.store local.get $0 @@ -8411,23 +8411,23 @@ global.get $~lib/memory/__stack_pointer global.get $~lib/__closure_env local.tee $1 - i32.load offset=8 + i32.load offset=4 local.tee $2 i32.store global.get $~lib/memory/__stack_pointer local.get $1 - i32.load offset=8 + i32.load offset=4 local.tee $0 i32.store offset=4 local.get $2 local.get $0 i32.load local.get $1 - i32.load offset=4 + i32.load offset=8 i32.add i32.store local.get $1 - i32.load offset=8 + i32.load offset=4 global.get $~lib/memory/__stack_pointer i32.const 8 i32.add @@ -8458,23 +8458,23 @@ global.get $~lib/memory/__stack_pointer global.get $~lib/__closure_env local.tee $1 - i32.load offset=8 + i32.load offset=4 local.tee $2 i32.store global.get $~lib/memory/__stack_pointer local.get $1 - i32.load offset=8 + i32.load offset=4 local.tee $0 i32.store offset=4 local.get $2 local.get $0 i32.load local.get $1 - i32.load offset=4 + i32.load offset=8 i32.mul i32.store local.get $1 - i32.load offset=8 + i32.load offset=4 global.get $~lib/memory/__stack_pointer i32.const 8 i32.add diff --git a/tests/compiler/closure-complex.debug.wat b/tests/compiler/closure-complex.debug.wat new file mode 100644 index 0000000000..5c8a248e17 --- /dev/null +++ b/tests/compiler/closure-complex.debug.wat @@ -0,0 +1,5800 @@ +(module + (type $0 (func (param i32) (result i32))) + (type $1 (func (param i32 i32))) + (type $2 (func (result i32))) + (type $3 (func (param i32))) + (type $4 (func (param i32 i32) (result i32))) + (type $5 (func)) + (type $6 (func (param i32 i32 i32))) + (type $7 (func (param i32 i32 i32 i32))) + (type $8 (func (param i32 i32 i64) (result i32))) + (type $9 (func (param i32 i32 i32) (result i32))) + (type $10 (func (param i32 i32 i32 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/shared/runtime/Runtime.Stub i32 (i32.const 0)) + (global $~lib/shared/runtime/Runtime.Minimal i32 (i32.const 1)) + (global $~lib/shared/runtime/Runtime.Incremental i32 (i32.const 2)) + (global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0)) + (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) + (global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) + (global $~lib/__closure_env (mut i32) (i32.const 0)) + (global $~argumentsLength (mut i32) (i32.const 0)) + (global $~lib/native/ASC_RUNTIME i32 (i32.const 2)) + (global $~lib/rt/__rtti_base i32 (i32.const 1408)) + (global $~lib/memory/__data_end i32 (i32.const 1480)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34248)) + (global $~lib/memory/__heap_base i32 (i32.const 34248)) + (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) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00") + (data $9 (i32.const 444) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00") + (data $10 (i32.const 476) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00$\00\00\00c\00l\00o\00s\00u\00r\00e\00-\00c\00o\00m\00p\00l\00e\00x\00.\00t\00s\00\00\00\00\00\00\00\00\00") + (data $11 (i32.const 540) "\1c\00\00\00\00\00\00\00\00\00\00\00\07\00\00\00\08\00\00\00\03\00\00\00\00\00\00\00\00\00\00\00") + (data $12 (i32.const 572) "\1c\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $13 (i32.const 604) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\04\00\00\00\00\00\00\00\00\00\00\00") + (data $14 (i32.const 636) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1c\00\00\00I\00n\00v\00a\00l\00i\00d\00 \00l\00e\00n\00g\00t\00h\00") + (data $15 (i32.const 684) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\1a\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00.\00t\00s\00\00\00") + (data $16 (i32.const 732) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\05\00\00\00\00\00\00\00\00\00\00\00") + (data $17 (i32.const 764) "|\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00^\00\00\00E\00l\00e\00m\00e\00n\00t\00 \00t\00y\00p\00e\00 \00m\00u\00s\00t\00 \00b\00e\00 \00n\00u\00l\00l\00a\00b\00l\00e\00 \00i\00f\00 \00a\00r\00r\00a\00y\00 \00i\00s\00 \00h\00o\00l\00e\00y\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $18 (i32.const 892) "\1c\00\00\00\00\00\00\00\00\00\00\00\n\00\00\00\08\00\00\00\06\00\00\00\00\00\00\00\00\00\00\00") + (data $19 (i32.const 924) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\07\00\00\00\00\00\00\00\00\00\00\00") + (data $20 (i32.const 956) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00") + (data $21 (i32.const 988) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\t\00\00\00\00\00\00\00\00\00\00\00") + (data $22 (i32.const 1020) "\1c\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $23 (i32.const 1052) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\n\00\00\00\00\00\00\00\00\00\00\00") + (data $24 (i32.const 1084) "\1c\00\00\00\00\00\00\00\00\00\00\00\r\00\00\00\08\00\00\00\0b\00\00\00\00\00\00\00\00\00\00\00") + (data $25 (i32.const 1116) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\0c\00\00\00\00\00\00\00\00\00\00\00") + (data $26 (i32.const 1148) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\r\00\00\00\00\00\00\00\00\00\00\00") + (data $27 (i32.const 1180) "\1c\00\00\00\00\00\00\00\00\00\00\00\0e\00\00\00\08\00\00\00\0e\00\00\00\00\00\00\00\00\00\00\00") + (data $28 (i32.const 1212) ",\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\14\00\00\00\01\00\00\00\02\00\00\00\03\00\00\00\04\00\00\00\05\00\00\00\00\00\00\00\00\00\00\00") + (data $29 (i32.const 1260) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\0f\00\00\00\00\00\00\00\00\00\00\00") + (data $30 (i32.const 1292) ",\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\14\00\00\00\01\00\00\00\02\00\00\00\03\00\00\00\04\00\00\00\05\00\00\00\00\00\00\00\00\00\00\00") + (data $31 (i32.const 1340) "\1c\00\00\00\00\00\00\00\00\00\00\00\0f\00\00\00\08\00\00\00\10\00\00\00\00\00\00\00\00\00\00\00") + (data $32 (i32.const 1372) "\1c\00\00\00\00\00\00\00\00\00\00\00\10\00\00\00\08\00\00\00\11\00\00\00\00\00\00\00\00\00\00\00") + (data $33 (i32.const 1408) "\11\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00\02A\00\00\02\t\00\00\00\00\00\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 18 18 funcref) + (elem $0 (i32.const 1) $closure-complex/testNestedArrowsWithClassCapture~anonymous|0 $closure-complex/testNestedArrowsWithClassCapture~anonymous|1 $closure-complex/testArrowClosureWithClass~anonymous|0 $closure-complex/createCounterOperations~anonymous|0 $closure-complex/createCounterOperations~anonymous|1 $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0~anonymous|0 $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0 $closure-complex/testDeeplyNestedClassCreation~anonymous|0 $closure-complex/ClosureFactory#createAdder~anonymous|0 $closure-complex/SelfReferencing#addCallback~anonymous|0 $closure-complex/testMultipleClosuresSharing~anonymous|0 $closure-complex/testMultipleClosuresSharing~anonymous|1 $closure-complex/testNestedArrowFunctions~anonymous|0~anonymous|0 $closure-complex/testNestedArrowFunctions~anonymous|0 $closure-complex/testComplexPipeline~anonymous|0 $closure-complex/testCurriedWithClass~anonymous|0~anonymous|0 $closure-complex/testCurriedWithClass~anonymous|0) + (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 $closure-complex/Counter#set:count (param $this i32) (param $count i32) + local.get $this + local.get $count + i32.store + ) + (func $closure-complex/Counter#get:count (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $closure-complex/Calculator#set:result (param $this i32) (param $result i32) + local.get $this + local.get $result + i32.store + ) + (func $closure-complex/Calculator#get:result (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/__newBuffer (param $size i32) (param $id i32) (param $data i32) (result i32) + (local $buffer i32) + local.get $size + local.get $id + call $~lib/rt/itcms/__new + local.set $buffer + local.get $data + if + local.get $buffer + local.get $data + local.get $size + memory.copy + end + local.get $buffer + return + ) + (func $~lib/rt/itcms/__link (param $parentPtr i32) (param $childPtr i32) (param $expectMultiple i32) + (local $child i32) + (local $parent i32) + (local $parentColor i32) + local.get $childPtr + i32.eqz + if + return + end + i32.const 1 + drop + local.get $parentPtr + i32.eqz + if + i32.const 0 + i32.const 96 + i32.const 295 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $childPtr + i32.const 20 + i32.sub + local.set $child + local.get $child + call $~lib/rt/itcms/Object#get:color + global.get $~lib/rt/itcms/white + i32.eq + if + local.get $parentPtr + i32.const 20 + i32.sub + local.set $parent + local.get $parent + call $~lib/rt/itcms/Object#get:color + local.set $parentColor + local.get $parentColor + global.get $~lib/rt/itcms/white + i32.eqz + i32.eq + if + local.get $expectMultiple + if + local.get $parent + call $~lib/rt/itcms/Object#makeGray + else + local.get $child + call $~lib/rt/itcms/Object#makeGray + end + else + local.get $parentColor + i32.const 3 + i32.eq + if (result i32) + global.get $~lib/rt/itcms/state + i32.const 1 + i32.eq + else + i32.const 0 + end + if + local.get $child + call $~lib/rt/itcms/Object#makeGray + end + end + end + ) + (func $~lib/array/Array<%28%29=>i32>#get:length_ (param $this i32) (result i32) + local.get $this + i32.load offset=12 + ) + (func $~lib/arraybuffer/ArrayBufferView#get:byteLength (param $this i32) (result i32) + local.get $this + i32.load offset=8 + ) + (func $~lib/arraybuffer/ArrayBufferView#get:buffer (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/rt/itcms/Object#get:rtSize (param $this i32) (result i32) + local.get $this + i32.load offset=16 + ) + (func $~lib/rt/itcms/__renew (param $oldPtr i32) (param $size i32) (result i32) + (local $oldObj i32) + (local $newPtr i32) + (local $4 i32) + (local $5 i32) + local.get $oldPtr + i32.const 20 + i32.sub + local.set $oldObj + local.get $size + local.get $oldObj + call $~lib/rt/common/BLOCK#get:mmInfo + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.sub + i32.le_u + if + local.get $oldObj + local.get $size + call $~lib/rt/itcms/Object#set:rtSize + local.get $oldPtr + return + end + local.get $size + local.get $oldObj + call $~lib/rt/itcms/Object#get:rtId + call $~lib/rt/itcms/__new + local.set $newPtr + local.get $newPtr + local.get $oldPtr + local.get $size + local.tee $4 + local.get $oldObj + call $~lib/rt/itcms/Object#get:rtSize + local.tee $5 + local.get $4 + local.get $5 + i32.lt_u + select + memory.copy + local.get $newPtr + return + ) + (func $~lib/array/Array<%28%29=>i32>#get:dataStart (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/array/Array<%28%29=>i32>#set:length_ (param $this i32) (param $length_ i32) + local.get $this + local.get $length_ + i32.store offset=12 + ) + (func $closure-complex/ClosureFactory#set:baseValue (param $this i32) (param $baseValue i32) + local.get $this + local.get $baseValue + i32.store + ) + (func $closure-complex/ClosureFactory#get:baseValue (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $closure-complex/ClosureFactory#createAdder~anonymous|0 (result i32) + (local $$closureEnv i32) + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + local.get $$closureEnv + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get $$closureEnv + i32.load offset=8 + local.get $$closureEnv + i32.load offset=12 + i32.add + local.get $$closureEnv + i32.load offset=4 + i32.add + return + ) + (func $closure-complex/SelfReferencing#set:value (param $this i32) (param $value i32) + local.get $this + local.get $value + i32.store + ) + (func $closure-complex/SelfReferencing#set:callbacks (param $this i32) (param $callbacks i32) + local.get $this + local.get $callbacks + i32.store offset=4 + local.get $this + local.get $callbacks + i32.const 0 + call $~lib/rt/itcms/__link + ) + (func $closure-complex/SelfReferencing#get:callbacks (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $closure-complex/SelfReferencing#get:value (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $closure-complex/testMultipleClosuresSharing~anonymous|1 (result i32) + (local $$closureEnv i32) + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + ) + (func $closure-complex/testNestedArrowFunctions~anonymous|0~anonymous|0 (result i32) + (local $$closureEnv i32) + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + i32.const 2 + i32.mul + ) + (func $closure-complex/testNestedArrowFunctions~anonymous|0 (param $x i32) (result i32) + (local $$closureEnv i32) + (local $$env i32) + (local $captured i32) + (local $4 i32) + global.get $~lib/__closure_env + local.set $$closureEnv + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + local.get $$closureEnv + i32.store + local.get $$env + local.get $x + local.get $$closureEnv + i32.load offset=4 + i32.add + i32.store offset=4 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $4 + local.get $4 + i32.const 13 + i32.store + local.get $4 + local.get $$env + i32.store offset=4 + local.get $4 + return + ) + (func $~lib/array/Array#get:length_ (param $this i32) (result i32) + local.get $this + i32.load offset=12 + ) + (func $~lib/array/Array#get:dataStart (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $closure-complex/testCurriedWithClass~anonymous|0 (param $c i32) (result i32) + (local $$env i32) + (local $2 i32) + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + local.get $c + i32.store offset=4 + i32.const 8 + i32.const 15 + call $~lib/rt/itcms/__new + local.set $2 + local.get $2 + i32.const 16 + i32.store + local.get $2 + local.get $$env + i32.store offset=4 + local.get $2 + return + ) + (func $start:closure-complex + 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 + call $closure-complex/testNestedArrowsWithClassCapture + i32.const 12 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 61 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testArrowClosureWithClass + i32.const 40 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 80 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testFactoryWithClassMethods + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 101 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testDeeplyNestedClassCreation + i32.const 222 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 130 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testClassReturningClosures + i32.const 223 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 162 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testThisCaptureInClosures + i32.const 120 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 206 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testMultipleClosuresSharing + i32.const 6 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 224 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testNestedArrowFunctions + i32.const 70 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 242 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testComplexPipeline + i32.const 35 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 264 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + call $closure-complex/testCurriedWithClass + i32.const 60 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 496 + i32.const 286 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $~lib/rt/__visit_globals (param $0 i32) + (local $1 i32) + i32.const 224 + local.get $0 + call $~lib/rt/itcms/__visit + i32.const 656 + local.get $0 + call $~lib/rt/itcms/__visit + i32.const 784 + 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.get $1 + call $~lib/rt/itcms/__visit + ) + (func $~lib/object/Object~visit (param $0 i32) (param $1 i32) + ) + (func $~lib/function/Function<%28%29=>i32>#get:_env (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/function/Function<%28%29=>i32>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/function/Function<%28%29=>i32>#__visit + ) + (func $~lib/function/Function<%28i32%29=>void>#get:_env (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/function/Function<%28i32%29=>void>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/function/Function<%28i32%29=>void>#__visit + ) + (func $~lib/array/Array<%28%29=>i32>#get:buffer (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/array/Array<%28%29=>i32>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/array/Array<%28%29=>i32>#__visit + ) + (func $~lib/array/Array#get:buffer (param $this i32) (result i32) + local.get $this + i32.load + ) + (func $~lib/array/Array~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/array/Array#__visit + ) + (func $~lib/function/Function<%28%29=>closure-complex/Calculator>#get:_env (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/function/Function<%28%29=>closure-complex/Calculator>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/function/Function<%28%29=>closure-complex/Calculator>#__visit + ) + (func $closure-complex/SelfReferencing~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 offset=4 + local.get $1 + call $~lib/rt/itcms/__visit + ) + (func $~lib/function/Function<%28%29=>void>#get:_env (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/function/Function<%28%29=>void>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/function/Function<%28%29=>void>#__visit + ) + (func $~lib/function/Function<%28i32%29=>%28%29=>i32>#get:_env (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/function/Function<%28i32%29=>%28%29=>i32>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/function/Function<%28i32%29=>%28%29=>i32>#__visit + ) + (func $~lib/function/Function<%28i32%29=>closure-complex/Calculator>#get:_env (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/function/Function<%28i32%29=>closure-complex/Calculator>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/function/Function<%28i32%29=>closure-complex/Calculator>#__visit + ) + (func $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator>#get:_env (param $this i32) (result i32) + local.get $this + i32.load offset=4 + ) + (func $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/object/Object~visit + local.get $0 + local.get $1 + call $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator>#__visit + ) + (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) + block $invalid + block $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator> + block $~lib/function/Function<%28i32%29=>closure-complex/Calculator> + block $~lib/function/Function<%28i32%29=>%28%29=>i32> + block $~lib/function/Function<%28%29=>void> + block $closure-complex/SelfReferencing + block $closure-complex/ClosureFactory + block $~lib/function/Function<%28%29=>closure-complex/Calculator> + block $~lib/array/Array + block $~lib/array/Array<%28%29=>i32> + block $~lib/function/Function<%28i32%29=>void> + block $closure-complex/Calculator + block $~lib/function/Function<%28%29=>i32> + block $closure-complex/Counter + 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 $closure-complex/Counter $~lib/function/Function<%28%29=>i32> $closure-complex/Calculator $~lib/function/Function<%28i32%29=>void> $~lib/array/Array<%28%29=>i32> $~lib/array/Array $~lib/function/Function<%28%29=>closure-complex/Calculator> $closure-complex/ClosureFactory $closure-complex/SelfReferencing $~lib/function/Function<%28%29=>void> $~lib/function/Function<%28i32%29=>%28%29=>i32> $~lib/function/Function<%28i32%29=>closure-complex/Calculator> $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator> $invalid + end + return + end + return + end + return + end + local.get $0 + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit + return + end + return + end + local.get $0 + local.get $1 + call $~lib/function/Function<%28%29=>i32>~visit + return + end + return + end + local.get $0 + local.get $1 + call $~lib/function/Function<%28i32%29=>void>~visit + return + end + local.get $0 + local.get $1 + call $~lib/array/Array<%28%29=>i32>~visit + return + end + local.get $0 + local.get $1 + call $~lib/array/Array~visit + return + end + local.get $0 + local.get $1 + call $~lib/function/Function<%28%29=>closure-complex/Calculator>~visit + return + end + return + end + local.get $0 + local.get $1 + call $closure-complex/SelfReferencing~visit + return + end + local.get $0 + local.get $1 + call $~lib/function/Function<%28%29=>void>~visit + return + end + local.get $0 + local.get $1 + call $~lib/function/Function<%28i32%29=>%28%29=>i32>~visit + return + end + local.get $0 + local.get $1 + call $~lib/function/Function<%28i32%29=>closure-complex/Calculator>~visit + return + end + local.get $0 + local.get $1 + call $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator>~visit + return + end + unreachable + ) + (func $~start + call $start:closure-complex + ) + (func $~stack_check + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__data_end + i32.lt_s + if + i32.const 34272 + i32.const 34320 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $closure-complex/Counter#constructor (param $this i32) (result 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 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 4 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + global.get $~lib/memory/__stack_pointer + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + call $~lib/object/Object#constructor + local.tee $this + i32.store + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + i32.const 0 + call $closure-complex/Counter#set:count + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $closure-complex/Counter#increment (param $this i32) (result 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 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + call $closure-complex/Counter#get:count + i32.const 1 + i32.add + call $closure-complex/Counter#set:count + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/Counter#get:count + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $closure-complex/testNestedArrowsWithClassCapture~anonymous|0 (result i32) + (local $$closureEnv i32) + (local $result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $closure-complex/Counter#increment + local.set $result + local.get $result + local.get $$closureEnv + i32.load offset=8 + i32.mul + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $closure-complex/Calculator#constructor (param $this i32) (result 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 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 6 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + global.get $~lib/memory/__stack_pointer + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + call $~lib/object/Object#constructor + local.tee $this + i32.store + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + i32.const 0 + call $closure-complex/Calculator#set:result + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $closure-complex/Calculator#add (param $this i32) (param $x i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + call $closure-complex/Calculator#get:result + local.get $x + i32.add + call $closure-complex/Calculator#set:result + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $closure-complex/testArrowClosureWithClass~anonymous|0 (param $x i32) + (local $$closureEnv i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + local.get $x + call $closure-complex/Calculator#add + drop + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/Calculator#getResult (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/Calculator#get:result + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $closure-complex/testArrowClosureWithClass (result i32) + (local $$env i32) + (local $calc i32) + (local $2 i32) + (local $addToCalc i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 20 + memory.fill + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + i32.const 0 + call $closure-complex/Calculator#constructor + i32.store offset=4 + local.get $$env + i32.load offset=4 + local.set $7 + global.get $~lib/memory/__stack_pointer + local.get $7 + i32.store + local.get $7 + i32.const 10 + call $closure-complex/Calculator#set:result + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 7 + call $~lib/rt/itcms/__new + local.set $2 + local.get $2 + i32.const 3 + i32.store + local.get $2 + local.get $$env + i32.store offset=4 + local.get $2 + local.tee $addToCalc + i32.store offset=4 + i32.const 5 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $addToCalc + local.tee $4 + i32.store offset=8 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $3) + i32.const 10 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $addToCalc + local.tee $5 + i32.store offset=12 + local.get $5 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $5 + i32.load + call_indirect (type $3) + i32.const 15 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $addToCalc + local.tee $6 + i32.store offset=16 + local.get $6 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $6 + i32.load + call_indirect (type $3) + local.get $$env + i32.load offset=4 + local.set $7 + global.get $~lib/memory/__stack_pointer + local.get $7 + i32.store + local.get $7 + call $closure-complex/Calculator#getResult + local.set $7 + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $7 + return + ) + (func $closure-complex/createCounterOperations~anonymous|0 (result i32) + (local $$closureEnv i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/Counter#increment + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $~lib/array/ensureCapacity (param $array i32) (param $newSize i32) (param $alignLog2 i32) (param $canGrow i32) + (local $oldCapacity i32) + (local $oldData i32) + (local $6 i32) + (local $7 i32) + (local $newCapacity i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $newData i32) + (local $14 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $array + local.set $14 + global.get $~lib/memory/__stack_pointer + local.get $14 + i32.store + local.get $14 + call $~lib/arraybuffer/ArrayBufferView#get:byteLength + local.set $oldCapacity + local.get $newSize + local.get $oldCapacity + local.get $alignLog2 + i32.shr_u + i32.gt_u + if + local.get $newSize + i32.const 1073741820 + local.get $alignLog2 + i32.shr_u + i32.gt_u + if + i32.const 656 + i32.const 704 + i32.const 19 + i32.const 48 + call $~lib/builtins/abort + unreachable + end + local.get $array + local.set $14 + global.get $~lib/memory/__stack_pointer + local.get $14 + i32.store + local.get $14 + call $~lib/arraybuffer/ArrayBufferView#get:buffer + local.set $oldData + local.get $newSize + local.tee $6 + i32.const 8 + local.tee $7 + local.get $6 + local.get $7 + i32.gt_u + select + local.get $alignLog2 + i32.shl + local.set $newCapacity + local.get $canGrow + if + local.get $oldCapacity + i32.const 1 + i32.shl + local.tee $9 + i32.const 1073741820 + local.tee $10 + local.get $9 + local.get $10 + i32.lt_u + select + local.tee $11 + local.get $newCapacity + local.tee $12 + local.get $11 + local.get $12 + i32.gt_u + select + local.set $newCapacity + end + local.get $oldData + local.get $newCapacity + call $~lib/rt/itcms/__renew + local.set $newData + i32.const 2 + global.get $~lib/shared/runtime/Runtime.Incremental + i32.ne + drop + local.get $newData + local.get $oldData + i32.ne + if + local.get $array + local.get $newData + i32.store + local.get $array + local.get $newData + i32.store offset=4 + local.get $array + local.get $newData + i32.const 0 + call $~lib/rt/itcms/__link + end + local.get $array + local.get $newCapacity + i32.store offset=8 + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array<%28%29=>i32>#push (param $this i32) (param $value i32) (result i32) + (local $oldLen i32) + (local $len i32) + (local $4 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $4 + call $~lib/array/Array<%28%29=>i32>#get:length_ + local.set $oldLen + local.get $oldLen + i32.const 1 + i32.add + local.set $len + local.get $this + local.get $len + i32.const 2 + i32.const 1 + call $~lib/array/ensureCapacity + i32.const 1 + drop + local.get $this + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $4 + call $~lib/array/Array<%28%29=>i32>#get:dataStart + local.get $oldLen + i32.const 2 + i32.shl + i32.add + local.get $value + i32.store + local.get $this + local.get $value + i32.const 1 + call $~lib/rt/itcms/__link + local.get $this + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $4 + local.get $len + call $~lib/array/Array<%28%29=>i32>#set:length_ + local.get $len + local.set $4 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $4 + return + ) + (func $closure-complex/Counter#getCount (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/Counter#get:count + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $closure-complex/createCounterOperations~anonymous|1 (result i32) + (local $$closureEnv i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/Counter#getCount + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $closure-complex/createCounterOperations (param $counter i32) (result i32) + (local $1 i32) + (local $operations i32) + (local $$env i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + local.get $counter + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 2 + i32.const 8 + i32.const 592 + call $~lib/rt/__newArray + local.tee $operations + i32.store + local.get $operations + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=4 + local.get $6 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $4 + local.get $4 + i32.const 4 + i32.store + local.get $4 + local.get $$env + i32.store offset=4 + local.get $4 + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=8 + local.get $6 + call $~lib/array/Array<%28%29=>i32>#push + drop + local.get $operations + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=4 + local.get $6 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $5 + local.get $5 + i32.const 5 + i32.store + local.get $5 + local.get $$env + i32.store offset=4 + local.get $5 + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=8 + local.get $6 + call $~lib/array/Array<%28%29=>i32>#push + drop + local.get $operations + local.set $6 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $6 + return + ) + (func $~lib/array/Array<%28%29=>i32>#__get (param $this i32) (param $index i32) (result i32) + (local $value i32) + (local $3 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 $index + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store + local.get $3 + call $~lib/array/Array<%28%29=>i32>#get:length_ + i32.ge_u + if + i32.const 224 + i32.const 704 + i32.const 114 + i32.const 42 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store + local.get $3 + call $~lib/array/Array<%28%29=>i32>#get:dataStart + local.get $index + i32.const 2 + i32.shl + i32.add + i32.load + local.tee $value + i32.store offset=4 + i32.const 1 + drop + i32.const 0 + i32.eqz + drop + local.get $value + i32.eqz + if + i32.const 784 + i32.const 704 + i32.const 118 + i32.const 40 + call $~lib/builtins/abort + unreachable + end + local.get $value + local.set $3 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + return + ) + (func $closure-complex/testFactoryWithClassMethods (result i32) + (local $counter i32) + (local $ops i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 28 + memory.fill + global.get $~lib/memory/__stack_pointer + i32.const 0 + call $closure-complex/Counter#constructor + local.tee $counter + i32.store + global.get $~lib/memory/__stack_pointer + local.get $counter + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=4 + local.get $6 + call $closure-complex/createCounterOperations + local.tee $ops + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $ops + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=4 + local.get $6 + i32.const 0 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $2 + i32.store offset=12 + local.get $2 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $2 + i32.load + call_indirect (type $2) + drop + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $ops + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=4 + local.get $6 + i32.const 0 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $3 + i32.store offset=16 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $2) + drop + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $ops + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=4 + local.get $6 + i32.const 0 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $4 + i32.store offset=20 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $2) + drop + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $ops + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=4 + local.get $6 + i32.const 1 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $5 + i32.store offset=24 + local.get $5 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $5 + i32.load + call_indirect (type $2) + local.set $6 + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $6 + return + ) + (func $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0~anonymous|0 (result i32) + (local $$closureEnv i32) + (local $calc i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/__closure_env + local.set $$closureEnv + global.get $~lib/memory/__stack_pointer + i32.const 0 + call $closure-complex/Calculator#constructor + local.tee $calc + i32.store + local.get $calc + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + local.get $$closureEnv + i32.load + i32.load + i32.load offset=4 + local.get $$closureEnv + i32.load + i32.load offset=4 + i32.add + local.get $$closureEnv + i32.load offset=4 + i32.add + call $closure-complex/Calculator#set:result + local.get $calc + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $closure-complex/Calculator#multiply (param $this i32) (param $x i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + call $closure-complex/Calculator#get:result + local.get $x + i32.mul + call $closure-complex/Calculator#set:result + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0 (result i32) + (local $$closureEnv i32) + (local $$env i32) + (local $level2Value i32) + (local $3 i32) + (local $level3 i32) + (local $5 i32) + (local $calculator i32) + (local $7 i32) + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 20 + memory.fill + global.get $~lib/__closure_env + local.set $$closureEnv + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + local.get $$closureEnv + i32.store + local.get $$env + i32.const 1 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 10 + call $~lib/rt/itcms/__new + local.set $3 + local.get $3 + i32.const 6 + i32.store + local.get $3 + local.get $$env + i32.store offset=4 + local.get $3 + local.tee $level3 + i32.store + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $level3 + local.tee $5 + i32.store offset=4 + local.get $5 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $5 + i32.load + call_indirect (type $2) + local.tee $calculator + i32.store offset=8 + local.get $calculator + local.set $7 + global.get $~lib/memory/__stack_pointer + local.get $7 + i32.store offset=16 + local.get $7 + i32.const 2 + call $closure-complex/Calculator#multiply + local.set $7 + global.get $~lib/memory/__stack_pointer + local.get $7 + i32.store offset=12 + local.get $7 + call $closure-complex/Calculator#getResult + local.set $7 + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $7 + return + ) + (func $closure-complex/ClosureFactory#constructor (param $this i32) (param $baseValue i32) (result i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 11 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + i32.const 0 + call $closure-complex/ClosureFactory#set:baseValue + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $2 + local.get $baseValue + call $closure-complex/ClosureFactory#set:baseValue + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + ) + (func $closure-complex/ClosureFactory#createAdder (param $this i32) (param $amount i32) (result i32) + (local $$env i32) + (local $base i32) + (local $counter i32) + (local $5 i32) + (local $6 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + i32.const 16 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + local.get $amount + i32.store offset=12 + local.get $$env + local.get $this + local.set $6 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store + local.get $6 + call $closure-complex/ClosureFactory#get:baseValue + i32.store offset=8 + local.get $$env + i32.const 0 + i32.store offset=4 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $5 + local.get $5 + i32.const 9 + i32.store + local.get $5 + local.get $$env + i32.store offset=4 + local.get $5 + local.set $6 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $6 + return + ) + (func $closure-complex/testClassReturningClosures (result i32) + (local $factory i32) + (local $adder i32) + (local $sum i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 20 + memory.fill + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 100 + call $closure-complex/ClosureFactory#constructor + local.tee $factory + i32.store + global.get $~lib/memory/__stack_pointer + local.get $factory + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=4 + local.get $5 + i32.const 10 + call $closure-complex/ClosureFactory#createAdder + local.tee $adder + i32.store offset=8 + i32.const 0 + local.set $sum + local.get $sum + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $adder + local.tee $3 + i32.store offset=12 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $2) + i32.add + local.set $sum + local.get $sum + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $adder + local.tee $4 + i32.store offset=16 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $2) + i32.add + local.set $sum + local.get $sum + local.set $5 + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $5 + return + ) + (func $closure-complex/SelfReferencing#constructor (param $this i32) (param $value i32) (result i32) + (local $2 i32) + (local $3 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 12 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + local.get $3 + i32.const 0 + call $closure-complex/SelfReferencing#set:value + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + local.get $3 + i32.const 0 + i32.const 2 + i32.const 8 + i32.const 1040 + call $~lib/rt/__newArray + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=8 + local.get $3 + call $closure-complex/SelfReferencing#set:callbacks + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + local.get $3 + local.get $value + call $closure-complex/SelfReferencing#set:value + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + ) + (func $closure-complex/SelfReferencing#addCallback~anonymous|0 (result i32) + (local $$closureEnv i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/SelfReferencing#get:value + i32.const 2 + i32.mul + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $closure-complex/SelfReferencing#addCallback (param $this i32) + (local $$env i32) + (local $self i32) + (local $3 i32) + (local $4 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + local.get $this + i32.store offset=4 + local.get $this + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=8 + local.get $4 + call $closure-complex/SelfReferencing#get:callbacks + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $4 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $3 + local.get $3 + i32.const 10 + i32.store + local.get $3 + local.get $$env + i32.store offset=4 + local.get $3 + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + call $~lib/array/Array<%28%29=>i32>#push + drop + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/SelfReferencing#setValue (param $this i32) (param $newValue i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + local.get $newValue + call $closure-complex/SelfReferencing#set:value + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array<%28%29=>i32>#get:length (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $~lib/array/Array<%28%29=>i32>#get:length_ + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $closure-complex/SelfReferencing#executeCallbacks (param $this i32) (result i32) + (local $sum i32) + (local $i i32) + (local $3 i32) + (local $4 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + i32.const 0 + local.set $sum + i32.const 0 + local.set $i + loop $for-loop|0 + local.get $i + local.get $this + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + call $closure-complex/SelfReferencing#get:callbacks + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $4 + call $~lib/array/Array<%28%29=>i32>#get:length + i32.lt_s + if + local.get $sum + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $this + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + call $closure-complex/SelfReferencing#get:callbacks + local.set $4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $4 + local.get $i + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $3 + i32.store offset=8 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $2) + i32.add + local.set $sum + local.get $i + i32.const 1 + i32.add + local.set $i + br $for-loop|0 + end + end + local.get $sum + local.set $4 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $4 + return + ) + (func $closure-complex/testThisCaptureInClosures (result i32) + (local $obj 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 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 10 + call $closure-complex/SelfReferencing#constructor + local.tee $obj + i32.store + local.get $obj + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + call $closure-complex/SelfReferencing#addCallback + local.get $obj + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + call $closure-complex/SelfReferencing#addCallback + local.get $obj + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + i32.const 20 + call $closure-complex/SelfReferencing#setValue + local.get $obj + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + call $closure-complex/SelfReferencing#addCallback + local.get $obj + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + call $closure-complex/SelfReferencing#executeCallbacks + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $closure-complex/testMultipleClosuresSharing~anonymous|0 + (local $$closureEnv i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.get $$closureEnv + i32.load offset=8 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/Counter#increment + i32.add + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array#get:length (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $~lib/array/Array#get:length_ + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $~lib/array/Array#__get (param $this i32) (param $index i32) (result i32) + (local $value i32) + (local $3 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $index + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store + local.get $3 + call $~lib/array/Array#get:length_ + i32.ge_u + if + i32.const 224 + i32.const 704 + i32.const 114 + i32.const 42 + call $~lib/builtins/abort + unreachable + end + local.get $this + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store + local.get $3 + call $~lib/array/Array#get:dataStart + local.get $index + i32.const 2 + i32.shl + i32.add + i32.load + local.set $value + i32.const 0 + drop + local.get $value + local.set $3 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + return + ) + (func $closure-complex/testComplexPipeline~anonymous|0 (result i32) + (local $$closureEnv i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store + local.get $1 + call $closure-complex/Counter#increment + drop + local.get $$closureEnv + i32.load offset=8 + local.get $$closureEnv + i32.load offset=12 + i32.mul + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + return + ) + (func $closure-complex/testComplexPipeline (result i32) + (local $$env i32) + (local $counter i32) + (local $2 i32) + (local $data i32) + (local $multiplier i32) + (local $result i32) + (local $i i32) + (local $value i32) + (local $8 i32) + (local $process i32) + (local $10 i32) + (local $11 i32) + global.get $~lib/memory/__stack_pointer + i32.const 16 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store offset=8 + i32.const 16 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + i32.const 0 + call $closure-complex/Counter#constructor + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 5 + i32.const 2 + i32.const 9 + i32.const 1312 + call $~lib/rt/__newArray + local.tee $data + i32.store + local.get $$env + i32.const 2 + i32.store offset=12 + i32.const 0 + local.set $result + i32.const 0 + local.set $i + loop $for-loop|1 + local.get $i + local.get $data + local.set $11 + global.get $~lib/memory/__stack_pointer + local.get $11 + i32.store offset=4 + local.get $11 + call $~lib/array/Array#get:length + i32.lt_s + if + local.get $$env + local.get $data + local.set $11 + global.get $~lib/memory/__stack_pointer + local.get $11 + i32.store offset=4 + local.get $11 + local.get $i + call $~lib/array/Array#__get + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $8 + local.get $8 + i32.const 15 + i32.store + local.get $8 + local.get $$env + i32.store offset=4 + local.get $8 + local.tee $process + i32.store offset=8 + local.get $result + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $process + local.tee $10 + i32.store offset=12 + local.get $10 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $10 + i32.load + call_indirect (type $2) + i32.add + local.set $result + local.get $i + i32.const 1 + i32.add + local.set $i + br $for-loop|1 + end + end + local.get $result + local.get $$env + i32.load offset=4 + local.set $11 + global.get $~lib/memory/__stack_pointer + local.get $11 + i32.store offset=4 + local.get $11 + call $closure-complex/Counter#getCount + i32.add + local.set $11 + global.get $~lib/memory/__stack_pointer + i32.const 16 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $11 + return + ) + (func $closure-complex/testCurriedWithClass~anonymous|0~anonymous|0 (param $x i32) (result i32) + (local $$closureEnv i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + local.get $$closureEnv + i32.load offset=4 + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + local.get $x + call $closure-complex/Calculator#add + drop + local.get $$closureEnv + i32.load offset=4 + local.set $2 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + return + ) + (func $closure-complex/testCurriedWithClass (result i32) + (local $calc i32) + (local $1 i32) + (local $addTo i32) + (local $3 i32) + (local $adder i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + global.get $~lib/memory/__stack_pointer + i32.const 32 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 32 + memory.fill + global.get $~lib/memory/__stack_pointer + i32.const 0 + call $closure-complex/Calculator#constructor + local.tee $calc + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 16 + call $~lib/rt/itcms/__new + local.set $1 + local.get $1 + i32.const 17 + i32.store + local.get $1 + i32.const 0 + i32.store offset=4 + local.get $1 + local.tee $addTo + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $calc + local.set $8 + global.get $~lib/memory/__stack_pointer + local.get $8 + i32.store offset=8 + local.get $8 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $addTo + local.tee $3 + i32.store offset=12 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $0) + local.tee $adder + i32.store offset=16 + i32.const 10 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $adder + local.tee $5 + i32.store offset=20 + local.get $5 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $5 + i32.load + call_indirect (type $0) + drop + i32.const 20 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $adder + local.tee $6 + i32.store offset=24 + local.get $6 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $6 + i32.load + call_indirect (type $0) + drop + i32.const 30 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $adder + local.tee $7 + i32.store offset=28 + local.get $7 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $7 + i32.load + call_indirect (type $0) + drop + local.get $calc + local.set $8 + global.get $~lib/memory/__stack_pointer + local.get $8 + i32.store offset=8 + local.get $8 + call $closure-complex/Calculator#getResult + local.set $8 + global.get $~lib/memory/__stack_pointer + i32.const 32 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $8 + return + ) + (func $~lib/function/Function<%28%29=>i32>#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/function/Function<%28%29=>i32>#get:_env + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/function/Function<%28i32%29=>void>#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/function/Function<%28i32%29=>void>#get:_env + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array<%28%29=>i32>#__visit (param $this i32) (param $cookie i32) + (local $cur i32) + (local $end i32) + (local $val i32) + (local $5 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + i32.const 1 + drop + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store + local.get $5 + call $~lib/array/Array<%28%29=>i32>#get:dataStart + local.set $cur + local.get $cur + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store + local.get $5 + call $~lib/array/Array<%28%29=>i32>#get:length_ + i32.const 2 + i32.shl + i32.add + local.set $end + loop $while-continue|0 + local.get $cur + local.get $end + i32.lt_u + if + local.get $cur + i32.load + local.set $val + local.get $val + if + local.get $val + local.get $cookie + call $~lib/rt/itcms/__visit + end + local.get $cur + i32.const 4 + i32.add + local.set $cur + br $while-continue|0 + end + end + local.get $this + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store + local.get $5 + call $~lib/array/Array<%28%29=>i32>#get:buffer + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + i32.const 0 + drop + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/array/Array#get:buffer + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/function/Function<%28%29=>closure-complex/Calculator>#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/function/Function<%28%29=>closure-complex/Calculator>#get:_env + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/function/Function<%28%29=>void>#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/function/Function<%28%29=>void>#get:_env + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/function/Function<%28i32%29=>%28%29=>i32>#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/function/Function<%28i32%29=>%28%29=>i32>#get:_env + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/function/Function<%28i32%29=>closure-complex/Calculator>#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/function/Function<%28i32%29=>closure-complex/Calculator>#get:_env + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator>#__visit (param $this i32) (param $cookie i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + local.set $2 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store + local.get $2 + call $~lib/function/Function<%28closure-complex/Calculator%29=>%28i32%29=>closure-complex/Calculator>#get:_env + local.get $cookie + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/object/Object#constructor (param $this i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $this + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 0 + call $~lib/rt/itcms/__new + local.tee $this + i32.store + end + local.get $this + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $closure-complex/testNestedArrowsWithClassCapture~anonymous|1 (result i32) + (local $$closureEnv i32) + (local $sum i32) + (local $i i32) + (local $3 i32) + (local $4 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/__closure_env + local.set $$closureEnv + i32.const 0 + local.set $sum + i32.const 0 + local.set $i + loop $for-loop|0 + local.get $i + i32.const 3 + i32.lt_s + if + local.get $sum + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $$closureEnv + i32.load offset=12 + local.tee $3 + i32.store + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $2) + i32.add + local.set $sum + local.get $i + i32.const 1 + i32.add + local.set $i + br $for-loop|0 + end + end + local.get $sum + local.set $4 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $4 + return + ) + (func $closure-complex/testNestedArrowsWithClassCapture (result i32) + (local $$env i32) + (local $counter i32) + (local $multiplier i32) + (local $3 i32) + (local $innerIncrement i32) + (local $5 i32) + (local $innerProcess i32) + (local $7 i32) + (local $8 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 + i32.const 16 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + i32.const 0 + call $closure-complex/Counter#constructor + i32.store offset=4 + local.get $$env + i32.const 2 + i32.store offset=8 + local.get $$env + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $3 + local.get $3 + i32.const 1 + i32.store + local.get $3 + local.get $$env + i32.store offset=4 + local.get $3 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $5 + local.get $5 + i32.const 2 + i32.store + local.get $5 + local.get $$env + i32.store offset=4 + local.get $5 + local.tee $innerProcess + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $innerProcess + local.tee $7 + i32.store offset=4 + local.get $7 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $7 + i32.load + call_indirect (type $2) + local.set $8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $8 + return + ) + (func $~lib/rt/__newArray (param $length i32) (param $alignLog2 i32) (param $id i32) (param $data i32) (result i32) + (local $bufferSize i32) + (local $buffer i32) + (local $array i32) + (local $7 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $length + local.get $alignLog2 + i32.shl + local.set $bufferSize + global.get $~lib/memory/__stack_pointer + local.get $bufferSize + i32.const 1 + local.get $data + call $~lib/rt/__newBuffer + local.tee $buffer + i32.store + i32.const 16 + local.get $id + call $~lib/rt/itcms/__new + local.set $array + local.get $array + local.get $buffer + i32.store + local.get $array + local.get $buffer + i32.const 0 + call $~lib/rt/itcms/__link + local.get $array + local.get $buffer + i32.store offset=4 + local.get $array + local.get $bufferSize + i32.store offset=8 + local.get $array + local.get $length + i32.store offset=12 + local.get $array + local.set $7 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $7 + return + ) + (func $closure-complex/testDeeplyNestedClassCreation~anonymous|0 (result i32) + (local $$closureEnv i32) + (local $$env i32) + (local $level1Value i32) + (local $3 i32) + (local $level2 i32) + (local $5 i32) + (local $6 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/__closure_env + local.set $$closureEnv + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + local.get $$closureEnv + i32.store + local.get $$env + i32.const 10 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $3 + local.get $3 + i32.const 7 + i32.store + local.get $3 + local.get $$env + i32.store offset=4 + local.get $3 + local.tee $level2 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $level2 + local.tee $5 + i32.store offset=4 + local.get $5 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $5 + i32.load + call_indirect (type $2) + local.set $6 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $6 + return + ) + (func $closure-complex/testDeeplyNestedClassCreation (result i32) + (local $$env i32) + (local $outerValue i32) + (local $2 i32) + (local $level1 i32) + (local $4 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 + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + i32.const 100 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $2 + local.get $2 + i32.const 8 + i32.store + local.get $2 + local.get $$env + i32.store offset=4 + local.get $2 + local.tee $level1 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $level1 + local.tee $4 + i32.store offset=4 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $2) + local.set $5 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $5 + return + ) + (func $closure-complex/testMultipleClosuresSharing (result i32) + (local $$env i32) + (local $shared i32) + (local $counter i32) + (local $3 i32) + (local $incrementShared i32) + (local $5 i32) + (local $getShared i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + global.get $~lib/memory/__stack_pointer + i32.const 24 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 24 + memory.fill + i32.const 12 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + i32.const 0 + i32.store offset=4 + local.get $$env + i32.const 0 + call $closure-complex/Counter#constructor + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 13 + call $~lib/rt/itcms/__new + local.set $3 + local.get $3 + i32.const 11 + i32.store + local.get $3 + local.get $$env + i32.store offset=4 + local.get $3 + local.tee $incrementShared + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.set $5 + local.get $5 + i32.const 12 + i32.store + local.get $5 + local.get $$env + i32.store offset=4 + local.get $5 + local.tee $getShared + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $incrementShared + local.tee $7 + i32.store offset=8 + local.get $7 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $7 + i32.load + call_indirect (type $5) + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $incrementShared + local.tee $8 + i32.store offset=12 + local.get $8 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $8 + i32.load + call_indirect (type $5) + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $incrementShared + local.tee $9 + i32.store offset=16 + local.get $9 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $9 + i32.load + call_indirect (type $5) + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $getShared + local.tee $10 + i32.store offset=20 + local.get $10 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $10 + i32.load + call_indirect (type $2) + local.set $11 + global.get $~lib/memory/__stack_pointer + i32.const 24 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $11 + return + ) + (func $closure-complex/testNestedArrowFunctions (result i32) + (local $$env i32) + (local $base i32) + (local $2 i32) + (local $outer i32) + (local $4 i32) + (local $fn1 i32) + (local $6 i32) + (local $fn2 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 28 + memory.fill + i32.const 8 + call $~lib/rt/tlsf/__alloc + local.set $$env + local.get $$env + i32.const 0 + i32.store + local.get $$env + i32.const 10 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 14 + call $~lib/rt/itcms/__new + local.set $2 + local.get $2 + i32.const 14 + i32.store + local.get $2 + local.get $$env + i32.store offset=4 + local.get $2 + local.tee $outer + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 5 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $outer + local.tee $4 + i32.store offset=4 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $0) + local.tee $fn1 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 10 + global.get $~lib/memory/__stack_pointer + i32.const 1 + global.set $~argumentsLength + local.get $outer + local.tee $6 + i32.store offset=12 + local.get $6 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $6 + i32.load + call_indirect (type $0) + local.tee $fn2 + i32.store offset=16 + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $fn1 + local.tee $8 + i32.store offset=20 + local.get $8 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $8 + i32.load + call_indirect (type $2) + global.get $~lib/memory/__stack_pointer + i32.const 0 + global.set $~argumentsLength + local.get $fn2 + local.tee $9 + i32.store offset=24 + local.get $9 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $9 + i32.load + call_indirect (type $2) + i32.add + local.set $10 + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $10 + return + ) +) diff --git a/tests/compiler/closure-complex.json b/tests/compiler/closure-complex.json new file mode 100644 index 0000000000..454738fb3d --- /dev/null +++ b/tests/compiler/closure-complex.json @@ -0,0 +1,5 @@ +{ + "asc_flags": [ + "--enable", "closures" + ] +} diff --git a/tests/compiler/closure-complex.release.wat b/tests/compiler/closure-complex.release.wat new file mode 100644 index 0000000000..d1282a7c4b --- /dev/null +++ b/tests/compiler/closure-complex.release.wat @@ -0,0 +1,4360 @@ +(module + (type $0 (func (result i32))) + (type $1 (func (param i32) (result i32))) + (type $2 (func)) + (type $3 (func (param i32))) + (type $4 (func (param i32 i32))) + (type $5 (func (param i32 i32) (result i32))) + (type $6 (func (param i32 i32 i32 i32))) + (type $7 (func (param i32 i32 i64))) + (type $8 (func (param i32 i32 i32))) + (type $9 (func (param i32 i32 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 $~lib/__closure_env (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 35272)) + (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) "\1c") + (data $8.1 (i32.const 1448) "\05\00\00\00\08\00\00\00\01") + (data $9 (i32.const 1468) "\1c") + (data $9.1 (i32.const 1480) "\05\00\00\00\08\00\00\00\02") + (data $10 (i32.const 1500) "<") + (data $10.1 (i32.const 1512) "\02\00\00\00$\00\00\00c\00l\00o\00s\00u\00r\00e\00-\00c\00o\00m\00p\00l\00e\00x\00.\00t\00s") + (data $11 (i32.const 1564) "\1c") + (data $11.1 (i32.const 1576) "\07\00\00\00\08\00\00\00\03") + (data $12 (i32.const 1596) "\1c") + (data $12.1 (i32.const 1608) "\01") + (data $13 (i32.const 1628) "\1c") + (data $13.1 (i32.const 1640) "\05\00\00\00\08\00\00\00\04") + (data $14 (i32.const 1660) ",") + (data $14.1 (i32.const 1672) "\02\00\00\00\1c\00\00\00I\00n\00v\00a\00l\00i\00d\00 \00l\00e\00n\00g\00t\00h") + (data $15 (i32.const 1708) ",") + (data $15.1 (i32.const 1720) "\02\00\00\00\1a\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00.\00t\00s") + (data $16 (i32.const 1756) "\1c") + (data $16.1 (i32.const 1768) "\05\00\00\00\08\00\00\00\05") + (data $17 (i32.const 1788) "|") + (data $17.1 (i32.const 1800) "\02\00\00\00^\00\00\00E\00l\00e\00m\00e\00n\00t\00 \00t\00y\00p\00e\00 \00m\00u\00s\00t\00 \00b\00e\00 \00n\00u\00l\00l\00a\00b\00l\00e\00 \00i\00f\00 \00a\00r\00r\00a\00y\00 \00i\00s\00 \00h\00o\00l\00e\00y") + (data $18 (i32.const 1916) "\1c") + (data $18.1 (i32.const 1928) "\n\00\00\00\08\00\00\00\06") + (data $19 (i32.const 1948) "\1c") + (data $19.1 (i32.const 1960) "\05\00\00\00\08\00\00\00\07") + (data $20 (i32.const 1980) "\1c") + (data $20.1 (i32.const 1992) "\05\00\00\00\08\00\00\00\08") + (data $21 (i32.const 2012) "\1c") + (data $21.1 (i32.const 2024) "\05\00\00\00\08\00\00\00\t") + (data $22 (i32.const 2044) "\1c") + (data $22.1 (i32.const 2056) "\01") + (data $23 (i32.const 2076) "\1c") + (data $23.1 (i32.const 2088) "\05\00\00\00\08\00\00\00\n") + (data $24 (i32.const 2108) "\1c") + (data $24.1 (i32.const 2120) "\r\00\00\00\08\00\00\00\0b") + (data $25 (i32.const 2140) "\1c") + (data $25.1 (i32.const 2152) "\05\00\00\00\08\00\00\00\0c") + (data $26 (i32.const 2172) "\1c") + (data $26.1 (i32.const 2184) "\05\00\00\00\08\00\00\00\r") + (data $27 (i32.const 2204) "\1c") + (data $27.1 (i32.const 2216) "\0e\00\00\00\08\00\00\00\0e") + (data $28 (i32.const 2236) ",") + (data $28.1 (i32.const 2248) "\01\00\00\00\14\00\00\00\01\00\00\00\02\00\00\00\03\00\00\00\04\00\00\00\05") + (data $29 (i32.const 2284) "\1c") + (data $29.1 (i32.const 2296) "\05\00\00\00\08\00\00\00\0f") + (data $30 (i32.const 2316) ",") + (data $30.1 (i32.const 2328) "\01\00\00\00\14\00\00\00\01\00\00\00\02\00\00\00\03\00\00\00\04\00\00\00\05") + (data $31 (i32.const 2364) "\1c") + (data $31.1 (i32.const 2376) "\0f\00\00\00\08\00\00\00\10") + (data $32 (i32.const 2396) "\1c") + (data $32.1 (i32.const 2408) "\10\00\00\00\08\00\00\00\11") + (data $33 (i32.const 2432) "\11\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00\02A\00\00\02\t\00\00\00\00\00\00 ") + (table $0 18 18 funcref) + (elem $0 (i32.const 1) $closure-complex/testNestedArrowsWithClassCapture~anonymous|0 $closure-complex/testNestedArrowsWithClassCapture~anonymous|1 $closure-complex/testArrowClosureWithClass~anonymous|0 $closure-complex/createCounterOperations~anonymous|0 $closure-complex/createCounterOperations~anonymous|1 $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0~anonymous|0 $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0 $closure-complex/testDeeplyNestedClassCreation~anonymous|0 $closure-complex/ClosureFactory#createAdder~anonymous|0 $closure-complex/SelfReferencing#addCallback~anonymous|0 $closure-complex/testMultipleClosuresSharing~anonymous|0 $closure-complex/testMultipleClosuresSharing~anonymous|1 $closure-complex/testNestedArrowFunctions~anonymous|0~anonymous|0 $closure-complex/testNestedArrowFunctions~anonymous|0 $closure-complex/testComplexPipeline~anonymous|0 $closure-complex/testCurriedWithClass~anonymous|0~anonymous|0 $closure-complex/testCurriedWithClass~anonymous|0) + (export "memory" (memory $0)) + (start $~start) + (func $~lib/rt/itcms/visitRoots + (local $0 i32) + (local $1 i32) + i32.const 1248 + call $~lib/rt/itcms/__visit + i32.const 1680 + call $~lib/rt/itcms/__visit + i32.const 1808 + 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/Object#makeGray (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + local.get $0 + global.get $~lib/rt/itcms/iter + i32.eq + if + local.get $0 + i32.load offset=8 + local.tee $1 + i32.eqz + if + i32.const 0 + i32.const 1120 + i32.const 148 + i32.const 30 + call $~lib/builtins/abort + unreachable + end + local.get $1 + global.set $~lib/rt/itcms/iter + end + block $__inlined_func$~lib/rt/itcms/Object#unlink$235 + local.get $0 + i32.load offset=4 + i32.const -4 + i32.and + local.tee $1 + i32.eqz + if + local.get $0 + i32.load offset=8 + i32.eqz + local.get $0 + i32.const 35272 + 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$235 + end + local.get $0 + 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 $1 + local.get $2 + i32.store offset=8 + local.get $2 + local.get $1 + 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 $0 + i32.load offset=12 + local.tee $1 + i32.const 2 + i32.le_u + if (result i32) + i32.const 1 + else + local.get $1 + i32.const 2432 + 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 $1 + i32.const 2 + i32.shl + i32.const 2436 + i32.add + i32.load + i32.const 32 + i32.and + end + local.set $3 + local.get $2 + i32.load offset=8 + local.set $1 + local.get $0 + 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 $0 + local.get $1 + i32.store offset=8 + local.get $1 + local.get $0 + local.get $1 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + local.get $2 + local.get $0 + i32.store offset=8 + ) + (func $~lib/rt/itcms/__visit (param $0 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 $0 + i32.load offset=4 + i32.const 3 + i32.and + i32.eq + if + local.get $0 + 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/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 35280 + i32.const 0 + i32.store + i32.const 36848 + 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 35280 + 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 35280 + 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 35280 + i32.const 36852 + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + i32.const 35280 + 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 35272 + 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 35272 + 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 35272 + 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.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 $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) (param $1 i32) (result i32) + (local $2 i32) + local.get $1 + i32.const 256 + i32.lt_u + if + local.get $1 + i32.const 4 + i32.shr_u + local.set $1 + else + local.get $1 + i32.const 536870910 + i32.lt_u + if + local.get $1 + i32.const 1 + i32.const 27 + local.get $1 + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + local.set $1 + end + local.get $1 + i32.const 31 + local.get $1 + i32.clz + i32.sub + local.tee $2 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + local.set $1 + local.get $2 + i32.const 7 + i32.sub + local.set $2 + end + local.get $1 + i32.const 16 + i32.lt_u + local.get $2 + i32.const 23 + i32.lt_u + i32.and + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 334 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $2 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + i32.const -1 + local.get $1 + i32.shl + i32.and + local.tee $1 + if (result i32) + local.get $0 + local.get $1 + i32.ctz + local.get $2 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + else + local.get $0 + i32.load + i32.const -1 + local.get $2 + i32.const 1 + i32.add + i32.shl + i32.and + local.tee $1 + if (result i32) + local.get $0 + local.get $1 + i32.ctz + local.tee $1 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + local.tee $2 + 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 $2 + i32.ctz + local.get $1 + 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/tlsf/allocateBlock (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + local.get $1 + i32.const 1073741820 + i32.gt_u + if + i32.const 1056 + i32.const 1392 + i32.const 461 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $1 + i32.const 12 + i32.le_u + if (result i32) + i32.const 12 + else + local.get $1 + i32.const 19 + i32.add + i32.const -16 + i32.and + i32.const 4 + i32.sub + end + local.tee $3 + call $~lib/rt/tlsf/searchBlock + local.tee $1 + i32.eqz + if + memory.size + local.tee $1 + local.get $3 + i32.const 256 + i32.ge_u + if (result i32) + local.get $3 + i32.const 536870910 + i32.lt_u + if (result i32) + local.get $3 + i32.const 1 + i32.const 27 + local.get $3 + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + else + local.get $3 + end + else + local.get $3 + end + i32.const 4 + local.get $0 + i32.load offset=1568 + local.get $1 + i32.const 16 + i32.shl + i32.const 4 + i32.sub + i32.ne + i32.shl + i32.add + i32.const 65535 + i32.add + i32.const -65536 + i32.and + i32.const 16 + i32.shr_u + local.tee $2 + local.get $1 + 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 $0 + local.get $1 + i32.const 16 + i32.shl + memory.size + i64.extend_i32_s + i64.const 16 + i64.shl + call $~lib/rt/tlsf/addMemory + local.get $0 + local.get $3 + call $~lib/rt/tlsf/searchBlock + local.tee $1 + i32.eqz + if + i32.const 0 + i32.const 1392 + i32.const 499 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + end + local.get $3 + local.get $1 + i32.load + i32.const -4 + i32.and + i32.gt_u + if + i32.const 0 + i32.const 1392 + i32.const 501 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $1 + call $~lib/rt/tlsf/removeBlock + local.get $1 + i32.load + local.set $4 + local.get $3 + i32.const 4 + i32.add + i32.const 15 + i32.and + if + i32.const 0 + i32.const 1392 + i32.const 361 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + i32.const -4 + i32.and + local.get $3 + i32.sub + local.tee $2 + i32.const 16 + i32.ge_u + if + local.get $1 + local.get $3 + local.get $4 + i32.const 2 + i32.and + i32.or + i32.store + local.get $1 + i32.const 4 + i32.add + local.get $3 + i32.add + local.tee $3 + local.get $2 + i32.const 4 + i32.sub + i32.const 1 + i32.or + i32.store + local.get $0 + local.get $3 + call $~lib/rt/tlsf/insertBlock + else + local.get $1 + local.get $4 + i32.const -2 + i32.and + i32.store + local.get $1 + i32.const 4 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $0 + local.get $0 + i32.load + i32.const -3 + i32.and + i32.store + end + local.get $1 + ) + (func $~lib/rt/itcms/__new (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + local.get $0 + i32.const 1073741804 + i32.ge_u + if + i32.const 1056 + i32.const 1120 + i32.const 261 + i32.const 31 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/rt/itcms/total + global.get $~lib/rt/itcms/threshold + i32.ge_u + if + block $__inlined_func$~lib/rt/itcms/interrupt$69 + i32.const 2048 + local.set $2 + loop $do-loop|0 + local.get $2 + call $~lib/rt/itcms/step + i32.sub + local.set $2 + 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 $2 + 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.get $0 + i32.const 16 + i32.add + call $~lib/rt/tlsf/allocateBlock + local.tee $2 + local.get $1 + i32.store offset=12 + local.get $2 + local.get $0 + i32.store offset=16 + global.get $~lib/rt/itcms/fromSpace + local.tee $1 + i32.load offset=8 + local.set $3 + local.get $2 + local.get $1 + global.get $~lib/rt/itcms/white + i32.or + i32.store offset=4 + local.get $2 + local.get $3 + i32.store offset=8 + local.get $3 + local.get $2 + local.get $3 + i32.load offset=4 + i32.const 3 + i32.and + i32.or + i32.store offset=4 + local.get $1 + local.get $2 + i32.store offset=8 + global.get $~lib/rt/itcms/total + local.get $2 + i32.load + i32.const -4 + i32.and + i32.const 4 + i32.add + i32.add + global.set $~lib/rt/itcms/total + local.get $2 + i32.const 20 + i32.add + local.tee $1 + i32.const 0 + local.get $0 + memory.fill + local.get $1 + ) + (func $~lib/rt/itcms/__link (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + local.get $1 + i32.eqz + if + return + end + local.get $0 + i32.eqz + if + i32.const 0 + i32.const 1120 + i32.const 295 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/rt/itcms/white + local.get $1 + i32.const 20 + i32.sub + local.tee $1 + i32.load offset=4 + i32.const 3 + i32.and + i32.eq + if + local.get $0 + i32.const 20 + i32.sub + local.tee $0 + i32.load offset=4 + i32.const 3 + i32.and + local.tee $3 + global.get $~lib/rt/itcms/white + i32.eqz + i32.eq + if + local.get $0 + local.get $1 + local.get $2 + select + call $~lib/rt/itcms/Object#makeGray + else + global.get $~lib/rt/itcms/state + i32.const 1 + i32.eq + local.get $3 + i32.const 3 + i32.eq + i32.and + if + local.get $1 + call $~lib/rt/itcms/Object#makeGray + end + end + end + ) + (func $closure-complex/ClosureFactory#createAdder~anonymous|0 (result i32) + (local $0 i32) + global.get $~lib/__closure_env + local.tee $0 + local.get $0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get $0 + i32.load offset=4 + local.get $0 + i32.load offset=8 + local.get $0 + i32.load offset=12 + i32.add + i32.add + ) + (func $closure-complex/testMultipleClosuresSharing~anonymous|1 (result i32) + global.get $~lib/__closure_env + i32.load offset=4 + ) + (func $closure-complex/testNestedArrowFunctions~anonymous|0~anonymous|0 (result i32) + global.get $~lib/__closure_env + i32.load offset=4 + i32.const 1 + i32.shl + ) + (func $closure-complex/testNestedArrowFunctions~anonymous|0 (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + global.get $~lib/__closure_env + local.set $1 + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $3 + i32.const 4 + i32.add + local.tee $2 + local.get $1 + i32.store + local.get $3 + local.get $0 + local.get $1 + i32.load offset=4 + i32.add + i32.store offset=8 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $0 + i32.const 13 + i32.store + local.get $0 + local.get $2 + i32.store offset=4 + local.get $0 + ) + (func $closure-complex/testCurriedWithClass~anonymous|0 (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $2 + i32.const 4 + i32.add + local.tee $1 + i32.const 0 + i32.store + local.get $2 + local.get $0 + i32.store offset=8 + i32.const 8 + i32.const 15 + call $~lib/rt/itcms/__new + local.tee $0 + i32.const 16 + i32.store + local.get $0 + local.get $1 + i32.store offset=4 + local.get $0 + ) + (func $start:closure-complex + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + memory.size + i32.const 16 + i32.shl + i32.const 35272 + 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 + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 16 + call $~lib/rt/tlsf/allocateBlock + local.tee $3 + i32.const 4 + i32.add + local.tee $4 + i32.const 0 + i32.store + local.get $3 + call $closure-complex/Counter#constructor + i32.store offset=8 + local.get $3 + i32.const 2 + i32.store offset=12 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $5 + i32.const 1 + i32.store + local.get $5 + local.get $4 + i32.store offset=4 + local.get $3 + local.get $5 + i32.store offset=16 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $5 + i32.const 2 + i32.store + local.get $5 + local.get $4 + i32.store offset=4 + local.get $5 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=4 + local.get $5 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $5 + i32.load + call_indirect (type $0) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 12 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 61 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 20 + memory.fill + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $3 + i32.const 4 + i32.add + local.tee $4 + i32.const 0 + i32.store + local.get $3 + call $closure-complex/Calculator#constructor + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.load offset=8 + local.tee $5 + i32.store + local.get $5 + i32.const 10 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 7 + call $~lib/rt/itcms/__new + local.tee $6 + i32.const 3 + i32.store + local.get $6 + local.get $4 + i32.store offset=4 + local.get $6 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=8 + local.get $6 + i32.load offset=4 + global.set $~lib/__closure_env + i32.const 5 + local.get $6 + i32.load + call_indirect (type $3) + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=12 + local.get $6 + i32.load offset=4 + global.set $~lib/__closure_env + i32.const 10 + local.get $6 + i32.load + call_indirect (type $3) + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=16 + local.get $6 + i32.load offset=4 + global.set $~lib/__closure_env + i32.const 15 + local.get $6 + i32.load + call_indirect (type $3) + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.load offset=8 + local.tee $3 + i32.store + local.get $3 + call $closure-complex/Calculator#getResult + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 40 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 80 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 28 + memory.fill + global.get $~lib/memory/__stack_pointer + call $closure-complex/Counter#constructor + local.tee $3 + i32.store + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $5 + i32.const 4 + i32.add + local.tee $6 + i32.const 0 + i32.store + local.get $5 + local.get $3 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 8 + i32.const 1616 + call $~lib/rt/__newArray + local.tee $3 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $5 + i32.const 4 + i32.store + local.get $5 + local.get $6 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=8 + local.get $3 + local.get $5 + call $~lib/array/Array<%28%29=>i32>#push + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $5 + i32.const 5 + i32.store + local.get $5 + local.get $6 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=8 + local.get $3 + local.get $5 + call $~lib/array/Array<%28%29=>i32>#push + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.const 0 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $4 + i32.store offset=12 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $0) + drop + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.const 0 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $4 + i32.store offset=16 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $0) + drop + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.const 0 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $4 + i32.store offset=20 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $0) + drop + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.const 1 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $3 + i32.store offset=24 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $0) + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 3 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 101 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + 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 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $3 + i32.const 4 + i32.add + local.tee $4 + i32.const 0 + i32.store + local.get $3 + i32.const 100 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $5 + i32.const 8 + i32.store + local.get $5 + local.get $4 + i32.store offset=4 + local.get $5 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=4 + local.get $5 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $5 + i32.load + call_indirect (type $0) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 222 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 130 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 20 + memory.fill + global.get $~lib/memory/__stack_pointer + 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 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 11 + call $~lib/rt/itcms/__new + local.tee $4 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + i32.const 100 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $4 + i32.store + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + 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 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 16 + call $~lib/rt/tlsf/allocateBlock + local.tee $5 + i32.const 4 + i32.add + local.tee $6 + i32.const 0 + i32.store + local.get $5 + i32.const 10 + i32.store offset=16 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $5 + local.get $4 + i32.load + i32.store offset=12 + local.get $5 + i32.const 0 + i32.store offset=8 + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $4 + i32.const 9 + i32.store + local.get $4 + local.get $6 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=12 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $0) + local.set $3 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=16 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $0) + local.get $3 + i32.add + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 223 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 162 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + 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 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 12 + call $~lib/rt/itcms/__new + local.tee $4 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + i32.const 0 + i32.const 8 + i32.const 2064 + call $~lib/rt/__newArray + local.set $5 + global.get $~lib/memory/__stack_pointer + local.get $5 + i32.store offset=8 + local.get $4 + local.get $5 + i32.store offset=4 + local.get $4 + local.get $5 + i32.const 0 + call $~lib/rt/itcms/__link + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + i32.const 10 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $4 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + call $closure-complex/SelfReferencing#addCallback + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + call $closure-complex/SelfReferencing#addCallback + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + 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 2504 + 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 $4 + i32.store + local.get $4 + i32.const 20 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + call $closure-complex/SelfReferencing#addCallback + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + loop $for-loop|0 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.load offset=4 + local.tee $3 + i32.store + local.get $3 + call $~lib/array/Array<%28%29=>i32>#get:length + local.get $2 + i32.gt_s + if + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.load offset=4 + local.tee $3 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $3 + local.get $2 + call $~lib/array/Array<%28%29=>i32>#__get + local.tee $3 + i32.store offset=8 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $0) + local.get $1 + i32.add + local.set $1 + local.get $2 + i32.const 1 + i32.add + local.set $2 + br $for-loop|0 + end + end + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + i32.const 120 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 206 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 24 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 24 + memory.fill + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 12 + call $~lib/rt/tlsf/allocateBlock + local.tee $1 + i32.const 4 + i32.add + local.tee $2 + i32.const 0 + i32.store + local.get $1 + i32.const 0 + i32.store offset=8 + local.get $1 + call $closure-complex/Counter#constructor + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 13 + call $~lib/rt/itcms/__new + local.tee $3 + i32.const 11 + i32.store + local.get $3 + local.get $2 + i32.store offset=4 + local.get $3 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $4 + i32.const 12 + i32.store + local.get $4 + local.get $2 + i32.store offset=4 + local.get $4 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=8 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $2) + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=12 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $2) + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=16 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $3 + i32.load + call_indirect (type $2) + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=20 + local.get $4 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $4 + i32.load + call_indirect (type $0) + global.get $~lib/memory/__stack_pointer + i32.const 24 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 6 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 224 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 28 + memory.fill + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $1 + i32.const 4 + i32.add + local.tee $2 + i32.const 0 + i32.store + local.get $1 + i32.const 10 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 14 + call $~lib/rt/itcms/__new + local.tee $3 + i32.const 14 + i32.store + local.get $3 + local.get $2 + i32.store offset=4 + local.get $3 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=4 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + global.get $~lib/memory/__stack_pointer + i32.const 5 + local.get $3 + i32.load + call_indirect (type $1) + local.tee $1 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.store offset=12 + local.get $3 + i32.load offset=4 + global.set $~lib/__closure_env + global.get $~lib/memory/__stack_pointer + i32.const 10 + local.get $3 + i32.load + call_indirect (type $1) + local.tee $2 + i32.store offset=16 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=20 + local.get $1 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $1 + i32.load + call_indirect (type $0) + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=24 + local.get $2 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $2 + i32.load + call_indirect (type $0) + local.get $1 + i32.add + global.get $~lib/memory/__stack_pointer + i32.const 28 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 70 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 242 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 16 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store offset=8 + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 16 + call $~lib/rt/tlsf/allocateBlock + local.tee $1 + i32.const 4 + i32.add + local.tee $3 + i32.const 0 + i32.store + local.get $1 + call $closure-complex/Counter#constructor + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 5 + i32.const 9 + i32.const 2336 + call $~lib/rt/__newArray + local.tee $4 + i32.store + local.get $1 + i32.const 2 + i32.store offset=16 + i32.const 0 + local.set $2 + loop $for-loop|1 + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + local.get $4 + call $~lib/array/Array<%28%29=>i32>#get:length + local.get $0 + i32.gt_s + if + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store offset=4 + 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 2504 + 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 $4 + i32.store + local.get $0 + local.get $4 + i32.load offset=12 + i32.ge_u + if + i32.const 1248 + i32.const 1728 + i32.const 114 + i32.const 42 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + local.get $4 + i32.store + local.get $4 + i32.load offset=4 + local.get $0 + i32.const 2 + i32.shl + i32.add + i32.load + local.set $5 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + local.get $5 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $6 + i32.const 15 + i32.store + local.get $6 + local.get $3 + i32.store offset=4 + local.get $6 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $6 + i32.store offset=12 + local.get $6 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $6 + i32.load + call_indirect (type $0) + local.get $2 + i32.add + local.set $2 + local.get $0 + i32.const 1 + i32.add + local.set $0 + br $for-loop|1 + end + end + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.load offset=8 + local.tee $0 + i32.store offset=4 + local.get $0 + call $closure-complex/Calculator#getResult + local.get $2 + i32.add + global.get $~lib/memory/__stack_pointer + i32.const 16 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 35 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 264 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 32 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 32 + memory.fill + global.get $~lib/memory/__stack_pointer + call $closure-complex/Calculator#constructor + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 16 + call $~lib/rt/itcms/__new + local.tee $2 + i32.const 17 + i32.store + local.get $2 + i32.const 0 + i32.store offset=4 + local.get $2 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=12 + local.get $2 + i32.load offset=4 + global.set $~lib/__closure_env + global.get $~lib/memory/__stack_pointer + local.get $0 + local.get $2 + i32.load + call_indirect (type $1) + local.tee $1 + i32.store offset=16 + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=20 + local.get $1 + i32.load offset=4 + global.set $~lib/__closure_env + i32.const 10 + local.get $1 + i32.load + call_indirect (type $1) + drop + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=24 + local.get $1 + i32.load offset=4 + global.set $~lib/__closure_env + i32.const 20 + local.get $1 + i32.load + call_indirect (type $1) + drop + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=28 + local.get $1 + i32.load offset=4 + global.set $~lib/__closure_env + i32.const 30 + local.get $1 + i32.load + call_indirect (type $1) + drop + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + local.get $0 + call $closure-complex/Calculator#getResult + global.get $~lib/memory/__stack_pointer + i32.const 32 + i32.add + global.set $~lib/memory/__stack_pointer + i32.const 60 + i32.ne + if + i32.const 0 + i32.const 1520 + i32.const 286 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + return + end + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + ) + (func $~lib/rt/__visit_members (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + block $folding-inner3 + block $folding-inner2 + block $folding-inner1 + block $invalid + block $closure-complex/SelfReferencing + block $closure-complex/ClosureFactory + block $~lib/array/Array + block $~lib/array/Array<%28%29=>i32> + block $closure-complex/Calculator + block $closure-complex/Counter + 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 $closure-complex/Counter $folding-inner1 $closure-complex/Calculator $folding-inner1 $~lib/array/Array<%28%29=>i32> $~lib/array/Array $folding-inner1 $closure-complex/ClosureFactory $closure-complex/SelfReferencing $folding-inner1 $folding-inner1 $folding-inner1 $folding-inner1 $invalid + end + return + end + return + end + return + end + local.get $0 + i32.load + call $~lib/rt/itcms/__visit + return + end + return + end + return + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner3 + 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 + i32.load offset=4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $1 + local.get $0 + i32.load offset=12 + i32.const 2 + i32.shl + i32.add + local.set $2 + loop $while-continue|0 + local.get $1 + local.get $2 + i32.lt_u + if + local.get $1 + i32.load + local.tee $3 + if + local.get $3 + call $~lib/rt/itcms/__visit + end + local.get $1 + i32.const 4 + i32.add + local.set $1 + br $while-continue|0 + end + end + br $folding-inner2 + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner3 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + br $folding-inner2 + end + return + end + local.get $0 + i32.load offset=4 + call $~lib/rt/itcms/__visit + return + end + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner3 + 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 + i32.load offset=4 + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + return + end + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + i32.load + call $~lib/rt/itcms/__visit + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + return + end + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + ) + (func $~start + call $start:closure-complex + ) + (func $closure-complex/Counter#constructor (result i32) + (local $0 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 4 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) + (func $closure-complex/Counter#increment (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + local.get $0 + i32.load + i32.const 1 + i32.add + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + i32.load + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/testNestedArrowsWithClassCapture~anonymous|0 (result i32) + (local $0 i32) + (local $1 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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + global.get $~lib/__closure_env + local.tee $0 + i32.load offset=4 + local.tee $1 + i32.store + local.get $1 + call $closure-complex/Counter#increment + local.get $0 + i32.load offset=8 + i32.mul + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/Calculator#constructor (result i32) + (local $0 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.const 6 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $0 + call $~lib/object/Object#constructor + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + i32.const 0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) + (func $closure-complex/Calculator#add (param $0 i32) (param $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + local.get $1 + local.get $0 + i32.load + i32.add + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/testArrowClosureWithClass~anonymous|0 (param $0 i32) + (local $1 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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + global.get $~lib/__closure_env + i32.load offset=4 + local.tee $1 + i32.store + local.get $1 + local.get $0 + call $closure-complex/Calculator#add + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/Calculator#getResult (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + i32.load + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/createCounterOperations~anonymous|0 (result i32) + (local $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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + global.get $~lib/__closure_env + i32.load offset=4 + local.tee $0 + i32.store + local.get $0 + call $closure-complex/Counter#increment + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array<%28%29=>i32>#push (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 2504 + 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 + i32.load offset=12 + local.tee $6 + i32.const 1 + i32.add + local.tee $5 + local.set $2 + 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 2504 + 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 $2 + local.get $0 + i32.load offset=8 + local.tee $3 + i32.const 2 + i32.shr_u + i32.gt_u + if + local.get $2 + i32.const 268435455 + i32.gt_u + if + i32.const 1680 + i32.const 1728 + i32.const 19 + i32.const 48 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + block $__inlined_func$~lib/rt/itcms/__renew$233 + i32.const 1073741820 + local.get $3 + i32.const 1 + i32.shl + local.tee $3 + local.get $3 + i32.const 1073741820 + i32.ge_u + select + local.tee $3 + i32.const 8 + local.get $2 + local.get $2 + i32.const 8 + i32.le_u + select + i32.const 2 + i32.shl + local.tee $2 + local.get $2 + local.get $3 + i32.lt_u + select + local.tee $4 + local.get $0 + i32.load + local.tee $3 + i32.const 20 + i32.sub + local.tee $7 + i32.load + i32.const -4 + i32.and + i32.const 16 + i32.sub + i32.le_u + if + local.get $7 + local.get $4 + i32.store offset=16 + local.get $3 + local.set $2 + br $__inlined_func$~lib/rt/itcms/__renew$233 + end + local.get $4 + local.get $7 + i32.load offset=12 + call $~lib/rt/itcms/__new + local.tee $2 + local.get $3 + local.get $4 + local.get $7 + i32.load offset=16 + local.tee $7 + local.get $4 + local.get $7 + i32.lt_u + select + memory.copy + end + local.get $2 + local.get $3 + i32.ne + if + local.get $0 + local.get $2 + i32.store + local.get $0 + local.get $2 + i32.store offset=4 + local.get $0 + local.get $2 + i32.const 0 + call $~lib/rt/itcms/__link + end + local.get $0 + local.get $4 + i32.store offset=8 + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + i32.load offset=4 + local.get $6 + i32.const 2 + i32.shl + i32.add + local.get $1 + i32.store + local.get $0 + local.get $1 + i32.const 1 + call $~lib/rt/itcms/__link + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + local.get $5 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + return + end + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + ) + (func $closure-complex/createCounterOperations~anonymous|1 (result i32) + (local $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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + global.get $~lib/__closure_env + i32.load offset=4 + local.tee $0 + i32.store + local.get $0 + call $closure-complex/Calculator#getResult + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array<%28%29=>i32>#__get (param $0 i32) (param $1 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $1 + local.get $0 + i32.load offset=12 + i32.ge_u + if + i32.const 1248 + i32.const 1728 + i32.const 114 + i32.const 42 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.load offset=4 + local.get $1 + i32.const 2 + i32.shl + i32.add + i32.load + local.tee $0 + i32.store offset=4 + local.get $0 + i32.eqz + if + i32.const 1808 + i32.const 1728 + i32.const 118 + i32.const 40 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) + (func $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0~anonymous|0 (result i32) + (local $0 i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/__closure_env + local.set $1 + global.get $~lib/memory/__stack_pointer + call $closure-complex/Calculator#constructor + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + local.get $1 + i32.load offset=4 + local.get $1 + i32.load + local.tee $1 + i32.load + i32.load offset=4 + local.get $1 + i32.load offset=4 + i32.add + i32.add + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) + (func $closure-complex/testDeeplyNestedClassCreation~anonymous|0~anonymous|0 (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.sub + global.set $~lib/memory/__stack_pointer + block $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 20 + memory.fill + global.get $~lib/__closure_env + local.set $0 + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $1 + i32.const 4 + i32.add + local.tee $2 + local.get $0 + i32.store + local.get $1 + i32.const 1 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 10 + call $~lib/rt/itcms/__new + local.tee $1 + i32.const 6 + i32.store + local.get $1 + local.get $2 + i32.store offset=4 + local.get $1 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + i32.load offset=4 + global.set $~lib/__closure_env + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.load + call_indirect (type $0) + local.tee $0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=16 + 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 2504 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + local.get $0 + i32.load + i32.const 1 + i32.shl + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=12 + local.get $0 + call $closure-complex/Calculator#getResult + global.get $~lib/memory/__stack_pointer + i32.const 20 + i32.add + global.set $~lib/memory/__stack_pointer + return + end + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + ) + (func $closure-complex/SelfReferencing#addCallback~anonymous|0 (result i32) + (local $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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + global.get $~lib/__closure_env + i32.load offset=4 + local.tee $0 + i32.store + local.get $0 + i32.load + i32.const 1 + i32.shl + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/SelfReferencing#addCallback (param $0 i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store offset=8 + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $2 + i32.const 4 + i32.add + local.tee $1 + i32.const 0 + i32.store + local.get $2 + local.get $0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.load offset=4 + local.tee $0 + i32.store + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $2 + i32.const 10 + i32.store + local.get $2 + local.get $1 + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + local.get $2 + i32.store offset=4 + local.get $0 + local.get $2 + call $~lib/array/Array<%28%29=>i32>#push + global.get $~lib/memory/__stack_pointer + i32.const 12 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/array/Array<%28%29=>i32>#get:length (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + i32.load offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/testMultipleClosuresSharing~anonymous|0 + (local $0 i32) + (local $1 i32) + (local $2 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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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/__closure_env + local.tee $0 + i32.load offset=4 + local.set $1 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.load offset=8 + local.tee $2 + i32.store + local.get $0 + local.get $2 + call $closure-complex/Counter#increment + local.get $1 + i32.add + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/testComplexPipeline~anonymous|0 (result i32) + (local $0 i32) + (local $1 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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + global.get $~lib/__closure_env + local.tee $0 + i32.load offset=4 + local.tee $1 + i32.store + local.get $1 + call $closure-complex/Counter#increment + drop + local.get $0 + i32.load offset=8 + local.get $0 + i32.load offset=12 + i32.mul + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $closure-complex/testCurriedWithClass~anonymous|0~anonymous|0 (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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 + global.get $~lib/__closure_env + local.tee $1 + i32.load offset=4 + local.tee $2 + i32.store + local.get $2 + local.get $0 + call $closure-complex/Calculator#add + local.get $1 + i32.load offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) + (func $~lib/object/Object#constructor (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.store + local.get $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 0 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + ) + (func $closure-complex/testNestedArrowsWithClassCapture~anonymous|1 (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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/__closure_env + local.set $3 + loop $for-loop|0 + local.get $0 + i32.const 3 + i32.lt_s + if + global.get $~lib/memory/__stack_pointer + local.get $3 + i32.load offset=12 + local.tee $1 + i32.store + local.get $1 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $1 + i32.load + call_indirect (type $0) + local.get $2 + i32.add + local.set $2 + local.get $0 + i32.const 1 + i32.add + local.set $0 + br $for-loop|0 + end + end + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $2 + ) + (func $~lib/rt/__newArray (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 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 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + 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.const 2 + i32.shl + local.tee $4 + i32.const 1 + call $~lib/rt/itcms/__new + local.set $3 + local.get $2 + if + local.get $3 + local.get $2 + local.get $4 + memory.copy + end + local.get $3 + i32.store + i32.const 16 + local.get $1 + call $~lib/rt/itcms/__new + local.tee $1 + local.get $3 + i32.store + local.get $1 + local.get $3 + i32.const 0 + call $~lib/rt/itcms/__link + local.get $1 + local.get $3 + i32.store offset=4 + local.get $1 + local.get $4 + i32.store offset=8 + local.get $1 + local.get $0 + i32.store offset=12 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $closure-complex/testDeeplyNestedClassCreation~anonymous|0 (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 2504 + i32.lt_s + if + i32.const 35296 + i32.const 35344 + i32.const 1 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $~lib/memory/__stack_pointer + i64.const 0 + i64.store + global.get $~lib/__closure_env + local.set $0 + global.get $~lib/rt/tlsf/ROOT + i32.eqz + if + call $~lib/rt/tlsf/initialize + end + global.get $~lib/rt/tlsf/ROOT + i32.const 8 + call $~lib/rt/tlsf/allocateBlock + local.tee $1 + i32.const 4 + i32.add + local.tee $2 + local.get $0 + i32.store + local.get $1 + i32.const 10 + i32.store offset=8 + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $1 + i32.const 7 + i32.store + local.get $1 + local.get $2 + i32.store offset=4 + local.get $1 + i32.store + global.get $~lib/memory/__stack_pointer + local.get $1 + i32.store offset=4 + local.get $1 + i32.load offset=4 + global.set $~lib/__closure_env + local.get $1 + i32.load + call_indirect (type $0) + global.get $~lib/memory/__stack_pointer + i32.const 8 + i32.add + global.set $~lib/memory/__stack_pointer + ) +) diff --git a/tests/compiler/closure-complex.ts b/tests/compiler/closure-complex.ts new file mode 100644 index 0000000000..26eeeed9be --- /dev/null +++ b/tests/compiler/closure-complex.ts @@ -0,0 +1,279 @@ +class Counter { + private count: i32 = 0; + + increment(): i32 { + this.count++; + return this.count; + } + + getCount(): i32 { + return this.count; + } +} + +class Calculator { + result: i32 = 0; + + add(x: i32): Calculator { + this.result += x; + return this; + } + + multiply(x: i32): Calculator { + this.result *= x; + return this; + } + + getResult(): i32 { + return this.result; + } +} + +// ============================================================================ +// Test 1: Nested arrow functions with class instance capture +// ============================================================================ +function testNestedArrowsWithClassCapture(): i32 { + let counter = new Counter(); + let multiplier = 2; + + let innerIncrement = (): i32 => { + let result = counter.increment(); + return result * multiplier; + }; + + let innerProcess = (): i32 => { + let sum = 0; + for (let i = 0; i < 3; i++) { + sum += innerIncrement(); + } + return sum; + }; + + return innerProcess(); // (1*2) + (2*2) + (3*2) = 12 +} +assert(testNestedArrowsWithClassCapture() == 12); + +// ============================================================================ +// Test 2: Arrow closure capturing class instance +// ============================================================================ +function testArrowClosureWithClass(): i32 { + let calc = new Calculator(); + calc.result = 10; + + let addToCalc = (x: i32): void => { + calc.add(x); + }; + + addToCalc(5); + addToCalc(10); + addToCalc(15); + + return calc.getResult(); // 10 + 5 + 10 + 15 = 40 +} +assert(testArrowClosureWithClass() == 40); + +// ============================================================================ +// Test 3: Factory function returning closures that use class methods +// ============================================================================ +function createCounterOperations(counter: Counter): Array<() => i32> { + let operations: Array<() => i32> = []; + operations.push((): i32 => counter.increment()); + operations.push((): i32 => counter.getCount()); + return operations; +} + +function testFactoryWithClassMethods(): i32 { + let counter = new Counter(); + let ops = createCounterOperations(counter); + + ops[0](); // increment -> 1 + ops[0](); // increment -> 2 + ops[0](); // increment -> 3 + return ops[1](); // getCount -> 3 +} +assert(testFactoryWithClassMethods() == 3); + +// ============================================================================ +// Test 4: Deeply nested arrow functions creating classes +// ============================================================================ +function testDeeplyNestedClassCreation(): i32 { + let outerValue = 100; + + let level1 = (): i32 => { + let level1Value = 10; + + let level2 = (): i32 => { + let level2Value = 1; + + let level3 = (): Calculator => { + let calc = new Calculator(); + calc.result = outerValue + level1Value + level2Value; + return calc; + }; + + let calculator = level3(); + return calculator.multiply(2).getResult(); + }; + + return level2(); + }; + + return level1(); // (100 + 10 + 1) * 2 = 222 +} +assert(testDeeplyNestedClassCreation() == 222); + +// ============================================================================ +// Test 5: Class with method returning closure +// ============================================================================ +class ClosureFactory { + private baseValue: i32; + + constructor(baseValue: i32) { + this.baseValue = baseValue; + } + + createAdder(amount: i32): () => i32 { + let base = this.baseValue; + let counter = 0; + return (): i32 => { + counter++; + return base + amount + counter; + }; + } +} + +function testClassReturningClosures(): i32 { + let factory = new ClosureFactory(100); + let adder = factory.createAdder(10); + + let sum = 0; + sum += adder(); // 100 + 10 + 1 = 111 + sum += adder(); // 100 + 10 + 2 = 112 + + return sum; // 111 + 112 = 223 +} +assert(testClassReturningClosures() == 223); + +// ============================================================================ +// Test 6: Closure capturing 'this' in class methods +// ============================================================================ +class SelfReferencing { + value: i32; + callbacks: Array<() => i32> = []; + + constructor(value: i32) { + this.value = value; + } + + addCallback(): void { + let self = this; + this.callbacks.push((): i32 => { + return self.value * 2; + }); + } + + executeCallbacks(): i32 { + let sum = 0; + for (let i = 0; i < this.callbacks.length; i++) { + sum += this.callbacks[i](); + } + return sum; + } + + setValue(newValue: i32): void { + this.value = newValue; + } +} + +function testThisCaptureInClosures(): i32 { + let obj = new SelfReferencing(10); + + obj.addCallback(); + obj.addCallback(); + obj.setValue(20); + obj.addCallback(); + + // value is now 20, each callback returns 40 + return obj.executeCallbacks(); // 40 + 40 + 40 = 120 +} +assert(testThisCaptureInClosures() == 120); + +// ============================================================================ +// Test 7: Multiple closures sharing same variables +// ============================================================================ +function testMultipleClosuresSharing(): i32 { + let shared = 0; + let counter = new Counter(); + + let incrementShared = (): void => { shared += counter.increment(); }; + let getShared = (): i32 => shared; + + incrementShared(); // shared = 0 + 1 = 1 + incrementShared(); // shared = 1 + 2 = 3 + incrementShared(); // shared = 3 + 3 = 6 + + return getShared(); // 6 +} +assert(testMultipleClosuresSharing() == 6); + +// ============================================================================ +// Test 8: Nested arrow functions +// ============================================================================ +function testNestedArrowFunctions(): i32 { + let base = 10; + + let outer = (x: i32): (() => i32) => { + let captured = x + base; + return (): i32 => captured * 2; + }; + + let fn1 = outer(5); // captured = 15, returns () => 30 + let fn2 = outer(10); // captured = 20, returns () => 40 + + return fn1() + fn2(); // 30 + 40 = 70 +} +assert(testNestedArrowFunctions() == 70); + +// ============================================================================ +// Test 9: Complex pipeline with closures and classes +// ============================================================================ +function testComplexPipeline(): i32 { + let counter = new Counter(); + let data: Array = [1, 2, 3, 4, 5]; + let multiplier = 2; + + let result = 0; + for (let i = 0; i < data.length; i++) { + let value = data[i]; + let process = (): i32 => { + counter.increment(); + return value * multiplier; + }; + result += process(); + } + + return result + counter.getCount(); // (2+4+6+8+10) + 5 = 30 + 5 = 35 +} +assert(testComplexPipeline() == 35); + +// ============================================================================ +// Test 10: Curried function with class +// ============================================================================ +function testCurriedWithClass(): i32 { + let calc = new Calculator(); + + let addTo = (c: Calculator): (x: i32) => Calculator => { + return (x: i32): Calculator => { + c.add(x); + return c; + }; + }; + + let adder = addTo(calc); + adder(10); + adder(20); + adder(30); + + return calc.getResult(); // 10 + 20 + 30 = 60 +} +assert(testCurriedWithClass() == 60); diff --git a/tests/compiler/closure-stress.debug.wat b/tests/compiler/closure-stress.debug.wat index 2a313fb5cc..cd4bb3a0d4 100644 --- a/tests/compiler/closure-stress.debug.wat +++ b/tests/compiler/closure-stress.debug.wat @@ -2753,8 +2753,8 @@ return ) (func $closure-stress/makeCounter (result i32) - (local $count i32) (local $$env i32) + (local $count i32) (local $2 i32) i32.const 8 call $~lib/rt/tlsf/__alloc @@ -3177,9 +3177,9 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load offset=8 - local.get $$closureEnv i32.load offset=4 + local.get $$closureEnv + i32.load offset=8 i32.add ) (func $closure-stress/makeAdder~anonymous|0 (param $x i32) (result i32) @@ -3457,11 +3457,11 @@ i32.store local.get $$env local.get $fn - i32.store offset=4 + i32.store offset=8 local.get $$env i32.const 0 call $"~lib/map/Map#constructor" - i32.store offset=8 + i32.store offset=4 i32.const 8 i32.const 11 call $~lib/rt/itcms/__new @@ -3517,8 +3517,8 @@ i32.load offset=12 ) (func $closure-stress/multipleClosureReturns (param $which i32) (result i32) - (local $a i32) (local $$env i32) + (local $a i32) (local $b i32) (local $c i32) (local $5 i32) @@ -3956,15 +3956,12 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load local.get $$closureEnv - i32.load i32.load offset=4 i32.const 1 i32.add i32.store offset=4 local.get $$closureEnv - i32.load i32.load offset=4 return ) @@ -4091,10 +4088,10 @@ i32.load offset=4 local.get $$closureEnv i32.load - i32.load offset=8 + i32.load offset=4 i32.add local.get $$closureEnv - i32.load offset=12 + i32.load offset=4 i32.add return ) @@ -4857,9 +4854,9 @@ return ) (func $closure-stress/simpleClosureArray (result i32) + (local $$env i32) (local $fns i32) (local $v0 i32) - (local $$env i32) (local $3 i32) (local $v1 i32) (local $5 i32) @@ -5347,8 +5344,8 @@ local.get $1 ) (func $closure-stress/captureArray (result i32) - (local $arr i32) (local $$env i32) + (local $arr i32) (local $2 i32) (local $sum i32) (local $4 i32) @@ -5567,8 +5564,8 @@ local.get $1 ) (func $closure-stress/mutateCapturedArray (result i32) - (local $arr i32) (local $$env i32) + (local $arr i32) (local $2 i32) (local $doubleAll i32) (local $4 i32) @@ -5968,8 +5965,8 @@ return ) (func $closure-stress/testMapWithClosure (result i32) - (local $multiplier i32) (local $$env i32) + (local $multiplier i32) (local $arr i32) (local $3 i32) (local $result i32) @@ -6238,8 +6235,8 @@ return ) (func $closure-stress/testFilterWithClosure (result i32) - (local $threshold i32) (local $$env i32) + (local $threshold i32) (local $arr i32) (local $i i32) (local $4 i32) @@ -6273,7 +6270,7 @@ i32.store i32.const 0 local.set $i - loop $for-loop|0 + loop $for-loop|1 local.get $i i32.const 10 i32.lt_s @@ -6291,7 +6288,7 @@ i32.const 1 i32.add local.set $i - br $for-loop|0 + br $for-loop|1 end end global.get $~lib/memory/__stack_pointer @@ -6402,8 +6399,8 @@ return ) (func $closure-stress/testReduceWithClosure (result i32) - (local $bonus i32) (local $$env i32) + (local $bonus i32) (local $arr i32) (local $result i32) (local $4 i32) @@ -6427,7 +6424,7 @@ i32.store local.get $$env i32.const 100 - i32.store offset=4 + i32.store offset=8 global.get $~lib/memory/__stack_pointer i32.const 0 i32.const 5 @@ -6494,7 +6491,7 @@ local.get $7 i32.const 0 call $closure-stress/reduceArray - i32.store offset=8 + i32.store offset=4 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 4 @@ -7201,7 +7198,7 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $4 global.get $~lib/memory/__stack_pointer local.get $4 @@ -7211,7 +7208,7 @@ call $"~lib/map/Map#has" if local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $4 global.get $~lib/memory/__stack_pointer local.get $4 @@ -7232,7 +7229,7 @@ i32.const 1 global.set $~argumentsLength local.get $$closureEnv - i32.load offset=4 + i32.load offset=8 local.tee $2 i32.store offset=4 local.get $2 @@ -7243,7 +7240,7 @@ call_indirect (type $1) local.set $result local.get $$closureEnv - i32.load offset=8 + i32.load offset=4 local.set $4 global.get $~lib/memory/__stack_pointer local.get $4 @@ -7786,8 +7783,8 @@ global.set $~lib/memory/__stack_pointer ) (func $closure-stress/testRangeWithClosure (result i32) - (local $sum i32) (local $$env i32) + (local $sum i32) (local $n i32) (local $3 i32) (local $4 i32) @@ -7840,8 +7837,8 @@ return ) (func $closure-stress/makeAdderPair (param $initial i32) (result i32) - (local $value i32) (local $$env i32) + (local $value i32) (local $arr i32) (local $4 i32) (local $5 i32) @@ -10050,8 +10047,8 @@ global.set $~lib/memory/__stack_pointer ) (func $closure-stress/testBidirectionalMutation (result i32) - (local $value i32) (local $$env i32) + (local $value i32) (local $2 i32) (local $setter i32) (local $4 i32) @@ -10201,8 +10198,8 @@ return ) (func $closure-stress/testSharedMutation (result i32) - (local $value i32) (local $$env i32) + (local $value i32) (local $2 i32) (local $inc i32) (local $4 i32) @@ -10370,8 +10367,8 @@ return ) (func $closure-stress/testOuterScopeMutation (result i32) - (local $value i32) (local $$env i32) + (local $value i32) (local $2 i32) (local $double i32) (local $4 i32) @@ -10519,8 +10516,8 @@ return ) (func $closure-stress/closureInConditional (param $useFirst i32) (result i32) - (local $a i32) (local $$env i32) + (local $a i32) (local $b i32) (local $getter i32) (local $5 i32) @@ -10600,10 +10597,10 @@ return ) (func $closure-stress/closureEscapingBlock (result i32) + (local $$env i32) (local $value i32) (local $captured i32) (local $inner i32) - (local $$env i32) (local $4 i32) (local $5 i32) (local $6 i32) @@ -10706,8 +10703,8 @@ local.get $1 ) (func $closure-stress/captureClassInstance (result i32) - (local $c i32) (local $$env i32) + (local $c i32) (local $2 i32) (local $inc i32) (local $4 i32) @@ -10911,8 +10908,8 @@ return ) (func $closure-stress/captureOnlyNoParams (result i32) - (local $x i32) (local $$env i32) + (local $x i32) (local $y i32) (local $3 i32) (local $fn i32) @@ -11012,8 +11009,8 @@ return ) (func $closure-stress/captureSmallTypes (result i32) - (local $a i32) (local $$env i32) + (local $a i32) (local $b i32) (local $c i32) (local $d i32) @@ -11082,8 +11079,8 @@ return ) (func $closure-stress/manyClosuresSameEnv (result i32) - (local $value i32) (local $$env i32) + (local $value i32) (local $2 i32) (local $inc1 i32) (local $4 i32) @@ -11286,8 +11283,8 @@ return ) (func $closure-stress/manyCaptures (result i32) - (local $a i32) (local $$env i32) + (local $a i32) (local $b i32) (local $c i32) (local $d i32) @@ -11388,8 +11385,8 @@ return ) (func $closure-stress/simpleIIFE (result i32) - (local $v1 i32) (local $$env i32) + (local $v1 i32) (local $2 i32) (local $3 i32) (local $result i32) @@ -11444,8 +11441,8 @@ return ) (func $closure-stress/interleavedClosures (result i32) - (local $total i32) (local $$env i32) + (local $total i32) (local $2 i32) (local $get i32) (local $4 i32) @@ -11629,8 +11626,8 @@ return ) (func $closure-stress/captureString (result i32) - (local $s i32) (local $$env i32) + (local $s i32) (local $2 i32) (local $fn i32) (local $4 i32) @@ -11687,8 +11684,8 @@ return ) (func $closure-stress/mutateStringRef (result i32) - (local $s i32) (local $$env i32) + (local $s i32) (local $2 i32) (local $append i32) (local $4 i32) @@ -11805,11 +11802,10 @@ ) (func $closure-stress/testNestedClosureFunctions~anonymous|0 (result i32) (local $$closureEnv i32) - (local $$env i32) - (local $2 i32) + (local $1 i32) (local $innerInner i32) + (local $3 i32) (local $4 i32) - (local $5 i32) global.get $~lib/memory/__stack_pointer i32.const 8 i32.sub @@ -11820,12 +11816,6 @@ i64.store global.get $~lib/__closure_env local.set $$closureEnv - i32.const 8 - call $~lib/rt/tlsf/__alloc - local.set $$env - local.get $$env - local.get $$closureEnv - i32.store local.get $$closureEnv local.get $$closureEnv i32.load offset=4 @@ -11836,42 +11826,42 @@ i32.const 8 i32.const 4 call $~lib/rt/itcms/__new - local.set $2 - local.get $2 + local.set $1 + local.get $1 i32.const 64 i32.store - local.get $2 - local.get $$env + local.get $1 + local.get $$closureEnv i32.store offset=4 - local.get $2 + local.get $1 local.tee $innerInner i32.store global.get $~lib/memory/__stack_pointer i32.const 0 global.set $~argumentsLength local.get $innerInner - local.tee $4 + local.tee $3 i32.store offset=4 - local.get $4 + local.get $3 i32.load offset=4 global.set $~lib/__closure_env - local.get $4 + local.get $3 i32.load call_indirect (type $0) drop local.get $$closureEnv i32.load offset=4 - local.set $5 + local.set $4 global.get $~lib/memory/__stack_pointer i32.const 8 i32.add global.set $~lib/memory/__stack_pointer - local.get $5 + local.get $4 return ) (func $closure-stress/testNestedClosureFunctions (result i32) - (local $x i32) (local $$env i32) + (local $x i32) (local $2 i32) (local $inner i32) (local $4 i32) @@ -11928,8 +11918,8 @@ return ) (func $closure-stress/testTwoClosuresSameVar (result i32) - (local $a i32) (local $$env i32) + (local $a i32) (local $2 i32) (local $b i32) (local $4 i32) @@ -12062,8 +12052,8 @@ ) (func $closure-stress/testDeeplyNestedClosures~anonymous|0~anonymous|0 (result i32) (local $$closureEnv i32) - (local $level3 i32) (local $$env i32) + (local $level3 i32) (local $3 i32) (local $fn3 i32) (local $5 i32) @@ -12078,7 +12068,7 @@ i64.store global.get $~lib/__closure_env local.set $$closureEnv - i32.const 16 + i32.const 8 call $~lib/rt/tlsf/__alloc local.set $$env local.get $$env @@ -12086,7 +12076,7 @@ i32.store local.get $$env i32.const 100 - i32.store offset=12 + i32.store offset=4 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 4 @@ -12123,8 +12113,8 @@ ) (func $closure-stress/testDeeplyNestedClosures~anonymous|0 (result i32) (local $$closureEnv i32) - (local $level2 i32) (local $$env i32) + (local $level2 i32) (local $3 i32) (local $fn2 i32) (local $5 i32) @@ -12139,7 +12129,7 @@ i64.store global.get $~lib/__closure_env local.set $$closureEnv - i32.const 12 + i32.const 8 call $~lib/rt/tlsf/__alloc local.set $$env local.get $$env @@ -12147,7 +12137,7 @@ i32.store local.get $$env i32.const 10 - i32.store offset=8 + i32.store offset=4 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 4 @@ -12183,8 +12173,8 @@ return ) (func $closure-stress/testDeeplyNestedClosures (result i32) - (local $level1 i32) (local $$env i32) + (local $level1 i32) (local $2 i32) (local $fn1 i32) (local $4 i32) diff --git a/tests/compiler/closure-stress.release.wat b/tests/compiler/closure-stress.release.wat index fd81fb0f00..87ccca356e 100644 --- a/tests/compiler/closure-stress.release.wat +++ b/tests/compiler/closure-stress.release.wat @@ -230,7 +230,7 @@ (data $96 (i32.const 4496) "\14\00\00\00 \00\00\00 \00\00\00 ") (data $96.1 (i32.const 4552) "\02A\00\00\02\t\00\00 \00\00\00\00\00\00\00\10\t\12") (table $0 75 75 funcref) - (elem $0 (i32.const 1) $closure-stress/captureI32Param~anonymous|0 $closure-stress/captureI64Param~anonymous|0 $closure-stress/captureF32Param~anonymous|0 $closure-stress/captureF64Param~anonymous|0 $closure-stress/captureBool~anonymous|0 $closure-stress/captureMultipleI32~anonymous|0 $closure-stress/captureMixedTypes~anonymous|0 $closure-stress/capture8Params~anonymous|0 $closure-stress/captureParamsAndLocals~anonymous|0 $closure-stress/makeCounter~anonymous|0 $closure-stress/testBidirectionalMutation~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/testSharedMutation~anonymous|0 $closure-stress/testSharedMutation~anonymous|1 $closure-stress/captureI32Param~anonymous|0 $closure-stress/testOuterScopeMutation~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/curriedAdd~anonymous|0 $closure-stress/makeGreaterThan~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/simpleClosureArray~anonymous|1 $closure-stress/simpleClosureArray~anonymous|2 $closure-stress/captureI32Param~anonymous|0 $closure-stress/simpleClosureArray~anonymous|1 $closure-stress/captureI32Param~anonymous|0 $closure-stress/captureArray~anonymous|0 $closure-stress/mutateCapturedArray~anonymous|0 $closure-stress/captureArray~anonymous|0 $closure-stress/captureClassInstance~anonymous|0 $closure-stress/captureClassInstance~anonymous|1 $closure-stress/testMapWithClosure~anonymous|0 $closure-stress/testFilterWithClosure~anonymous|0 $closure-stress/testReduceWithClosure~anonymous|0 $closure-stress/testReduceWithClosure~anonymous|1 $closure-stress/makeAdder~anonymous|0 $closure-stress/testMapWithClosure~anonymous|0 $closure-stress/compose~anonymous|0 $closure-stress/expensiveComputation $closure-stress/memoize~anonymous|0 $closure-stress/emptyClosure~anonymous|0 $closure-stress/captureOnlyNoParams~anonymous|0 $closure-stress/emptyClosure~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/simpleClosureArray~anonymous|1 $closure-stress/simpleClosureArray~anonymous|2 $closure-stress/makeFactorial~anonymous|0 $closure-stress/captureSmallTypes~anonymous|0 $closure-stress/testSharedMutation~anonymous|0 $closure-stress/manyClosuresSameEnv~anonymous|1 $closure-stress/manyClosuresSameEnv~anonymous|2 $closure-stress/manyClosuresSameEnv~anonymous|3 $closure-stress/manyClosuresSameEnv~anonymous|4 $closure-stress/captureI32Param~anonymous|0 $closure-stress/manyCaptures~anonymous|0 $closure-stress/simpleIIFE~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/testSharedMutation~anonymous|0 $closure-stress/interleavedClosures~anonymous|2 $closure-stress/interleavedClosures~anonymous|3 $closure-stress/captureString~anonymous|0 $closure-stress/mutateStringRef~anonymous|0 $closure-stress/captureString~anonymous|0 $closure-stress/testNestedClosureFunctions~anonymous|0~anonymous|0 $closure-stress/testNestedClosureFunctions~anonymous|0 $closure-stress/testRangeWithClosure~anonymous|0 $closure-stress/captureOnlyNoParams~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/makeCounter~anonymous|0 $closure-stress/testDeeplyNestedClosures~anonymous|0~anonymous|0~anonymous|0 $closure-stress/testDeeplyNestedClosures~anonymous|0~anonymous|0 $closure-stress/testDeeplyNestedClosures~anonymous|0 $closure-stress/makeCounter~anonymous|0 $closure-stress/captureI32Param~anonymous|0) + (elem $0 (i32.const 1) $closure-stress/captureI32Param~anonymous|0 $closure-stress/captureI64Param~anonymous|0 $closure-stress/captureF32Param~anonymous|0 $closure-stress/captureF64Param~anonymous|0 $closure-stress/captureBool~anonymous|0 $closure-stress/captureMultipleI32~anonymous|0 $closure-stress/captureMixedTypes~anonymous|0 $closure-stress/capture8Params~anonymous|0 $closure-stress/captureParamsAndLocals~anonymous|0 $closure-stress/makeCounter~anonymous|0 $closure-stress/testBidirectionalMutation~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/testSharedMutation~anonymous|0 $closure-stress/testSharedMutation~anonymous|1 $closure-stress/captureI32Param~anonymous|0 $closure-stress/testOuterScopeMutation~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/curriedAdd~anonymous|0 $closure-stress/makeGreaterThan~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/simpleClosureArray~anonymous|1 $closure-stress/simpleClosureArray~anonymous|2 $closure-stress/captureI32Param~anonymous|0 $closure-stress/simpleClosureArray~anonymous|1 $closure-stress/captureI32Param~anonymous|0 $closure-stress/captureArray~anonymous|0 $closure-stress/mutateCapturedArray~anonymous|0 $closure-stress/captureArray~anonymous|0 $closure-stress/captureClassInstance~anonymous|0 $closure-stress/captureClassInstance~anonymous|1 $closure-stress/testMapWithClosure~anonymous|0 $closure-stress/testFilterWithClosure~anonymous|0 $closure-stress/testReduceWithClosure~anonymous|0 $closure-stress/testReduceWithClosure~anonymous|1 $closure-stress/makeAdder~anonymous|0 $closure-stress/testMapWithClosure~anonymous|0 $closure-stress/compose~anonymous|0 $closure-stress/expensiveComputation $closure-stress/memoize~anonymous|0 $closure-stress/emptyClosure~anonymous|0 $closure-stress/testReduceWithClosure~anonymous|1 $closure-stress/emptyClosure~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/simpleClosureArray~anonymous|1 $closure-stress/simpleClosureArray~anonymous|2 $closure-stress/makeFactorial~anonymous|0 $closure-stress/captureSmallTypes~anonymous|0 $closure-stress/testSharedMutation~anonymous|0 $closure-stress/manyClosuresSameEnv~anonymous|1 $closure-stress/manyClosuresSameEnv~anonymous|2 $closure-stress/manyClosuresSameEnv~anonymous|3 $closure-stress/manyClosuresSameEnv~anonymous|4 $closure-stress/captureI32Param~anonymous|0 $closure-stress/manyCaptures~anonymous|0 $closure-stress/simpleIIFE~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/captureI32Param~anonymous|0 $closure-stress/testSharedMutation~anonymous|0 $closure-stress/interleavedClosures~anonymous|2 $closure-stress/interleavedClosures~anonymous|3 $closure-stress/captureString~anonymous|0 $closure-stress/mutateStringRef~anonymous|0 $closure-stress/captureString~anonymous|0 $closure-stress/makeCounter~anonymous|0 $closure-stress/testNestedClosureFunctions~anonymous|0 $closure-stress/testRangeWithClosure~anonymous|0 $closure-stress/testReduceWithClosure~anonymous|1 $closure-stress/captureI32Param~anonymous|0 $closure-stress/makeCounter~anonymous|0 $closure-stress/testDeeplyNestedClosures~anonymous|0~anonymous|0~anonymous|0 $closure-stress/testDeeplyNestedClosures~anonymous|0~anonymous|0 $closure-stress/testDeeplyNestedClosures~anonymous|0 $closure-stress/makeCounter~anonymous|0 $closure-stress/captureI32Param~anonymous|0) (export "memory" (memory $0)) (start $~start) (func $closure-stress/captureI32Param~anonymous|0 (result i32) @@ -311,7 +311,7 @@ local.get $1 global.set $~lib/rt/itcms/iter end - block $__inlined_func$~lib/rt/itcms/Object#unlink$369 + block $__inlined_func$~lib/rt/itcms/Object#unlink$368 local.get $0 i32.load offset=4 i32.const -4 @@ -335,7 +335,7 @@ call $~lib/builtins/abort unreachable end - br $__inlined_func$~lib/rt/itcms/Object#unlink$369 + br $__inlined_func$~lib/rt/itcms/Object#unlink$368 end local.get $0 i32.load offset=8 @@ -2196,9 +2196,9 @@ (local $0 i32) global.get $~lib/__closure_env local.tee $0 - i32.load offset=8 - local.get $0 i32.load offset=4 + local.get $0 + i32.load offset=8 i32.add ) (func $closure-stress/makeAdder~anonymous|0 (param $0 i32) (result i32) @@ -2281,15 +2281,6 @@ (func $closure-stress/emptyClosure~anonymous|0 (result i32) i32.const 42 ) - (func $closure-stress/captureOnlyNoParams~anonymous|0 (result i32) - (local $0 i32) - global.get $~lib/__closure_env - local.tee $0 - i32.load offset=4 - local.get $0 - i32.load offset=8 - i32.add - ) (func $closure-stress/multipleClosureReturns (param $0 i32) (result i32) (local $1 i32) (local $2 i32) @@ -2498,22 +2489,6 @@ global.get $~lib/__closure_env i32.load offset=4 ) - (func $closure-stress/testNestedClosureFunctions~anonymous|0~anonymous|0 (result i32) - (local $0 i32) - (local $1 i32) - global.get $~lib/__closure_env - local.tee $0 - i32.load - local.tee $1 - local.get $1 - i32.load offset=4 - i32.const 1 - i32.add - i32.store offset=4 - local.get $0 - i32.load - i32.load offset=4 - ) (func $closure-stress/testRangeWithClosure~anonymous|0 (param $0 i32) (local $1 i32) global.get $~lib/__closure_env @@ -2532,12 +2507,12 @@ i32.load local.set $0 local.get $1 - i32.load offset=12 + i32.load offset=4 local.get $0 i32.load i32.load offset=4 local.get $0 - i32.load offset=8 + i32.load offset=4 i32.add i32.add ) @@ -2881,7 +2856,7 @@ global.get $~lib/memory/__stack_pointer local.get $0 i32.store - block $__inlined_func$~lib/rt/itcms/__renew$311 + block $__inlined_func$~lib/rt/itcms/__renew$310 i32.const 1073741820 local.get $2 i32.const 1 @@ -2924,7 +2899,7 @@ i32.store offset=16 local.get $2 local.set $1 - br $__inlined_func$~lib/rt/itcms/__renew$311 + br $__inlined_func$~lib/rt/itcms/__renew$310 end local.get $3 local.get $4 @@ -4053,7 +4028,7 @@ global.get $~lib/memory/__stack_pointer global.get $~lib/__closure_env local.tee $2 - i32.load offset=8 + i32.load offset=4 local.tee $1 i32.store global.get $~lib/memory/__stack_pointer @@ -4111,7 +4086,7 @@ if global.get $~lib/memory/__stack_pointer local.get $2 - i32.load offset=8 + i32.load offset=4 local.tee $2 i32.store global.get $~lib/memory/__stack_pointer @@ -4172,7 +4147,7 @@ end global.get $~lib/memory/__stack_pointer local.get $2 - i32.load offset=4 + i32.load offset=8 local.tee $1 i32.store offset=4 local.get $1 @@ -4185,7 +4160,7 @@ local.set $1 global.get $~lib/memory/__stack_pointer local.get $2 - i32.load offset=8 + i32.load offset=4 local.tee $2 i32.store local.get $2 @@ -4437,7 +4412,7 @@ local.get $0 local.tee $1 i32.store - block $__inlined_func$~lib/string/String#concat$377 + block $__inlined_func$~lib/string/String#concat$376 local.get $0 i32.const 20 i32.sub @@ -4456,7 +4431,7 @@ global.set $~lib/memory/__stack_pointer i32.const 3936 local.set $0 - br $__inlined_func$~lib/string/String#concat$377 + br $__inlined_func$~lib/string/String#concat$376 end global.get $~lib/memory/__stack_pointer local.get $0 @@ -6631,7 +6606,7 @@ call $~lib/array/Array#constructor local.tee $0 i32.store - loop $for-loop|01 + loop $for-loop|1 local.get $1 i32.const 10 i32.lt_s @@ -6647,7 +6622,7 @@ i32.const 1 i32.add local.set $1 - br $for-loop|01 + br $for-loop|1 end end global.get $~lib/memory/__stack_pointer @@ -6687,7 +6662,7 @@ call $~lib/array/Array#constructor local.tee $4 i32.store - loop $for-loop|03 + loop $for-loop|02 global.get $~lib/memory/__stack_pointer local.get $0 i32.store offset=4 @@ -6770,7 +6745,7 @@ i32.const 1 i32.add local.set $2 - br $for-loop|03 + br $for-loop|02 end end global.get $~lib/memory/__stack_pointer @@ -6831,7 +6806,7 @@ i32.store offset=4 local.get $2 i32.const 100 - i32.store offset=8 + i32.store offset=12 global.get $~lib/memory/__stack_pointer i32.const 5 call $~lib/array/Array#constructor @@ -6889,7 +6864,7 @@ global.get $~lib/memory/__stack_pointer i64.const 0 i64.store - loop $for-loop|05 + loop $for-loop|04 global.get $~lib/memory/__stack_pointer local.get $4 i32.store @@ -6921,7 +6896,7 @@ i32.const 1 i32.add local.set $0 - br $for-loop|05 + br $for-loop|04 end end global.get $~lib/memory/__stack_pointer @@ -6930,7 +6905,7 @@ global.set $~lib/memory/__stack_pointer local.get $2 local.get $1 - i32.store offset=12 + i32.store offset=8 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 4 @@ -7218,7 +7193,7 @@ i32.store offset=4 local.get $1 i32.const 2928 - i32.store offset=8 + i32.store offset=12 global.get $~lib/memory/__stack_pointer i32.const 12 i32.sub @@ -7301,7 +7276,7 @@ global.set $~lib/memory/__stack_pointer local.get $1 local.get $3 - i32.store offset=12 + i32.store offset=8 i32.const 8 i32.const 11 call $~lib/rt/itcms/__new @@ -8095,7 +8070,7 @@ i32.store i32.const 0 local.set $0 - loop $for-loop|00 + loop $for-loop|05 local.get $0 i32.const 10 i32.lt_s @@ -8141,14 +8116,14 @@ i32.const 1 i32.add local.set $0 - br $for-loop|00 + br $for-loop|05 end end i32.const 0 local.set $0 i32.const 0 local.set $1 - loop $for-loop|1 + loop $for-loop|10 local.get $1 i32.const 10 i32.lt_s @@ -8175,7 +8150,7 @@ i32.const 1 i32.add local.set $1 - br $for-loop|1 + br $for-loop|10 end end global.get $~lib/memory/__stack_pointer @@ -8643,7 +8618,7 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.store - loop $for-loop|016 + loop $for-loop|01 local.get $1 i32.const 10 i32.lt_s @@ -8662,7 +8637,7 @@ i32.const 1 i32.add local.set $1 - br $for-loop|016 + br $for-loop|01 end end global.get $~lib/memory/__stack_pointer @@ -9308,7 +9283,6 @@ (local $0 i32) (local $1 i32) (local $2 i32) - (local $3 i32) global.get $~lib/memory/__stack_pointer i32.const 8 i32.sub @@ -9328,22 +9302,8 @@ i64.const 0 i64.store global.get $~lib/__closure_env - local.set $3 - global.get $~lib/rt/tlsf/ROOT - i32.eqz - if - call $~lib/rt/tlsf/initialize - end - global.get $~lib/rt/tlsf/ROOT - i32.const 8 - call $~lib/rt/tlsf/allocateBlock - i32.const 4 - i32.add - local.tee $0 - local.get $3 - i32.store - local.get $3 - local.get $3 + local.tee $2 + local.get $2 i32.load offset=4 i32.const 1 i32.add @@ -9352,25 +9312,25 @@ i32.const 8 i32.const 4 call $~lib/rt/itcms/__new - local.tee $2 + local.tee $1 i32.const 64 i32.store + local.get $1 local.get $2 - local.get $0 i32.store offset=4 - local.get $2 + local.get $1 i32.store global.get $~lib/memory/__stack_pointer - local.get $2 + local.get $1 i32.store offset=4 - local.get $2 + local.get $1 i32.load offset=4 global.set $~lib/__closure_env - local.get $2 + local.get $1 i32.load call_indirect (type $0) drop - local.get $3 + local.get $2 i32.load offset=4 global.get $~lib/memory/__stack_pointer i32.const 8 @@ -9407,7 +9367,7 @@ call $~lib/rt/tlsf/initialize end global.get $~lib/rt/tlsf/ROOT - i32.const 16 + i32.const 8 call $~lib/rt/tlsf/allocateBlock local.tee $1 i32.const 4 @@ -9417,7 +9377,7 @@ i32.store local.get $1 i32.const 100 - i32.store offset=16 + i32.store offset=8 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 4 @@ -9474,7 +9434,7 @@ call $~lib/rt/tlsf/initialize end global.get $~lib/rt/tlsf/ROOT - i32.const 12 + i32.const 8 call $~lib/rt/tlsf/allocateBlock local.tee $1 i32.const 4 @@ -9484,7 +9444,7 @@ i32.store local.get $1 i32.const 10 - i32.store offset=12 + i32.store offset=8 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 4 diff --git a/tests/compiler/closure.debug.wat b/tests/compiler/closure.debug.wat index 3518b2bcb7..0f7bf52bf0 100644 --- a/tests/compiler/closure.debug.wat +++ b/tests/compiler/closure.debug.wat @@ -34,10 +34,10 @@ (global $~lib/native/ASC_RUNTIME i32 (i32.const 2)) (global $closure/counter1 (mut i32) (i32.const 0)) (global $closure/counter2 (mut i32) (i32.const 0)) - (global $~lib/rt/__rtti_base i32 (i32.const 1552)) - (global $~lib/memory/__data_end i32 (i32.const 1616)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34384)) - (global $~lib/memory/__heap_base i32 (i32.const 34384)) + (global $~lib/rt/__rtti_base i32 (i32.const 1584)) + (global $~lib/memory/__data_end i32 (i32.const 1648)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 34416)) + (global $~lib/memory/__heap_base i32 (i32.const 34416)) (memory $0 1) (data $0 (i32.const 12) "\1c\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00") (data $1 (i32.const 44) "<\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") @@ -72,13 +72,14 @@ (data $30 (i32.const 1260) "\1c\00\00\00\00\00\00\00\00\00\00\00\n\00\00\00\08\00\00\00\13\00\00\00\00\00\00\00\00\00\00\00") (data $31 (i32.const 1292) "\1c\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data $32 (i32.const 1324) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\14\00\00\00\00\00\00\00\00\00\00\00") - (data $33 (i32.const 1356) "\1c\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\08\00\00\00\15\00\00\00\00\00\00\00\00\00\00\00") - (data $34 (i32.const 1388) "\1c\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\08\00\00\00\16\00\00\00\00\00\00\00\00\00\00\00") - (data $35 (i32.const 1420) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\17\00\00\00\00\00\00\00\00\00\00\00") - (data $36 (i32.const 1452) "\1c\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\08\00\00\00\18\00\00\00\00\00\00\00\00\00\00\00") - (data $37 (i32.const 1484) "\1c\00\00\00\00\00\00\00\00\00\00\00\r\00\00\00\08\00\00\00\19\00\00\00\00\00\00\00\00\00\00\00") - (data $38 (i32.const 1516) "\1c\00\00\00\00\00\00\00\00\00\00\00\0e\00\00\00\08\00\00\00\1a\00\00\00\00\00\00\00\00\00\00\00") - (data $39 (i32.const 1552) "\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\02A\00\00\02\t\00\00\00\00\00\00\00\00\00\00\02A\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $33 (i32.const 1356) "\1c\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (data $34 (i32.const 1388) "\1c\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\08\00\00\00\15\00\00\00\00\00\00\00\00\00\00\00") + (data $35 (i32.const 1420) "\1c\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\08\00\00\00\16\00\00\00\00\00\00\00\00\00\00\00") + (data $36 (i32.const 1452) "\1c\00\00\00\00\00\00\00\00\00\00\00\05\00\00\00\08\00\00\00\17\00\00\00\00\00\00\00\00\00\00\00") + (data $37 (i32.const 1484) "\1c\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\08\00\00\00\18\00\00\00\00\00\00\00\00\00\00\00") + (data $38 (i32.const 1516) "\1c\00\00\00\00\00\00\00\00\00\00\00\r\00\00\00\08\00\00\00\19\00\00\00\00\00\00\00\00\00\00\00") + (data $39 (i32.const 1548) "\1c\00\00\00\00\00\00\00\00\00\00\00\0e\00\00\00\08\00\00\00\1a\00\00\00\00\00\00\00\00\00\00\00") + (data $40 (i32.const 1584) "\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\02A\00\00\02\t\00\00\00\00\00\00\00\00\00\00\02A\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (table $0 27 27 funcref) (elem $0 (i32.const 1) $closure/testCaptureParam~anonymous|0 $closure/testCaptureVar~anonymous|0 $closure/testCaptureLet~anonymous|0 $closure/testClosureWrite~anonymous|0 $closure/testClosureWrite~anonymous|1 $closure/testMultipleCaptures~anonymous|0 $closure/testSharedEnvironment~anonymous|0 $closure/testSharedEnvironment~anonymous|1 $closure/testCaptureInWhile~anonymous|0 $closure/testCaptureInDoWhile~anonymous|0 $closure/testCaptureInFor~anonymous|0 $closure/testCaptureInSwitch~anonymous|0 $closure/testCaptureInSwitch~anonymous|1 $closure/testCaptureInSwitch~anonymous|2 $closure/testCaptureInArrayLiteral~anonymous|0 $closure/testCaptureInArrayLiteral~anonymous|1 $closure/testCaptureInArrayLiteral~anonymous|2 $closure/testNestedClosureCapture~anonymous|0~anonymous|0 $closure/testNestedClosureCapture~anonymous|0 $closure/testMultipleClosuresInArray~anonymous|0 $closure/testCaptureInTernary~anonymous|0 $closure/testCaptureFromCondition~anonymous|0 $closure/testDeepLoopCapture~anonymous|0 $closure/makeCounter~anonymous|0 $closure/testDefaultParamCapture~anonymous|0@varargs $closure/testDefaultParamWithOtherParam~anonymous|0@varargs) (export "memory" (memory $0)) @@ -2323,8 +2324,8 @@ i32.load offset=4 ) (func $closure/testCaptureVar (result i32) - (local $x i32) (local $$env i32) + (local $x i32) (local $2 i32) i32.const 8 call $~lib/rt/tlsf/__alloc @@ -2356,8 +2357,8 @@ i32.load offset=4 ) (func $closure/testCaptureLet (result i32) - (local $x i32) (local $$env i32) + (local $x i32) (local $2 i32) i32.const 8 call $~lib/rt/tlsf/__alloc @@ -2703,34 +2704,26 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load i32.load offset=4 local.get $y i32.add ) (func $closure/testNestedClosureCapture~anonymous|0 (result i32) (local $$closureEnv i32) - (local $$env i32) - (local $2 i32) + (local $1 i32) global.get $~lib/__closure_env local.set $$closureEnv i32.const 8 - call $~lib/rt/tlsf/__alloc - local.set $$env - local.get $$env - local.get $$closureEnv - i32.store - i32.const 8 i32.const 9 call $~lib/rt/itcms/__new - local.set $2 - local.get $2 + local.set $1 + local.get $1 i32.const 18 i32.store - local.get $2 - local.get $$env + local.get $1 + local.get $$closureEnv i32.store offset=4 - local.get $2 + local.get $1 return ) (func $closure/testMultipleClosuresInArray~anonymous|0 @@ -2776,9 +2769,9 @@ global.get $~lib/__closure_env local.set $$closureEnv local.get $$closureEnv - i32.load offset=8 - local.get $$closureEnv i32.load offset=4 + local.get $$closureEnv + i32.load offset=8 i32.gt_s ) (func $closure/testDeepLoopCapture~anonymous|0 @@ -2811,8 +2804,8 @@ return ) (func $closure/makeCounter (result i32) - (local $count i32) (local $$env i32) + (local $count i32) (local $2 i32) i32.const 8 call $~lib/rt/tlsf/__alloc @@ -3601,8 +3594,8 @@ global.get $~lib/memory/__data_end i32.lt_s if - i32.const 34416 - i32.const 34464 + i32.const 34448 + i32.const 34496 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -3869,8 +3862,8 @@ return ) (func $closure/testCaptureInArrayLiteral (result i32) - (local $x i32) (local $$env i32) + (local $x i32) (local $y i32) (local $3 i32) (local $4 i32) @@ -4181,8 +4174,8 @@ return ) (func $closure/testMultipleClosuresInArray (result i32) - (local $shared i32) (local $$env i32) + (local $shared i32) (local $2 i32) (local $incrementers i32) (local $i i32) @@ -4214,13 +4207,13 @@ i32.const 0 i32.const 2 i32.const 11 - i32.const 1312 + i32.const 1376 call $~lib/rt/__newArray local.tee $incrementers i32.store i32.const 0 local.set $i - loop $for-loop|0 + loop $for-loop|2 local.get $i i32.const 3 i32.lt_s @@ -4253,12 +4246,12 @@ i32.const 1 i32.add local.set $i - br $for-loop|0 + br $for-loop|2 end end i32.const 0 local.set $i|6 - loop $for-loop|1 + loop $for-loop|3 local.get $i|6 local.get $incrementers local.set $8 @@ -4292,7 +4285,7 @@ i32.const 1 i32.add local.set $i|6 - br $for-loop|1 + br $for-loop|3 end end local.get $$env @@ -4664,8 +4657,8 @@ global.set $~lib/memory/__stack_pointer ) (func $closure/testClosureWrite (result i32) - (local $counter i32) (local $$env i32) + (local $counter i32) (local $2 i32) (local $increment i32) (local $4 i32) @@ -4778,8 +4771,8 @@ return ) (func $closure/testSharedEnvironment (result i32) - (local $value i32) (local $$env i32) + (local $value i32) (local $2 i32) (local $setter i32) (local $4 i32) @@ -4869,8 +4862,8 @@ return ) (func $closure/testCaptureInWhile (result i32) - (local $sum i32) (local $$env i32) + (local $sum i32) (local $i i32) (local $3 i32) (local $adder i32) @@ -4896,7 +4889,7 @@ local.get $$env i32.const 0 i32.store offset=8 - loop $while-continue|0 + loop $while-continue|1 local.get $$env i32.load offset=8 i32.const 3 @@ -4934,7 +4927,7 @@ i32.const 1 i32.add i32.store offset=8 - br $while-continue|0 + br $while-continue|1 end end local.get $$env @@ -4948,8 +4941,8 @@ return ) (func $closure/testCaptureInDoWhile (result i32) - (local $product i32) (local $$env i32) + (local $product i32) (local $i i32) (local $3 i32) (local $multiplier i32) @@ -4975,7 +4968,7 @@ local.get $$env i32.const 1 i32.store offset=8 - loop $do-loop|0 + loop $do-loop|1 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 5 @@ -5012,7 +5005,7 @@ i32.load offset=8 i32.const 4 i32.le_s - br_if $do-loop|0 + br_if $do-loop|1 end local.get $$env i32.load offset=4 @@ -5025,8 +5018,8 @@ return ) (func $closure/testCaptureInFor (result i32) - (local $result i32) (local $$env i32) + (local $result i32) (local $i i32) (local $3 i32) (local $addI i32) @@ -5052,7 +5045,7 @@ local.get $$env i32.const 1 i32.store offset=8 - loop $for-loop|0 + loop $for-loop|1 local.get $$env i32.load offset=8 i32.const 5 @@ -5090,7 +5083,7 @@ i32.const 1 i32.add i32.store offset=8 - br $for-loop|0 + br $for-loop|1 end end local.get $$env @@ -5104,8 +5097,8 @@ return ) (func $closure/testCaptureInSwitch (param $x i32) (result i32) - (local $captured i32) (local $$env i32) + (local $captured i32) (local $3 i32) (local $4 i32) (local $setCaptured i32) @@ -5135,21 +5128,21 @@ local.get $$env i32.const 0 i32.store offset=4 - block $break|0 - block $case2|0 - block $case1|0 - block $case0|0 + block $break|1 + block $case2|1 + block $case1|1 + block $case0|1 local.get $x local.set $3 local.get $3 i32.const 1 i32.eq - br_if $case0|0 + br_if $case0|1 local.get $3 i32.const 2 i32.eq - br_if $case1|0 - br $case2|0 + br_if $case1|1 + br $case2|1 end global.get $~lib/memory/__stack_pointer i32.const 8 @@ -5177,7 +5170,7 @@ local.get $6 i32.load call_indirect (type $3) - br $break|0 + br $break|1 end global.get $~lib/memory/__stack_pointer i32.const 8 @@ -5205,7 +5198,7 @@ local.get $9 i32.load call_indirect (type $3) - br $break|0 + br $break|1 end global.get $~lib/memory/__stack_pointer i32.const 8 @@ -5233,7 +5226,7 @@ local.get $12 i32.load call_indirect (type $3) - br $break|0 + br $break|1 end local.get $$env i32.load offset=4 @@ -5299,8 +5292,8 @@ return ) (func $closure/testNestedClosureCapture (result i32) - (local $outer i32) (local $$env i32) + (local $outer i32) (local $2 i32) (local $makeAdder i32) (local $4 i32) @@ -5378,8 +5371,8 @@ return ) (func $closure/testCaptureInTernary (result i32) - (local $flag i32) (local $$env i32) + (local $flag i32) (local $a i32) (local $b i32) (local $4 i32) @@ -5474,8 +5467,8 @@ return ) (func $closure/testCaptureFromCondition (result i32) - (local $threshold i32) (local $$env i32) + (local $threshold i32) (local $value i32) (local $3 i32) (local $isAboveThreshold i32) @@ -5501,10 +5494,10 @@ i32.store local.get $$env i32.const 50 - i32.store offset=4 + i32.store offset=8 local.get $$env i32.const 75 - i32.store offset=8 + i32.store offset=4 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 12 @@ -5546,7 +5539,7 @@ end local.get $$env i32.const 25 - i32.store offset=8 + i32.store offset=4 global.get $~lib/memory/__stack_pointer i32.const 0 global.set $~argumentsLength @@ -5573,8 +5566,8 @@ return ) (func $closure/testDeepLoopCapture (result i32) - (local $total i32) (local $$env i32) + (local $total i32) (local $i i32) (local $j i32) (local $4 i32) @@ -5601,7 +5594,7 @@ local.get $$env i32.const 0 i32.store offset=8 - loop $for-loop|0 + loop $for-loop|2 local.get $$env i32.load offset=8 i32.const 2 @@ -5610,7 +5603,7 @@ local.get $$env i32.const 0 i32.store offset=12 - loop $for-loop|1 + loop $for-loop|3 local.get $$env i32.load offset=12 i32.const 2 @@ -5648,7 +5641,7 @@ i32.const 1 i32.add i32.store offset=12 - br $for-loop|1 + br $for-loop|3 end end local.get $$env @@ -5657,7 +5650,7 @@ i32.const 1 i32.add i32.store offset=8 - br $for-loop|0 + br $for-loop|2 end end local.get $$env @@ -5671,8 +5664,8 @@ return ) (func $closure/testDefaultParamCapture (result i32) - (local $defaultVal i32) (local $$env i32) + (local $defaultVal i32) (local $2 i32) (local $fn i32) (local $4 i32) @@ -5730,8 +5723,8 @@ return ) (func $closure/testDefaultParamWithOtherParam (result i32) - (local $multiplier i32) (local $$env i32) + (local $multiplier i32) (local $2 i32) (local $fn i32) (local $4 i32) diff --git a/tests/compiler/closure.release.wat b/tests/compiler/closure.release.wat index 7b855eedb1..8a8b71622e 100644 --- a/tests/compiler/closure.release.wat +++ b/tests/compiler/closure.release.wat @@ -28,7 +28,7 @@ (global $closure/fn5 (mut i32) (i32.const 0)) (global $closure/counter1 (mut i32) (i32.const 0)) (global $closure/counter2 (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 35408)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 35440)) (memory $0 1) (data $0 (i32.const 1036) "\1c") (data $0.1 (i32.const 1048) "\04\00\00\00\08\00\00\00\01") @@ -91,20 +91,22 @@ (data $32 (i32.const 2348) "\1c") (data $32.1 (i32.const 2360) "\05\00\00\00\08\00\00\00\14") (data $33 (i32.const 2380) "\1c") - (data $33.1 (i32.const 2392) "\04\00\00\00\08\00\00\00\15") + (data $33.1 (i32.const 2392) "\01") (data $34 (i32.const 2412) "\1c") - (data $34.1 (i32.const 2424) "\0c\00\00\00\08\00\00\00\16") + (data $34.1 (i32.const 2424) "\04\00\00\00\08\00\00\00\15") (data $35 (i32.const 2444) "\1c") - (data $35.1 (i32.const 2456) "\05\00\00\00\08\00\00\00\17") + (data $35.1 (i32.const 2456) "\0c\00\00\00\08\00\00\00\16") (data $36 (i32.const 2476) "\1c") - (data $36.1 (i32.const 2488) "\04\00\00\00\08\00\00\00\18") + (data $36.1 (i32.const 2488) "\05\00\00\00\08\00\00\00\17") (data $37 (i32.const 2508) "\1c") - (data $37.1 (i32.const 2520) "\r\00\00\00\08\00\00\00\19") + (data $37.1 (i32.const 2520) "\04\00\00\00\08\00\00\00\18") (data $38 (i32.const 2540) "\1c") - (data $38.1 (i32.const 2552) "\0e\00\00\00\08\00\00\00\1a") - (data $39 (i32.const 2576) "\0f\00\00\00 \00\00\00 \00\00\00 ") - (data $39.1 (i32.const 2608) "\02A\00\00\02\t") - (data $39.2 (i32.const 2624) "\02A") + (data $38.1 (i32.const 2552) "\r\00\00\00\08\00\00\00\19") + (data $39 (i32.const 2572) "\1c") + (data $39.1 (i32.const 2584) "\0e\00\00\00\08\00\00\00\1a") + (data $40 (i32.const 2608) "\0f\00\00\00 \00\00\00 \00\00\00 ") + (data $40.1 (i32.const 2640) "\02A\00\00\02\t") + (data $40.2 (i32.const 2656) "\02A") (table $0 27 27 funcref) (elem $0 (i32.const 1) $closure/testCaptureParam~anonymous|0 $closure/testCaptureParam~anonymous|0 $closure/testCaptureParam~anonymous|0 $closure/testClosureWrite~anonymous|0 $closure/testCaptureParam~anonymous|0 $closure/testMultipleCaptures~anonymous|0 $closure/testSharedEnvironment~anonymous|0 $closure/testCaptureParam~anonymous|0 $closure/testCaptureInWhile~anonymous|0 $closure/testCaptureInDoWhile~anonymous|0 $closure/testCaptureInWhile~anonymous|0 $closure/testCaptureInSwitch~anonymous|0 $closure/testCaptureInSwitch~anonymous|1 $closure/testCaptureInSwitch~anonymous|2 $closure/testCaptureParam~anonymous|0 $closure/testCaptureInArrayLiteral~anonymous|1 $closure/testCaptureInArrayLiteral~anonymous|2 $closure/testNestedClosureCapture~anonymous|0~anonymous|0 $closure/testNestedClosureCapture~anonymous|0 $closure/testClosureWrite~anonymous|0 $closure/testCaptureInTernary~anonymous|0 $closure/testCaptureFromCondition~anonymous|0 $closure/testDeepLoopCapture~anonymous|0 $closure/makeCounter~anonymous|0 $closure/testDefaultParamCapture~anonymous|0@varargs $closure/testDefaultParamWithOtherParam~anonymous|0@varargs) (export "memory" (memory $0)) @@ -185,7 +187,7 @@ local.get $1 global.set $~lib/rt/itcms/iter end - block $__inlined_func$~lib/rt/itcms/Object#unlink$200 + block $__inlined_func$~lib/rt/itcms/Object#unlink$199 local.get $0 i32.load offset=4 i32.const -4 @@ -197,7 +199,7 @@ i32.load offset=8 i32.eqz local.get $0 - i32.const 35408 + i32.const 35440 i32.lt_u i32.and i32.eqz @@ -209,7 +211,7 @@ call $~lib/builtins/abort unreachable end - br $__inlined_func$~lib/rt/itcms/Object#unlink$200 + br $__inlined_func$~lib/rt/itcms/Object#unlink$199 end local.get $0 i32.load offset=8 @@ -246,7 +248,7 @@ i32.const 1 else local.get $1 - i32.const 2576 + i32.const 2608 i32.load i32.gt_u if @@ -260,7 +262,7 @@ local.get $1 i32.const 2 i32.shl - i32.const 2580 + i32.const 2612 i32.add i32.load i32.const 32 @@ -844,10 +846,10 @@ if unreachable end - i32.const 35408 + i32.const 35440 i32.const 0 i32.store - i32.const 36976 + i32.const 37008 i32.const 0 i32.store loop $for-loop|0 @@ -858,7 +860,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 35408 + i32.const 35440 i32.add i32.const 0 i32.store offset=4 @@ -876,7 +878,7 @@ i32.add i32.const 2 i32.shl - i32.const 35408 + i32.const 35440 i32.add i32.const 0 i32.store offset=96 @@ -894,14 +896,14 @@ br $for-loop|0 end end - i32.const 35408 - i32.const 36980 + i32.const 35440 + i32.const 37012 memory.size i64.extend_i32_s i64.const 16 i64.shl call $~lib/rt/tlsf/addMemory - i32.const 35408 + i32.const 35440 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (result i32) @@ -986,7 +988,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 35408 + i32.const 35440 i32.lt_u if local.get $0 @@ -1082,7 +1084,7 @@ unreachable end local.get $0 - i32.const 35408 + i32.const 35440 i32.lt_u if local.get $0 @@ -1105,7 +1107,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 35408 + i32.const 35440 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1750,7 +1752,6 @@ ) (func $closure/testNestedClosureCapture~anonymous|0~anonymous|0 (param $0 i32) (result i32) global.get $~lib/__closure_env - i32.load i32.load offset=4 local.get $0 i32.add @@ -1760,29 +1761,16 @@ (local $1 i32) global.get $~lib/__closure_env local.set $1 - global.get $~lib/rt/tlsf/ROOT - i32.eqz - if - call $~lib/rt/tlsf/initialize - end - global.get $~lib/rt/tlsf/ROOT - i32.const 8 - call $~lib/rt/tlsf/allocateBlock - i32.const 4 - i32.add - local.tee $0 - local.get $1 - i32.store i32.const 8 i32.const 9 call $~lib/rt/itcms/__new - local.tee $1 + local.tee $0 i32.const 18 i32.store - local.get $1 local.get $0 - i32.store offset=4 local.get $1 + i32.store offset=4 + local.get $0 ) (func $closure/testCaptureInTernary~anonymous|0 (result i32) (local $0 i32) @@ -1801,9 +1789,9 @@ (local $0 i32) global.get $~lib/__closure_env local.tee $0 - i32.load offset=8 - local.get $0 i32.load offset=4 + local.get $0 + i32.load offset=8 i32.gt_s ) (func $closure/testDeepLoopCapture~anonymous|0 @@ -1878,7 +1866,7 @@ global.set $~lib/memory/__stack_pointer block $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1888,7 +1876,7 @@ memory.size i32.const 16 i32.shl - i32.const 35408 + i32.const 35440 i32.sub i32.const 1 i32.shr_u @@ -2072,7 +2060,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2239,7 +2227,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2331,7 +2319,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2357,7 +2345,7 @@ local.get $2 i32.const 0 i32.store offset=12 - loop $while-continue|0 + loop $while-continue|1 local.get $2 i32.load offset=12 i32.const 3 @@ -2392,7 +2380,7 @@ i32.const 1 i32.add i32.store offset=12 - br $while-continue|0 + br $while-continue|1 end end local.get $2 @@ -2416,7 +2404,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2442,7 +2430,7 @@ local.get $2 i32.const 1 i32.store offset=12 - loop $do-loop|0 + loop $do-loop|1 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 5 @@ -2476,7 +2464,7 @@ i32.load offset=12 i32.const 4 i32.le_s - br_if $do-loop|0 + br_if $do-loop|1 end local.get $2 i32.load offset=8 @@ -2499,7 +2487,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2525,7 +2513,7 @@ local.get $2 i32.const 1 i32.store offset=12 - loop $for-loop|0 + loop $for-loop|1 local.get $2 i32.load offset=12 i32.const 5 @@ -2560,7 +2548,7 @@ i32.const 1 i32.add i32.store offset=12 - br $for-loop|0 + br $for-loop|1 end end local.get $2 @@ -2620,7 +2608,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2772,7 +2760,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2855,7 +2843,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2884,11 +2872,11 @@ global.get $~lib/memory/__stack_pointer i32.const 0 i32.const 11 - i32.const 2336 + i32.const 2400 call $~lib/rt/__newArray local.tee $6 i32.store - loop $for-loop|00 + loop $for-loop|2 local.get $1 i32.const 3 i32.lt_s @@ -2913,7 +2901,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -2959,10 +2947,10 @@ i32.const 1 i32.add local.set $1 - br $for-loop|00 + br $for-loop|2 end end - loop $for-loop|1 + loop $for-loop|3 global.get $~lib/memory/__stack_pointer local.get $6 i32.store offset=4 @@ -2971,7 +2959,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -3012,7 +3000,7 @@ i32.const 1 i32.add local.set $0 - br $for-loop|1 + br $for-loop|3 end end local.get $4 @@ -3036,7 +3024,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -3134,7 +3122,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -3159,10 +3147,10 @@ i32.store local.get $0 i32.const 50 - i32.store offset=8 + i32.store offset=12 local.get $0 i32.const 75 - i32.store offset=12 + i32.store offset=8 global.get $~lib/memory/__stack_pointer i32.const 8 i32.const 12 @@ -3197,7 +3185,7 @@ end local.get $0 i32.const 25 - i32.store offset=12 + i32.store offset=8 i32.const 0 global.set $~argumentsLength global.get $~lib/memory/__stack_pointer @@ -3228,7 +3216,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -3254,7 +3242,7 @@ local.get $0 i32.const 0 i32.store offset=12 - loop $for-loop|01 + loop $for-loop|20 local.get $0 i32.load offset=12 i32.const 2 @@ -3263,7 +3251,7 @@ local.get $0 i32.const 0 i32.store offset=16 - loop $for-loop|12 + loop $for-loop|31 local.get $0 i32.load offset=16 i32.const 2 @@ -3298,7 +3286,7 @@ i32.const 1 i32.add i32.store offset=16 - br $for-loop|12 + br $for-loop|31 end end local.get $0 @@ -3307,7 +3295,7 @@ i32.const 1 i32.add i32.store offset=12 - br $for-loop|01 + br $for-loop|20 end end local.get $0 @@ -3445,7 +3433,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -3511,7 +3499,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -3579,8 +3567,8 @@ global.set $~lib/memory/__stack_pointer return end - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -3629,11 +3617,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s if - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -3725,7 +3713,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner1 global.get $~lib/memory/__stack_pointer @@ -3754,7 +3742,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s br_if $folding-inner1 global.get $~lib/memory/__stack_pointer @@ -3772,8 +3760,8 @@ global.set $~lib/memory/__stack_pointer return end - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -3791,11 +3779,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s if - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -3829,7 +3817,7 @@ global.get $~lib/memory/__stack_pointer local.get $0 i32.store - block $__inlined_func$~lib/rt/itcms/__renew$199 + block $__inlined_func$~lib/rt/itcms/__renew$198 i32.const 1073741820 local.get $2 i32.const 1 @@ -3872,7 +3860,7 @@ i32.store offset=16 local.get $2 local.set $1 - br $__inlined_func$~lib/rt/itcms/__renew$199 + br $__inlined_func$~lib/rt/itcms/__renew$198 end local.get $3 local.get $4 @@ -3921,11 +3909,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s if - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -3992,11 +3980,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s if - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -4058,11 +4046,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s if - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -4089,9 +4077,9 @@ local.get $2 i32.const 0 i32.store offset=8 - block $break|0 - block $case2|0 - block $case1|0 + block $break|1 + block $case2|1 + block $case1|1 local.get $0 i32.const 1 i32.ne @@ -4099,8 +4087,8 @@ local.get $0 i32.const 2 i32.eq - br_if $case1|0 - br $case2|0 + br_if $case1|1 + br $case2|1 end global.get $~lib/memory/__stack_pointer i32.const 8 @@ -4119,7 +4107,7 @@ global.get $~lib/memory/__stack_pointer local.get $0 i32.store offset=4 - br $break|0 + br $break|1 end global.get $~lib/memory/__stack_pointer i32.const 8 @@ -4138,7 +4126,7 @@ global.get $~lib/memory/__stack_pointer local.get $0 i32.store offset=12 - br $break|0 + br $break|1 end global.get $~lib/memory/__stack_pointer i32.const 8 @@ -4180,11 +4168,11 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 2640 + i32.const 2672 i32.lt_s if - i32.const 35440 - i32.const 35488 + i32.const 35472 + i32.const 35520 i32.const 1 i32.const 1 call $~lib/builtins/abort