From 2c009c67d304c9877963bfd7e531de0a33a0616c Mon Sep 17 00:00:00 2001
From: dcodeIO <dcode@dcode.io>
Date: Sat, 13 Jan 2018 23:38:07 +0100
Subject: [PATCH] Initial element access compilation; Carefully approaching std
 array

---
 src/ast.ts                                    |   12 +-
 src/builtins.ts                               |    4 +-
 src/compiler.ts                               |   55 +-
 src/constants.ts                              |    6 +
 src/diagnosticMessages.generated.ts           |    2 +
 src/diagnosticMessages.json                   |    1 +
 src/parser.ts                                 |   27 +-
 src/program.ts                                |   60 +-
 src/types.ts                                  |    4 +-
 std/assembly.d.ts                             |   19 +-
 std/assembly/array.ts                         |   88 +-
 tests/compiler.js                             |    8 +-
 tests/compiler/class.ts                       |    2 +-
 tests/compiler/class.wast                     |    4 +-
 .../compiler/std/array.optimized-inlined.wast | 2918 ++++++++++++++
 tests/compiler/std/array.optimized.wast       | 2911 ++++++++++++++
 tests/compiler/std/array.ts                   |   76 +-
 tests/compiler/std/array.wast                 | 3335 +++++++++++++++++
 tests/compiler/std/carray.optimized.wast      |  157 +
 tests/compiler/std/carray.ts                  |   26 +
 tests/compiler/std/carray.wast                |  287 ++
 21 files changed, 9914 insertions(+), 88 deletions(-)
 create mode 100644 tests/compiler/std/array.optimized-inlined.wast
 create mode 100644 tests/compiler/std/carray.optimized.wast
 create mode 100644 tests/compiler/std/carray.ts
 create mode 100644 tests/compiler/std/carray.wast

diff --git a/src/ast.ts b/src/ast.ts
index d5abb7f7..383d49d1 100644
--- a/src/ast.ts
+++ b/src/ast.ts
@@ -363,12 +363,12 @@ export abstract class Node {
           stmt.decoratorKind = DecoratorKind.OPERATOR;
           break;
 
-        case "struct":
-          stmt.decoratorKind = DecoratorKind.STRUCT;
+        case "explicit":
+          stmt.decoratorKind = DecoratorKind.EXPLICIT;
           break;
 
-        case "size":
-          stmt.decoratorKind = DecoratorKind.SIZE;
+        case "offset":
+          stmt.decoratorKind = DecoratorKind.OFFSET;
           break;
 
         default:
@@ -1382,8 +1382,8 @@ export const enum DecoratorKind {
   CUSTOM,
   GLOBAL,
   OPERATOR,
-  STRUCT,
-  SIZE
+  EXPLICIT,
+  OFFSET
 }
 
 /** Depresents a decorator. */
diff --git a/src/builtins.ts b/src/builtins.ts
index 760e7960..fd0aedd3 100644
--- a/src/builtins.ts
+++ b/src/builtins.ts
@@ -1349,7 +1349,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
       }
       arg0 = compiler.compileExpression(operands[0], usizeType);
       compiler.currentType = typeArguments[0];
-      return module.createLoad(typeArguments[0].size >>> 3, typeArguments[0].is(TypeFlags.SIGNED | TypeFlags.INTEGER), arg0, typeArguments[0].toNativeType());
+      return module.createLoad(typeArguments[0].byteSize, typeArguments[0].is(TypeFlags.SIGNED | TypeFlags.INTEGER), arg0, typeArguments[0].toNativeType());
 
     case "store": // store<T?>(offset: usize, value: T) -> void
       compiler.currentType = Type.void;
@@ -1372,7 +1372,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
       }
       type = compiler.currentType;
       compiler.currentType = Type.void;
-      return module.createStore(type.size >>> 3, arg0, arg1, type.toNativeType());
+      return module.createStore(type.byteSize, arg0, arg1, type.toNativeType());
 
     case "sizeof": // sizeof<T!>() -> usize
       compiler.currentType = usizeType;
