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