diff --git a/src/compiler.ts b/src/compiler.ts
index ff29563d..0d696dbd 100644
--- a/src/compiler.ts
+++ b/src/compiler.ts
@@ -2217,6 +2217,16 @@ export class Compiler extends DiagnosticEmitter {
         this.error(DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, expression.range, (<Property>element).internalName);
         return this.module.createUnreachable();
 
+      case ElementKind.FUNCTION_PROTOTYPE:
+        if (expression.kind == NodeKind.ELEMENTACCESS) { // @operator("[]")
+          assert(resolved.target && resolved.target.kind == ElementKind.CLASS && element.simpleName == (<Class>resolved.target).prototype.fnIndexedGet)
+          var resolvedIndexedSet = (<FunctionPrototype>element).resolve(null);
+          if (resolvedIndexedSet) {
+            elementType = resolvedIndexedSet.returnType;
+            break;
+          }
+        }
+        // fall-through
       default:
         this.error(DiagnosticCode.Operation_not_supported, expression.range);
         return this.module.createUnreachable();
@@ -2275,11 +2285,11 @@ export class Compiler extends DiagnosticEmitter {
         this.currentType = tee ? (<Field>element).type : Type.void;
         var elementNativeType = (<Field>element).type.toNativeType();
         if (!tee)
-          return this.module.createStore((<Field>element).type.byteSize, targetExpr, valueWithCorrectType, elementNativeType, (<Field>element).memoryOffset);
+          return this.module.createStore((<Field>element).type.size >> 3, targetExpr, valueWithCorrectType, elementNativeType, (<Field>element).memoryOffset);
         tempLocal = this.currentFunction.getAndFreeTempLocal((<Field>element).type);
         return this.module.createBlock(null, [ // TODO: simplify if valueWithCorrectType has no side effects
           this.module.createSetLocal(tempLocal.index, valueWithCorrectType),
-          this.module.createStore((<Field>element).type.byteSize, targetExpr, this.module.createGetLocal(tempLocal.index, elementNativeType), elementNativeType, (<Field>element).memoryOffset),
+          this.module.createStore((<Field>element).type.size >> 3, targetExpr, this.module.createGetLocal(tempLocal.index, elementNativeType), elementNativeType, (<Field>element).memoryOffset),
           this.module.createGetLocal(tempLocal.index, elementNativeType)
         ], elementNativeType);
 
@@ -2325,6 +2335,38 @@ export class Compiler extends DiagnosticEmitter {
         } else
           this.error(DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, expression.range, (<Property>element).internalName);
         return this.module.createUnreachable();
+
+      case ElementKind.FUNCTION_PROTOTYPE:
+        if (expression.kind == NodeKind.ELEMENTACCESS) { // @operator("[]")
+          assert(resolved.target && resolved.target.kind == ElementKind.CLASS);
+          var resolvedIndexedGet = (<FunctionPrototype>element).resolve();
+          if (!resolvedIndexedGet)
+            return this.module.createUnreachable();
+          var indexedSetName = (<Class>resolved.target).prototype.fnIndexedSet;
+          var indexedSet: Element | null;
+          if (indexedSetName != null && (<Class>resolved.target).members && (indexedSet = (<Map<string,Element>>(<Class>resolved.target).members).get(indexedSetName)) && indexedSet.kind == ElementKind.FUNCTION_PROTOTYPE) { // @operator("[]=")
+            var resolvedIndexedSet = (<FunctionPrototype>indexedSet).resolve();
+            if (!resolvedIndexedSet)
+              return this.module.createUnreachable();
+            targetExpr = this.compileExpression(<Expression>resolved.targetExpression, this.options.target == Target.WASM64 ? Type.usize64 : Type.usize32, ConversionKind.NONE);
+            assert(this.currentType.classType);
+            var elementExpr = this.compileExpression((<ElementAccessExpression>expression).elementExpression, Type.i32);
+            if (!tee) {
+              this.currentType = resolvedIndexedSet.returnType;
+              return this.makeCall(resolvedIndexedSet, [ targetExpr, elementExpr, valueWithCorrectType ]);
+            }
+            this.currentType = resolvedIndexedGet.returnType;
+            tempLocal = this.currentFunction.getAndFreeTempLocal(this.currentType);
+            return this.module.createBlock(null, [
+              this.makeCall(resolvedIndexedSet, [ targetExpr, elementExpr, this.module.createTeeLocal(tempLocal.index, valueWithCorrectType) ]),
+              this.module.createGetLocal(tempLocal.index, tempLocal.type.toNativeType()) // TODO: could be different from an actual __get (needs 2 temp locals)
+            ], this.currentType.toNativeType());
+          } else {
+            this.error(DiagnosticCode.Index_signature_in_type_0_only_permits_reading, expression.range, (<Class>resolved.target).internalName);
+            return this.module.createUnreachable();
+          }
+        }
+        // fall-through
     }
     this.error(DiagnosticCode.Operation_not_supported, expression.range);
     return this.module.createUnreachable();
@@ -2465,8 +2507,11 @@ export class Compiler extends DiagnosticEmitter {
     var resolved = this.program.resolveElementAccess(expression, this.currentFunction); // reports
     if (!resolved)
       return this.module.createUnreachable();
-
-    throw new Error("not implemented"); // TODO
+    assert(resolved.element.kind == ElementKind.FUNCTION_PROTOTYPE && resolved.target && resolved.target.kind == ElementKind.CLASS);
+    var instance = (<FunctionPrototype>resolved.element).resolve(null, (<Class>resolved.target).contextualTypeArguments);
+    if (!instance)
+      return this.module.createUnreachable();
+    return this.compileCall(instance, [ expression.expression, expression.elementExpression ], expression);
   }
 
   compileIdentifierExpression(expression: IdentifierExpression, contextualType: Type): ExpressionRef {
@@ -2632,7 +2677,7 @@ export class Compiler extends DiagnosticEmitter {
         assert((<Field>element).memoryOffset >= 0);
         targetExpr = this.compileExpression(<Expression>resolved.targetExpression, this.options.target == Target.WASM64 ? Type.usize64 : Type.usize32);
         this.currentType = (<Field>element).type;
-        return this.module.createLoad((<Field>element).type.byteSize, (<Field>element).type.is(TypeFlags.SIGNED | TypeFlags.INTEGER),
+        return this.module.createLoad((<Field>element).type.size >> 3, (<Field>element).type.is(TypeFlags.SIGNED | TypeFlags.INTEGER),
           targetExpr,
           (<Field>element).type.toNativeType(),
           (<Field>element).memoryOffset
diff --git a/src/constants.ts b/src/constants.ts
index 205980c3..c596b068 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,8 +1,14 @@
 // internal naming scheme
 
+/** Path delimited inserted between file system levels. */
 export const PATH_DELIMITER = "/";
+/** Substitution used to indicate the parent directory. */
 export const PARENT_SUBST = "..";
+/** Function name prefix used for getters. */
 export const GETTER_PREFIX = "get:";
+/** Function name prefix used for setters. */
 export const SETTER_PREFIX = "set:";
+/** Delimiter used between class names and instance members. */
 export const INSTANCE_DELIMITER = "#";
+/** Delimited used between class and namespace names and static members. */
 export const STATIC_DELIMITER = ".";
diff --git a/src/diagnosticMessages.generated.ts b/src/diagnosticMessages.generated.ts
index cb20ec77..2a6c9f4e 100644
--- a/src/diagnosticMessages.generated.ts
+++ b/src/diagnosticMessages.generated.ts
@@ -79,6 +79,7 @@ export enum DiagnosticCode {
   Export_declaration_conflicts_with_exported_declaration_of_0 = 2484,
   Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property = 2540,
   The_target_of_an_assignment_must_be_a_variable_or_a_property_access = 2541,
+  Index_signature_in_type_0_only_permits_reading = 2542,
   Expected_0_arguments_but_got_1 = 2554,
   Expected_at_least_0_arguments_but_got_1 = 2555,
   Expected_0_type_arguments_but_got_1 = 2558,
@@ -166,6 +167,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
     case 2484: return "Export declaration conflicts with exported declaration of '{0}'.";
     case 2540: return "Cannot assign to '{0}' because it is a constant or a read-only property.";
     case 2541: return "The target of an assignment must be a variable or a property access.";
+    case 2542: return "Index signature in type '{0}' only permits reading.";
     case 2554: return "Expected {0} arguments, but got {1}.";
     case 2555: return "Expected at least {0} arguments, but got {1}.";
     case 2558: return "Expected {0} type arguments, but got {1}.";
diff --git a/src/diagnosticMessages.json b/src/diagnosticMessages.json
index a91c46ac..ef824f3e 100644
--- a/src/diagnosticMessages.json
+++ b/src/diagnosticMessages.json
@@ -79,6 +79,7 @@
   "Export declaration conflicts with exported declaration of '{0}'.": 2484,
   "Cannot assign to '{0}' because it is a constant or a read-only property.": 2540,
   "The target of an assignment must be a variable or a property access.": 2541,
+  "Index signature in type '{0}' only permits reading.": 2542,
   "Expected {0} arguments, but got {1}.": 2554,
   "Expected at least {0} arguments, but got {1}.": 2555,
   "Expected {0} type arguments, but got {1}.": 2558,
diff --git a/src/parser.ts b/src/parser.ts
index 80acd2e7..a61cb28e 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -1580,6 +1580,19 @@ export class Parser extends DiagnosticEmitter {
 
     var startPos = expr.range.start;
 
+    // ElementAccessExpression
+    if (tn.skip(Token.OPENBRACKET)) {
+      next = this.parseExpression(tn); // resets precedence
+      if (!next)
+        return null;
+      if (tn.skip(Token.CLOSEBRACKET))
+        expr = Node.createElementAccessExpression(<Expression>expr, <Expression>next, tn.range(startPos, tn.pos));
+      else {
+        this.error(DiagnosticCode._0_expected, tn.range(), "]");
+        return null;
+      }
+    }
+
     // CallExpression
     var typeArguments = this.tryParseTypeArgumentsBeforeArguments(tn); // skips '(' on success
     // there might be better ways to distinguish a LESSTHAN from a CALL with type arguments
@@ -1593,7 +1606,6 @@ export class Parser extends DiagnosticEmitter {
     var token: Token;
     var next: Expression | null = null;
     var nextPrecedence: Precedence;
-
     while ((nextPrecedence = determinePrecedence(token = tn.peek())) >= precedence) { // precedence climbing
       tn.next();
 
@@ -1604,19 +1616,6 @@ export class Parser extends DiagnosticEmitter {
           return null;
         expr = Node.createAssertionExpression(AssertionKind.AS, expr, toType, tn.range(startPos, tn.pos));
 
-      // ElementAccessExpression
-      } else if (token == Token.OPENBRACKET) {
-        next = this.parseExpression(tn); // resets precedence
-        if (!next)
-          return null;
-
-        if (tn.skip(Token.CLOSEBRACKET))
-          expr = Node.createElementAccessExpression(<Expression>expr, <Expression>next, tn.range(startPos, tn.pos));
-        else {
-          this.error(DiagnosticCode._0_expected, tn.range(), "]");
-          return null;
-        }
-
       // UnaryPostfixExpression
       } else if (token == Token.PLUS_PLUS || token == Token.MINUS_MINUS) {
         if (expr.kind != NodeKind.IDENTIFIER && expr.kind != NodeKind.ELEMENTACCESS && expr.kind != NodeKind.PROPERTYACCESS)
diff --git a/src/program.ts b/src/program.ts
index 6570186a..5907e2bd 100644
--- a/src/program.ts
+++ b/src/program.ts
@@ -290,8 +290,8 @@ export class Program extends DiagnosticEmitter {
 
     this.checkGlobalAlias(prototype, declaration);
 
-    if (hasDecorator("struct", declaration.decorators)) {
-      prototype.isStruct = true;
+    if (hasDecorator("explicit", declaration.decorators)) {
+      prototype.isExplicit = true;
       if (declaration.implementsTypes && declaration.implementsTypes.length)
         this.error(DiagnosticCode.Structs_cannot_implement_interfaces, Range.join(declaration.name.range, declaration.implementsTypes[declaration.implementsTypes.length - 1].range));
     } else if (declaration.implementsTypes.length)
@@ -413,8 +413,8 @@ export class Program extends DiagnosticEmitter {
       } else
         classPrototype.instanceMembers = new Map();
       instancePrototype = new FunctionPrototype(this, name, internalName, declaration, classPrototype);
-      // if (classPrototype.isStruct && instancePrototype.isAbstract) {
-      //   this.error( Structs cannot declare abstract methods. );
+      // if (classPrototype.isExplicit && instancePrototype.isAbstract) {
+      //   this.error( Explicit classes cannot declare abstract methods. );
       // }
       classPrototype.instanceMembers.set(name, instancePrototype);
     }
@@ -436,19 +436,19 @@ export class Program extends DiagnosticEmitter {
               switch ((<StringLiteralExpression>firstArg).value) {
 
                 case "[]":
-                  classPrototype.opIndexedGet = instancePrototype;
+                  classPrototype.fnIndexedGet = instancePrototype.simpleName;
                   break;
 
                 case "[]=":
-                  classPrototype.opIndexedSet = instancePrototype;
+                  classPrototype.fnIndexedSet = instancePrototype.simpleName;
                   break;
 
                 case "+":
-                  classPrototype.opConcat = instancePrototype;
+                  classPrototype.fnConcat = instancePrototype.simpleName;
                   break;
 
                 case "==":
-                  classPrototype.opEquals = instancePrototype;
+                  classPrototype.fnEquals = instancePrototype.simpleName;
                   break;
 
                 default: // TBD: does it make sense to provide more, even though not JS/TS-compatible?
@@ -1078,13 +1078,15 @@ export class Program extends DiagnosticEmitter {
     var target = resolvedElement.element;
     switch (target.kind) {
 
-      // TBD: should indexed access on static classes, like `Heap`, be a supported as well?
-      case ElementKind.CLASS:
-        var type = (<Class>target).type;
+      case ElementKind.GLOBAL:
+      case ElementKind.LOCAL:
+      case ElementKind.FIELD:
+        var type = (<VariableLikeElement>target).type;
         if (type.classType) {
-          var indexedGet: FunctionPrototype | null;
-          if (indexedGet = (target = type.classType).prototype.opIndexedGet)
-            return resolvedElement.set(indexedGet).withTarget(target, targetExpression);
+          var indexedGetName = (target = type.classType).prototype.fnIndexedGet;
+          var indexedGet: Element | null;
+          if (indexedGetName != null && target.members && (indexedGet = target.members.get(indexedGetName)) && indexedGet.kind == ElementKind.FUNCTION_PROTOTYPE)
+            return resolvedElement.set(indexedGet).withTarget(type.classType, targetExpression);
         }
         break;
     }
@@ -1221,8 +1223,8 @@ export enum ElementFlags {
   PRIVATE = 1 << 15,
   /** Is an abstract member. */
   ABSTRACT = 1 << 16,
-  /** Is a struct-like class with limited capabilites. */
-  STRUCT = 1 << 17,
+  /** Is an explicitly layed out and allocated class with limited capabilites. */
+  EXPLICIT = 1 << 17,
   /** Has already inherited base class static members. */
   HAS_STATIC_BASE_MEMBERS = 1 << 18
 }
@@ -1877,13 +1879,13 @@ export class ClassPrototype extends Element {
   basePrototype: ClassPrototype | null = null; // set in Program#initialize
 
   /** Overloaded indexed get method, if any. */
-  opIndexedGet: FunctionPrototype | null = null; // TODO: indexedGet and indexedSet as an accessor?
+  fnIndexedGet: string | null = null;
   /** Overloaded indexed set method, if any. */
-  opIndexedSet: FunctionPrototype | null = null;
+  fnIndexedSet: string | null = null;
   /** Overloaded concatenation method, if any. */
-  opConcat: FunctionPrototype | null = null;
+  fnConcat: string | null = null;
   /** Overloaded equality comparison method, if any. */
-  opEquals: FunctionPrototype | null = null;
+  fnEquals: string | null = null;
 
   constructor(program: Program, simpleName: string, internalName: string, declaration: ClassDeclaration | null = null) {
     super(program, simpleName, internalName);
@@ -1903,9 +1905,9 @@ export class ClassPrototype extends Element {
     }
   }
 
-  /** Whether a struct-like class with limited capabilities or not. */
-  get isStruct(): bool { return (this.flags & ElementFlags.STRUCT) != 0; }
-  set isStruct(is: bool) { if (is) this.flags |= ElementFlags.STRUCT; else this.flags &= ~ElementFlags.STRUCT; }
+  /** Whether explicitly layed out and allocated */
+  get isExplicit(): bool { return (this.flags & ElementFlags.EXPLICIT) != 0; }
+  set isExplicit(is: bool) { if (is) this.flags |= ElementFlags.EXPLICIT; else this.flags &= ~ElementFlags.EXPLICIT; }
 
   resolve(typeArguments: Type[] | null, contextualTypeArguments: Map<string,Type> | null = null): Class | null {
     var instanceKey = typeArguments ? typesToString(typeArguments) : "";
@@ -1933,7 +1935,7 @@ export class ClassPrototype extends Element {
         this.program.error(DiagnosticCode.A_class_may_only_extend_another_class, declaration.extendsType.range);
         return null;
       }
-      if (baseClass.prototype.isStruct != this.isStruct) {
+      if (baseClass.prototype.isExplicit != this.isExplicit) {
         this.program.error(DiagnosticCode.Structs_cannot_extend_classes_and_vice_versa, Range.join(declaration.name.range, declaration.extendsType.range));
         return null;
       }
@@ -1957,9 +1959,9 @@ export class ClassPrototype extends Element {
     instance.contextualTypeArguments = contextualTypeArguments;
     this.instances.set(instanceKey, instance);
 
-    var memoryOffset: i32 = 0;
+    var memoryOffset: u32 = 0;
     if (baseClass) {
-      memoryOffset = baseClass.type.byteSize;
+      memoryOffset = baseClass.currentMemoryOffset;
       if (baseClass.members) {
         if (!instance.members)
           instance.members = new Map();
@@ -1983,7 +1985,7 @@ export class ClassPrototype extends Element {
             var fieldType = this.program.resolveType(fieldDeclaration.type, instance.contextualTypeArguments); // reports
             if (fieldType) {
               var fieldInstance = new Field(<FieldPrototype>member, (<FieldPrototype>member).internalName, fieldType);
-              switch (fieldType.size >> 3) { // align (byteSize might vary if a class type)
+              switch (fieldType.byteSize) { // align
                 case 1: break;
                 case 2: if (memoryOffset & 1) ++memoryOffset; break;
                 case 4: if (memoryOffset & 3) memoryOffset = (memoryOffset | 3) + 1; break;
@@ -2015,7 +2017,7 @@ export class ClassPrototype extends Element {
         }
       }
 
-    instance.type.byteSize = memoryOffset; // sizeof<this>() is its byte size in memory
+    instance.currentMemoryOffset = memoryOffset; // sizeof<this>() is its byte size in memory
     return instance;
   }
 
@@ -2051,6 +2053,8 @@ export class Class extends Element {
   base: Class | null;
   /** Contextual type arguments for fields and methods. */
   contextualTypeArguments: Map<string,Type> | null = null;
+  /** Current member memory offset. */
+  currentMemoryOffset: u32 = 0;
 
   /** Constructs a new class. */
   constructor(prototype: ClassPrototype, internalName: string, typeArguments: Type[] | null = null, base: Class | null = null) {
diff --git a/src/types.ts b/src/types.ts
index 58b30d2b..c04ea0d8 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -76,8 +76,8 @@ export class Type {
   /** Type flags. */
   flags: TypeFlags;
   /** Size in bits. */
-  size: i32;
-  /** Size in bytes. */
+  size: u32;
+  /** Size in bytes. Ceiled to 8-bits. */
   byteSize: i32;
   /** Underlying class type, if a class type. */
   classType: Class | null;
diff --git a/std/assembly.d.ts b/std/assembly.d.ts
index 0dbd48de..da856b9a 100644
--- a/std/assembly.d.ts
+++ b/std/assembly.d.ts
@@ -202,6 +202,12 @@ declare class Array<T> {
   constructor(capacity?: i32);
 }
 
+/** Class representing a C-like array of values of type `T` with limited capabilities. */
+declare class CArray<T> {
+  [key: number]: T;
+  private constructor();
+}
+
 /** Class representing a sequence of characters. */
 declare class String {
 
@@ -281,13 +287,16 @@ interface Number {}
 interface Object {}
 interface RegExp {}
 
-// Internal decorators (not yet implemented)
+// Internal decorators
 
-/** Annotates an element being part of the global namespace. */
+/** Annotates an element as a program global. */
 declare function global(target: Function): any;
 
-/** Annotates a method being an operator overload. */
+/** Annotates a method as an operator overload. */
 declare function operator(token: string): any;
 
-declare function struct(target: Function): any;
-declare function size(size: usize): any;
+/** Annotates a class as explicitly layed out and allocated. */
+declare function explicit(target: Function): any;
+
+/** Annoates a class field with an explicit offset. */
+declare function offset(offset: usize): any;
diff --git a/std/assembly/array.ts b/std/assembly/array.ts
index 42d35eb8..d62d57de 100644
--- a/std/assembly/array.ts
+++ b/std/assembly/array.ts
@@ -1,44 +1,92 @@
 export class Array<T> {
 
-  private ptr: usize;
-
-  readonly capacity: i32;
+  private __memory: usize;
+  private __capacity: i32;
   length: i32;
 
   constructor(capacity: i32 = 0) {
     if (capacity < 0)
       throw new RangeError("invalid array length");
-    this.capacity = this.length = capacity;
-    if (capacity > 0) {
-      this.ptr = Heap.allocate(<usize>capacity);
-    } else {
-      this.ptr = 0;
-    }
+    this.__capacity = this.length = capacity;
+    this.__memory = capacity > 0 ? Heap.allocate(<usize>capacity * sizeof<T>()) : 0;
   }
 
   @operator("[]")
   private __get(index: i32): T {
-    assert(index > 0 && index < this.capacity);
-    throw new Error("not implemented");
+    if (<u32>index >= this.__capacity)
+      throw new RangeError("index out of range");
+    return load<T>(this.__memory + <usize>index * sizeof<T>());
   }
 
   @operator("[]=")
   private __set(index: i32, value: T): void {
-    assert(index > 0 && index < this.capacity);
-    throw new Error("not implemented");
+    if (<u32>index >= this.__capacity)
+      throw new RangeError("index out of range");
+    store<T>(this.__memory + <usize>index * sizeof<T>(), value);
   }
 
-  dispose(): void {
-    store<i64>(changetype<usize>(this), 0);
-    Heap.dispose(this.ptr);
-    this.ptr = 0;
-    Heap.dispose(changetype<usize>(this));
+  indexOf(searchElement: T, fromIndex: i32 = 0): i32 {
+    if (<u32>fromIndex >= this.__capacity)
+      throw new RangeError("fromIndex out of range");
+    for (var index: usize = <usize>fromIndex, length: usize = min<u32>(this.length, this.__capacity); index < length; ++index)
+      if (load<T>(this.__memory + index * sizeof<T>()) == searchElement)
+        return index;
+    return -1;
   }
 
-  // TODO
+  private __grow(capacity: i32): void {
+    assert(capacity > this.__capacity);
+    var newMemory = Heap.allocate(<usize>(capacity * sizeof<T>()));
+    if (this.__memory)
+      Heap.copy(newMemory, this.__memory, this.__capacity * sizeof<T>());
+    Heap.dispose(this.__memory);
+    this.__memory = newMemory;
+    this.__capacity = capacity;
+  }
+
+  push(element: T): i32 {
+    if (<u32>this.length >= this.__capacity)
+      this.__grow(max(this.length + 1, this.__capacity * 2));
+    store<T>(this.__memory + <usize>this.length * sizeof<T>(), element);
+    return ++this.length;
+  }
+
+  pop(): T {
+    if (this.length < 1 || <u32>this.length > this.__capacity)
+      throw new RangeError("index out of range");
+    --this.length;
+    return load<T>(this.__memory + <usize>this.length * sizeof<T>());
+  }
+
+  shift(): T {
+    if (this.length < 1 || <u32>this.length > this.__capacity)
+      throw new RangeError("index out of range");
+    var element = load<T>(this.__memory);
+    Heap.copy(this.__memory, this.__memory + sizeof<T>(), (this.__capacity - 1) * sizeof<T>());
+    Heap.fill(this.__memory + (this.__capacity - 1) * sizeof<T>(), 0, sizeof<T>());
+    --this.length;
+    return element;
+  }
+
+  unshift(element: T): i32 {
+    var capacity = this.__capacity;
+    if (<u32>this.length >= capacity)
+      this.__grow(max(this.length + 1, capacity * 2));
+
+    // FIXME: needs memmove (Heap.copy is just memcpy). it's also inefficient because
+    // __grow copies and then unshift copies again.
+    // Heap.copy(this.__memory + sizeof<T>(), this.__memory, capacity * sizeof<T>());
+
+    if (capacity)
+      for (var index: usize = capacity; index > 0; --index)
+        store<T>(this.__memory + index * sizeof<T>(), load<T>(this.__memory + (index - 1) * sizeof<T>()));
+
+    store<T>(this.__memory, element);
+    return ++this.length;
+  }
 }
 
-@struct
+@explicit
 export class CArray<T> {
 
   private constructor() {}
diff --git a/tests/compiler.js b/tests/compiler.js
index 9cfec7be..9aa71cf6 100644
--- a/tests/compiler.js
+++ b/tests/compiler.js
@@ -72,11 +72,15 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
         var wasmModule = new WebAssembly.Module(binary);
         var wasmInstance = new WebAssembly.Instance(wasmModule, {
           env: {
-            externalFunc: function() {},
+            externalFunc: function(arg0, arg1, arg2) {
+              console.log("env.externalFunc called with: " + arg0 + ", " + arg1 + ", " + arg2);
+            },
             externalConst: 1
           },
           external: {
-            externalFunc: function() {},
+            externalFunc: function(arg0, arg1, arg2) {
+              console.log("external.externalFunc called with: " + arg0 + ", " + arg1 + ", " + arg2);
+            },
             externalConst: 2
           }
         });
diff --git a/tests/compiler/class.ts b/tests/compiler/class.ts
index ed66240e..80355753 100644
--- a/tests/compiler/class.ts
+++ b/tests/compiler/class.ts
@@ -10,7 +10,7 @@ class Animal<T> {
   instanceSub<T>(a: T, b: T): T { return a - b + <T>Animal.ONE; } // tsc does not allow this
 }
 
-assert(sizeof<Animal<f64>>() == 7);
+assert(sizeof<Animal<f64>>() == sizeof<usize>());
 
 Animal.ONE;
 Animal.add(1,2);
diff --git a/tests/compiler/class.wast b/tests/compiler/class.wast
index 2a4972c0..eb088a4b 100644
--- a/tests/compiler/class.wast
+++ b/tests/compiler/class.wast
@@ -145,8 +145,8 @@
   (if
    (i32.eqz
     (i32.eq
-     (i32.const 7)
-     (i32.const 7)
+     (i32.const 4)
+     (i32.const 4)
     )
    )
    (unreachable)
diff --git a/tests/compiler/std/array.optimized-inlined.wast b/tests/compiler/std/array.optimized-inlined.wast
new file mode 100644
index 00000000..4b0efda5
--- /dev/null
+++ b/tests/compiler/std/array.optimized-inlined.wast
@@ -0,0 +1,2918 @@
+(module
+ (type $ii (func (param i32) (result i32)))
+ (type $iiii (func (param i32 i32 i32) (result i32)))
+ (type $iv (func (param i32)))
+ (type $iiv (func (param i32 i32)))
+ (type $iii (func (param i32 i32) (result i32)))
+ (type $v (func))
+ (global $std:heap/HEAP_OFFSET (mut i32) (i32.const 0))
+ (global $std/array/arr (mut i32) (i32.const 0))
+ (global $std/array/i (mut i32) (i32.const 0))
+ (global $HEAP_BASE i32 (i32.const 4))
+ (memory $0 1)
+ (export "memory" (memory $0))
+ (start $start)
+ (func $std:heap/Heap.allocate (; 0 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (local $2 i32)
+  (if
+   (i32.eqz
+    (get_local $0)
+   )
+   (return
+    (i32.const 0)
+   )
+  )
+  (set_local $1
+   (current_memory)
+  )
+  (if
+   (i32.gt_u
+    (i32.add
+     (get_global $std:heap/HEAP_OFFSET)
+     (get_local $0)
+    )
+    (i32.shl
+     (get_local $1)
+     (i32.const 16)
+    )
+   )
+   (if
+    (i32.lt_s
+     (grow_memory
+      (select
+       (tee_local $2
+        (i32.trunc_s/f64
+         (f64.ceil
+          (f64.div
+           (f64.convert_u/i32
+            (get_local $0)
+           )
+           (f64.const 65536)
+          )
+         )
+        )
+       )
+       (tee_local $1
+        (i32.sub
+         (i32.mul
+          (get_local $1)
+          (i32.const 2)
+         )
+         (get_local $1)
+        )
+       )
+       (i32.gt_s
+        (get_local $2)
+        (get_local $1)
+       )
+      )
+     )
+     (i32.const 0)
+    )
+    (unreachable)
+   )
+  )
+  (set_local $1
+   (get_global $std:heap/HEAP_OFFSET)
+  )
+  (if
+   (block (result i32)
+    (set_global $std:heap/HEAP_OFFSET
+     (i32.add
+      (get_global $std:heap/HEAP_OFFSET)
+      (get_local $0)
+     )
+    )
+    (i32.and
+     (get_global $std:heap/HEAP_OFFSET)
+     (i32.const 7)
+    )
+   )
+   (set_global $std:heap/HEAP_OFFSET
+    (i32.add
+     (i32.or
+      (get_global $std:heap/HEAP_OFFSET)
+      (i32.const 7)
+     )
+     (i32.const 1)
+    )
+   )
+  )
+  (get_local $1)
+ )
+ (func $std:heap/Heap.copy (; 1 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+  (local $3 i32)
+  (local $4 i32)
+  (local $5 i32)
+  (if
+   (i32.lt_u
+    (get_local $0)
+    (get_global $HEAP_BASE)
+   )
+   (unreachable)
+  )
+  (set_local $4
+   (get_local $0)
+  )
+  (loop $continue|0
+   (if
+    (if (result i32)
+     (get_local $2)
+     (i32.rem_u
+      (get_local $1)
+      (i32.const 4)
+     )
+     (get_local $2)
+    )
+    (block
+     (set_local $4
+      (i32.add
+       (tee_local $3
+        (get_local $4)
+       )
+       (i32.const 1)
+      )
+     )
+     (i32.store8
+      (get_local $3)
+      (block (result i32)
+       (set_local $1
+        (i32.add
+         (tee_local $3
+          (get_local $1)
+         )
+         (i32.const 1)
+        )
+       )
+       (i32.load8_u
+        (get_local $3)
+       )
+      )
+     )
+     (set_local $2
+      (i32.sub
+       (get_local $2)
+       (i32.const 1)
+      )
+     )
+     (br $continue|0)
+    )
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.rem_u
+     (get_local $4)
+     (i32.const 4)
+    )
+   )
+   (block
+    (loop $continue|1
+     (if
+      (i32.ge_u
+       (get_local $2)
+       (i32.const 16)
+      )
+      (block
+       (i32.store
+        (get_local $4)
+        (i32.load
+         (get_local $1)
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 4)
+        )
+        (i32.load
+         (i32.add
+          (get_local $1)
+          (i32.const 4)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 8)
+        )
+        (i32.load
+         (i32.add
+          (get_local $1)
+          (i32.const 8)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 12)
+        )
+        (i32.load
+         (i32.add
+          (get_local $1)
+          (i32.const 12)
+         )
+        )
+       )
+       (set_local $1
+        (i32.add
+         (get_local $1)
+         (i32.const 16)
+        )
+       )
+       (set_local $4
+        (i32.add
+         (get_local $4)
+         (i32.const 16)
+        )
+       )
+       (set_local $2
+        (i32.sub
+         (get_local $2)
+         (i32.const 16)
+        )
+       )
+       (br $continue|1)
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 8)
+     )
+     (block
+      (i32.store
+       (get_local $4)
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (i32.store
+       (i32.add
+        (get_local $4)
+        (i32.const 4)
+       )
+       (i32.load
+        (i32.add
+         (get_local $1)
+         (i32.const 4)
+        )
+       )
+      )
+      (set_local $4
+       (i32.add
+        (get_local $4)
+        (i32.const 8)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 8)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 4)
+     )
+     (block
+      (i32.store
+       (get_local $4)
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (set_local $4
+       (i32.add
+        (get_local $4)
+        (i32.const 4)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 4)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 2)
+     )
+     (block
+      (i32.store16
+       (get_local $4)
+       (i32.load16_u
+        (get_local $1)
+       )
+      )
+      (set_local $4
+       (i32.add
+        (get_local $4)
+        (i32.const 2)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 2)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 1)
+     )
+     (block
+      (set_local $3
+       (get_local $4)
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $3
+         (get_local $1)
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+     )
+    )
+    (return
+     (get_local $0)
+    )
+   )
+  )
+  (if
+   (i32.ge_u
+    (get_local $2)
+    (i32.const 32)
+   )
+   (block $break|2
+    (block $case2|2
+     (block $case1|2
+      (block $case0|2
+       (block $tablify|0
+        (br_table $case0|2 $case1|2 $case2|2 $tablify|0
+         (i32.sub
+          (i32.rem_u
+           (get_local $4)
+           (i32.const 4)
+          )
+          (i32.const 1)
+         )
+        )
+       )
+       (br $break|2)
+      )
+      (set_local $5
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (set_local $4
+       (i32.add
+        (tee_local $3
+         (get_local $4)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $1
+         (i32.add
+          (tee_local $3
+           (get_local $1)
+          )
+          (i32.const 1)
+         )
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+      (set_local $4
+       (i32.add
+        (tee_local $3
+         (get_local $4)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $1
+         (i32.add
+          (tee_local $3
+           (get_local $1)
+          )
+          (i32.const 1)
+         )
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+      (set_local $4
+       (i32.add
+        (tee_local $3
+         (get_local $4)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $1
+         (i32.add
+          (tee_local $3
+           (get_local $1)
+          )
+          (i32.const 1)
+         )
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+      (set_local $2
+       (i32.sub
+        (get_local $2)
+        (i32.const 3)
+       )
+      )
+      (loop $continue|3
+       (if
+        (i32.ge_u
+         (get_local $2)
+         (i32.const 17)
+        )
+        (block
+         (i32.store
+          (get_local $4)
+          (i32.or
+           (i32.shr_u
+            (get_local $5)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $3
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 1)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $4)
+           (i32.const 4)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $3)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $5
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 5)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $4)
+           (i32.const 8)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $5)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $3
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 9)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $4)
+           (i32.const 12)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $3)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $5
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 13)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (set_local $1
+          (i32.add
+           (get_local $1)
+           (i32.const 16)
+          )
+         )
+         (set_local $4
+          (i32.add
+           (get_local $4)
+           (i32.const 16)
+          )
+         )
+         (set_local $2
+          (i32.sub
+           (get_local $2)
+           (i32.const 16)
+          )
+         )
+         (br $continue|3)
+        )
+       )
+      )
+      (br $break|2)
+     )
+     (set_local $5
+      (i32.load
+       (get_local $1)
+      )
+     )
+     (set_local $4
+      (i32.add
+       (tee_local $3
+        (get_local $4)
+       )
+       (i32.const 1)
+      )
+     )
+     (i32.store8
+      (get_local $3)
+      (block (result i32)
+       (set_local $1
+        (i32.add
+         (tee_local $3
+          (get_local $1)
+         )
+         (i32.const 1)
+        )
+       )
+       (i32.load8_u
+        (get_local $3)
+       )
+      )
+     )
+     (set_local $4
+      (i32.add
+       (tee_local $3
+        (get_local $4)
+       )
+       (i32.const 1)
+      )
+     )
+     (i32.store8
+      (get_local $3)
+      (block (result i32)
+       (set_local $1
+        (i32.add
+         (tee_local $3
+          (get_local $1)
+         )
+         (i32.const 1)
+        )
+       )
+       (i32.load8_u
+        (get_local $3)
+       )
+      )
+     )
+     (set_local $2
+      (i32.sub
+       (get_local $2)
+       (i32.const 2)
+      )
+     )
+     (loop $continue|4
+      (if
+       (i32.ge_u
+        (get_local $2)
+        (i32.const 18)
+       )
+       (block
+        (i32.store
+         (get_local $4)
+         (i32.or
+          (i32.shr_u
+           (get_local $5)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $3
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 2)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (i32.store
+         (i32.add
+          (get_local $4)
+          (i32.const 4)
+         )
+         (i32.or
+          (i32.shr_u
+           (get_local $3)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $5
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 6)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (i32.store
+         (i32.add
+          (get_local $4)
+          (i32.const 8)
+         )
+         (i32.or
+          (i32.shr_u
+           (get_local $5)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $3
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 10)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (i32.store
+         (i32.add
+          (get_local $4)
+          (i32.const 12)
+         )
+         (i32.or
+          (i32.shr_u
+           (get_local $3)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $5
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 14)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (set_local $1
+         (i32.add
+          (get_local $1)
+          (i32.const 16)
+         )
+        )
+        (set_local $4
+         (i32.add
+          (get_local $4)
+          (i32.const 16)
+         )
+        )
+        (set_local $2
+         (i32.sub
+          (get_local $2)
+          (i32.const 16)
+         )
+        )
+        (br $continue|4)
+       )
+      )
+     )
+     (br $break|2)
+    )
+    (set_local $5
+     (i32.load
+      (get_local $1)
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $2
+     (i32.sub
+      (get_local $2)
+      (i32.const 1)
+     )
+    )
+    (loop $continue|5
+     (if
+      (i32.ge_u
+       (get_local $2)
+       (i32.const 19)
+      )
+      (block
+       (i32.store
+        (get_local $4)
+        (i32.or
+         (i32.shr_u
+          (get_local $5)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $3
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 3)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 4)
+        )
+        (i32.or
+         (i32.shr_u
+          (get_local $3)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $5
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 7)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 8)
+        )
+        (i32.or
+         (i32.shr_u
+          (get_local $5)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $3
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 11)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 12)
+        )
+        (i32.or
+         (i32.shr_u
+          (get_local $3)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $5
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 15)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (set_local $1
+        (i32.add
+         (get_local $1)
+         (i32.const 16)
+        )
+       )
+       (set_local $4
+        (i32.add
+         (get_local $4)
+         (i32.const 16)
+        )
+       )
+       (set_local $2
+        (i32.sub
+         (get_local $2)
+         (i32.const 16)
+        )
+       )
+       (br $continue|5)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 16)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 8)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 4)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 2)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 1)
+   )
+   (block
+    (set_local $3
+     (get_local $4)
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $3
+       (get_local $1)
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (get_local $0)
+ )
+ (func $std:array/Array#__grow (; 2 ;) (type $iiv) (param $0 i32) (param $1 i32)
+  (local $2 i32)
+  (local $3 i32)
+  (if
+   (i32.le_s
+    (get_local $1)
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (unreachable)
+  )
+  (set_local $2
+   (call $std:heap/Heap.allocate
+    (i32.mul
+     (get_local $1)
+     (i32.const 4)
+    )
+   )
+  )
+  (if
+   (i32.load
+    (get_local $0)
+   )
+   (drop
+    (call $std:heap/Heap.copy
+     (get_local $2)
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (i32.load offset=4
+       (get_local $0)
+      )
+      (i32.const 4)
+     )
+    )
+   )
+  )
+  (block
+   (block $__inlined_func$std:heap/Heap.dispose
+    (set_local $3
+     (i32.load
+      (get_local $0)
+     )
+    )
+    (nop)
+   )
+  )
+  (i32.store
+   (get_local $0)
+   (get_local $2)
+  )
+  (i32.store offset=4
+   (get_local $0)
+   (get_local $1)
+  )
+ )
+ (func $std:array/Array#push (; 3 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (local $2 i32)
+  (local $3 i32)
+  (if
+   (i32.ge_u
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (call $std:array/Array#__grow
+    (get_local $0)
+    (select
+     (tee_local $2
+      (i32.add
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (tee_local $3
+      (i32.mul
+       (i32.load offset=4
+        (get_local $0)
+       )
+       (i32.const 2)
+      )
+     )
+     (i32.gt_s
+      (get_local $2)
+      (get_local $3)
+     )
+    )
+   )
+  )
+  (i32.store
+   (i32.add
+    (i32.load
+     (get_local $0)
+    )
+    (i32.mul
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+   )
+   (get_local $1)
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (tee_local $2
+    (i32.add
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 1)
+    )
+   )
+  )
+  (get_local $2)
+ )
+ (func $std:array/Array#__get (; 4 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (if
+   (i32.ge_u
+    (get_local $1)
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (unreachable)
+  )
+  (i32.load
+   (i32.add
+    (i32.load
+     (get_local $0)
+    )
+    (i32.mul
+     (get_local $1)
+     (i32.const 4)
+    )
+   )
+  )
+ )
+ (func $std:array/Array#pop (; 5 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (if
+   (i32.and
+    (if (result i32)
+     (tee_local $1
+      (i32.lt_s
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (get_local $1)
+     (i32.gt_u
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.load offset=4
+       (get_local $0)
+      )
+     )
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (i32.sub
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.const 1)
+   )
+  )
+  (i32.load
+   (i32.add
+    (i32.load
+     (get_local $0)
+    )
+    (i32.mul
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+   )
+  )
+ )
+ (func $std:array/Array#unshift (; 6 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (local $2 i32)
+  (local $3 i32)
+  (local $4 i32)
+  (if
+   (i32.ge_u
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (tee_local $2
+     (i32.load offset=4
+      (get_local $0)
+     )
+    )
+   )
+   (call $std:array/Array#__grow
+    (get_local $0)
+    (select
+     (tee_local $3
+      (i32.add
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (tee_local $4
+      (i32.mul
+       (get_local $2)
+       (i32.const 2)
+      )
+     )
+     (i32.gt_s
+      (get_local $3)
+      (get_local $4)
+     )
+    )
+   )
+  )
+  (if
+   (get_local $2)
+   (loop $continue|0
+    (if
+     (i32.gt_u
+      (get_local $2)
+      (i32.const 0)
+     )
+     (block
+      (i32.store
+       (i32.add
+        (i32.load
+         (get_local $0)
+        )
+        (i32.mul
+         (get_local $2)
+         (i32.const 4)
+        )
+       )
+       (i32.load
+        (i32.add
+         (i32.load
+          (get_local $0)
+         )
+         (i32.mul
+          (i32.sub
+           (get_local $2)
+           (i32.const 1)
+          )
+          (i32.const 4)
+         )
+        )
+       )
+      )
+      (set_local $2
+       (i32.sub
+        (get_local $2)
+        (i32.const 1)
+       )
+      )
+      (br $continue|0)
+     )
+    )
+   )
+  )
+  (i32.store
+   (i32.load
+    (get_local $0)
+   )
+   (get_local $1)
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (tee_local $3
+    (i32.add
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 1)
+    )
+   )
+  )
+  (get_local $3)
+ )
+ (func $std:heap/Heap.fill (; 7 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+  (local $3 i32)
+  (local $4 i64)
+  (local $5 i32)
+  (if
+   (i32.lt_u
+    (get_local $0)
+    (get_global $HEAP_BASE)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (get_local $2)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (tee_local $3
+    (get_local $0)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 1)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 2)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 1)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 2)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 2)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 3)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 6)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 3)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 4)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 8)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (tee_local $3
+    (i32.add
+     (get_local $3)
+     (tee_local $5
+      (i32.and
+       (i32.sub
+        (i32.const 0)
+        (get_local $3)
+       )
+       (i32.const 3)
+      )
+     )
+    )
+   )
+   (tee_local $1
+    (i32.mul
+     (get_local $1)
+     (i32.const 16843009)
+    )
+   )
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (tee_local $2
+      (i32.and
+       (i32.sub
+        (get_local $2)
+        (get_local $5)
+       )
+       (i32.const -4)
+      )
+     )
+    )
+    (i32.const 4)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 8)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 4)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 8)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 12)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 8)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 24)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 12)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 16)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 20)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 24)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 28)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 24)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 20)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 16)
+   )
+   (get_local $1)
+  )
+  (set_local $3
+   (i32.add
+    (get_local $3)
+    (tee_local $5
+     (i32.add
+      (i32.and
+       (get_local $3)
+       (i32.const 4)
+      )
+      (i32.const 24)
+     )
+    )
+   )
+  )
+  (set_local $2
+   (i32.sub
+    (get_local $2)
+    (get_local $5)
+   )
+  )
+  (set_local $4
+   (i64.or
+    (i64.extend_u/i32
+     (get_local $1)
+    )
+    (i64.shl
+     (i64.extend_u/i32
+      (get_local $1)
+     )
+     (i64.const 32)
+    )
+   )
+  )
+  (loop $continue|0
+   (if
+    (i32.ge_u
+     (get_local $2)
+     (i32.const 32)
+    )
+    (block
+     (i64.store
+      (get_local $3)
+      (get_local $4)
+     )
+     (i64.store
+      (i32.add
+       (get_local $3)
+       (i32.const 8)
+      )
+      (get_local $4)
+     )
+     (i64.store
+      (i32.add
+       (get_local $3)
+       (i32.const 16)
+      )
+      (get_local $4)
+     )
+     (i64.store
+      (i32.add
+       (get_local $3)
+       (i32.const 24)
+      )
+      (get_local $4)
+     )
+     (set_local $2
+      (i32.sub
+       (get_local $2)
+       (i32.const 32)
+      )
+     )
+     (set_local $3
+      (i32.add
+       (get_local $3)
+       (i32.const 32)
+      )
+     )
+     (br $continue|0)
+    )
+   )
+  )
+  (get_local $0)
+ )
+ (func $std:array/Array#shift (; 8 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (if
+   (i32.and
+    (if (result i32)
+     (tee_local $1
+      (i32.lt_s
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (get_local $1)
+     (i32.gt_u
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.load offset=4
+       (get_local $0)
+      )
+     )
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (set_local $1
+   (i32.load
+    (i32.load
+     (get_local $0)
+    )
+   )
+  )
+  (drop
+   (call $std:heap/Heap.copy
+    (i32.load
+     (get_local $0)
+    )
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+    (i32.mul
+     (i32.sub
+      (i32.load offset=4
+       (get_local $0)
+      )
+      (i32.const 1)
+     )
+     (i32.const 4)
+    )
+   )
+  )
+  (drop
+   (call $std:heap/Heap.fill
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (i32.sub
+       (i32.load offset=4
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+      (i32.const 4)
+     )
+    )
+    (i32.const 0)
+    (i32.const 4)
+   )
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (i32.sub
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.const 1)
+   )
+  )
+  (get_local $1)
+ )
+ (func $start (; 9 ;) (type $v)
+  (set_global $std:heap/HEAP_OFFSET
+   (get_global $HEAP_BASE)
+  )
+  (set_global $std/array/arr
+   (call $std:heap/Heap.allocate
+    (i32.const 12)
+   )
+  )
+  (if
+   (i32.load offset=8
+    (get_global $std/array/arr)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.load offset=4
+    (get_global $std/array/arr)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 42)
+   )
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#pop
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.ne
+    (get_global $std/array/i)
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.load offset=8
+    (get_global $std/array/arr)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 43)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 44)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 2)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 2)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 45)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 3)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#unshift
+    (get_global $std/array/arr)
+    (i32.const 42)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 3)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#unshift
+    (get_global $std/array/arr)
+    (i32.const 41)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 5)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 8)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 41)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 3)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 4)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#shift
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.ne
+    (get_global $std/array/i)
+    (i32.const 41)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 8)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 3)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#pop
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.ne
+    (get_global $std/array/i)
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 3)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 8)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+ )
+)
diff --git a/tests/compiler/std/array.optimized.wast b/tests/compiler/std/array.optimized.wast
index 7a4e7940..0c9e3bc4 100644
--- a/tests/compiler/std/array.optimized.wast
+++ b/tests/compiler/std/array.optimized.wast
@@ -1,4 +1,2915 @@
 (module
+ (type $ii (func (param i32) (result i32)))
+ (type $iiii (func (param i32 i32 i32) (result i32)))
+ (type $iv (func (param i32)))
+ (type $iiv (func (param i32 i32)))
+ (type $iii (func (param i32 i32) (result i32)))
+ (type $v (func))
+ (global $std:heap/HEAP_OFFSET (mut i32) (i32.const 0))
+ (global $std/array/arr (mut i32) (i32.const 0))
+ (global $std/array/i (mut i32) (i32.const 0))
+ (global $HEAP_BASE i32 (i32.const 4))
  (memory $0 1)
  (export "memory" (memory $0))
+ (start $start)
+ (func $std:heap/Heap.allocate (; 0 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (local $2 i32)
+  (if
+   (i32.eqz
+    (get_local $0)
+   )
+   (return
+    (i32.const 0)
+   )
+  )
+  (set_local $1
+   (current_memory)
+  )
+  (if
+   (i32.gt_u
+    (i32.add
+     (get_global $std:heap/HEAP_OFFSET)
+     (get_local $0)
+    )
+    (i32.shl
+     (get_local $1)
+     (i32.const 16)
+    )
+   )
+   (if
+    (i32.lt_s
+     (grow_memory
+      (select
+       (tee_local $2
+        (i32.trunc_s/f64
+         (f64.ceil
+          (f64.div
+           (f64.convert_u/i32
+            (get_local $0)
+           )
+           (f64.const 65536)
+          )
+         )
+        )
+       )
+       (tee_local $1
+        (i32.sub
+         (i32.mul
+          (get_local $1)
+          (i32.const 2)
+         )
+         (get_local $1)
+        )
+       )
+       (i32.gt_s
+        (get_local $2)
+        (get_local $1)
+       )
+      )
+     )
+     (i32.const 0)
+    )
+    (unreachable)
+   )
+  )
+  (set_local $1
+   (get_global $std:heap/HEAP_OFFSET)
+  )
+  (if
+   (block (result i32)
+    (set_global $std:heap/HEAP_OFFSET
+     (i32.add
+      (get_global $std:heap/HEAP_OFFSET)
+      (get_local $0)
+     )
+    )
+    (i32.and
+     (get_global $std:heap/HEAP_OFFSET)
+     (i32.const 7)
+    )
+   )
+   (set_global $std:heap/HEAP_OFFSET
+    (i32.add
+     (i32.or
+      (get_global $std:heap/HEAP_OFFSET)
+      (i32.const 7)
+     )
+     (i32.const 1)
+    )
+   )
+  )
+  (get_local $1)
+ )
+ (func $std:heap/Heap.copy (; 1 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+  (local $3 i32)
+  (local $4 i32)
+  (local $5 i32)
+  (if
+   (i32.lt_u
+    (get_local $0)
+    (get_global $HEAP_BASE)
+   )
+   (unreachable)
+  )
+  (set_local $4
+   (get_local $0)
+  )
+  (loop $continue|0
+   (if
+    (if (result i32)
+     (get_local $2)
+     (i32.rem_u
+      (get_local $1)
+      (i32.const 4)
+     )
+     (get_local $2)
+    )
+    (block
+     (set_local $4
+      (i32.add
+       (tee_local $3
+        (get_local $4)
+       )
+       (i32.const 1)
+      )
+     )
+     (i32.store8
+      (get_local $3)
+      (block (result i32)
+       (set_local $1
+        (i32.add
+         (tee_local $3
+          (get_local $1)
+         )
+         (i32.const 1)
+        )
+       )
+       (i32.load8_u
+        (get_local $3)
+       )
+      )
+     )
+     (set_local $2
+      (i32.sub
+       (get_local $2)
+       (i32.const 1)
+      )
+     )
+     (br $continue|0)
+    )
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.rem_u
+     (get_local $4)
+     (i32.const 4)
+    )
+   )
+   (block
+    (loop $continue|1
+     (if
+      (i32.ge_u
+       (get_local $2)
+       (i32.const 16)
+      )
+      (block
+       (i32.store
+        (get_local $4)
+        (i32.load
+         (get_local $1)
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 4)
+        )
+        (i32.load
+         (i32.add
+          (get_local $1)
+          (i32.const 4)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 8)
+        )
+        (i32.load
+         (i32.add
+          (get_local $1)
+          (i32.const 8)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 12)
+        )
+        (i32.load
+         (i32.add
+          (get_local $1)
+          (i32.const 12)
+         )
+        )
+       )
+       (set_local $1
+        (i32.add
+         (get_local $1)
+         (i32.const 16)
+        )
+       )
+       (set_local $4
+        (i32.add
+         (get_local $4)
+         (i32.const 16)
+        )
+       )
+       (set_local $2
+        (i32.sub
+         (get_local $2)
+         (i32.const 16)
+        )
+       )
+       (br $continue|1)
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 8)
+     )
+     (block
+      (i32.store
+       (get_local $4)
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (i32.store
+       (i32.add
+        (get_local $4)
+        (i32.const 4)
+       )
+       (i32.load
+        (i32.add
+         (get_local $1)
+         (i32.const 4)
+        )
+       )
+      )
+      (set_local $4
+       (i32.add
+        (get_local $4)
+        (i32.const 8)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 8)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 4)
+     )
+     (block
+      (i32.store
+       (get_local $4)
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (set_local $4
+       (i32.add
+        (get_local $4)
+        (i32.const 4)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 4)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 2)
+     )
+     (block
+      (i32.store16
+       (get_local $4)
+       (i32.load16_u
+        (get_local $1)
+       )
+      )
+      (set_local $4
+       (i32.add
+        (get_local $4)
+        (i32.const 2)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 2)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 1)
+     )
+     (block
+      (set_local $3
+       (get_local $4)
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $3
+         (get_local $1)
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+     )
+    )
+    (return
+     (get_local $0)
+    )
+   )
+  )
+  (if
+   (i32.ge_u
+    (get_local $2)
+    (i32.const 32)
+   )
+   (block $break|2
+    (block $case2|2
+     (block $case1|2
+      (block $case0|2
+       (block $tablify|0
+        (br_table $case0|2 $case1|2 $case2|2 $tablify|0
+         (i32.sub
+          (i32.rem_u
+           (get_local $4)
+           (i32.const 4)
+          )
+          (i32.const 1)
+         )
+        )
+       )
+       (br $break|2)
+      )
+      (set_local $5
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (set_local $4
+       (i32.add
+        (tee_local $3
+         (get_local $4)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $1
+         (i32.add
+          (tee_local $3
+           (get_local $1)
+          )
+          (i32.const 1)
+         )
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+      (set_local $4
+       (i32.add
+        (tee_local $3
+         (get_local $4)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $1
+         (i32.add
+          (tee_local $3
+           (get_local $1)
+          )
+          (i32.const 1)
+         )
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+      (set_local $4
+       (i32.add
+        (tee_local $3
+         (get_local $4)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.store8
+       (get_local $3)
+       (block (result i32)
+        (set_local $1
+         (i32.add
+          (tee_local $3
+           (get_local $1)
+          )
+          (i32.const 1)
+         )
+        )
+        (i32.load8_u
+         (get_local $3)
+        )
+       )
+      )
+      (set_local $2
+       (i32.sub
+        (get_local $2)
+        (i32.const 3)
+       )
+      )
+      (loop $continue|3
+       (if
+        (i32.ge_u
+         (get_local $2)
+         (i32.const 17)
+        )
+        (block
+         (i32.store
+          (get_local $4)
+          (i32.or
+           (i32.shr_u
+            (get_local $5)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $3
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 1)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $4)
+           (i32.const 4)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $3)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $5
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 5)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $4)
+           (i32.const 8)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $5)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $3
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 9)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $4)
+           (i32.const 12)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $3)
+            (i32.const 24)
+           )
+           (i32.shl
+            (tee_local $5
+             (i32.load
+              (i32.add
+               (get_local $1)
+               (i32.const 13)
+              )
+             )
+            )
+            (i32.const 8)
+           )
+          )
+         )
+         (set_local $1
+          (i32.add
+           (get_local $1)
+           (i32.const 16)
+          )
+         )
+         (set_local $4
+          (i32.add
+           (get_local $4)
+           (i32.const 16)
+          )
+         )
+         (set_local $2
+          (i32.sub
+           (get_local $2)
+           (i32.const 16)
+          )
+         )
+         (br $continue|3)
+        )
+       )
+      )
+      (br $break|2)
+     )
+     (set_local $5
+      (i32.load
+       (get_local $1)
+      )
+     )
+     (set_local $4
+      (i32.add
+       (tee_local $3
+        (get_local $4)
+       )
+       (i32.const 1)
+      )
+     )
+     (i32.store8
+      (get_local $3)
+      (block (result i32)
+       (set_local $1
+        (i32.add
+         (tee_local $3
+          (get_local $1)
+         )
+         (i32.const 1)
+        )
+       )
+       (i32.load8_u
+        (get_local $3)
+       )
+      )
+     )
+     (set_local $4
+      (i32.add
+       (tee_local $3
+        (get_local $4)
+       )
+       (i32.const 1)
+      )
+     )
+     (i32.store8
+      (get_local $3)
+      (block (result i32)
+       (set_local $1
+        (i32.add
+         (tee_local $3
+          (get_local $1)
+         )
+         (i32.const 1)
+        )
+       )
+       (i32.load8_u
+        (get_local $3)
+       )
+      )
+     )
+     (set_local $2
+      (i32.sub
+       (get_local $2)
+       (i32.const 2)
+      )
+     )
+     (loop $continue|4
+      (if
+       (i32.ge_u
+        (get_local $2)
+        (i32.const 18)
+       )
+       (block
+        (i32.store
+         (get_local $4)
+         (i32.or
+          (i32.shr_u
+           (get_local $5)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $3
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 2)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (i32.store
+         (i32.add
+          (get_local $4)
+          (i32.const 4)
+         )
+         (i32.or
+          (i32.shr_u
+           (get_local $3)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $5
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 6)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (i32.store
+         (i32.add
+          (get_local $4)
+          (i32.const 8)
+         )
+         (i32.or
+          (i32.shr_u
+           (get_local $5)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $3
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 10)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (i32.store
+         (i32.add
+          (get_local $4)
+          (i32.const 12)
+         )
+         (i32.or
+          (i32.shr_u
+           (get_local $3)
+           (i32.const 16)
+          )
+          (i32.shl
+           (tee_local $5
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 14)
+             )
+            )
+           )
+           (i32.const 16)
+          )
+         )
+        )
+        (set_local $1
+         (i32.add
+          (get_local $1)
+          (i32.const 16)
+         )
+        )
+        (set_local $4
+         (i32.add
+          (get_local $4)
+          (i32.const 16)
+         )
+        )
+        (set_local $2
+         (i32.sub
+          (get_local $2)
+          (i32.const 16)
+         )
+        )
+        (br $continue|4)
+       )
+      )
+     )
+     (br $break|2)
+    )
+    (set_local $5
+     (i32.load
+      (get_local $1)
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $2
+     (i32.sub
+      (get_local $2)
+      (i32.const 1)
+     )
+    )
+    (loop $continue|5
+     (if
+      (i32.ge_u
+       (get_local $2)
+       (i32.const 19)
+      )
+      (block
+       (i32.store
+        (get_local $4)
+        (i32.or
+         (i32.shr_u
+          (get_local $5)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $3
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 3)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 4)
+        )
+        (i32.or
+         (i32.shr_u
+          (get_local $3)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $5
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 7)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 8)
+        )
+        (i32.or
+         (i32.shr_u
+          (get_local $5)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $3
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 11)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (i32.store
+        (i32.add
+         (get_local $4)
+         (i32.const 12)
+        )
+        (i32.or
+         (i32.shr_u
+          (get_local $3)
+          (i32.const 8)
+         )
+         (i32.shl
+          (tee_local $5
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 15)
+            )
+           )
+          )
+          (i32.const 24)
+         )
+        )
+       )
+       (set_local $1
+        (i32.add
+         (get_local $1)
+         (i32.const 16)
+        )
+       )
+       (set_local $4
+        (i32.add
+         (get_local $4)
+         (i32.const 16)
+        )
+       )
+       (set_local $2
+        (i32.sub
+         (get_local $2)
+         (i32.const 16)
+        )
+       )
+       (br $continue|5)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 16)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 8)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 4)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 2)
+   )
+   (block
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+    (set_local $4
+     (i32.add
+      (tee_local $3
+       (get_local $4)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $1
+       (i32.add
+        (tee_local $3
+         (get_local $1)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 1)
+   )
+   (block
+    (set_local $3
+     (get_local $4)
+    )
+    (i32.store8
+     (get_local $3)
+     (block (result i32)
+      (set_local $3
+       (get_local $1)
+      )
+      (i32.load8_u
+       (get_local $3)
+      )
+     )
+    )
+   )
+  )
+  (get_local $0)
+ )
+ (func $std:heap/Heap.dispose (; 2 ;) (type $iv) (param $0 i32)
+  (nop)
+ )
+ (func $std:array/Array#__grow (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32)
+  (local $2 i32)
+  (if
+   (i32.le_s
+    (get_local $1)
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (unreachable)
+  )
+  (set_local $2
+   (call $std:heap/Heap.allocate
+    (i32.mul
+     (get_local $1)
+     (i32.const 4)
+    )
+   )
+  )
+  (if
+   (i32.load
+    (get_local $0)
+   )
+   (drop
+    (call $std:heap/Heap.copy
+     (get_local $2)
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (i32.load offset=4
+       (get_local $0)
+      )
+      (i32.const 4)
+     )
+    )
+   )
+  )
+  (call $std:heap/Heap.dispose
+   (i32.load
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (get_local $0)
+   (get_local $2)
+  )
+  (i32.store offset=4
+   (get_local $0)
+   (get_local $1)
+  )
+ )
+ (func $std:array/Array#push (; 4 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (local $2 i32)
+  (local $3 i32)
+  (if
+   (i32.ge_u
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (call $std:array/Array#__grow
+    (get_local $0)
+    (select
+     (tee_local $2
+      (i32.add
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (tee_local $3
+      (i32.mul
+       (i32.load offset=4
+        (get_local $0)
+       )
+       (i32.const 2)
+      )
+     )
+     (i32.gt_s
+      (get_local $2)
+      (get_local $3)
+     )
+    )
+   )
+  )
+  (i32.store
+   (i32.add
+    (i32.load
+     (get_local $0)
+    )
+    (i32.mul
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+   )
+   (get_local $1)
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (tee_local $2
+    (i32.add
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 1)
+    )
+   )
+  )
+  (get_local $2)
+ )
+ (func $std:array/Array#__get (; 5 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (if
+   (i32.ge_u
+    (get_local $1)
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (unreachable)
+  )
+  (i32.load
+   (i32.add
+    (i32.load
+     (get_local $0)
+    )
+    (i32.mul
+     (get_local $1)
+     (i32.const 4)
+    )
+   )
+  )
+ )
+ (func $std:array/Array#pop (; 6 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (if
+   (i32.and
+    (if (result i32)
+     (tee_local $1
+      (i32.lt_s
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (get_local $1)
+     (i32.gt_u
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.load offset=4
+       (get_local $0)
+      )
+     )
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (i32.sub
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.const 1)
+   )
+  )
+  (i32.load
+   (i32.add
+    (i32.load
+     (get_local $0)
+    )
+    (i32.mul
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+   )
+  )
+ )
+ (func $std:array/Array#unshift (; 7 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (local $2 i32)
+  (local $3 i32)
+  (local $4 i32)
+  (if
+   (i32.ge_u
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (tee_local $2
+     (i32.load offset=4
+      (get_local $0)
+     )
+    )
+   )
+   (call $std:array/Array#__grow
+    (get_local $0)
+    (select
+     (tee_local $3
+      (i32.add
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (tee_local $4
+      (i32.mul
+       (get_local $2)
+       (i32.const 2)
+      )
+     )
+     (i32.gt_s
+      (get_local $3)
+      (get_local $4)
+     )
+    )
+   )
+  )
+  (if
+   (get_local $2)
+   (loop $continue|0
+    (if
+     (i32.gt_u
+      (get_local $2)
+      (i32.const 0)
+     )
+     (block
+      (i32.store
+       (i32.add
+        (i32.load
+         (get_local $0)
+        )
+        (i32.mul
+         (get_local $2)
+         (i32.const 4)
+        )
+       )
+       (i32.load
+        (i32.add
+         (i32.load
+          (get_local $0)
+         )
+         (i32.mul
+          (i32.sub
+           (get_local $2)
+           (i32.const 1)
+          )
+          (i32.const 4)
+         )
+        )
+       )
+      )
+      (set_local $2
+       (i32.sub
+        (get_local $2)
+        (i32.const 1)
+       )
+      )
+      (br $continue|0)
+     )
+    )
+   )
+  )
+  (i32.store
+   (i32.load
+    (get_local $0)
+   )
+   (get_local $1)
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (tee_local $3
+    (i32.add
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 1)
+    )
+   )
+  )
+  (get_local $3)
+ )
+ (func $std:heap/Heap.fill (; 8 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+  (local $3 i32)
+  (local $4 i64)
+  (local $5 i32)
+  (if
+   (i32.lt_u
+    (get_local $0)
+    (get_global $HEAP_BASE)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (get_local $2)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (tee_local $3
+    (get_local $0)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 1)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 2)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 1)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 2)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 2)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 3)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 6)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 3)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 4)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 8)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (tee_local $3
+    (i32.add
+     (get_local $3)
+     (tee_local $5
+      (i32.and
+       (i32.sub
+        (i32.const 0)
+        (get_local $3)
+       )
+       (i32.const 3)
+      )
+     )
+    )
+   )
+   (tee_local $1
+    (i32.mul
+     (get_local $1)
+     (i32.const 16843009)
+    )
+   )
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (tee_local $2
+      (i32.and
+       (i32.sub
+        (get_local $2)
+        (get_local $5)
+       )
+       (i32.const -4)
+      )
+     )
+    )
+    (i32.const 4)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 8)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 4)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 8)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 12)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 8)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 24)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 12)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 16)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 20)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 24)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 28)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 24)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 20)
+   )
+   (get_local $1)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 16)
+   )
+   (get_local $1)
+  )
+  (set_local $3
+   (i32.add
+    (get_local $3)
+    (tee_local $5
+     (i32.add
+      (i32.and
+       (get_local $3)
+       (i32.const 4)
+      )
+      (i32.const 24)
+     )
+    )
+   )
+  )
+  (set_local $2
+   (i32.sub
+    (get_local $2)
+    (get_local $5)
+   )
+  )
+  (set_local $4
+   (i64.or
+    (i64.extend_u/i32
+     (get_local $1)
+    )
+    (i64.shl
+     (i64.extend_u/i32
+      (get_local $1)
+     )
+     (i64.const 32)
+    )
+   )
+  )
+  (loop $continue|0
+   (if
+    (i32.ge_u
+     (get_local $2)
+     (i32.const 32)
+    )
+    (block
+     (i64.store
+      (get_local $3)
+      (get_local $4)
+     )
+     (i64.store
+      (i32.add
+       (get_local $3)
+       (i32.const 8)
+      )
+      (get_local $4)
+     )
+     (i64.store
+      (i32.add
+       (get_local $3)
+       (i32.const 16)
+      )
+      (get_local $4)
+     )
+     (i64.store
+      (i32.add
+       (get_local $3)
+       (i32.const 24)
+      )
+      (get_local $4)
+     )
+     (set_local $2
+      (i32.sub
+       (get_local $2)
+       (i32.const 32)
+      )
+     )
+     (set_local $3
+      (i32.add
+       (get_local $3)
+       (i32.const 32)
+      )
+     )
+     (br $continue|0)
+    )
+   )
+  )
+  (get_local $0)
+ )
+ (func $std:array/Array#shift (; 9 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (if
+   (i32.and
+    (if (result i32)
+     (tee_local $1
+      (i32.lt_s
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (get_local $1)
+     (i32.gt_u
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.load offset=4
+       (get_local $0)
+      )
+     )
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (set_local $1
+   (i32.load
+    (i32.load
+     (get_local $0)
+    )
+   )
+  )
+  (drop
+   (call $std:heap/Heap.copy
+    (i32.load
+     (get_local $0)
+    )
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+    (i32.mul
+     (i32.sub
+      (i32.load offset=4
+       (get_local $0)
+      )
+      (i32.const 1)
+     )
+     (i32.const 4)
+    )
+   )
+  )
+  (drop
+   (call $std:heap/Heap.fill
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (i32.sub
+       (i32.load offset=4
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+      (i32.const 4)
+     )
+    )
+    (i32.const 0)
+    (i32.const 4)
+   )
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (i32.sub
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.const 1)
+   )
+  )
+  (get_local $1)
+ )
+ (func $start (; 10 ;) (type $v)
+  (set_global $std:heap/HEAP_OFFSET
+   (get_global $HEAP_BASE)
+  )
+  (set_global $std/array/arr
+   (call $std:heap/Heap.allocate
+    (i32.const 12)
+   )
+  )
+  (if
+   (i32.load offset=8
+    (get_global $std/array/arr)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.load offset=4
+    (get_global $std/array/arr)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 42)
+   )
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#pop
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.ne
+    (get_global $std/array/i)
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.load offset=8
+    (get_global $std/array/arr)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 43)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 44)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 2)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 2)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 45)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 3)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#unshift
+    (get_global $std/array/arr)
+    (i32.const 42)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 3)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#unshift
+    (get_global $std/array/arr)
+    (i32.const 41)
+   )
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 5)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 8)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 41)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 3)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 4)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#shift
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.ne
+    (get_global $std/array/i)
+    (i32.const 41)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 4)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 8)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 3)
+    )
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#pop
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.ne
+    (get_global $std/array/i)
+    (i32.const 45)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=8
+     (get_global $std/array/arr)
+    )
+    (i32.const 3)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load offset=4
+     (get_global $std/array/arr)
+    )
+    (i32.const 8)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 1)
+    )
+    (i32.const 43)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/Array#__get
+     (get_global $std/array/arr)
+     (i32.const 2)
+    )
+    (i32.const 44)
+   )
+   (unreachable)
+  )
+ )
 )
diff --git a/tests/compiler/std/array.ts b/tests/compiler/std/array.ts
index 7c464175..31b5c0e4 100644
--- a/tests/compiler/std/array.ts
+++ b/tests/compiler/std/array.ts
@@ -1 +1,75 @@
-// Array.fromPtr<i32>(1);
+var arr = changetype<i32[]>(Heap.allocate(sizeof<usize>() + 2 * sizeof<i32>()));
+
+assert(arr.length == 0);
+assert(arr.__capacity == 0);
+
+arr.push(42);
+
+assert(arr[0] == 42);
+assert(arr.length == 1);
+assert(arr.__capacity == 1);
+
+var i = arr.pop();
+
+assert(i == 42);
+assert(arr.length == 0);
+assert(arr.__capacity == 1);
+
+arr.push(43);
+
+assert(arr.length == 1);
+assert(arr.__capacity == 1);
+assert(arr[0] == 43);
+
+arr.push(44);
+
+assert(arr.length == 2);
+assert(arr.__capacity == 2);
+assert(arr[0] == 43);
+assert(arr[1] == 44);
+
+arr.push(45);
+
+assert(arr.length == 3);
+assert(arr.__capacity == 4);
+assert(arr[0] == 43);
+assert(arr[1] == 44);
+assert(arr[2] == 45);
+
+arr.unshift(42); // see FIXME in std:array
+
+assert(arr.length == 4);
+assert(arr.__capacity == 4);
+assert(arr[0] == 42);
+assert(arr[1] == 43);
+assert(arr[2] == 44);
+assert(arr[3] == 45);
+
+arr.unshift(41);
+
+assert(arr.length == 5);
+assert(arr.__capacity == 8);
+assert(arr[0] == 41);
+assert(arr[1] == 42);
+assert(arr[2] == 43);
+assert(arr[3] == 44);
+assert(arr[4] == 45);
+
+i = arr.shift();
+
+assert(i == 41);
+assert(arr.length == 4);
+assert(arr.__capacity == 8);
+assert(arr[0] == 42);
+assert(arr[1] == 43);
+assert(arr[2] == 44);
+assert(arr[3] == 45);
+
+i = arr.pop();
+
+assert(i == 45);
+assert(arr.length == 3);
+assert(arr.__capacity == 8);
+assert(arr[0] == 42);
+assert(arr[1] == 43);
+assert(arr[2] == 44);
diff --git a/tests/compiler/std/array.wast b/tests/compiler/std/array.wast
index 03f8e437..265e87d3 100644
--- a/tests/compiler/std/array.wast
+++ b/tests/compiler/std/array.wast
@@ -1,7 +1,3340 @@
 (module
+ (type $i (func (result i32)))
+ (type $ii (func (param i32) (result i32)))
+ (type $iiii (func (param i32 i32 i32) (result i32)))
+ (type $iv (func (param i32)))
+ (type $iiv (func (param i32 i32)))
+ (type $iii (func (param i32 i32) (result i32)))
+ (type $v (func))
+ (global $std:heap/HEAP_OFFSET (mut i32) (i32.const 0))
+ (global $std:heap/ALIGN_LOG2 i32 (i32.const 3))
+ (global $std:heap/ALIGN_SIZE i32 (i32.const 8))
+ (global $std:heap/ALIGN_MASK i32 (i32.const 7))
+ (global $std/array/arr (mut i32) (i32.const 0))
+ (global $std/array/i (mut i32) (i32.const 0))
  (global $HEAP_BASE i32 (i32.const 4))
  (memory $0 1)
  (export "memory" (memory $0))
+ (start $start)
+ (func $std:heap/Heap.allocate (; 0 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (local $2 i32)
+  (local $3 i32)
+  (local $4 i32)
+  (if
+   (i32.eqz
+    (get_local $0)
+   )
+   (return
+    (i32.const 0)
+   )
+  )
+  (block
+   (set_local $1
+    (current_memory)
+   )
+  )
+  (if
+   (i32.gt_u
+    (i32.add
+     (get_global $std:heap/HEAP_OFFSET)
+     (get_local $0)
+    )
+    (i32.shl
+     (get_local $1)
+     (i32.const 16)
+    )
+   )
+   (if
+    (i32.lt_s
+     (grow_memory
+      (select
+       (tee_local $2
+        (i32.trunc_s/f64
+         (f64.ceil
+          (f64.div
+           (f64.convert_u/i32
+            (get_local $0)
+           )
+           (f64.const 65536)
+          )
+         )
+        )
+       )
+       (tee_local $3
+        (i32.sub
+         (i32.mul
+          (get_local $1)
+          (i32.const 2)
+         )
+         (get_local $1)
+        )
+       )
+       (i32.gt_s
+        (get_local $2)
+        (get_local $3)
+       )
+      )
+     )
+     (i32.const 0)
+    )
+    (unreachable)
+   )
+  )
+  (block
+   (set_local $4
+    (get_global $std:heap/HEAP_OFFSET)
+   )
+  )
+  (if
+   (i32.and
+    (block (result i32)
+     (set_global $std:heap/HEAP_OFFSET
+      (i32.add
+       (get_global $std:heap/HEAP_OFFSET)
+       (get_local $0)
+      )
+     )
+     (get_global $std:heap/HEAP_OFFSET)
+    )
+    (i32.const 7)
+   )
+   (set_global $std:heap/HEAP_OFFSET
+    (i32.add
+     (i32.or
+      (get_global $std:heap/HEAP_OFFSET)
+      (i32.const 7)
+     )
+     (i32.const 1)
+    )
+   )
+  )
+  (return
+   (get_local $4)
+  )
+ )
+ (func $std:heap/Heap.copy (; 1 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+  (local $3 i32)
+  (local $4 i32)
+  (local $5 i32)
+  (local $6 i32)
+  (if
+   (i32.eqz
+    (i32.ge_u
+     (get_local $0)
+     (get_global $HEAP_BASE)
+    )
+   )
+   (unreachable)
+  )
+  (block
+   (set_local $3
+    (get_local $0)
+   )
+  )
+  (nop)
+  (block $break|0
+   (loop $continue|0
+    (if
+     (if (result i32)
+      (i32.ne
+       (get_local $2)
+       (i32.const 0)
+      )
+      (i32.rem_u
+       (get_local $1)
+       (i32.const 4)
+      )
+      (get_local $2)
+     )
+     (block
+      (block
+       (i32.store8
+        (block (result i32)
+         (set_local $6
+          (get_local $3)
+         )
+         (set_local $3
+          (i32.add
+           (get_local $6)
+           (i32.const 1)
+          )
+         )
+         (get_local $6)
+        )
+        (i32.load8_u
+         (block (result i32)
+          (set_local $6
+           (get_local $1)
+          )
+          (set_local $1
+           (i32.add
+            (get_local $6)
+            (i32.const 1)
+           )
+          )
+          (get_local $6)
+         )
+        )
+       )
+       (set_local $2
+        (i32.sub
+         (get_local $2)
+         (i32.const 1)
+        )
+       )
+      )
+      (br $continue|0)
+     )
+    )
+   )
+  )
+  (if
+   (i32.eq
+    (i32.rem_u
+     (get_local $3)
+     (i32.const 4)
+    )
+    (i32.const 0)
+   )
+   (block
+    (block $break|1
+     (loop $continue|1
+      (if
+       (i32.ge_u
+        (get_local $2)
+        (i32.const 16)
+       )
+       (block
+        (block
+         (i32.store
+          (get_local $3)
+          (i32.load
+           (get_local $1)
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $3)
+           (i32.const 4)
+          )
+          (i32.load
+           (i32.add
+            (get_local $1)
+            (i32.const 4)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $3)
+           (i32.const 8)
+          )
+          (i32.load
+           (i32.add
+            (get_local $1)
+            (i32.const 8)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $3)
+           (i32.const 12)
+          )
+          (i32.load
+           (i32.add
+            (get_local $1)
+            (i32.const 12)
+           )
+          )
+         )
+         (set_local $1
+          (i32.add
+           (get_local $1)
+           (i32.const 16)
+          )
+         )
+         (set_local $3
+          (i32.add
+           (get_local $3)
+           (i32.const 16)
+          )
+         )
+         (set_local $2
+          (i32.sub
+           (get_local $2)
+           (i32.const 16)
+          )
+         )
+        )
+        (br $continue|1)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 8)
+     )
+     (block
+      (i32.store
+       (get_local $3)
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (i32.store
+       (i32.add
+        (get_local $3)
+        (i32.const 4)
+       )
+       (i32.load
+        (i32.add
+         (get_local $1)
+         (i32.const 4)
+        )
+       )
+      )
+      (set_local $3
+       (i32.add
+        (get_local $3)
+        (i32.const 8)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 8)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 4)
+     )
+     (block
+      (i32.store
+       (get_local $3)
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (set_local $3
+       (i32.add
+        (get_local $3)
+        (i32.const 4)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 4)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 2)
+     )
+     (block
+      (i32.store16
+       (get_local $3)
+       (i32.load16_u
+        (get_local $1)
+       )
+      )
+      (set_local $3
+       (i32.add
+        (get_local $3)
+        (i32.const 2)
+       )
+      )
+      (set_local $1
+       (i32.add
+        (get_local $1)
+        (i32.const 2)
+       )
+      )
+     )
+    )
+    (if
+     (i32.and
+      (get_local $2)
+      (i32.const 1)
+     )
+     (i32.store8
+      (block (result i32)
+       (set_local $6
+        (get_local $3)
+       )
+       (set_local $3
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+      (i32.load8_u
+       (block (result i32)
+        (set_local $6
+         (get_local $1)
+        )
+        (set_local $1
+         (i32.add
+          (get_local $6)
+          (i32.const 1)
+         )
+        )
+        (get_local $6)
+       )
+      )
+     )
+    )
+    (return
+     (get_local $0)
+    )
+   )
+  )
+  (if
+   (i32.ge_u
+    (get_local $2)
+    (i32.const 32)
+   )
+   (block $break|2
+    (block $case2|2
+     (block $case1|2
+      (block $case0|2
+       (set_local $6
+        (i32.rem_u
+         (get_local $3)
+         (i32.const 4)
+        )
+       )
+       (br_if $case0|2
+        (i32.eq
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (br_if $case1|2
+        (i32.eq
+         (get_local $6)
+         (i32.const 2)
+        )
+       )
+       (br_if $case2|2
+        (i32.eq
+         (get_local $6)
+         (i32.const 3)
+        )
+       )
+       (br $break|2)
+      )
+      (set_local $4
+       (i32.load
+        (get_local $1)
+       )
+      )
+      (i32.store8
+       (block (result i32)
+        (set_local $6
+         (get_local $3)
+        )
+        (set_local $3
+         (i32.add
+          (get_local $6)
+          (i32.const 1)
+         )
+        )
+        (get_local $6)
+       )
+       (i32.load8_u
+        (block (result i32)
+         (set_local $6
+          (get_local $1)
+         )
+         (set_local $1
+          (i32.add
+           (get_local $6)
+           (i32.const 1)
+          )
+         )
+         (get_local $6)
+        )
+       )
+      )
+      (i32.store8
+       (block (result i32)
+        (set_local $6
+         (get_local $3)
+        )
+        (set_local $3
+         (i32.add
+          (get_local $6)
+          (i32.const 1)
+         )
+        )
+        (get_local $6)
+       )
+       (i32.load8_u
+        (block (result i32)
+         (set_local $6
+          (get_local $1)
+         )
+         (set_local $1
+          (i32.add
+           (get_local $6)
+           (i32.const 1)
+          )
+         )
+         (get_local $6)
+        )
+       )
+      )
+      (i32.store8
+       (block (result i32)
+        (set_local $6
+         (get_local $3)
+        )
+        (set_local $3
+         (i32.add
+          (get_local $6)
+          (i32.const 1)
+         )
+        )
+        (get_local $6)
+       )
+       (i32.load8_u
+        (block (result i32)
+         (set_local $6
+          (get_local $1)
+         )
+         (set_local $1
+          (i32.add
+           (get_local $6)
+           (i32.const 1)
+          )
+         )
+         (get_local $6)
+        )
+       )
+      )
+      (set_local $2
+       (i32.sub
+        (get_local $2)
+        (i32.const 3)
+       )
+      )
+      (block $break|3
+       (loop $continue|3
+        (if
+         (i32.ge_u
+          (get_local $2)
+          (i32.const 17)
+         )
+         (block
+          (block
+           (set_local $5
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 1)
+             )
+            )
+           )
+           (i32.store
+            (get_local $3)
+            (i32.or
+             (i32.shr_u
+              (get_local $4)
+              (i32.const 24)
+             )
+             (i32.shl
+              (get_local $5)
+              (i32.const 8)
+             )
+            )
+           )
+           (set_local $4
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 5)
+             )
+            )
+           )
+           (i32.store
+            (i32.add
+             (get_local $3)
+             (i32.const 4)
+            )
+            (i32.or
+             (i32.shr_u
+              (get_local $5)
+              (i32.const 24)
+             )
+             (i32.shl
+              (get_local $4)
+              (i32.const 8)
+             )
+            )
+           )
+           (set_local $5
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 9)
+             )
+            )
+           )
+           (i32.store
+            (i32.add
+             (get_local $3)
+             (i32.const 8)
+            )
+            (i32.or
+             (i32.shr_u
+              (get_local $4)
+              (i32.const 24)
+             )
+             (i32.shl
+              (get_local $5)
+              (i32.const 8)
+             )
+            )
+           )
+           (set_local $4
+            (i32.load
+             (i32.add
+              (get_local $1)
+              (i32.const 13)
+             )
+            )
+           )
+           (i32.store
+            (i32.add
+             (get_local $3)
+             (i32.const 12)
+            )
+            (i32.or
+             (i32.shr_u
+              (get_local $5)
+              (i32.const 24)
+             )
+             (i32.shl
+              (get_local $4)
+              (i32.const 8)
+             )
+            )
+           )
+           (set_local $1
+            (i32.add
+             (get_local $1)
+             (i32.const 16)
+            )
+           )
+           (set_local $3
+            (i32.add
+             (get_local $3)
+             (i32.const 16)
+            )
+           )
+           (set_local $2
+            (i32.sub
+             (get_local $2)
+             (i32.const 16)
+            )
+           )
+          )
+          (br $continue|3)
+         )
+        )
+       )
+      )
+      (br $break|2)
+     )
+     (set_local $4
+      (i32.load
+       (get_local $1)
+      )
+     )
+     (i32.store8
+      (block (result i32)
+       (set_local $6
+        (get_local $3)
+       )
+       (set_local $3
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+      (i32.load8_u
+       (block (result i32)
+        (set_local $6
+         (get_local $1)
+        )
+        (set_local $1
+         (i32.add
+          (get_local $6)
+          (i32.const 1)
+         )
+        )
+        (get_local $6)
+       )
+      )
+     )
+     (i32.store8
+      (block (result i32)
+       (set_local $6
+        (get_local $3)
+       )
+       (set_local $3
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+      (i32.load8_u
+       (block (result i32)
+        (set_local $6
+         (get_local $1)
+        )
+        (set_local $1
+         (i32.add
+          (get_local $6)
+          (i32.const 1)
+         )
+        )
+        (get_local $6)
+       )
+      )
+     )
+     (set_local $2
+      (i32.sub
+       (get_local $2)
+       (i32.const 2)
+      )
+     )
+     (block $break|4
+      (loop $continue|4
+       (if
+        (i32.ge_u
+         (get_local $2)
+         (i32.const 18)
+        )
+        (block
+         (block
+          (set_local $5
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 2)
+            )
+           )
+          )
+          (i32.store
+           (get_local $3)
+           (i32.or
+            (i32.shr_u
+             (get_local $4)
+             (i32.const 16)
+            )
+            (i32.shl
+             (get_local $5)
+             (i32.const 16)
+            )
+           )
+          )
+          (set_local $4
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 6)
+            )
+           )
+          )
+          (i32.store
+           (i32.add
+            (get_local $3)
+            (i32.const 4)
+           )
+           (i32.or
+            (i32.shr_u
+             (get_local $5)
+             (i32.const 16)
+            )
+            (i32.shl
+             (get_local $4)
+             (i32.const 16)
+            )
+           )
+          )
+          (set_local $5
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 10)
+            )
+           )
+          )
+          (i32.store
+           (i32.add
+            (get_local $3)
+            (i32.const 8)
+           )
+           (i32.or
+            (i32.shr_u
+             (get_local $4)
+             (i32.const 16)
+            )
+            (i32.shl
+             (get_local $5)
+             (i32.const 16)
+            )
+           )
+          )
+          (set_local $4
+           (i32.load
+            (i32.add
+             (get_local $1)
+             (i32.const 14)
+            )
+           )
+          )
+          (i32.store
+           (i32.add
+            (get_local $3)
+            (i32.const 12)
+           )
+           (i32.or
+            (i32.shr_u
+             (get_local $5)
+             (i32.const 16)
+            )
+            (i32.shl
+             (get_local $4)
+             (i32.const 16)
+            )
+           )
+          )
+          (set_local $1
+           (i32.add
+            (get_local $1)
+            (i32.const 16)
+           )
+          )
+          (set_local $3
+           (i32.add
+            (get_local $3)
+            (i32.const 16)
+           )
+          )
+          (set_local $2
+           (i32.sub
+            (get_local $2)
+            (i32.const 16)
+           )
+          )
+         )
+         (br $continue|4)
+        )
+       )
+      )
+     )
+     (br $break|2)
+    )
+    (set_local $4
+     (i32.load
+      (get_local $1)
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (set_local $2
+     (i32.sub
+      (get_local $2)
+      (i32.const 1)
+     )
+    )
+    (block $break|5
+     (loop $continue|5
+      (if
+       (i32.ge_u
+        (get_local $2)
+        (i32.const 19)
+       )
+       (block
+        (block
+         (set_local $5
+          (i32.load
+           (i32.add
+            (get_local $1)
+            (i32.const 3)
+           )
+          )
+         )
+         (i32.store
+          (get_local $3)
+          (i32.or
+           (i32.shr_u
+            (get_local $4)
+            (i32.const 8)
+           )
+           (i32.shl
+            (get_local $5)
+            (i32.const 24)
+           )
+          )
+         )
+         (set_local $4
+          (i32.load
+           (i32.add
+            (get_local $1)
+            (i32.const 7)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $3)
+           (i32.const 4)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $5)
+            (i32.const 8)
+           )
+           (i32.shl
+            (get_local $4)
+            (i32.const 24)
+           )
+          )
+         )
+         (set_local $5
+          (i32.load
+           (i32.add
+            (get_local $1)
+            (i32.const 11)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $3)
+           (i32.const 8)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $4)
+            (i32.const 8)
+           )
+           (i32.shl
+            (get_local $5)
+            (i32.const 24)
+           )
+          )
+         )
+         (set_local $4
+          (i32.load
+           (i32.add
+            (get_local $1)
+            (i32.const 15)
+           )
+          )
+         )
+         (i32.store
+          (i32.add
+           (get_local $3)
+           (i32.const 12)
+          )
+          (i32.or
+           (i32.shr_u
+            (get_local $5)
+            (i32.const 8)
+           )
+           (i32.shl
+            (get_local $4)
+            (i32.const 24)
+           )
+          )
+         )
+         (set_local $1
+          (i32.add
+           (get_local $1)
+           (i32.const 16)
+          )
+         )
+         (set_local $3
+          (i32.add
+           (get_local $3)
+           (i32.const 16)
+          )
+         )
+         (set_local $2
+          (i32.sub
+           (get_local $2)
+           (i32.const 16)
+          )
+         )
+        )
+        (br $continue|5)
+       )
+      )
+     )
+    )
+    (br $break|2)
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 16)
+   )
+   (block
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 8)
+   )
+   (block
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 4)
+   )
+   (block
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 2)
+   )
+   (block
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+    (i32.store8
+     (block (result i32)
+      (set_local $6
+       (get_local $3)
+      )
+      (set_local $3
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+     (i32.load8_u
+      (block (result i32)
+       (set_local $6
+        (get_local $1)
+       )
+       (set_local $1
+        (i32.add
+         (get_local $6)
+         (i32.const 1)
+        )
+       )
+       (get_local $6)
+      )
+     )
+    )
+   )
+  )
+  (if
+   (i32.and
+    (get_local $2)
+    (i32.const 1)
+   )
+   (i32.store8
+    (block (result i32)
+     (set_local $6
+      (get_local $3)
+     )
+     (set_local $3
+      (i32.add
+       (get_local $6)
+       (i32.const 1)
+      )
+     )
+     (get_local $6)
+    )
+    (i32.load8_u
+     (block (result i32)
+      (set_local $6
+       (get_local $1)
+      )
+      (set_local $1
+       (i32.add
+        (get_local $6)
+        (i32.const 1)
+       )
+      )
+      (get_local $6)
+     )
+    )
+   )
+  )
+  (return
+   (get_local $0)
+  )
+ )
+ (func $std:heap/Heap.dispose (; 2 ;) (type $iv) (param $0 i32)
+ )
+ (func $std:array/Array#__grow (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32)
+  (local $2 i32)
+  (if
+   (i32.eqz
+    (i32.gt_s
+     (get_local $1)
+     (i32.load offset=4
+      (get_local $0)
+     )
+    )
+   )
+   (unreachable)
+  )
+  (block
+   (set_local $2
+    (call $std:heap/Heap.allocate
+     (i32.mul
+      (get_local $1)
+      (i32.const 4)
+     )
+    )
+   )
+  )
+  (if
+   (i32.load
+    (get_local $0)
+   )
+   (drop
+    (call $std:heap/Heap.copy
+     (get_local $2)
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (i32.load offset=4
+       (get_local $0)
+      )
+      (i32.const 4)
+     )
+    )
+   )
+  )
+  (call $std:heap/Heap.dispose
+   (i32.load
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (get_local $0)
+   (get_local $2)
+  )
+  (i32.store offset=4
+   (get_local $0)
+   (get_local $1)
+  )
+ )
+ (func $std:array/Array#push (; 4 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (local $2 i32)
+  (local $3 i32)
+  (if
+   (i32.ge_u
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (call $std:array/Array#__grow
+    (get_local $0)
+    (select
+     (tee_local $2
+      (i32.add
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (tee_local $3
+      (i32.mul
+       (i32.load offset=4
+        (get_local $0)
+       )
+       (i32.const 2)
+      )
+     )
+     (i32.gt_s
+      (get_local $2)
+      (get_local $3)
+     )
+    )
+   )
+  )
+  (i32.store
+   (i32.add
+    (i32.load
+     (get_local $0)
+    )
+    (i32.mul
+     (i32.load offset=8
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+   )
+   (get_local $1)
+  )
+  (return
+   (block (result i32)
+    (set_local $2
+     (i32.add
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store offset=8
+     (get_local $0)
+     (get_local $2)
+    )
+    (get_local $2)
+   )
+  )
+ )
+ (func $std:array/Array#__get (; 5 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (if
+   (i32.ge_u
+    (get_local $1)
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+   (unreachable)
+  )
+  (return
+   (i32.load
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (get_local $1)
+      (i32.const 4)
+     )
+    )
+   )
+  )
+ )
+ (func $std:array/Array#pop (; 6 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (if
+   (i32.and
+    (if (result i32)
+     (i32.ne
+      (tee_local $1
+       (i32.lt_s
+        (i32.load offset=8
+         (get_local $0)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.const 0)
+     )
+     (get_local $1)
+     (i32.gt_u
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.load offset=4
+       (get_local $0)
+      )
+     )
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (i32.sub
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.const 1)
+   )
+  )
+  (return
+   (i32.load
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.const 4)
+     )
+    )
+   )
+  )
+ )
+ (func $std:array/Array#unshift (; 7 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (local $2 i32)
+  (local $3 i32)
+  (local $4 i32)
+  (local $5 i32)
+  (block
+   (set_local $2
+    (i32.load offset=4
+     (get_local $0)
+    )
+   )
+  )
+  (if
+   (i32.ge_u
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (get_local $2)
+   )
+   (call $std:array/Array#__grow
+    (get_local $0)
+    (select
+     (tee_local $3
+      (i32.add
+       (i32.load offset=8
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+     )
+     (tee_local $4
+      (i32.mul
+       (get_local $2)
+       (i32.const 2)
+      )
+     )
+     (i32.gt_s
+      (get_local $3)
+      (get_local $4)
+     )
+    )
+   )
+  )
+  (if
+   (get_local $2)
+   (block $break|0
+    (block
+     (set_local $5
+      (get_local $2)
+     )
+    )
+    (loop $continue|0
+     (if
+      (i32.gt_u
+       (get_local $5)
+       (i32.const 0)
+      )
+      (block
+       (i32.store
+        (i32.add
+         (i32.load
+          (get_local $0)
+         )
+         (i32.mul
+          (get_local $5)
+          (i32.const 4)
+         )
+        )
+        (i32.load
+         (i32.add
+          (i32.load
+           (get_local $0)
+          )
+          (i32.mul
+           (i32.sub
+            (get_local $5)
+            (i32.const 1)
+           )
+           (i32.const 4)
+          )
+         )
+        )
+       )
+       (set_local $5
+        (i32.sub
+         (get_local $5)
+         (i32.const 1)
+        )
+       )
+       (br $continue|0)
+      )
+     )
+    )
+   )
+  )
+  (i32.store
+   (i32.load
+    (get_local $0)
+   )
+   (get_local $1)
+  )
+  (return
+   (block (result i32)
+    (set_local $3
+     (i32.add
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.const 1)
+     )
+    )
+    (i32.store offset=8
+     (get_local $0)
+     (get_local $3)
+    )
+    (get_local $3)
+   )
+  )
+ )
+ (func $std:heap/Heap.fill (; 8 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+  (local $3 i32)
+  (local $4 i32)
+  (local $5 i32)
+  (local $6 i64)
+  (if
+   (i32.eqz
+    (i32.ge_u
+     (get_local $0)
+     (get_global $HEAP_BASE)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (get_local $2)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (block
+   (set_local $3
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (get_local $3)
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 1)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 2)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 1)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 2)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 2)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 3)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 6)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store8
+   (i32.add
+    (get_local $3)
+    (i32.const 3)
+   )
+   (get_local $1)
+  )
+  (i32.store8
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 4)
+   )
+   (get_local $1)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 8)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (block
+   (set_local $4
+    (i32.and
+     (i32.sub
+      (i32.const 0)
+      (get_local $3)
+     )
+     (i32.const 3)
+    )
+   )
+  )
+  (set_local $3
+   (i32.add
+    (get_local $3)
+    (get_local $4)
+   )
+  )
+  (set_local $2
+   (i32.sub
+    (get_local $2)
+    (get_local $4)
+   )
+  )
+  (set_local $2
+   (i32.and
+    (get_local $2)
+    (i32.sub
+     (i32.const 0)
+     (i32.const 4)
+    )
+   )
+  )
+  (block
+   (set_local $5
+    (i32.mul
+     (i32.div_u
+      (i32.sub
+       (i32.const 0)
+       (i32.const 1)
+      )
+      (i32.const 255)
+     )
+     (get_local $1)
+    )
+   )
+  )
+  (i32.store
+   (get_local $3)
+   (get_local $5)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 4)
+   )
+   (get_local $5)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 8)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 4)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 8)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 12)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 8)
+   )
+   (get_local $5)
+  )
+  (if
+   (i32.le_u
+    (get_local $2)
+    (i32.const 24)
+   )
+   (return
+    (get_local $0)
+   )
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 12)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 16)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 20)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.add
+    (get_local $3)
+    (i32.const 24)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 28)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 24)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 20)
+   )
+   (get_local $5)
+  )
+  (i32.store
+   (i32.sub
+    (i32.add
+     (get_local $3)
+     (get_local $2)
+    )
+    (i32.const 16)
+   )
+   (get_local $5)
+  )
+  (set_local $4
+   (i32.add
+    (i32.const 24)
+    (i32.and
+     (get_local $3)
+     (i32.const 4)
+    )
+   )
+  )
+  (set_local $3
+   (i32.add
+    (get_local $3)
+    (get_local $4)
+   )
+  )
+  (set_local $2
+   (i32.sub
+    (get_local $2)
+    (get_local $4)
+   )
+  )
+  (block
+   (set_local $6
+    (i64.or
+     (i64.extend_u/i32
+      (get_local $5)
+     )
+     (i64.shl
+      (i64.extend_u/i32
+       (get_local $5)
+      )
+      (i64.const 32)
+     )
+    )
+   )
+  )
+  (block $break|0
+   (loop $continue|0
+    (if
+     (i32.ge_u
+      (get_local $2)
+      (i32.const 32)
+     )
+     (block
+      (block
+       (i64.store
+        (get_local $3)
+        (get_local $6)
+       )
+       (i64.store
+        (i32.add
+         (get_local $3)
+         (i32.const 8)
+        )
+        (get_local $6)
+       )
+       (i64.store
+        (i32.add
+         (get_local $3)
+         (i32.const 16)
+        )
+        (get_local $6)
+       )
+       (i64.store
+        (i32.add
+         (get_local $3)
+         (i32.const 24)
+        )
+        (get_local $6)
+       )
+       (set_local $2
+        (i32.sub
+         (get_local $2)
+         (i32.const 32)
+        )
+       )
+       (set_local $3
+        (i32.add
+         (get_local $3)
+         (i32.const 32)
+        )
+       )
+      )
+      (br $continue|0)
+     )
+    )
+   )
+  )
+  (return
+   (get_local $0)
+  )
+ )
+ (func $std:array/Array#shift (; 9 ;) (type $ii) (param $0 i32) (result i32)
+  (local $1 i32)
+  (local $2 i32)
+  (if
+   (i32.and
+    (if (result i32)
+     (i32.ne
+      (tee_local $1
+       (i32.lt_s
+        (i32.load offset=8
+         (get_local $0)
+        )
+        (i32.const 1)
+       )
+      )
+      (i32.const 0)
+     )
+     (get_local $1)
+     (i32.gt_u
+      (i32.load offset=8
+       (get_local $0)
+      )
+      (i32.load offset=4
+       (get_local $0)
+      )
+     )
+    )
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (block
+   (set_local $2
+    (i32.load
+     (i32.load
+      (get_local $0)
+     )
+    )
+   )
+  )
+  (drop
+   (call $std:heap/Heap.copy
+    (i32.load
+     (get_local $0)
+    )
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.const 4)
+    )
+    (i32.mul
+     (i32.sub
+      (i32.load offset=4
+       (get_local $0)
+      )
+      (i32.const 1)
+     )
+     (i32.const 4)
+    )
+   )
+  )
+  (drop
+   (call $std:heap/Heap.fill
+    (i32.add
+     (i32.load
+      (get_local $0)
+     )
+     (i32.mul
+      (i32.sub
+       (i32.load offset=4
+        (get_local $0)
+       )
+       (i32.const 1)
+      )
+      (i32.const 4)
+     )
+    )
+    (i32.const 0)
+    (i32.const 4)
+   )
+  )
+  (i32.store offset=8
+   (get_local $0)
+   (i32.sub
+    (i32.load offset=8
+     (get_local $0)
+    )
+    (i32.const 1)
+   )
+  )
+  (return
+   (get_local $2)
+  )
+ )
+ (func $start (; 10 ;) (type $v)
+  (set_global $std:heap/HEAP_OFFSET
+   (get_global $HEAP_BASE)
+  )
+  (set_global $std/array/arr
+   (call $std:heap/Heap.allocate
+    (i32.add
+     (i32.const 4)
+     (i32.mul
+      (i32.const 2)
+      (i32.const 4)
+     )
+    )
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 0)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 0)
+    )
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 42)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 1)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 1)
+    )
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#pop
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (get_global $std/array/i)
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 0)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 1)
+    )
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 43)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 1)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 1)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 43)
+    )
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 44)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 2)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 2)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 43)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 1)
+     )
+     (i32.const 44)
+    )
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#push
+    (get_global $std/array/arr)
+    (i32.const 45)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 3)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 4)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 43)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 1)
+     )
+     (i32.const 44)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 2)
+     )
+     (i32.const 45)
+    )
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#unshift
+    (get_global $std/array/arr)
+    (i32.const 42)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 4)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 4)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 1)
+     )
+     (i32.const 43)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 2)
+     )
+     (i32.const 44)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 3)
+     )
+     (i32.const 45)
+    )
+   )
+   (unreachable)
+  )
+  (drop
+   (call $std:array/Array#unshift
+    (get_global $std/array/arr)
+    (i32.const 41)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 5)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 8)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 41)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 1)
+     )
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 2)
+     )
+     (i32.const 43)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 3)
+     )
+     (i32.const 44)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 4)
+     )
+     (i32.const 45)
+    )
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#shift
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (get_global $std/array/i)
+     (i32.const 41)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 4)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 8)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 1)
+     )
+     (i32.const 43)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 2)
+     )
+     (i32.const 44)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 3)
+     )
+     (i32.const 45)
+    )
+   )
+   (unreachable)
+  )
+  (set_global $std/array/i
+   (call $std:array/Array#pop
+    (get_global $std/array/arr)
+   )
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (get_global $std/array/i)
+     (i32.const 45)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=8
+      (get_global $std/array/arr)
+     )
+     (i32.const 3)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load offset=4
+      (get_global $std/array/arr)
+     )
+     (i32.const 8)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 0)
+     )
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 1)
+     )
+     (i32.const 43)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/Array#__get
+      (get_global $std/array/arr)
+      (i32.const 2)
+     )
+     (i32.const 44)
+    )
+   )
+   (unreachable)
+  )
+ )
 )
 (;
 [program.elements]
@@ -83,6 +3416,8 @@
   FUNCTION_PROTOTYPE: parseInt
   FUNCTION_PROTOTYPE: std:string/parseFloat
   FUNCTION_PROTOTYPE: parseFloat
+  GLOBAL: std/array/arr
+  GLOBAL: std/array/i
 [program.exports]
   CLASS_PROTOTYPE: std:array/Array
   CLASS_PROTOTYPE: std:array/CArray
diff --git a/tests/compiler/std/carray.optimized.wast b/tests/compiler/std/carray.optimized.wast
new file mode 100644
index 00000000..4247e770
--- /dev/null
+++ b/tests/compiler/std/carray.optimized.wast
@@ -0,0 +1,157 @@
+(module
+ (type $iii (func (param i32 i32) (result i32)))
+ (type $iiiv (func (param i32 i32 i32)))
+ (type $v (func))
+ (global $std/carray/arr (mut i32) (i32.const 0))
+ (global $HEAP_BASE i32 (i32.const 4))
+ (memory $0 1)
+ (export "memory" (memory $0))
+ (start $start)
+ (func $std:array/CArray#__get (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (i32.load
+   (i32.add
+    (get_local $0)
+    (i32.mul
+     (get_local $1)
+     (i32.const 4)
+    )
+   )
+  )
+ )
+ (func $std:array/CArray#__set (; 1 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
+  (i32.store
+   (i32.add
+    (get_local $0)
+    (i32.mul
+     (get_local $1)
+     (i32.const 4)
+    )
+   )
+   (get_local $2)
+  )
+ )
+ (func $start (; 2 ;) (type $v)
+  (local $0 i32)
+  (set_global $std/carray/arr
+   (get_global $HEAP_BASE)
+  )
+  (if
+   (i32.load
+    (get_global $HEAP_BASE)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.load
+    (i32.add
+     (get_global $HEAP_BASE)
+     (i32.const 4)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (call $std:array/CArray#__get
+    (get_global $std/carray/arr)
+    (i32.const 0)
+   )
+   (unreachable)
+  )
+  (if
+   (call $std:array/CArray#__get
+    (get_global $std/carray/arr)
+    (i32.const 1)
+   )
+   (unreachable)
+  )
+  (call $std:array/CArray#__set
+   (get_global $std/carray/arr)
+   (i32.const 0)
+   (i32.const 42)
+  )
+  (call $std:array/CArray#__set
+   (get_global $std/carray/arr)
+   (i32.const 1)
+   (i32.const 24)
+  )
+  (if
+   (i32.ne
+    (i32.load
+     (get_global $HEAP_BASE)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load
+     (i32.add
+      (get_global $HEAP_BASE)
+      (i32.const 4)
+     )
+    )
+    (i32.const 24)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/CArray#__get
+     (get_global $std/carray/arr)
+     (i32.const 0)
+    )
+    (i32.const 42)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/CArray#__get
+     (get_global $std/carray/arr)
+     (i32.const 1)
+    )
+    (i32.const 24)
+   )
+   (unreachable)
+  )
+  (if
+   (block (result i32)
+    (call $std:array/CArray#__set
+     (get_global $std/carray/arr)
+     (i32.const 3)
+     (tee_local $0
+      (i32.const 9000)
+     )
+    )
+    (i32.ne
+     (get_local $0)
+     (i32.const 9000)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (i32.load
+     (i32.add
+      (get_global $HEAP_BASE)
+      (i32.const 12)
+     )
+    )
+    (i32.const 9000)
+   )
+   (unreachable)
+  )
+  (if
+   (i32.ne
+    (call $std:array/CArray#__get
+     (get_global $std/carray/arr)
+     (i32.const 3)
+    )
+    (i32.const 9000)
+   )
+   (unreachable)
+  )
+ )
+)
diff --git a/tests/compiler/std/carray.ts b/tests/compiler/std/carray.ts
new file mode 100644
index 00000000..5b7277a3
--- /dev/null
+++ b/tests/compiler/std/carray.ts
@@ -0,0 +1,26 @@
+// TBD: While this is useful as long as the pointer is just a local or global,
+// things go haywire, compared to C, as soon as the CArray is a member of a
+// class. Also, multi dimensional arrays cannot be implemented C-like because
+// their length isn't known at compile time.
+
+var arr: CArray<i32> = changetype<CArray<i32>>(HEAP_BASE);
+
+assert(load<i32>(HEAP_BASE) == 0);
+assert(load<i32>(HEAP_BASE + 4) == 0);
+
+assert(arr[0] == 0);
+assert(arr[1] == 0);
+
+arr[0] = 42;
+arr[1] = 24;
+
+assert(load<i32>(HEAP_BASE) == 42);
+assert(load<i32>(HEAP_BASE + 4) == 24);
+
+assert(arr[0] == 42);
+assert(arr[1] == 24);
+
+assert((arr[3] = 9000) == 9000);
+
+assert(load<i32>(HEAP_BASE + 12) == 9000);
+assert(arr[3] == 9000);
diff --git a/tests/compiler/std/carray.wast b/tests/compiler/std/carray.wast
new file mode 100644
index 00000000..651ea64b
--- /dev/null
+++ b/tests/compiler/std/carray.wast
@@ -0,0 +1,287 @@
+(module
+ (type $iii (func (param i32 i32) (result i32)))
+ (type $iiiv (func (param i32 i32 i32)))
+ (type $v (func))
+ (global $std/carray/arr (mut i32) (i32.const 0))
+ (global $HEAP_BASE i32 (i32.const 4))
+ (memory $0 1)
+ (export "memory" (memory $0))
+ (start $start)
+ (func $std:array/CArray#__get (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
+  (return
+   (i32.load
+    (i32.add
+     (get_local $0)
+     (i32.mul
+      (get_local $1)
+      (i32.const 4)
+     )
+    )
+   )
+  )
+ )
+ (func $std:array/CArray#__set (; 1 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
+  (i32.store
+   (i32.add
+    (get_local $0)
+    (i32.mul
+     (get_local $1)
+     (i32.const 4)
+    )
+   )
+   (get_local $2)
+  )
+ )
+ (func $start (; 2 ;) (type $v)
+  (local $0 i32)
+  (set_global $std/carray/arr
+   (get_global $HEAP_BASE)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load
+      (get_global $HEAP_BASE)
+     )
+     (i32.const 0)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load
+      (i32.add
+       (get_global $HEAP_BASE)
+       (i32.const 4)
+      )
+     )
+     (i32.const 0)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/CArray#__get
+      (get_global $std/carray/arr)
+      (i32.const 0)
+     )
+     (i32.const 0)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/CArray#__get
+      (get_global $std/carray/arr)
+      (i32.const 1)
+     )
+     (i32.const 0)
+    )
+   )
+   (unreachable)
+  )
+  (call $std:array/CArray#__set
+   (get_global $std/carray/arr)
+   (i32.const 0)
+   (i32.const 42)
+  )
+  (call $std:array/CArray#__set
+   (get_global $std/carray/arr)
+   (i32.const 1)
+   (i32.const 24)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load
+      (get_global $HEAP_BASE)
+     )
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load
+      (i32.add
+       (get_global $HEAP_BASE)
+       (i32.const 4)
+      )
+     )
+     (i32.const 24)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/CArray#__get
+      (get_global $std/carray/arr)
+      (i32.const 0)
+     )
+     (i32.const 42)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/CArray#__get
+      (get_global $std/carray/arr)
+      (i32.const 1)
+     )
+     (i32.const 24)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (block (result i32)
+      (call $std:array/CArray#__set
+       (get_global $std/carray/arr)
+       (i32.const 3)
+       (tee_local $0
+        (i32.const 9000)
+       )
+      )
+      (get_local $0)
+     )
+     (i32.const 9000)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (i32.load
+      (i32.add
+       (get_global $HEAP_BASE)
+       (i32.const 12)
+      )
+     )
+     (i32.const 9000)
+    )
+   )
+   (unreachable)
+  )
+  (if
+   (i32.eqz
+    (i32.eq
+     (call $std:array/CArray#__get
+      (get_global $std/carray/arr)
+      (i32.const 3)
+     )
+     (i32.const 9000)
+    )
+   )
+   (unreachable)
+  )
+ )
+)
+(;
+[program.elements]
+  GLOBAL: NaN
+  GLOBAL: Infinity
+  FUNCTION_PROTOTYPE: isNaN
+  FUNCTION_PROTOTYPE: isFinite
+  FUNCTION_PROTOTYPE: clz
+  FUNCTION_PROTOTYPE: ctz
+  FUNCTION_PROTOTYPE: popcnt
+  FUNCTION_PROTOTYPE: rotl
+  FUNCTION_PROTOTYPE: rotr
+  FUNCTION_PROTOTYPE: abs
+  FUNCTION_PROTOTYPE: max
+  FUNCTION_PROTOTYPE: min
+  FUNCTION_PROTOTYPE: ceil
+  FUNCTION_PROTOTYPE: floor
+  FUNCTION_PROTOTYPE: copysign
+  FUNCTION_PROTOTYPE: nearest
+  FUNCTION_PROTOTYPE: reinterpret
+  FUNCTION_PROTOTYPE: sqrt
+  FUNCTION_PROTOTYPE: trunc
+  FUNCTION_PROTOTYPE: load
+  FUNCTION_PROTOTYPE: store
+  FUNCTION_PROTOTYPE: sizeof
+  FUNCTION_PROTOTYPE: select
+  FUNCTION_PROTOTYPE: unreachable
+  FUNCTION_PROTOTYPE: current_memory
+  FUNCTION_PROTOTYPE: grow_memory
+  FUNCTION_PROTOTYPE: changetype
+  FUNCTION_PROTOTYPE: assert
+  FUNCTION_PROTOTYPE: i8
+  FUNCTION_PROTOTYPE: i16
+  FUNCTION_PROTOTYPE: i32
+  FUNCTION_PROTOTYPE: i64
+  FUNCTION_PROTOTYPE: u8
+  FUNCTION_PROTOTYPE: u16
+  FUNCTION_PROTOTYPE: u32
+  FUNCTION_PROTOTYPE: u64
+  FUNCTION_PROTOTYPE: bool
+  FUNCTION_PROTOTYPE: f32
+  FUNCTION_PROTOTYPE: f64
+  FUNCTION_PROTOTYPE: isize
+  FUNCTION_PROTOTYPE: usize
+  GLOBAL: HEAP_BASE
+  CLASS_PROTOTYPE: std:array/Array
+  CLASS_PROTOTYPE: Array
+  CLASS_PROTOTYPE: std:array/CArray
+  CLASS_PROTOTYPE: CArray
+  CLASS_PROTOTYPE: std:error/Error
+  CLASS_PROTOTYPE: Error
+  CLASS_PROTOTYPE: std:error/RangeError
+  CLASS_PROTOTYPE: RangeError
+  GLOBAL: std:heap/ALIGN_LOG2
+  GLOBAL: std:heap/ALIGN_SIZE
+  GLOBAL: std:heap/ALIGN_MASK
+  GLOBAL: std:heap/HEAP_OFFSET
+  CLASS_PROTOTYPE: std:heap/Heap
+  CLASS_PROTOTYPE: Heap
+  PROPERTY: std:heap/Heap.used
+  PROPERTY: std:heap/Heap.free
+  PROPERTY: std:heap/Heap.size
+  FUNCTION_PROTOTYPE: std:heap/Heap.allocate
+  FUNCTION_PROTOTYPE: std:heap/Heap.dispose
+  FUNCTION_PROTOTYPE: std:heap/Heap.copy
+  FUNCTION_PROTOTYPE: std:heap/Heap.fill
+  FUNCTION_PROTOTYPE: std:heap/Heap.compare
+  CLASS_PROTOTYPE: std:map/Map
+  CLASS_PROTOTYPE: Map
+  CLASS_PROTOTYPE: std:regexp/RegExp
+  CLASS_PROTOTYPE: RegExp
+  CLASS_PROTOTYPE: std:set/Set
+  CLASS_PROTOTYPE: Set
+  GLOBAL: std:string/EMPTY
+  CLASS_PROTOTYPE: std:string/String
+  CLASS_PROTOTYPE: String
+  FUNCTION_PROTOTYPE: std:string/isWhiteSpaceOrLineTerminator
+  FUNCTION_PROTOTYPE: std:string/parseInt
+  FUNCTION_PROTOTYPE: parseInt
+  FUNCTION_PROTOTYPE: std:string/parseFloat
+  FUNCTION_PROTOTYPE: parseFloat
+  GLOBAL: std/carray/arr
+[program.exports]
+  CLASS_PROTOTYPE: std:array/Array
+  CLASS_PROTOTYPE: std:array/CArray
+  CLASS_PROTOTYPE: std:error/Error
+  CLASS_PROTOTYPE: std:error/RangeError
+  CLASS_PROTOTYPE: std:heap/Heap
+  CLASS_PROTOTYPE: std:map/Map
+  CLASS_PROTOTYPE: std:regexp/RegExp
+  CLASS_PROTOTYPE: std:set/Set
+  CLASS_PROTOTYPE: std:string/String
+  FUNCTION_PROTOTYPE: std:string/parseInt
+  FUNCTION_PROTOTYPE: std:string/parseFloat
+;)