## 1. Project Overview & Quickstart (wasmerio/BUILD)

# BUILD

The official build framework for the Armbian Linux distribution. This repository contains the complete toolchain and scripts required to compile custom OS images from source, including kernel configuration, U-Boot handling, and board-specific tweaks for various ARM and ARM64 single-board computers.

### Repository Details
- **Repository:** [wasmerio/BUILD](https://github.com/wasmerio/BUILD)
- **GitHub Stars:** ⭐ 5,342
- **Primary Language:** Shell

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (wasmerio/website)

## File: README.md

AssemblyScript's Website
========================



The site is built with [VuePress](https://vuepress.vuejs.org/) and reuses its default theme to ease upgrading to newer versions.

The more important files are:

* [src/**/*.md](./src)
  Documentation and site contents, i.e. what one would typically modify when extending the documentation.
* [src/.vuepress/sidebar.js](./src/.vuepress/sidebar.js)
  Sidebar contents.
* [src/.vuepress/nav.js](./src/.vuepress/nav.js)
  Top-navigation contents.
* [src/.vuepress/redirects](./src/.vuepress/redirects)
  Redirect map of (re)moved pages to new locations.
* [src/.vuepress/public/](./src/.vuepress/public)
  Assets folder for images etc.
* [src/.vuepress/public/sponsors](./src/.vuepress/public/sponsors)
  Sponsor logo overrides (file name is collective name).

Editor component
----------------

Markdown files can make use of a custom [editor component](./src/.vuepress/public/editor.html) using the `editor` language tag, like so:

````
```editor
#!optimize=size&runtime=none&noAssert&explicitStart&enable=simd,reference-types
export function add(a: i32, b: i32): i32 {
  return a + b
}

#!html
<script>
loader.instantiate(module_wasm, { /* imports */ })
  .then(({ exports }) => {
    console.log(exports.add(1, 2))
  })
</script>
```
````

The first line is an optional shebang indicating selected compiler options. Available options are:

* **optimize** = `string`
  Optimization preset to use. Valid presets are `speed`, `size` and `none`
* **noAssert**
  Replaces assertions with just their value without trapping.
* **debug**
  Enables debug information in emitted binaries.
* **runtime** = `string`
  Specifies the runtime variant to include in the program. Valid variants are `full`, `half`, `stub` and `none`.
* **noExportMemory**
  Does not export the memory to the host.
* **importMemory**
  Imports the memory from the host.
* **exportTable**
  Exports the function table to the host.
* **importTable**
  Imports the function table from the host.
* **explicitStart**
  Exports an explicit start function to call.
* **memoryBase** = `integer`
  Sets the start offset of emitted memory segments.
* **tableBase** = `integer`
  Sets the start offset of emitted table elements.
* **use** = `string`
  Comma separated list of global aliases, e.g. to switch the default 'Math' implementation used: `Math=JSMath`
* **enable** = `string`
  Comma-separated list of future WebAssembly features to enable. Valid features are `sign-extension`, `bulk-memory`, `simd`, `threads` and `reference-types`.

The current source and associated compiler options can be serialized into a base64 blob this way. For example, when the 🔗 button is clicked, `document.location.hash` is updated with that blob and the then-sharable link is copied to clipboard.

Building
--------

To work on the site locally, install the dependencies and start a development server serving at [localhost:8080](http://localhost:8080/):

```sh
npm install
npm start
```

To build the site to `dist`, i.e. to verify that it works as expected:

```sh
npm run build
```

Distribution files can also be served instead of using the development server with:

```sh
npm run serve
```

The page is automatically deployed on pushes to the repository, plus at least once a day to sync contributors and sponsors.

---

## File: package.json

{
  "name": "@assemblyscript/website",
  "private": true,
  "version": "0.0.0",
  "license": "Apache-2.0",
  "description": "AssebmlyScript's Website.",
  "scripts": {
    "start": "vuepress dev src --host localhost --no-cache",
    "build": "vuepress build src",
    "serve": "vuepress serve src",
    "preinstall": "npx npm-force-resolutions"
  },
  "devDependencies": {
    "@vuepress/plugin-html-redirect": "^0.1.2",
    "he": "^1.2.0",
    "node-fetch": "^2.6.1",
    "pngquant": "^3.1.0",
    "prism-themes": "^1.5.0",
    "sharp": "^0.27.0",
    "vuepress": "^1.8.0",
    "vuepress-plugin-serve": "^2.0.4",
    "vuepress-plugin-sitemap": "^2.3.1"
  },
  "resolutions": {
    "watchpack": "1.6.1"
  }
}

---

## File: data/testimonials.json

[
  {
    "name": "Surma",
    "text": "You are now able to write WebAssembly without learning a new language, and harness all these benefits WebAssembly might offer you. I think that is kind of powerful. AssemblyScript is absolutely usable, and very enjoyable!",
    "title": "WebAssembly for Web Developers (Google I/O ’19)",
    "link": "https://youtu.be/njt-Qzw0mVY",
    "date": "May 8th, 2019"
  },
  {
    "name": "Alon Zakai",
    "text": "AssemblyScript is designed with WebAssembly and code size in mind. It's not an existing language that we are using for a new purpose but it's a language designed for WebAssembly. It has great wasm-opt integration, in fact it's built with it, and it's very easy to get good code size.",
    "title": "Shipping Tiny WebAssembly Builds (WebAssembly Summit)",
    "link": "https://www.youtube.com/watch?v=_lLqZR4ufSI",
    "date": "Feb 10, 2020"
  },
  {
    "name": "Peter Salomonsen",
    "text": "I chose AssemblyScript because it has high-level readability and low-level control. It's like a high-level language but you get that low-level feeling and you can even directly write WebAssembly intrinsics if you want to.",
    "title": "WebAssembly Music (WebAssembly Summit)",
    "link": "https://www.youtube.com/watch?v=C8j_ieOm4vE",
    "date": "Feb 10, 2020"
  }
]

---

## File: data/tiers.json

{
  "platinum": {
    "name": "Platinum Sponsors",
    "minAmount": 50000,
    "size": 80
  },
  "gold": {
    "name": "Gold Sponsors",
    "minAmount": 10000,
    "size": 64
  },
  "silver": {
    "name": "Silver Sponsors",
    "minAmount": 2000,
    "size": 48
  },
  "bronze": {
    "name": "Bronze Sponsors",
    "minAmount": 200,
    "size": 36
  },
  "backer": {
    "name": "Individual Backers",
    "minAmount": 1,
    "size": 32
  }
}

---

## File: src/basics.md

---
---

# Basics

WebAssembly is fundamentally different from JavaScript, ultimately enabling entirely new use cases not only on the web. Consequently, AssemblyScript is much more similar to a static compiler than it is to a JavaScript VM. One can think of it as a mix of TypeScript's high level syntax and C's low-level capabilities. This page is dedicated to getting you up to speed in no time.

## Strictness

Unlike TypeScript, which targets a JavaScript environment with all of its dynamic features, AssemblyScript targets WebAssembly with all of its static guarantees, hence intentionally **avoids the dynamicness of JavaScript** where it cannot be compiled ahead of time _efficiently_.

Limiting ourselves to where WebAssembly excels, for example by assigning or inferring definite types, eliminates the need to ship a JIT doing the heavy lifting at runtime, yielding **predictable performance** right from the start of execution while guaranteeing that the resulting WebAssembly **modules are small**.

## Static typing

The first peculiarity one is going to notice when writing AssemblyScript is that its [basic types](./types.md) are a bit different from TypeScript's in that it uses WebAssembly's **more specific integer and floating point types**, with JavaScript's `number` merely an alias of WebAssembly's `f64`.

A JavaScript JIT would try to figure out the best representation of a numeric value while the code is executing, making assumptions as values flow around, potentially recompiling code multiple times, while AssemblyScript lets the developer **specify the ideal type in advance** with all its pros and cons. To give a few examples:

### No any or undefined

```ts
// 😢
function foo(a?) {
  var b = a + 1
  return b
}

// 😊
function foo(a: i32 = 0): i32 {
  var b = a + 1
  return b
}
```

### No union types

```ts
// 😢
function foo(a: i32 | string): void {
}

// 😊
function foo<T>(a: T): void {
}
```

### Strictly typed objects

```ts
// 😢
var a = {}
a.prop = "hello world"

// 😊
var a = new Map<string,string>()
a.set("prop", "hello world")

// 😊
class A {
  constructor(public prop: string) {}
}
var a = new A("hello world")
```

## Sandbox

WebAssembly modules execute in a sandbox, providing **strong security guarantees** for all sorts of use cases not necessarily limited to the browser. As such, a module has **no immediate access to the DOM** or other external APIs out of the box. Also, WebAssembly does not yet have a concept of objects, making it necessary to **translate and exchange objects via pointers** to linear memory either through the module's [exports and imports](./exports-and-imports.md) or by reading from respectively writing to the module's linear memory. The [loader](./loader.md) is able to help there.

## Quirks

Some patterns behave a little different in AssemblyScript compared to TypeScript. This section covers the more or less obvious ones and shows how to deal with them, so you can keep them in mind and build something great today.

### Triple equals

The special semantics of the `===` operator (`true` when both the value and type match) don't make a lot of sense in AssemblyScript because comparing two values of incompatible types is illegal anyway. Hence the `===` operator has been repurposed to perform an identity comparison, evaluating to `true` if both operands are **the exact same object**:

```ts
var a = "hello"
var b = a
var c = "h" + a.substring(1)

if (a === b) { /* true */ }
if (a === c) { /* false */ }
if (a == c) { /* true */ }
```

This semantical change turned out to be quite useful during implementation of some parts of the standard library where knowing if something is actually exactly the same makes a lot of sense, but it can be confusing for those coming from a TypeScript background where using `===` for everything unless required otherwise is common good practice. However, the alternative here is to make `===` a redundanat alias of `==` by sacrificing an otherwise useful feature, and it's still unclear if that'd be objectively better, so has been postponed multiple times.

### Nullability checks

Like TypeScript, the AssemblyScript compiler can propagate whether a value is nullable or not after a check:

```ts
function doSomething(something: string | null): void {
  if (something) {
    something.length // works
  }
}
```

This doesn't work on fields, however, because their value can change in between the check and the use of the value:

```ts
function doSomething(foo: Foo): void {
  if (foo.something) {
    // ... some code ...
    foo.something.length // fails
  }
}
```

For example, `foo.something` might be a property that sets the underlying field to `null` when accessed, or code in between may set the field to `null`. In fact, TypeScript [fails](https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEBiD29oG8BQ0PQvAtgUwBcALASwDsBzALiwICdyLoAfaMgVxBGgF43OQAblQBfVKgBm7MsAIl4ZaABN4AZVyFSlABQTENBPACUKdJhITouxADps+YoxNpMr5Wo2PKAURAQ81sbCbph68HaeWhQ2IHiUxILQAPRJWETwnErQeHR08HQANNAARuwE7ngQZADkBGYYYmKS0rLyiirqDlG+-oEGiM710GERXYy8-FzCIkA) in [both](https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEBiD29oG8BQ0PQPoXgWwFMAXACwEsA7AcwC5oIiAnSq6AH2goFcQRoBeaACISBXvCEBudJirF6+YuWoAKAJR0Gzau048+aTEegh5jeYNJkIAOhyKr1accxXb9wo9aDuvZy+hzIi5GCkDifwwAX1QY1AAzLgpgIjJ4MIATeABlB2UqFXjEOgR4NRQZDDJ46ELEG1xPfPLDAKL4BryWG1NqUkloAHpB+hJ4HgzoAkZGeEYAGmgAIy4iaCyCCAoAciJK6BiYoA) scenarios, leading to a runtime error. However, there can't be runtime errors like this in AssemblyScript, so one must instead use a local to be safe:

```ts
function doSomething(foo: Foo): void {
  let something = foo.something
  if (something) {
    something.length // works
  }
}
```

### Non-linear compilation

AssemblyScript does not compile a module linearly, but starts at the module's exports and only compiles what's reachable from them, often referred to as [tree-shaking](https://en.wikipedia.org/wiki/Tree_shaking). As such, dead code is always validated syntactically, but not necessarily checked for semantic correctness. While this mechanism significantly helps to reduce compile times and feels almost natural to those familiar with *executing* JavaScript, it may initially feel a little strange not only to those with a background in traditional compilers, for example because emitted diagnostics do not happen linearly, but also to those with a background in TypeScript, because even type annotations remain unchecked as part of dead code. The exception to the rule is top-level code, including top-level variable declarations and their initializers, that must be evaluated as soon as the respective file would first execute.

So far, so good. Shall we continue with a [status of WebAssembly and language features](./status.md)?

---

## File: src/built-with-assemblyscript.md

---
---

# Built with AssemblyScript

A place for all things AssemblyScript. Feel free to add your projects and applications.

## Benchmarks

* [Wasm Mandelbrot](https://github.com/ColinEberhardt/wasm-mandelbrot) \([demo](https://colineberhardt.github.io/wasm-mandelbrot/#AssemblyScript)\)
  A mandelbrot rendered using a variety of WebAssembly tools \(emscripten, AssemblyScript, asm.js, etc ...\)
* [WasmBoy Benchmark](https://wasmboy.app/benchmark/)
  Benchmarking WasmBoy emulator.
* [webassembly-wave](https://github.com/jtiscione/webassembly-wave) \([demo](https://jtiscione.github.io/webassembly-wave/index.html)\)
  JavaScript vs WebAssembly performance comparison - wave equation demo \(JS, C++, AssemblyScript\).
* [Sort Colors Benchmark](https://github.com/manueldois/WebAssembly/tree/master/Sort%20Colors%20Benchmark/src) \([demo](https://manueldois.github.io/WebAssembly/Sort%20Colors%20Benchmark/dist/index.html)\)
  Bench of sorting random colors by hue component on 2d canvas.
* [wasm-n-body](https://github.com/w8r/wasm-n-body)
  WebAssembly N-body simulation benchmark _\(use 1000 bodies compare to original\)._
* [as-benchmarks](https://github.com/nischayv/as-benchmarks) \([demo](https://nischayv.github.io/as-benchmarks/index.html)\)
  A set of computational benchmarks \(JS, AssemblyScript\).

## Blockchain

* [eWasm / Biturbo](https://github.com/ewasm/biturbo)
  Eth1 EE using Turboproofs.
* [ewasm / scout.ts ](https://github.com/ewasm/scout.ts)
  Scout is a Ethereum 2.0 Phase 2 execution prototyping engine \(AssemblyScript Port\).
* [NearProtocol / near-sdk-as](https://github.com/near/near-sdk-as)
  AssemblyScript tools for writing smart contracts for NearProtocol.
* [GraphProtocol / graph-ts](https://github.com/graphprotocol/graph-ts)
  TypeScript/AssemblyScript library for writing mappings for [The Graph](https://thegraph.com).
* [ChainSafe / as-sha256](https://github.com/ChainSafe/as-sha256)
  AssemblyScript implementation of SHA256 for [Lodestar](https://github.com/ChainSafe/lodestar).
* [ParityTech / srml-contracts-waterfall](https://github.com/paritytech/srml-contracts-waterfall)
  Collection of simple Substrate smart contract examples written in Rust and AssemblyScript and tests for Substrates SRML Contracts module.
* [CasperLabs / contract-as](https://github.com/CasperLabs/CasperLabs/tree/master/execution-engine/contract-as)
  AssemblyScript smart contracting library for the CasperLabs protocol.

## Build Tools

* [Zwitterion](https://github.com/lastmjs/zwitterion)
  A web dev server that lets you import anything\*.
* [rollup-plugin-assemblyscript](https://github.com/surma/rollup-plugin-assemblyscript)
  A Rollup plugin that allows you to import AssemblyScript files and compiles them on-the-fly.
* [visitor-as](https://github.com/willemneal/visitor-as)
  Tools for creating compiler transformers.

## Editors

* [WebAssembly Studio](https://github.com/wasdk/WebAssemblyStudio)
  Learn, Teach, Work and Play in the WebAssembly Studio.
* [Fastly Terrarium](https://wasm.fastlylabs.com/)
  A compilation toolchain and sandbox to run WebAssembly server-side, with native support for AssemblyScript.
* [NEAR Protocol Examples](https://examples.nearprotocol.com/?q=assembly)
  Examples that use [GitPod](https://gitpod.io/) to develop and deploy distributed web apps using NEAR smart contracts authored in AssemblyScript.
* [Iodide Notebook](https://alpha.iodide.io/notebooks/1234)
  Experimental tool for scientific communication and exploration on the web \([more](https://hacks.mozilla.org/2019/03/iodide-an-experimental-tool-for-scientific-communicatiodide-for-scientific-communication-exploration-on-the-web)\).

## Emulators

* [wasmBoy](https://github.com/torch2424/wasmBoy) \([demo](https://wasmboy.app/)\)
  Game Boy / Game Boy Color Emulator Library, written for WebAssembly using AssemblyScript.
* [Atari 2600](https://github.com/ColinEberhardt/atari2600-wasm)
  An Atari 2600 emulator written in AssemblyScript compiled to WebAssembly.
* [as-spectrum-engine](https://github.com/Dotneteer/as-spectrum-engine)
  AssemblyScript implementation of a ZX Spectrum emulator engine.

## Games

* [Chess](https://github.com/mhonert/chess) \([play](https://mhonert.github.io/chess)\)
  A free and open source chess game using AssemblyScript and React.
* [Gomoku WASM](https://github.com/jolestar/gomoku-wasm) \([play](http://jolestar.com/gomoku-wasm)\)
  A Gomoku game implements with WebAssembly using [as2d](https://github.com/as2d/as2d).

## Graphics

* [as2d](https://github.com/as2d/as2d)
  Bring the power of the CanvasRenderingContext2D prototype to AssemblyScript.
* [as-smallpt](https://github.com/01alchemist/as-smallpt)
  Port of C++ smallpt, a path tracing renderer.
* [Babylon.Font](https://github.com/ycw/Babylon.Font)
  Create 3d text in BabylonJS.
* [seam-carving-as](https://github.com/alexvictoor/seam-carving-as)
  Seam Carving experiments with AssemblyScript.

## Libraries

* [AS-LZMA](https://github.com/01alchemist/AS-LZMA)
  LZMA Decoder written in AssemblyScript.
* [assemblyscript-bson](https://github.com/nearprotocol/assemblyscript-bson)
  BSON encoder / decoder.
* [assemblyscript-json](https://github.com/nearprotocol/assemblyscript-json)
  JSON encoder / decoder.
* [as-bignum](https://github.com/MaxGraey/as-bignum) \(formerly bignum.wasm\)
  Fixed length big numbers like `u128`, `i256`, `fp128` and etc for AssemblyScript.
* [ASTL](https://github.com/samchon/astl)
  Migration project from C++ STL (Standard Template Library) to AssemblyScript. Containers, iterators, algorithms and functors are supported.
* [Levenshtein Wasm](https://github.com/kyranet/levenshtein-wasm)
  An experimental lightning-fast Wasm-compiled levenshtein library.
* [superfasthash](https://github.com/mjethani/superfasthash)
  An implementation of the SuperFastHash non-cryptographic hashing algorithm in JavaScript and WebAssembly.
* [as-wasi](https://github.com/jedisct1/as-wasi)
  An AssemblyScript API layer for WASI system calls.
* [WASM-Crypto](https://github.com/jedisct1/wasm-crypto)
  An AssemblyScript set of cryptographic primitives for building authentication and key exchange protocols.
* [rabin-wasm](https://github.com/hugomrdias/rabin-wasm)
  Rabin fingerprinting implemented in WASM _\(used by js-ipfs\)_**.**
* [galois](https://github.com/GuildOfWeavers/galois)
  Arithmetic and polynomial operations in finite fields.
* [merkle](https://github.com/GuildOfWeavers/merkle)
  Merkle tree and other data structures.
* [xoroshiro128starstar](https://github.com/krisselden/xoroshiro128starstar)
  An AssemblyScript port of xoroshiro128starstar.c
* [pixelmatch-asc](https://github.com/jamesmilneruk/pixelmatch-asc)
  Pixel level image comparison library.
* [as-bind](https://github.com/torch2424/as-bind)
  Isomorphic library to handle passing high-level data structures between AssemblyScript and JavaScript, built on top of the AssemblyScript loader.
* [wasmer-as](https://github.com/onsails/wasmer-as)
  Helpers for dealing with assemblyscript memory inside wasmer-runtime.
* [wasmbind](https://github.com/miracle2k/wasmbind)
  Work with AssemblyScript memory and classes from Python.
* [io-devices-lib](https://github.com/wasmerio/io-devices-lib)
  Library for interacting with the Wasmer Experimental IO Devices.

## Embedded / IoT

* [wasm3-arduino](https://github.com/wasm3/wasm3-arduino/tree/master/wasm_apps)
  Usage example with wasm3 which run on Arduino, PlatformIO, Particle.
* [Wasm3\_RGB\_Lamp](https://github.com/vshymanskyy/Wasm3_RGB_Lamp)
  Animating an RGB lamp, using WebAssembly \(AssemblyScript\).
* [wasm-arduino-wifi](https://github.com/alvarowolfx/wasm-arduino-wifi)
  Example how update WebAssembly via WiFi on arduino.

## Testing

* [as-pect](https://github.com/jtenner/as-pect)
  A test framework for AssemblyScript inspired by jest.

## Project Templates

* [worker-assemblyscript-template](https://github.com/JamesLMilner/worker-assemblyscript-template)
  A Cloudflare wrangler template for a AssemblyScript worker.

## Other

* [wasm-matrix](https://github.com/torch2424/wasm-matrix)
  A Matrix effect in your terminal using AssemblyScript and WASI, deployed to WAPM.
* [WebAssembly music experiment](https://petersalomonsen.com)
  A live coding environment in the browser for sequencing music with javascript and synthesizing instruments in AssemblyScript. Demonstrates compiling AssemblyScript directly in the browser, and live hot-swapping of webassembly modules.
* [WireWorld](https://github.com/dested/WireWorld) \([demo](https://dested.com/projects/wire/)\)
  The Wireworld Computer in Javascript/Canvas.

---

## File: src/compiler.md

---
---

# Compiler

Similar to TypeScript's `tsc` compiling to JavaScript, AssemblyScript's `asc` compiles to WebAssembly.

## Command line options

### Entry file\(s\)

Non-option arguments are treated as the names of entry files. A single program can have multiple entries, with the exports of each entry becoming the exports of the WebAssembly module. Exports of imported files that are not entry files do not become WebAssembly module exports.

```sh
asc entryFile.ts
```

### General

```
--version, -v         Prints just the compiler's version and exits.
--help, -h            Prints this message and exits.
--noColors            Disables terminal colors.
--config              Configuration file to apply. CLI arguments take precedence.
--target              Target configuration to use. Defaults to 'release'.
```

#### asconfig.json

Instead of providing the options outlined below on the command line, a configuration file typically named `asconfig.json` can be used. It may look like in the following example, excluding comments:

```json
{
  "extends": "./path/to/other/asconfig.json", // (optional) base config
  "entries": [
    // (optional) entry files, e.g.
    "./assembly/index.ts"
  ],
  "options": {
    // common options, e.g.
    "importTable": true
  },
  "targets": {
    // (optional) targets
    "release": {
      // additional options for the "release" target, e.g.
      "optimize": true,
      "binaryFile": "myModule.release.wasm"
    },
    "debug": {
      // additional options for the "debug" target, e.g.
      "debug": true,
      "binaryFile": "myModule.debug.wasm"
    }
  }
}
```

Provided command line options override options in the configuration file.

### Optimization

The compiler can optimize for both speed and size. `--optimizeLevel` \(0-3\) indicates how much the compiler focuses on optimizing the code with `--shrinkLevel` \(0-2, 1=s, 2=z\) indicating how much it focuses on keeping the size low during code generation and while optimizing. A convenient shorthand is `-O[optimizeLevel][shrinkLevel]` , with shrink level indicated by appending the letter `s` \(1\) or `z` \(2\) to the optimize level.

```
--optimize, -O        Optimizes the module. Typical shorthands are:

                       Default optimizations   -O / -O3s
                       Make a release build    -O --noAssert
                       Make a debug build      --debug
                       Optimize for speed      -O3
                       Optimize for size       -O3z --converge

--optimizeLevel       How much to focus on optimizing code. [0-3]
--shrinkLevel         How much to focus on shrinking code size. [0-2, s=1, z=2]
--converge            Re-optimizes until no further improvements can be made.
--noAssert            Replaces assertions with just their value without trapping.
```

### Output

Typical output formats are WebAssembly binary \(.wasm\) and/or text format \(.wat\). Often, both are used in tandem to run and also inspect generated code.

```
--outFile, -o         Specifies the output file. File extension indicates format.
--binaryFile, -b      Specifies the binary output file (.wasm).
--textFile, -t        Specifies the text output file (.wat).
```

There are several other output formats as well for tooling purposes with varying levels of maturity.

```
--jsFile, -j          Specifies the JavaScript output file (.js).
--idlFile, -i         Specifies the WebIDL output file (.webidl).
--tsdFile, -d         Specifies the TypeScript definition output file (.d.ts).
```

### Debugging

For easier debugging a [source map](./debugging.md#source-maps) can be emitted alongside the WebAssembly binary.

```
--sourceMap           Enables source map generation. Optionally takes the URL
                      used to reference the source map from the binary file.
```

It is also often useful to emit debug information, like function names, alongside the binary.

```
--debug               Enables debug information in emitted binaries.
```

### Features

There are several flags that enable or disable specific WebAssembly or compiler features. By default, only the bare minimum is exposed, and fully standardized WebAssembly features will be used.

```
--importMemory        Imports the memory from 'env.memory'.
--noExportMemory      Does not export the memory as 'memory'.
--initialMemory       Sets the initial memory size in pages.
--maximumMemory       Sets the maximum memory size in pages.
--sharedMemory        Declare memory as shared. Requires maximumMemory.
--importTable         Imports the function table from 'env.table'.
--exportTable         Exports the function table as 'table'.
--runtime             Specifies the runtime variant to include in the program.

                       incremental  TLSF + incremental GC (default)
                       minimal      TLSF + lightweight GC invoked externally
                       stub         Minimal runtime stub (never frees)
                       ...          Path to a custom runtime implementation

--exportRuntime       Exports the runtime helpers (__new, __collect etc.).
--explicitStart       Exports an explicit '_start' function to call.
--enable              Enables WebAssembly features being disabled by default.

                        sign-extension      Sign-extension operations
                        bulk-memory         Bulk memory operations.
                        simd                SIMD types and operations.
                        threads             Threading and atomic operations.
                        reference-types     Reference types and operations.
                        gc                  Garbage collection (anyref, WIP).

--disable             Disables WebAssembly features being enabled by default.

                        mutable-globals     Mutable global imports and exports.

--use, -u             Aliases a global object under another name, e.g., to switch
                      the default 'Math' implementation used: --use Math=JSMath
                      Can also be used to introduce an integer constant.
--lowMemoryLimit      Enforces very low (<64k) memory constraints.
```

### Linking

Specifying the base offsets of compiler-generated memory respectively the table leaves some space for other data in front. In its current form this is mostly useful to link additional data into an AssemblyScript binary after compilation, be it by populating the binary itself or initializing the data externally upon initialization. One good example is leaving some scratch space for a frame buffer.

```
--memoryBase          Sets the start offset of emitted memory segments.
--tableBase           Sets the start offset of emitted table elements.
```

### API

To integrate with the compiler, for example to post-process the AST, one or multiple custom [transforms](./transforms.md) can be specified.

```
--transform           Specifies the path to a custom transform to 'require'.
```

### Other

Other options include those forwarded to Binaryen and various flags useful in certain situations.

#### Binaryen

```
--trapMode            Sets the trap mode to use.

                       allow  Allow trapping operations. This is the default.
                       clamp  Replace trapping operations with clamping semantics.
                       js     Replace trapping operations with JS semantics.

--runPasses           Specifies additional Binaryen passes to run after other
                      optimizations, if any. See: Binaryen/src/passes/pass.cpp
--noValidate          Skips validating the module using Binaryen.
```

#### And the kitchen sink

```
--noColors            Disables terminal colors.
--baseDir             Specifies the base directory of input and output files.
--extension           Specifies an alternative file extension to use.
--noUnsafe            Disallows the use of unsafe features in user code.
                      Does not affect library files and external modules.
--noEmit              Performs compilation as usual but does not emit code.
--measure             Prints measuring information on I/O and compile times.
--pedantic            Make yourself sad for no good reason.
--lib                 Adds one or multiple paths to custom library components and
                      uses exports of all top-level files at this path as globals.
--path                Adds one or multiple paths to package resolution, similar
                      to node_modules. Prefers an 'ascMain' entry in a package's
                      package.json and falls back to an inner 'assembly/' folder.
--traceResolution     Enables tracing of package resolution.
--listFiles           Lists files to be compiled and exits.
-- ...                Specifies node.js options (CLI only). See: node --help
```

## API

The compiler can also be used programmatically.

* [Compiler frontend API](https://github.com/AssemblyScript/assemblyscript/tree/master/cli#api)
* [Browser SDK](https://github.com/AssemblyScript/assemblyscript/tree/master/lib/sdk) \([example](https://github.com/AssemblyScript/examples/tree/master/sdk)\)

---

## File: src/debugging.md

---
---

# Debugging

Recommendations on how to debug AssemblyScript modules.

## Source maps

The compiler supports generating a source map alongside a binary using the `--sourceMap` option.

### Relative source maps

By default, specifying the `--sourceMap` option will create a source mapping section pointing to the source map with a relative path, defaulting to `myModule.wasm.map` with `myModule` being the name of the respective binary. This works when instantiating a module with [WebAssembly.instantiateStreaming](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming) because the VM can obtain the absolute URL the source map is relative to from the provided `Response` object, but does not work if a module is instantiated from a buffer or otherwise without a path context.

### Absolute source maps

Where relative source maps cannot be used, for example if [WebAssembly.instantiate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate) is used to instantiate a module from a binary buffer, it is also possible to specify an absolute path to the source map using `--sourceMap absolutePathToSourceMap`.

## Stack traces

A JavaScript VM is able to display stack traces originating in WebAssembly code. However, optimizing a WebAssembly module will usually drop all the debug information, making these stack traces hard to grasp. Using an unoptimized module or a module otherwise preserving debug information can help here. The AssemblyScript compiler preserves debug information by specifying the `--debug` compiler option.

## Disabling assertions

By default, the compiler will preserve any `assert(expression)`s in a module, leading to an `abort` if one of the respective expectations failed. These assertions can be disabled with the `--noAssert` compiler option, though, essentially replacing them with `nop`s, doing nothing. Doing so can lead to smaller binaries once sufficiently confident that no assertions will be hit anyway, but also introduces the risk that a module explodes for no longer asserted reasons.

## Overriding `abort`

As mentioned above, assertions require that an implementation of the `abort` interface is present, which by default is imported as `abort` from within the `env` module, handling aborts externally. This can be overridden by specifying a custom abort handler through `--use abort=assembly/index/myAbort` \(here: a function named `myAbort` in `assembly/index.ts`\) or the abort interface can be disabled completely \(just trapping with an `unreachable`\) through `--use abort=`. The signature of the abort function, if overridden, is:

```ts
function abort(
  message: string | null,
  fileName: string | null,
  lineNumber: u32,
  columnNumber: u32
): void
```

## Manual tracing

The standard library provides a relatively basic `trace` utility function that is imported from the host and understood by the [loader](./loader.md). For example

```ts
trace("HERE", 2, value, otherValue)
```

will, by default, call the `trace` function imported from the `env` module with a string message and two arbitrary values that can be anything convertible to an `f64`. The loader for example will log the output to console. Similar to [overriding abort](./debugging.md#overriding-abort), the implementation can be overridden using the `--use` compiler option. Signature of the trace function is:

```ts
function trace(
  message: string,
  n: i32 = 0, // number of given parameters a0 to a4
  a0?: f64,
  a1?: f64,
  a2?: f64,
  a3?: f64,
  a4?: f64
): void
```

One thing to note here is that calling `trace` in top-level statements can lead to situations where [memory is accessed during instantiation](./memory.md#accessing-memory-during-instantiation), hence not being able to read the message without taking the respective precautions.

## Breakpoints

Some JavaScript engines also support adding break points when running WebAssembly binaries. Please consult your engine's documentation.

* [Chrome](https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints)
* [Firefox](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Set_a_breakpoint)
* [node.js](https://nodejs.org/api/debugger.html)
* [Safari](https://support.apple.com/de-de/guide/safari-developer/dev5e4caf347/mac)

## Additional resources

* [Making Web Assembly Even Faster: Debugging Web Assembly Performance with AssemblyScript and a Gameboy Emulator](https://medium.com/@torch2424/making-web-assembly-even-faster-debugging-web-assembly-performance-with-assemblyscript-and-a-4d30cb6463f1) \(Aaron Turner, March 2018\)

---

## File: src/development.md

---
---

# Development

Instructions for setting up a development environment.

::: tip
Please see our [contribution guidelines](https://github.com/AssemblyScript/assemblyscript/blob/master/CONTRIBUTING.md) before submitting your first pull request.
:::

## Setting up a development environment

The following sets up a development environment of the compiler where editing the sources applies changes immediately without having to go through a build step:

```sh
git clone https://github.com/AssemblyScript/assemblyscript.git
cd assemblyscript
npm install
npm link
```

Note that a development environment runs the sources directly by default, but will use distributions files once built. Cleaning the distribution files again with `npm run clean` resets this. Whether `asc` is running the sources or distribution files can be determined by checking the displayed version number. If it states `-dev`, it runs the sources directly.

## Building distribution files

To build an UMD bundle to `dist/assemblyscript.js` \(depends on [binaryen.js](https://github.com/AssemblyScript/binaryen.js)\), including a browser version of asc to `dist/asc.js` \(depends on assemblyscript.js\):

```sh
npm run build
```

Cleaning the distribution files \(again\):

```sh
npm run clean
```

Linting potential changes:

```sh
npm run check
```

 Running the [tests](https://github.com/AssemblyScript/assemblyscript/blob/master/tests):

```sh
npm test
```

Running everything in order \(check, clean, test, build, test\):

```sh
npm run all
```

## Creating tests

The test suite is composed of a set of tests for each component, like the parser, the compiler and runtime. For each pull request, all the tests are run automatically and the PR only goes green if it passes all of them. Please see the [instructions within the repository](https://github.com/AssemblyScript/assemblyscript/tree/master/tests) for all the details.

---

## File: src/editor-test.md

# Editor Test

Text before

```editor
#!runtime=stub
// Editor A

export function add(a: i32, b: i32): i32 {
  return a + b
}

export function sub(a: i32, b: i32): i32 {
  return a - b
}

#!html
<script>
loader.instantiate(module_wasm, { /* imports */ })
  .then(({ exports }) => {
    const output = document.getElementById('output')
    output.value += `add(1, 2) = ${exports.add(1, 2)}\n`
    output.value += `sub(1, 2) = ${exports.sub(1, 2)}\n`
  })
</script>

<textarea id="output" style="height: 100%; width: 100%" readonly></textarea>
```

Text between

```editor
#!runtime=stub
// Editor B

export function sub(a: i32, b: i32): i32 {
  return a - b
}

export function add(a: i32, b: i32): i32 {
  return a + b
}

#!html
<script>
loader.instantiate(module_wasm, { /* imports */ })
  .then(({ exports }) => {
    const output = document.getElementById('output')
    output.value += `sub(2, 3) = ${exports.sub(2, 3)}\n`
    output.value += `add(2, 3) = ${exports.add(2, 3)}\n`
  })
</script>

<textarea id="output" style="height: 100%; width: 100%" readonly></textarea>
```

Text after

---

## File: src/environment.md

---
---

# Environment

A WebAssembly environment is more limited than a usual browser environment, but AssemblyScript tries to fill the gaps by reimplementing commonly known functionality, besides providing direct access to WebAssembly instructions through built-ins.

## Standard library

AssemblyScript comes with its own [standard library](./stdlib/globals.md) very much resembling what developers became used to when writing JavaScript, with a few specialized classes, like `StaticArray`, that exist in AssemblyScript only to tackle very specific problems.

Additional rather low-level WebAssembly functionality that the standard library makes extensive use of is described below.

## Static type checks

By making use of the following special type checks, especially in generic contexts, untaken branches can be eliminated statically, leading to concrete WebAssembly functions that handle one type specificially.

* ```ts
  function isInteger<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression is of an integer type and not a reference. Compiles to a constant.

* ```ts
  function isFloat<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression is of a float type. Compiles to a constant.

* ```ts
  function isSigned<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression can represent negative numbers. Compiles to a constant.

* ```ts
  function isReference<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression is of a reference type. Compiles to a constant.

* ```ts
  function isString<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression can be used as a string. Compiles to a constant.

* ```ts
  function isArray<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression can be used as an array. Compiles to a constant.

* ```ts
  function isFunction<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression is of a function type. Compiles to a constant.

* ```ts
  function isNullable<T>(value?: T): bool
  ```
  Tests if the specified type _or_ expression is of a nullable reference type. Compiles to a constant.

* ```ts
  function isDefined(expression: auto): bool
  ```
  Tests if the specified expression resolves to a defined element. Compiles to a constant.

* ```ts
  function isConstant(expression: auto): bool
  ```
  Tests if the specified expression evaluates to a constant value. Compiles to a constant.

* ```ts
  function isManaged<T>(expression: auto): bool
  ```
  Tests if the specified type _or_ expression is of a managed type. Compiles to a constant. Usually only relevant when implementing custom collection-like classes.

### Example

```ts
function add<T>(a: T, b: T): T {
  return a + b // addition if numeric, string concatenation if a string
}

function add<T>(a: T, b: T): T {
  if (isString<T>()) { // eliminated if T is not a string
    return parseInt(a) + parseInt(b)
  } else { // eliminated if T is a string
    return a + b
  }
}
```

::: tip
If you are not going to use low-level WebAssembly in the foreseeable future, feel free to come back to the following paragraphs at a later time and continue at the next page[ ](./loader.md)right away.
:::

## Sizes and alignments

* ```ts
  function sizeof<T>(): usize
  ```
  Determines the byte size of the respective _basic type_. Means: If `T` is a class type, the size of `usize` is returned. To obtain the size of a class in memory, use `offsetof<T>()` instead. Compiles to a constant.

* ```ts
  function offsetof<T>(fieldName?: string): usize
  ```
  Determines the offset of the specified field within the given class type. Returns the class type's end offset \(means: where the next field would be located, before alignment\) if field name has been omitted. Compiles to a constant. The `fieldName` argument must be a compile-time constant `string` because there is no information about field names anymore in the final binary. Hence, the field's name must be known at the time the returned constant is computed.

* ```ts
  function alignof<T>(): usize
  ```
  Determines the alignment \(log2\) of the specified underlying _basic type_. Means: If `T` is a class type, the alignment of `usize` is returned. Compiles to a constant.

## Utility

* ```ts
  function assert<T>(isTrueish: T, message?: string): T
  ```
  Traps if the specified value is not true-ish, otherwise returns the non-nullable value. Like assertions in C, aborting the entire program if the expectation fails, with the `--noAssert` option to disable all assertions in production.

* ```ts
  function instantiate<T>(...args: auto[]): T
  ```
  Instantiates a new instance of `T` using the specified constructor arguments.

* ```ts
  function changetype<T>(value: auto): T
  ```
  Changes the type of a value to another one. Useful for casting class instances to their pointer values and vice-versa.

* ```ts
  function idof<T>(): u32
  ```
  Obtains the computed unique id of a class type. Usually only relevant when allocating objects or dealing with RTTI externally.

* ```ts
  function nameof<T>(value?: T): string
  ```
  Determines the name of a given type.

## Low-level WebAssembly operations

### Math

The following generic built-ins compile to WebAssembly instructions directly.

* ```ts
  function clz<T>(value: T): T
  ```
  Performs the sign-agnostic count leading zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered leading if the value is zero.

* ```ts
  function ctz<T>(value: T): T
  ```
  Performs the sign-agnostic count tailing zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered trailing if the value is zero.

* ```ts
  function popcnt<T>(value: T): T
  ```
  Performs the sign-agnostic count number of one bits operation on a 32-bit or 64-bit integer.

* ```ts
  function rotl<T>(value: T, shift: T): T
  ```
  Performs the sign-agnostic rotate left operation on a 32-bit or 64-bit integer.

* ```ts
  function rotr<T>(value: T, shift: T): T
  ```
  Performs the sign-agnostic rotate right operation on a 32-bit or 64-bit integer.

* ```ts
  function abs<T>(value: T): T
  ```
  Computes the absolute value of an integer or float.

* ```ts
  function max<T>(left: T, right: T): T
  ```
  Determines the maximum of two integers or floats. If either operand is `NaN`, returns `NaN`.

* ```ts
  function min<T>(left: T, right: T): T
  ```
  Determines the minimum of two integers or floats. If either operand is `NaN`, returns `NaN`.

* ```ts
  function ceil<T>(value: T): T
  ```
  Performs the ceiling operation on a 32-bit or 64-bit float.

* ```ts
  function floor<T>(value: T): T
  ```
  Performs the floor operation on a 32-bit or 64-bit float.

* ```ts
  function copysign<T>(x: T , y: T): T
  ```
  Composes a 32-bit or 64-bit float from the magnitude of `x` and the sign of `y`.

* ```ts
  function nearest<T>(value: T): T
  ```
  Rounds to the nearest integer tied to even of a 32-bit or 64-bit float.

* ```ts
  function reinterpret<T>(value: auto): T
  ```
  Reinterprets the bits of the specified value as type `T`. Valid reinterpretations are u32/i32 to/from f32 and u64/i64 to/from f64.

* ```ts
  function sqrt<T>(value: T): T
  ```
  Calculates the square root of a 32-bit or 64-bit float.

* ```ts
  function trunc<T>(value: T): T
  ```
  Rounds to the nearest integer towards zero of a 32-bit or 64-bit float.

### Memory

Similarly, the following built-ins emit WebAssembly instructions accessing or otherwise modifying memory.

* ```ts
  function load<T>(ptr: usize, immOffset?: usize): T
  ```
  Loads a value of the specified type from memory. Equivalent to dereferencing a pointer in other languages.

* ```ts
  function store<T>(ptr: usize, value: auto, immOffset?: usize): void
  ```
  Stores a value of the specified type to memory. Equivalent to dereferencing a pointer in other languages when assigning a value.

* ```ts
  function memory.size(): i32
  ```
  Returns the current size of the memory in units of pages. One page is 64kb.

* ```ts
  function memory.grow(value: i32): i32
  ```
  Grows linear memory by a given unsigned delta of pages. One page is 64kb. Returns the previous size of the memory in units of pages or `-1` on failure.
  
  ::: warning
  Calling `memory.grow` where a memory manager is present might break it.
  :::

* ```ts
  function memory.copy(dst: usize, src: usize, n: usize): void
  ```
  Copies `n` bytes from `src` to `dst` . Regions may overlap. Emits the respective instruction if bulk-memory is enabled, otherwise ships a polyfill.

* ```ts
  function memory.fill(dst: usize, value: u8, n: usize): void
  ```
  Fills `n` bytes at `dst` with the given byte `value`. Emits the respective instruction if bulk-memory is enabled, otherwise ships a polyfill.

* ```ts
  function memory.repeat(dst: usize, src: usize, srcLength: usize, count: usize): void
  ```
  Repeats a sequence of bytes given as `src` with `srcLength` `count` times into destination `dst`.

* ```ts
  function memory.compare(lhs: usize, rhs: usize, n: usize): i32
  ```
  Compares the first `n` bytes of `left` and `rigth` and returns a value that indicates their relationship:
  - **Negative** value if the first differing byte in `lhs` is less than the corresponding byte in `rhs`.  
  - **Positive** value if the first differing byte in `lhs` is greater than the corresponding byte in `rhs`.  
  - **Zero​** if all `n` bytes of `lhs` and `rhs` are equal.

* ```ts
  function memory.data(size: i32, align?: i32): usize
  ```
  Gets a pointer to a zeroed static chunk of memory of the given size. Alignment defaults to `16`. Arguments must be compile-time constants.

* ```ts
  function memory.data<T>(values: T[], align?: i32): usize
  ```
  Gets a pointer to a pre-initialized static chunk of memory. Alignment defaults to the size of `T`. Arguments must be compile-time constants.

The `immOffset` argument is a bit special here, because it becomes an actual immediate of the respective WebAssembly instruction instead of a normal operand. Thus it must be provided as a compile time constant value. This can be a literal or the value of a `const` variable that the compiler can precompute.

#### **Memory Manager**

An unsafe interface to just the dynamic memory manager, resembling `malloc`, `realloc` and `free` in C.

* ```ts
  function heap.alloc(size: usize): usize
  ```
  Allocates a chunk of memory of at least the specified size.

* ```ts
  function heap.realloc(ptr: usize, size: usize): usize
  ```
  Reallocates a chunk of memory to have at least the specified size.

* ```ts
  function heap.free(ptr: usize): void
  ```
  Frees a chunk of memory. Does hardly anything (most recent block only) with the "stub" runtime.

* ```ts
  function heap.reset(): void
  ```
  Dangerously resets the entire heap. Specific to the "stub" runtime.

#### **Memory Utility**

Sign-agnostic endian conversions \(reverse bytes\).

* ```ts
  function bswap<T>(value: T): T
  ```
  Reverses the byte order of the specified integer.

* ```ts
  function bswap16<T>(value: T): T
  ```
  Reverses only the last 2 bytes regardless of the type argument.

### Control flow

* ```ts
  function select<T>(ifTrue: T, ifFalse: T, condition: bool): T
  ```
  Selects one of two pre-evaluated values depending on the condition. Differs from an `if/else` in that both arms are always executed and the final value is picked based on the condition afterwards. Performs better than an `if/else` only if the condition is random \(means: branch prediction is not going to perform well\) and both alternatives are cheap. It is also worth to note that Binaryen will do relevant optimizations like switching to a `select` automatically, so using a ternary `? :` for example is just fine.

* ```ts
  function unreachable(): auto
  ```
  Emits an unreachable instruction that results in a runtime error \(trap\) when executed. Both a statement and an expression of any type. Beware that trapping in managed code will most likely lead to memory leaks or even break the program because it ends execution prematurely.

### Atomics 🦄

The following instructions represent the [WebAssembly threads and atomics](https://github.com/WebAssembly/threads) specification. Must be enabled with `--enable threads`.

* ```ts
  function atomic.load<T>(ptr: usize, immOffset?: usize): T
  ```
  Atomically loads an integer value from memory and returns it.

* ```ts
  function atomic.store<T>(ptr: usize, value: auto, immOffset?: usize): void
  ```
  Atomically stores an integer value to memory.

* ```ts
  function atomic.add<T>(ptr: usize, value: T, immOffset?: usize): T
  ```
  Atomically adds an integer value in memory.

* ```ts
  function atomic.sub<T>(ptr: usize, value: T, immOffset?: usize): T
  ```
  Atomically subtracts an integer value in memory.

* ```ts
  function atomic.and<T>(ptr: usize, value: T, immOffset?: usize): T
  ```
  Atomically performs a bitwise AND operation on an integer value in memory.

* ```ts
  function atomic.or<T>(ptr: usize, value: T, immOffset?: usize): T
  ```
  Atomically performs a bitwise OR operation on an integer value in memory.

* ```ts
  function atomic.xor<T>(ptr: usize, value: T, immOffset?: usize): T
  ```
  Atomically performs a bitwise XOR operation on an integer value in memory.

* ```ts
  function atomic.xchg<T>(ptr: usize, value: T, immOffset?: usize): T
  ```
  Atomically exchanges an integer value in memory.

* ```ts
  function atomic.cmpxchg<T>(ptr: usize, expected: T, replacement: T, immOffset?: usize): T
  ```
  Atomically compares and exchanges an integer value in memory if the condition is met.

* ```ts
  function atomic.wait<T>(ptr: usize, expected: T, timeout: i64): AtomicWaitResult
  ```

  Performs a wait operation on an address in memory suspending this agent if the integer condition is met. Return values are

  | Value | Description
  | :---- | :----------
  | 0     | OK - Woken by another agent.
  | 1     | NOT\_EQUAL - Loaded value did not match the expected value.
  | 2     | TIMED\_OUT - Not woken before the timeout expired.

* ```ts
  function atomic.notify(ptr: usize, count: i32): i32
  ```
  Performs a notify operation on an address in memory waking up suspended agents.

* ```ts
  function atomic.fence(): void
  ```
  Performs a fence operation, preserving synchronization guarantees of higher level languages.

Again, the `immOffset` argument must be a compile time constant value.

### SIMD 🦄

Likewise, these represent the [WebAssembly SIMD](https://github.com/WebAssembly/simd) specification. Must be enabled with `--enable simd`.

* ```ts
  function v128(a: i8, ... , p: i8): v128
  ```
  Initializes a 128-bit vector from sixteen 8-bit integer values. Arguments must be compile-time constants.

* ```ts
  function v128.splat<T>(x: T): v128
  ```
  Creates a vector with identical lanes.

* ```ts
  function v128.extract_lane<T>(x: v128, idx: u8): T
  ```
  Extracts one lane as a scalar.

* ```ts
  function v128.replace_lane<T>(x: v128, idx: u8, value: T): v128
  ```
  Replaces one lane.

* ```ts
  function v128.shuffle<T>(a: v128, b: v128, ...lanes: u8[]): v128
  ```
  Selects lanes from either vector according to the specified lane indexes.

* ```ts
  function v128.swizzle(a: v128, s: v128): v128
  ```
  Selects 8-bit lanes from the first vector according to the indexes \[0-15\] specified by the 8-bit lanes of the second vector.

* ```ts
  function v128.load(ptr: usize, immOffset?: usize, immAlign?: usize): v128
  ```
  Loads a vector from memory.

* ```ts
  function v128.load_splat<T>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
  ```
  Creates a vector with identical lanes by loading the splatted value.

* ```ts
  function v128.load_ext<TFrom>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
  ```
  Creates a vector by loading the lanes of the specified integer type and extending each to the next larger type.

* ```ts
  function v128.store(ptr: usize, value: v128, immOffset?: usize, immAlign?: usize): void
  ```
  Stores a vector to memory.

* ```ts
  function v128.add<T>(a: v128, b: v128): v128
  ```
  Adds each lane.

* ```ts
  function v128.sub<T>(a: v128, b: v128): v128
  ```
  Subtracts each lane.

* ```ts
  function v128.mul<T>(a: v128, b: v128): v128
  ```
  Multiplies each lane.

* ```ts
  function v128.div<T>(a: v128, b: v128): v128
  ```
  Divides each floating point lane.

* ```ts
  function v128.neg<T>(a: v128): v128
  ```
  Negates each lane.

* ```ts
  function v128.add_saturate<T>(a: v128, b: v128): v128
  ```
  Adds each signed small integer lane using saturation.

* ```ts
  function v128.sub_saturate<T>(a: v128, b: v128): v128
  ```
  Subtracts each signed small integer lane using saturation.

* ```ts
  function v128.shl<T>(a: v128, b: i32): v128
  ```
  Performs a bitwise left shift by a scalar on each integer lane.

* ```ts
  function v128.shr<T>(a: v128, b: i32): v128
  ```
  Performs a bitwise right shift by a scalar on each integer lane.

* ```ts
  function v128.and(a: v128, b: v128): v128
  ```
  Performs the bitwise `a & b` operation on each lane.

* ```ts
  function v128.or(a: v128, b: v128): v128
  ```
  Performs the bitwise `a | b` operation on each lane.

* ```ts
  function v128.xor(a: v128, b: v128): v128
  ```
  Performs the bitwise `a ^ b` operation on each lane.

* ```ts
  function v128.andnot(a: v128, b: v128): v128
  ```
  Performs the bitwise `!a & b` operation on each lane.

* ```ts
  function v128.not(a: v128): v128
  ```
  Performs the bitwise `!a` operation on each lane.

* ```ts
  function v128.bitselect(a: v128, b: v128, mask: v128): v128
  ```
  Selects bits of either vector according to the specified mask.

* ```ts
  function v128.any_true<T>(a: v128): bool
  ```
  Reduces a vector to a scalar indicating whether any lane is considered `true`.

* ```ts
  function v128.all_true<T>(a: v128): bool
  ```
  Reduces a vector to a scalar indicating whether all lanes are considered `true`.

* ```ts
  function v128.bitmask<T>(a: v128): bool
  ```
  Extracts the high bit of each integer lane (except 64-bit) and produces a scalar mask with all bits concatenated.

* ```ts
  function v128.max<T>(a: v128, b: v128): v128
  ```
  Computes the maximum of each lane.

* ```ts
  function v128.min<T>(a: v128, b: v128): v128
  ```
  Computes the minimum of each lane.

* ```ts
  function v128.dot<T>(a: v128, b: v128): v128
  ```
  Computes the dot product of two 16-bit integer lanes each, yielding lanes one size wider than the input.

* ```ts
  function v128.avgr<T>(a: v128, b: v128): v128)
  ```
  Computes the rounding average of each unsigned small integer lane.

* ```ts
  function v128.abs<T>(a: v128): v128
  ```
  Computes the absolute value of each lane (except 64-bit integers).

* ```ts
  function v128.sqrt<T>(a: v128): v128
  ```
  Computes the square root of each floating point lane.

* ```ts
  function v128.ceil<T>(a: v128): v128
  ```
  Performs the ceiling operation on each lane.

* ```ts
  function v128.floor<T>(a: v128): v128
  ```
  Performs the floor operation on each lane.

* ```ts
  function v128.trunc<T>(a: v128): v128
  ```
  Rounds to the nearest integer towards zero of each lane.

* ```ts
  function v128.nearest<T>(a: v128): v128
  ```
  Rounds to the nearest integer tied to even of each lane.

* ```ts
  function v128.eq<T>(a: v128, b: v128): v128
  ```
  Computes which lanes are equal.

* ```ts
  function v128.ne<T>(a: v128, b: v128): v128
  ```
  Computes which lanes are not equal.

* ```ts
  function v128.lt<T>(a: v128, b: v128): v128
  ```
  Computes which lanes of the first vector are less than those of the second.

* ```ts
  function v128.le<T>(a: v128, b: v128): v128
  ```
  Computes which lanes of the first vector are less than or equal those of the second.

* ```ts
  function v128.gt<T>(a: v128, b: v128): v128
  ```
  Computes which lanes of the first vector are greater than those of the second.

* ```ts
  function v128.ge<T>(a: v128, b: v128): v128
  ```
  Computes which lanes of the first vector are greater than or equal those of the second.

* ```ts
  function v128.convert<TFrom>(a: v128): v128
  ```
  Converts each lane from integer to floating point.

* ```ts
  function v128.trunc_sat<TTo>(a: v128): v128
  ```
  Truncates each lane from floating point to integer with saturation.

* ```ts
  function v128.narrow<TFrom>(a: v128, b: v128): v128
  ```
  Narrows wider integer lanes to their respective narrower lanes.

* ```ts
  function v128.widen_low<TFrom>(a: v128): v128
  ```
  Widens the low half of narrower integer lanes to their respective wider lanes.

* ```ts
  function v128.widen_high<TFrom>(a: v128): v128
  ```
  Widens the high half of narrower integer lanes to their respective wider lanes.

* ```ts
  function v128.qfma<T>(a: v128, b: v128, c: v128): v128
  ```
  Computes `(a * b) + c` for each floating point lane.

* ```ts
  function v128.qfms<T>(a: v128, b: v128, c: v128): v128
  ```
  Computes `(a * b) - c` for each floating point lane.

In addition, the namespaces `i8x16`, `i16x8`, `i32x4`, `i64x2` , `f32x4` and `f64x2` provide their respective non-generic instructions, like `i32x4.splat` etc. Each of them can also be used to create a literal directly:

* ```ts
  function i8x16(a: i8, ... , p: i8): v128
  ```
  Initializes a 128-bit vector from sixteen 8-bit integer values. Arguments must be compile-time constants.

* ```ts
  function i16x8(a: i16, ..., h: i16): v128
  ```
  Initializes a 128-bit vector from eight 16-bit integer values. Arguments must be compile-time constants.

* ```ts
  function i32x4(a: i32, b: i32, c: i32, d: i32): v128
  ```
  Initializes a 128-bit vector from four 32-bit integer values. Arguments must be compile-time constants.

* ```ts
  function i64x2(a: i64, b: i64): v128
  ```
  Initializes a 128-bit vector from two 64-bit integer values. Arguments must be compile-time constants.

* ```ts
  function f32x4(a: f32, b: f32, c: f32, d: f32): v128
  ```
  Initializes a 128-bit vector from four 32-bit float values. Arguments must be compile-time constants.

* ```ts
  function f64x2(a: f64, b: f64): v128
  ```
  Initializes a 128-bit vector from two 64-bit float values. Arguments must be compile-time constants.

The namespaces `v8x16`, `v16x8`, `v32x4` and `v64x2` provide the respective sign agnostic instructions according to text format.

---

## File: src/examples.md

---
sidebarDepth: 0
---

# Examples

A collection of AssemblyScript examples and [snippets](./examples/snippets.md).

## Starter examples

Small entertaining programs showcasing low-level WebAssembly capabilities. These compile to less than one or just a few kilobytes so their text format is easy to grasp.

### [Mandelbrot](./examples/mandelbrot.md)

Renders the Mandelbrot set to a canvas using 2048 discrete color values computed on the JS side.



[](./examples/mandelbrot.md)

### [Interference](./examples/interference.md)

Animates and renders an interference pattern to a canvas while keeping the image buffer in WebAssembly.



[](./examples/interference.md)

### [Game of Life](./examples/game-of-life.md)

Continuously updates a cellular automaton and visualizes its state on a canvas according to user input.



[](./examples/game-of-life.md)

## Advanced examples

### [Arrays](./examples/arrays.md)

Shows how to exchange and work with arrays using the loader.



### Examples repository

Various more advanced examples are available as part of the [examples repository](https://github.com/AssemblyScript/examples), including a sophisticated example of [using the loader](https://github.com/AssemblyScript/examples/tree/master/loader), [creating (node) libraries](https://github.com/AssemblyScript/examples/tree/master/i64), [utilizing the browser SDK](https://github.com/AssemblyScript/examples/tree/master/sdk) and [hooking into the compiler using transforms](https://github.com/AssemblyScript/examples/tree/master/transform).

## Additional resources

If you are interested in learning more about specific concepts, also make sure to give [Wasm By Example](https://wasmbyexample.dev/) a read.

---

## File: src/exports-and-imports.md

---
---

# Exports and imports

Setting up the API to talk to your WebAssembly module.

## Exports

Exports work very much like in TypeScript, with the notable difference that exports from an entry file also become the exports of the resulting WebAssembly module.

### Functions

```ts
export function add(a: i32, b: i32): i32 {
  return a + b
}
```

### Globals

```ts
export const foo = 1
export var bar = 2
```

Exporting or importing mutable globals requires that the engine supports the post-MVP and now standardized [Import/Export mutable globals proposal](https://github.com/WebAssembly/mutable-global), which is enabled by default.

### Classes

If an entire class \(possibly part of a namespace\) is exported from an entry file, its visible members will become distinct module exports using a JSDoc-like naming scheme that [the loader](./loader.md) understands to make a nice object structure of. For example

```ts
export namespace foo {
  export class Bar {
    a: i32 = 1
    getA(): i32 { return this.a }
  }
}
```

will yield the raw function exports

* foo.Bar\#**constructor**
* foo.Bar\#**get:a**
* foo.Bar\#**set:a**
* foo.Bar\#**getA**

which the loader combines back to a `foo.Bar` object:

```js
var bar = new myModule.foo.Bar()
bar.a = 2
console.log(bar.a)
```

Under the hood and without the loader, it'd look like this:

```js
var thisBar = myModule["foo.Bar#constructor"](0)
myModule["foo.Bar#set:a"](thisBar, 2)
console.log(myModule["foo.Bar#get:a"](thisBar))
```

As one can see the `this` argument must be provided as an additional first argument to the raw functions. No argument or `0` as the first argument to a constructor indicates that the constructor is expected to allocate on its own \(not extending a class with existing memory\). Of course one usually doesn't have to deal with these internals since the loader will already take care of it.

## Imports

With [WebAssembly ES Module Integration](https://github.com/WebAssembly/esm-integration) still in the pipeline, imports utilize the ambient context currently. For example

```ts
// env.ts
export declare function doSomething(foo: i32): void
```

creates an import of a function named `doSomething` from the `env` module, because that's the name of the file it lives is. It is also possible to use namespaces:

```ts
// foo.ts
export declare namespace console {
  export function logi(i: i32): void
  export function logf(f: f64): void
}
```

This will import the functions `console.logi` and `console.logf` from the `foo` module. Bonus: Don't forget `export`ing namespace members if you'd like to call them from outside the namespace.

A typical pattern is to `declare` the interface of each external module in its own file, using the name of the module as its file name, so the external module can be imported as if it was just another source file:

```ts
import { doSomething } from "./env";
import { console } from "./foo";
```

### Custom naming

Where automatic naming is not sufficient, the `@external` decorator can be used to give an element another external name:

```ts
// bar.ts
@external("doSomethingElse")
export declare function doSomething(foo: i32): void
// imports doSomethingElse from bar as doSomething

@external("foo", "baz")
export declare function doSomething(foo: i32): void
// imports baz from foo as doSomething
```

## On values crossing the boundary

More complex values than the basic integer and floating point types, like class instances or function references, are represented by an index or pointer within the WebAssembly module. The compiler knows how to work with these because it also knows the concrete type associated with the value. On the outside, however, for example in JS-code interacting with a WebAssembly module, all that's seen is the basic value.

* An **instance of a class** is a pointer to the structure in WebAssembly memory.
* A **function reference** is the index of the function in the WebAssembly table.

This is true in both directions, hence also applies when providing a value to a WebAssembly import. The most common structures like `String`, `ArrayBuffer` and the typed arrays are documented in [memory internals](./memory.md#internals), and custom classes adhere to [class layout](./interoperability.md#class-layout).

## Anatomy of a module

WebAssembly modules produced by the AssemblyScript compiler typically have the following set of imports and exports in addition to those defined in user code, with `?` indicating conditional presence. Recommended scenarios like using modules together with the [loader](./loader.md) or utilizing WASI via `import "wasi"` take care of these automatically.

### Exports

* ```ts
  const memory: WebAssembly.Memory
  ```
  The module's memory instance. Can be disabled with `--noExportMemory`.

* ```ts
  const table?: WebAssembly.Table
  ```
  The module's function table instance. Can be enabled with `--exportTable`.

* ```ts
  function _start?(): void
  ```
  Explicit start function to call. Can be enabled with `--explicitStart`. Also works with WASI.

* ```ts
  function __setArgumentsLength?(numArgs: i32): void
  ```
  Varargs helper to set what's known as `arguments.length` in JavaScript. Only present if there is at least one export of a function taking a variable number of arguments. Automatically utilized by the [loader](./loader.md).

* ```ts
  function __new?(size: usize, id: u32): usize
  function __pin?(ptr: usize): usize
  function __unpin?(ptr: usize): void
  function __collect?(): void
  ```
  [Garbage collection helpers](./garbage-collection.md). Only present when compiling with `--exportRuntime`.

### Imports

* ```ts
  const env.memory?: WebAssembly.Memory
  ```
  The module's memory instance. Can be enabled with `--importMemory`.

* ```ts
  const env.table?: WebAssembly.Table
  ```
  The module's table instance. Can be enabled with `--importTable`.

* ```ts
  function env.abort?(message: usize, fileName: usize, line: u32, column: u32): void
  ```
  Called on unrecoverable errors. Typically present if assertions are enabled. Automatically implemented by the [loader](./loader.md). Not present but otherwise implemented on `import "wasi"`.

* ```ts
  function env.trace?(message: usize, n: i32, a0..4?: f64): void
  ```
  Called when `trace` is called in user code. Only present if it is. Automatically implemented by the [loader](./loader.md). Not present but otherwise implemented on `import "wasi"`.

* ```ts
  function env.seed?(): f64
  ```
  Called when the random number generator needs to be seeded. Only present if it is. Automatically implemented by the [loader](./loader.md). Not present but otherwise implemented on `import "wasi"`.

---

## File: src/frequently-asked-questions.md

---
sidebarDepth: 0
---

# Frequently asked questions

Questions that may arise before, at or after this point. so if you're wondering about one thing or another, here it is:

## Is WebAssembly going to supersede JavaScript?

Probably not, and it is not meant to do so. There are use cases one can handle "better" than the other, with "better" depending on requirements. A requirement can be to make an algorithm more efficient on the one hand, which is where WebAssembly is good at, or to quickly add interactive elements to a web page, which JavaScript is great for. As always, picking the right tool for the job is key, and AssemblyScript just so happens to blur the line a bit.

## Is WebAssembly faster than JavaScript?

Not always, but it can be. The execution characteristics of ahead-of-time compiled WebAssembly differ from just-in-time compiled JavaScript in that it is _more predictable_ in a way that enables a WebAssembly program to remain on a reasonably fast path over the entire course of execution, while a JavaScript VM tries hard to do all sorts of smart optimizations before and _while_ the code is executing. This implies that a JavaScript VM can make both very smart decisions, especially for well-written code with a clear intent, but might also have to reconsider its strategy to do something more general if its assumptions did not hold. If you are primarily interested in performance, rules of thumb could be:

| Scenario                      | Recommendation
| :---------------------------- | :-------------
| Compute-heavy algorithm       | Use WebAssembly
| Mostly interacts with the DOM | Mostly use JavaScript
| Games                         | Use WebAssembly for CPU-intensive parts
| WebGL                         | Depends how much of it is calling APIs. Probably both.
| Websites, Blogs, ...          | JavaScript is your friend

Or: WebAssembly is great for computational tasks, stuff with numbers, but still needs some time to become more convenient and efficient _at the same time_ where sharing numbers between the module and the host is not enough.

## Is AssemblyScript faster than JavaScript?

Not always, but there are use cases especially well-suited for it, like creating a Game Boy emulator by making use of its low-level capabilities, essentially emitting raw WebAssembly using a nicer syntax. But pre-existing TypeScript code doesn't magically become faster just by compiling to WebAssembly, especially when making extensive use of managed objects that require memory management and garbage collection \(this has its cost in every language\) or talking to the host in structures that WebAssembly isn't currently good at, like strings or more complex objects. Low-level code \(just functions, numbers, math and hard work\) is always the best choice when all you care about is raw performance.

## How does AssemblyScript compare/relate to C++/Rust?

First and foremost: Both Emscripten \(C++\) and Rust have very mature tooling to compile to WebAssembly and are made by the smartest people in this field. Also, both can make use of compiler infrastructure that has been created by many individuals and corporations over years. In contrast, AssemblyScript is a relatively young project with limited resources that strives to create a viable alternative from another perspective.

More precisely: AssemblyScript is putting anything web - from APIs to syntax to WebAssembly - first and _then_ glues it all together, while others lift an existing ecosystem to the web. We believe that both approaches are fantastic, and fortunately for us, there is Binaryen, a compiler infrastructure and toolchain library for WebAssembly primarily created by the main author of Emscripten, that we can utilize to considerably close the gap. We are very thankful for it. Binaryen is not as optimal for AssemblyScript-generated code as it is for LLVM-generated code in a few cases, but it's already pretty good and continuously becoming better. It's also noteworthy that AssemblyScript is still behind in specific language features, but we are working on that.

In short: AssemblyScript differs in that it is new and tries another approach. It's not as mature as Emscripten and Rust, but there is something about the idea that is definitely appealing. If you find it appealing as well, AssemblyScript is for you.

## Will AssemblyScript support all of TypeScript eventually?

It very likely won't. While TypeScript adds *some* static typing to JavaScript, its type system also tries to describe any possible dynamic feature of JavaScript. TypeScript is a superset of JavaScript after all. As such there is a point where it becomes infeasible to support JavaScript features that TypeScript can describe without adding an interpreter mode to AssemblyScript, which is a non-goal.

## Will interop between AssemblyScript and JavaScript become better?

This is an open question. While there are WebAssembly proposals specifically aiming at improving interop, not all of them consider excellent interoperability between WebAssembly and the existing web platform as important as we do.

One point of disagreement for example stems from AssemblyScript's decision to chose JavaScript's 16-bit string encoding as a basis, initially exactly to aid compatibility and interop on the web, while others primarily interested in systems languages are advocating for just UTF-8. The UTF-8 everywhere sentiment may appear noble on paper, yet the reality we live in is that it would unnecessarily handicap AssemblyScript or other languages with most of their APIs designed for 16-bit Unicode, due to always having to re-encode and/or copy or alternatively having to break their APIs to be efficient. Our hopes are, however, since Java, .NET and many more languages are facing a similar challenge, that there'll ultimately be a solution that covers more languages.

Similarly, WebAssembly has primarily been designed with systems languages in mind so far and it did an exceptional job at bringing these to the web, yet it appears that the now predominant low-level mindset may eventually run counter to designing features that work well with the existing web platform, which is rather high-level. As such it is still subject to discussion whether for example WebAssembly GC strings, arrays and other objects will have good interop with JavaScript, or if JavaScript strings, arrays and other objects will have good interop with WebAssembly GC respectively. It is certainly important to design these APIs carefully, yet, in our opinion, WebAssembly may be missing the opportunity of its lifetime if it is not designed with excellent interop with JavaScript and the web in mind.

If you are interested in these aspects, feel free to join us in the respective spec discussions to inform the process.

## How can I help?

There are various ways to help. AssemblyScript is an open source project, and everyone is welcome to contribute [code](https://github.com/AssemblyScript/assemblyscript), [documentation](https://github.com/AssemblyScript/website), or [time](https://github.com/AssemblyScript/community-group). We also have an [OpenCollective](https://opencollective.com/assemblyscript) for those preferring to help the project out with a sponsorship.

---

## File: src/garbage-collection.md

---
sidebarDepth: 2
---

# Garbage Collection

::: tip NOTE
This section covers the new runtime added in AssemblyScript 0.18. The previous runtime documentation including migration guidelines [can be found here](./runtime.md).
:::

AssemblyScript implements garbage collection on top of linear memory while the WebAssembly [GC](https://github.com/WebAssembly/gc) 🦄 proposal is still in the works. More precisely it implements multiple runtime variants that are useful for different use cases, with the default being your typical memory manager and GC. The interface of the different variants is always the same, so these are interchangeable, yet differ in their level of sophistication. In case of doubt, starting out with the default is probably just fine.

## Runtime interface

Using the `--exportRuntime` compiler option, an interface to the runtime can be exported from the module to the host, so it becomes possible to allocate new objects and invoke the garbage collector externally.

* ```ts
  function __new(size: usize, id: u32): usize
  ```
  Allocates a new garbage collected instance of the object represented by the specified class id, of at least the specified size. Returns the pointer to the object, typically pointing at the object's data respectively its first field.

  Note that the [loader](./loader.md) provides more convenient wrappers like `__newString` and `__newArray` as well. `__new` is just the underlying implementation. The respective class id for the `id` argument can be obtained within WebAssembly via `idof<AClass>()`, typically exporting it to the host as a constant to use with `__new` or `__newArray`.

* ```ts
  function __pin(ptr: usize): usize
  ```
  Pins the object pointed to by `ptr` externally so it and its directly reachable members and indirectly reachable objects do not become garbage collected.

* ```ts
  function __unpin(ptr: usize): void
  ```
  Unpins the object pointed to by `ptr` externally so it can become garbage collected.

* ```ts
  function __collect(): void
  ```
  Performs a full garbage collection.

To interface with the runtime externally, for example to allocate objects in linear memory, you'll probably want to use the [loader](./loader.md) as well.

## Runtime variants

With the `--runtime` compiler option, one of multiple runtime variants can be selected, which determines the memory allocator and garbage collector included in a program:

```
  --runtime             Specifies the runtime variant to include in the program.

                         incremental  TLSF + incremental GC (default)
                         minimal      TLSF + lightweight GC invoked externally
                         stub         Minimal runtime stub (never frees)
                         ...          Path to a custom runtime implementation

  --exportRuntime       Exports the runtime helpers (__new, __collect etc.).
```

### Incremental runtime

This is the default runtime variant included in an AssemblyScript program, combining an Incremental Tri-Color Mark & Sweep (ITCMS) garbage collector with a Two-Level Segregate Fit (TLSF) memory manager. It is fully automated as one would expect from a typical GC, but its implementation has to go to lengths, involving some overhead, to polyfill functionality that is not yet provided by WebAssembly itself. It needs to maintain a shadow stack for example, and instruments binaries with it.

The incremental runtime is most suitable for non-trivial programs where short pause times are important, like in games, or where manually invoking the GC is not an option, like in WASI applications.

**Usage instructions**:

* When a managed object is exclusively referenced externally, `exports.__pin(objPtr)` it so it doesn't become collected when WebAssembly code executes.
* When the external object is not needed anymore, `exports.__unpin(objPtr)` it so it can become collected again.
* Note that a pinned object also keeps its directly reachable members and any indirectly reachable objects alive.
* It is safe to omit pinning an object externally if it is known to be referenced from within WebAssembly anyhow.
* It is possible to force a full collection (finishes current cycle, does another full cycle) using `exports.__collect()`, if so desired.

**Example usage:**

```js
function run() {
  let gameEnded = exports.updateGameProducingGarbage() // incrementally performs GC
  if (gameEnded) {
    exports.renderEndgameScreenProducingGarbage()
    exports.__collect() // optionally clean up the remains
  } else {
    requestAnimationFrame(run)
    exports.renderGameProducingGarbage() // incrementally performs GC
  }
}
run()
```

### Minimal runtime

The minimal runtime is similar to the incremental runtime, except that it doesn't go to lengths to polyfill WebAssembly features that are not yet available. It features a simpler (non-incremental) Two-Color Mark & Sweep (TCMS) garbage collector on top of TLSF, making it a reasonable compromise.

The minimal runtime works best for use-cases where the GC can be invoked externally at appropriate places, that is when the WebAssembly execution stack is known to be fully unwound. The execution stack is typically unwound when `exports.__collect()` is invoked neither directly nor indirectly from WebAssembly, for example when invoking it from JavaScript only. The AssemblyScript compiler itself is a good candidate for the minimal runtime for example, as it does bounded amounts of work in bounded amounts of time, so it is sufficient to call `exports.__collect()` occasionally when specific phases of compilation are complete.

Unlike the incremental runtime, the minimal runtime does not run interleaved with the program but always does a full garbage collection cycle when invoked externally, stopping the program while doing so. It is important to not overdo invoking the GC to avoid marking a lot but sweeping little for that reason. However, when used wisely, it typically has better throughput than the incremental runtime.

**Usage instructions:**

* Whenever you see fit, invoke `exports.__collect()` externally to collect all garbage. Note that this will mark & sweep all objects, so don't overdo calling it to avoid unnecessary overhead from marking a lot but sweeping little. In case of doubt, benchmark to find a reasonable sweet spot.
* When a managed object is exclusively referenced externally, `exports.__pin(objPtr)` it so it doesn't become collected when `exports.__collect()` is being invoked.
* When the external object is not needed anymore, `exports.__unpin(objPtr)` it so it can become collected again.
* Note that a pinned object also keeps its directly reachable members and any indirectly reachable objects alive.
* It is safe to omit pinning an object externally if
  * it is known to be referenced from within WebAssembly anyhow, directly or indirectly reachable from any root, like a global.
  * it is solely used as an argument to a WebAssembly function and not used externally anymore afterwards.
  * it is guaranteed that `exports.__collect()` will not be called while it is alive.
* In case of doubt, pin.

**Example usage:**

```js
function compute(arg) {
  exports.doSomeHeavyWorkProducingGarbage(arg)
  ...
  exports.__collect() // clean up all garbage
}
compute(1)
compute(2)
compute(3)
```

### Stub runtime

The stub is a maximally minimal runtime substitute, consisting of a simple and fast bump allocator with no means of freeing up memory again, except when freeing the respective most recently allocated object on top of the bump. As such, the stub runtime is useful where dynamic allocation, or garbage for that matter, is not a concern, for example because the program doesn't produce any or only executes a single time with a bounded limit of garbage before the entire module is terminated and collected by the host again.

**Usage instructions**:

* Since the stub runtime never frees memory, there is nothing special to take care of except that it leaks memory by design.

**Example usage**:

```js
function compute() {
  exports.doSomeHeavyWorkProducingGarbage()
}
compute()
// throw away the entire module instance
```

### Custom runtime

Even though of limited usefulness, it is also possible to create a new runtime (essentially a memory manager and a garbage collector) from scratch and include it instead of one of the options provided by AssemblyScript itself. To do so, a custom runtime needs to provide the implementations of the externally visible interfaces like `__new`, plus the underlying interfaces like `__alloc` and `__free`, on top of compiler-generated functionality like `__visit_members`, as described in more detail in [the runtime's README](https://github.com/AssemblyScript/assemblyscript/tree/master/std/assembly/rt). Looking at the implementation of the relatively simple stub runtime before diving into the more sophisticated ones may be a good starting point.

* Runtimes typically include a general purpose memory manager to also drive `heap.alloc` and `heap.free`
* Garbage collection is precise, with compiler-generated visitors aware of what's a pointer and what's not
* The interface is tailored for tracing GCs, so attempts to implement other forms of GC may not be viable

## The future: WebAssembly GC

The WebAssembly [GC](https://github.com/WebAssembly/gc) 🦄 proposal is still in the works but our focus is to switch to it as soon as possible, hopefully making most of the above redundant and the overall experience more convenient.

---

## File: src/index.md

---
metaTitle: AssemblyScript
navbar: false
sidebar: false
editLink: false
pageClass: frontpage
---


  
    <svg viewBox="0 0 768 256"></svg>
  
  <h1>A language made for WebAssembly.</h1>
  
    <a href="/introduction.html" class="docs">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"></svg>
      Get Started
    </a>
    <a href="https://github.com/AssemblyScript" target="_blank" rel="noopener" class="github">
      <svg viewBox="0 0 24 24"></svg>
      GitHub
    </a>
    <a href="https://www.npmjs.com/package/assemblyscript" target="_blank" rel="noopener" class="npm">
      <svg viewBox="0 0 24 24"></svg>
      npm
    </a>
  



  
    <h2>Designed for WebAssembly</h2>
    AssemblyScript targets WebAssembly's feature set specifically, giving developers low-level control over their code.
  
  
    <h2>Familiar TypeScript syntax</h2>
    Being a variant of TypeScript makes it easy to compile to WebAssembly without learning a new language.
  
  
    <h2>Right at your fingertips</h2>
    Integrates with the existing Web ecosystem - no heavy toolchains to set up. Simply `npm install` it!
  




```editor
#!runtime=stub
/** Calculates the n-th Fibonacci number. */
export function fib(n: i32): i32 {
  var a = 0, b = 1
  if (n > 0) {
    while (--n) {
      let t = a + b
      a = b
      b = t
    }
    return b
  }
  return a
}

#!html
<textarea id="output" style="height: 100%; width: 100%" readonly></textarea>
<script>
loader.instantiate(module_wasm, { /* imports */ })
  .then(({ exports }) => {
    const output = document.getElementById('output')
    for (let i = 0; i <= 10; ++i) {
      output.value += `fib(${i}) = ${exports.fib(i)}\n`
    }
  })
</script>
```




  AssemblyScript is free and open source software released under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0), builds upon [Binaryen](https://github.com/WebAssembly/binaryen) and is based on the [WebAssembly specification](https://webassembly.org/). It is brought to you by the following awesome people:
  <Contributors />



  <h2>Why AssemblyScript?</h2>
  <Testimonials />



  <h2>Thanks to our sponsors!</h2>
  Most of the core team members and most contributors do this open source work in their free time. If you use AssemblyScript for a serious task or plan to do so, and you'd like us to invest more time on it, [please donate](https://opencollective.com/assemblyscript/donate) to our [OpenCollective](https://opencollective.com/assemblyscript). By sponsoring this project, your logo will show up below. Thank you so much for your support!
  <Sponsors />



  <h2><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 245 240"></svg> Join our Discord</h2>
  If you have questions only a human can answer, would like to show others what you are working on or just want to hang out with other AssemblyScript folks, make sure to [join our Discord server](https://discord.gg/assemblyscript)! There you'll find channels for **#announcements**, **#help**, and more.
  <Community />


<style scoped>
#hero {
  margin-top: 2rem;
  text-align: center;
  height: 400px;
  background: #007acc;
}
#hero:before {
  content: '';
  position: absolute;
  z-index: 0;
  top: 0;
  left: 0;
  width: 100%;
  height: 520px;
  background: #007acc url(/images/header.svg) center bottom no-repeat;
  background-size: 1440px;
}
#hero > * {
  position: relative;
}
#hero h1 {
  color: #fff;
  margin: 1.3rem auto 1.8rem;
  font-size: 2rem;
  font-weight: 200;
}
#logo {
  display: inline-block;
  width: 640px;
}
#logo svg {
  width: 100%;
  height: 100%;
  max-height: 240px;
  fill: #fff;
}
@media only screen and (max-width: 740px) {
  #logo {
    width: 100%;
  }
  #logo svg {
    max-height: 213px;
  }
}
#features {
  padding: 1.2rem 0 0;
  margin-top: 2.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  align-content: stretch;
  justify-content: space-between;
}
#features .feature {
  flex-grow: 1;
  flex-basis: 30%;
  max-width: 30%;
}
#features h2 {
  font-size: 1.4rem;
  border-bottom: none;
  padding-bottom: 0;
  color: #3a5169;
}
.action {
  text-align: center;
  user-select: none;
}
.action a {
  display: inline-block;
  font-size: 1.2rem;
  color: #fff;
  background-color: #007acc;
  padding: .8rem 1.6rem;
  border-radius: 4px;
  transition: background-color .1s ease;
  box-sizing: border-box;
  border-bottom: 1px solid #006eb8;
  text-decoration: none !important;
  margin: 0.1rem 0;
}
.action a:hover {
  background-color: #1a8ae7;
}
.action a svg {
  width: 2em;
  position: relative;
  left: -10px;
  float: left;
  height: 32px;
}
.action a.docs {
  color: #111;
  background: #fff;
  border-bottom-color: #aaa;
}
.action a.docs:hover {
  background: #eee;
}
.action a.github {
  color: #fff;
  background: #24292e;
  border-bottom-color: #101214;
}
.action a.github:hover {
  background: #3e464f;
}
.action a.npm {
  color: #fff;
  background: #cb3837;
  border-bottom-color: #ba3232;
}
.action a.npm:hover {
  background: #eb3f3f;
}
@media only screen and (max-width: 720px) {
  .action a.github svg {
    float: none;
    left: 0;
    margin-bottom: -0.5rem;
  }
  .action a.npm {
    display: none;
  }
  .action a.github .title {
    display: none;
  }
  #features .feature {
    flex-basis: 100%;
    max-width: 100%;
  }
}
@media only screen and (max-width: 640px) {
  #try {
    display: none;
  }
}
#sponsors {
  margin-bottom: 2rem;
}
#community h2 svg {
  display: inline-block;
  height: 25px;
  position: relative;
  top: 3px;
}
</style>

<style>
.frontpage .page-edit {
  display: none;
}
</style>

---

## File: src/interoperability.md

---
---

# Interoperability

How to talk to AssemblyScript from C or other languages.

## Strings

Strings in AssemblyScript are stored in [WTF-16](https://simonsapin.github.io/wtf-8/#ill-formed-utf-16) encoding, closely matching JavaScript and its string APIs. When embedding AssemblyScript into a C or Rust environment, conversion between WTF-16 and UTF-8 is typically necessary \([API](./stdlib/string.md#encoding-api)\).

Details to keep in mind: In UTF-16, certain Unicode **code points** are represented by two UTF-16 **code units** called surrogate pairs. However, just like in JavaScript, strings are not sanitized so lone surrogates can appear in a string, which are technically ill-formed UTF-16. This is done to mimic JavaScript as closely as possible, and avoids string re-encoding when calling JavaScript APIs from WebAssembly.

We hope that future WebAssembly features will be designed with both C/Rust and JS/WebAPIs in mind without penalizing the respective other. ([1](https://github.com/WebAssembly/interface-types/issues/13), [2](https://github.com/WebAssembly/gc/issues/145))

## Class layout

Layout of objects in memory resembles that of non-packed C structs, and `@unmanaged` classes \(not tracked by GC, essentially C structs\) can be used to describe them:

```c
struct Foo {
  uint32_t bar;
  uint16_t baz;
  uint64_t qux;
}
```

```ts
@unmanaged class Foo {
  bar: u32; // aligned to 4 bytes
  baz: u16; // aligned to 2 bytes
  qux: u64; // aligned to 8 bytes
}

offsetof<Foo>("bar") == 0
offsetof<Foo>("baz") == 4
offsetof<Foo>("qux") == 8
offsetof<Foo>() == 16

var foo = changetype<Foo>(ptrToFoo)
foo.bar // -> i32.load(ptrToFoo, 0)
foo.baz // -> i32.load16_u(ptrToFoo, 4)
foo.qux // -> i64.load(ptrToFoo, 8)
```

More complex structures usually require manual offset calculation, mostly for the reason that it is not feasible to implement something more specific into AssemblyScript as it does not use such structures on its own:

```c
struct Foo {
  int32_t bar;
  uint32_t baz[10];
}
```

```ts
@unmanaged class Foo {
  bar: i32
  getBaz(i: i32): u32 {
    return load<u32>(
      changetype<usize>(this) + (<usize>i << alignof<u32>()),
      4 // or use offsetof/sizeof to calculate the base offset plus alignment
    )
  }
}
```

## Calling convention

Exported functions will properly wrap return values, but functions not visible externally do not guarantee proper wrapping.

```ts
export function getU8(): u8 {
  return someU8 // will wrap to someU8 & 0xff
}
```

On the other hand, calling any AssemblyScript function does not require wrapping of arguments.

## Optional arguments

If a function exported from AssemblyScript accepts optional arguments, the `exports.__setArgumentsLength(numArguments)` helper must be called with the number of actual arguments (while zeroing all the others) to inform the varargs stub to fill in the default values of omitted arguments. The [loader](./loader.md) does this automatically.

## Garbage collection

Also see the dedicated page on [garbage collection](./garbage-collection.md).

---

## File: src/introduction.md

---
sidebarDepth: 0
---

# Introduction

AssemblyScript compiles a **strict variant** of [TypeScript](https://www.typescriptlang.org) \(a typed superset of JavaScript\) to [WebAssembly](https://webassembly.org) using [Binaryen](https://github.com/WebAssembly/binaryen), looking like:

```ts
export function fib(n: i32): i32 {
  var a = 0, b = 1
  if (n > 0) {
    while (--n) {
      let t = a + b
      a = b
      b = t
    }
    return b
  }
  return a
}
```

```sh
asc fib.ts -b fib.wasm -O3
```

Its architecture differs from a JavaScript VM in that it compiles a program **ahead of time**, quite similar to your typical C compiler. One can think of it as TypeScript syntax on top of WebAssembly instructions, statically compiled, to produce lean and mean WebAssembly binaries.

## In a nutshell

On top of [WebAssembly types](./types.md), AssemblyScript not only provides [low-level built-ins](./environment.md#low-level-webassembly-operations) to access WebAssembly features directly, making it suitable as a thin layer on top of Wasm, but also comes with its own JavaScript-like [standard library](./environment.md#standard-library) and a relatively small [memory management and garbage collection runtime](./garbage-collection.md), making it suitable as a general purpose higher-level language for WebAssembly today.

For example, on the lowest level, memory can be accessed using the `load<T>(offset)` and `store<T>(offset, value)` built-ins that compile to WebAssembly instructions directly

```ts
store<i32>(8, load<i32>(0) + load<i32>(4))
```

while the standard library provides higher-level implementations of [Array](./stdlib/array.md), [ArrayBuffer](./stdlib/arraybuffer.md), [DataView](./stdlib/dataview.md), [Math](./stdlib/math.md) (double and single precision), [Uint8Array](./stdlib/typedarray.md), [String](./stdlib/string.md), [Map](./stdlib/map.md), [Set](./stdlib/set.md) etc.:

```ts
var view = new Int32Array(12)
view[2] = view[0] + view[1]
```

It is worth to note, however, that AssemblyScript still has its [quirks](./basics.md#quirks), and we are patiently waiting for [future WebAssembly features](./status.md) (marked as 🦄 throughout the documentation) to become available for us to use.

Sounds appealing to you? Read on!

---

## File: src/loader.md

---
sidebarDepth: 2
---

# Loader

AssemblyScript provides a tiny [module loader](https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader) that makes working with AssemblyScript modules as convenient as it gets without sacrificing efficiency. It about mirrors the relevant parts of the WebAssembly API while also providing utility to allocate and read strings, arrays and classes.

```ts
import loader from "@assemblyscript/loader"; // or require
loader.instantiate(
  // Binary to instantiate
  fetch("optimized.wasm"), // or fs.readFileSync
                           // or fs.promises.readFile
                           // or just a buffer
  // Additional imports
  { ... }
).then(({ exports }) => {
  ...
})
```

The loader basically instantiates the module using `WebAssembly` APIs, but also adds additional utility to it while evaluating export names and making a nice object structure of them. For example, if one exports an entire class `Foo` from the module, there will be an `exports.Foo` constructor etc. available when using the loader.

::: tip NOTE
Allocating objects or invoking the GC externally requires compiling with `--exportRuntime`. See: [Garbage collection](./garbage-collection.md).
:::

## Installation

For each version of the AssemblyScript compiler, there is a standalone version of the loader that can be installed from [npm](https://www.npmjs.com/package/@assemblyscript/loader):

```sh
npm install --save @assemblyscript/loader
```

On the web:

```html
<!-- ESM -->
<script type="module" src="https://cdn.jsdelivr.net/npm/@assemblyscript/loader/index.js"></script>
<!-- UMD -->
<script src="https://cdn.jsdelivr.net/npm/@assemblyscript/loader/umd/index.js"></script>
```

::: tip
If you need a [specific version](https://github.com/AssemblyScript/assemblyscript/releases) of the loader, append the respective version number as usual.
:::

## Usage

One task the loader does not perform is to implicitly translate between WebAssembly pointers and JavaScript objects, and that's where the mixed in utility comes into play. For example, if one has

```ts
// AssemblyScript
export function concat(a: string, b: string): string {
  return a + b
}
```

and then wants to call `concat` externally, the string arguments cannot just be JavaScript strings but must first be allocated in the module's memory with their lifetime tracked, like so:

```js
// JavaScript
const { concat } = myModule.exports
const { __newString, __getString } = myModule.exports

function doConcat(aStr, bStr) {
  let aPtr = __newString(aStr)
  let bPtr = __newString(bStr)
  let cPtr = concat(aPtr, bPtr)
  let cStr = __getString(cPtr)
  return cStr
}

console.log(doConcat("Hello ", "world!"))
```

### Creating arrays

Arrays (or more advanced classes for that matter) require a bit more cooperation because we need to know their value type in order to work with them properly. To achieve this, every class has a unique id internally, and a chunk of runtime type information (RTTI) is shipped with the module to evaluate class types. Here's an example of working with an `Int32Array`:

```ts
// AssemblyScript
export function sum(arr: Int32Array): i32 {
  let sum = 0
  for (let i = 0, k = arr.length; i < k; ++i) {
    sum += unchecked(arr[i])
  }
  return sum
}
export const Int32Array_ID = idof<Int32Array>()
```

```js
// JavaScript
const { sum, Int32Array_ID } = myModule.exports
const { __newArray } = myModule.exports

function doSum(values) {
  const arrPtr = __newArray(Int32Array_ID, values)
  return sum(arrPtr)
}

console.log(doSum([1, 2, 3]))
```

This works with all kinds of arrays, except that ids are different and values are interpreted differently, of course.

### Reading arrays

If one is instead interested in the values of an array being returned by the module, there are two approaches to this. Let's say we have the following module:

```ts
// AssemblyScript
export function getRandomArray(len: i32): Int32Array {
  const arr = new Int32Array(len)
  // fill with random values
  return arr
}
```

The first is, obviously, to read the array's values from the module's memory by essentially copying them to a JS array

```js
// JavaScript
const { getRandomArray } = myModule.exports
const { __getArray } = myModule.exports

function doGetRandomArray(len) {
  const arrPtr = getRandomArray(len)
  const values = __getArray(arrPtr)
  return values
}

console.log(doGetRandomArray(10))
```

which is always safe, while the second is to create a live view on the array, enabling two-way modification of its values:

```js
// JavaScript
const { getRandomArray } = myModule.exports
const { __getArrayView, __pin, __unpin } = myModule.exports

function doGetRandomArrayView(len) {
  const arrPtr = __pin(getRandomArray(len)) // pin if necessary
  const view = __getArrayView(arrPtr)
  return { ptr, view }
}

const randomArray = doGetRandomArrayView(10)
console.log(randomArray.view)
__unpin(randomArray.ptr) // unpin if necessary
```

The latter variant can be more efficient (and useful) but is a little dangerous because the view may become detached from the module's memory when memory automatically grows. Also, the viewed array can grow automatically when pushed to, with the view then referencing random memory. Pushing to an array can be avoided quite easily, yet it is notoriously hard to predict when module memory grows - but one can try to set a sufficiently large size of `--initialMemory` or defensively trigger a sufficiently large dynamic allocation being freed immediately before dealing with potentially problematic views.

### Custom classes

As mentioned earlier, the loader understands how to make a nice object structure of a module's exports, and it is possible to utilize it to work with classes in a more natural way. For example, when calling the following function externally

```ts
// AssemblyScript
export class Foo {
  constructor(public str: string) {}
  getString(): string {
    return this.str
  }
}

export function getFoo(): Foo { // this one
  return new Foo("Hello world!")
}
```

one can wrap the received pointer in a `myModule.exports.Foo` instance:

```js
// JavaScript
const { Foo, getFoo } = myModule.exports
const { __getString, __pin, __unpin } = myModule.exports

const fooPtr = __pin(getFoo()) // pin if necessary
const foo = Foo.wrap(fooPtr)
const strPtr = foo.getString()
console.log(__getString(strPtr))
__unpin(fooPtr) // unpin if necessary
```

## API

For reference, here comes the full API provided by the loader.

::: tip
Copying from and extending the examples above is typically sufficient.
:::

### Static members

* ```ts
  function instantiate<T>(
    moduleOrBuffer: WasmInstantiable,
    imports?: WasmImports
  ): Promise<ASUtil & T>
  ```
  Asynchronously instantiates an AssemblyScript module from anything that can be instantiated.

* ```ts
  function instantiateSync<T>(
    moduleOrBuffer: WasmInstantiable,
    imports?: WasmImports
  ): ASUtil & T
  ```
  Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. Not recommended.

* ```ts
  function instantiateStreaming<T>(
    response: Response | PromiseLike<Response>,
    imports?: WasmImports
  ): Promise<ASUtil & T>
  ```
  Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by fetch.

* ```ts
  function demangle<T>(
    exports: WasmExports,
    baseModule?: Object
  ): T
  ```
  Demangles an AssemblyScript module's exports to a friendly object structure. You usually don't have to call this manually as instantiation does this implicitly.

Note that `T` above can either be omitted if the shape of the module is unknown, or can reference a `.d.ts` (i.e. `typeof MyModule`) as produced by the compiler with the `-d` option.

### Module instance utility

The following utility functions are mixed into the module's exports.

* ```ts
  function __newString(str: string): number
  ```
  Allocates a new string in the module's memory and returns a pointer to it. Requires `--exportRuntime` for access to `__new`.

* ```ts
  function __newArray(id: number, values: number[]): number
  ```
  Allocates a new array in the module's memory and returns a pointer to it. The `id` is the unique runtime id of the respective array class. If you are using `Int32Array` for example, the best way to know the id is an `export const Int32Array_ID = idof()`. Requires `--exportRuntime` for access to `__new`.

* ```ts
  function __getString(ptr: number): string
  ```
  Copies a string's value from the module's memory to a JavaScript string. `ptr` must not be zero.

* ```ts
  function __getArrayBuffer(ptr: number): ArrayBuffer
  ```
  Copies an ArrayBuffer's value from the module's memory to a JavaScript buffer. `ptr` must not be zero.

* ```ts
  function __getArray(ptr: number): number[]
  ```
  Copies an array's values from the module's memory to a JavaScript array. Infers the array type from RTTI. `ptr` must not be zero.

* ```ts
  function __getArrayView(ptr: number): TypedArray
  ```
  Gets a live view on the values of an array in the module's memory. Infers the array type from RTTI. `ptr` must not be zero.

  This differs from `__getArray` in that the data isn't copied but remains live in both directions. That's faster but also unsafe because if the array grows or becomes garbage collected, the view will no longer represent the correct memory region and modifying its values in this state will most likely corrupt memory or otherwise explode. Use, but use with care.

* ```ts
  function __getInt8ArrayView(ptr: number): Int8Array
  function __getUint8ArrayView(ptr: number): Uint8Array
  function __getUint8ClampedArrayView(ptr: number): Uint8ClampedArray
  function __getInt16ArrayView(ptr: number): Int16Array
  function __getUint16ArrayView(ptr: number): Uint16Array
  function __getInt32ArrayView(ptr: number): Int32Array
  function __getUint32ArrayView(ptr: number): Uint32Array
  function __getInt64ArrayView(ptr: number): BigInt64Array
  function __getUint64ArrayView(ptr: number): BigUint64Array
  function __getFloat32ArrayView(ptr: number): Float32Array
  function __getFloat64ArrayView(ptr: number): Float64Array
  ```
  Slightly more efficient variants of `__getArrayView` where the type of the array is know beforehand. Doesn't try to infer the type.

### Module instance runtime interface

When compiling with `--exportRuntime`, the loader will expose the runtime interface (`__new`, `__pin`, `__unpin`, `__collect`) as well. See: [Garbage collection](./garbage-collection.md)

## Convenience vs. efficiency

Making the loader's API any more convenient has its tradeoffs. One would either have to include extended type information with the module itself or generate an additional JavaScript file of glue code that does (and hides) all the lifting. As such, one can consider the loader as a small and efficient building block that can do it all, yet does not sacrifice efficiency. If that's not exactly what you are looking for, take a look at more convenient tools below. Just remember that these have tradeoffs.

### More convenient tools

* [as-bind](https://github.com/torch2424/as-bind) is a library, built on top of the loader, to make passing high-level data structures between AssemblyScript and JavaScript more convenient.

## Advanced usage

### Direct memory access

All of the above can be mixed with direct [memory](./memory.md) accesses on `myModule.exports.memory.buffer`, for instance by adhering to [class layout](./interoperability.md#class-layout).

### TypeScript definitions

The compiler is able to emit definitions using the `-d` command line option that are compatible with modules demangled by the loader, and these can be used for proper typings in development:

```ts
// TypeScript
import MyModule from "myModule"; // pointing at the generated d.ts

loader.instantiate<typeof MyModule>(
  fetch("myModule.wasm"),
  { ... }
).then(({ exports }) => {
  ...
})
```

---

## File: src/memory.md

---
---

# Memory

Similar to other languages that use linear memory, and until the [GC](https://github.com/WebAssembly/gc) 🦄 proposal becomes available, all data in AssemblyScript is stored at a specific offset in linear memory so other parts of the program can read and modify it.

## Importing memory

The [WebAssembly.Memory](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory) instance used by your program can be imported from the host by using the `--importMemory` command line option. The module will then expect an import named `memory` within the `env` module to be provided upon instantiation.

An imported memory becomes the singleton memory of the module and can be accessed in the same way as a non-imported memory. Note that if the module defines `data` segments, it will place the data into the imported memory upon instantiation of the module, which must be taken into account when pre-populating the memory externally \(e.g. when utilizing `--memoryBase` to reserve some space as described in [Memory Regions](./memory.md#memory-regions) below\).

## Exporting memory

A module exports its memory as `memory` by default, unless disabled with `--noExportMemory`.

## Accessing memory during instantiation

AssemblyScript runs any top-level statements as part of the emitted WebAssembly module's implicit `start` function by default. Since the implicit start function executes immediately upon instantiation, this leads to a special case because control flow has not yet yielded back to the host, so the module's exported memory only becomes available externally *after* the implicit start function completes. The implicit start function may however already trigger external code that requires to read from memory, like when printing a string to console.

There are two solutions to this:

1. **Exporting an explicit start function**

   The `--explicitStart` command line argument can be used to force exporting the start function as `_start` instead of making it the module's implicit start function. When doing so it is important to call `exports._start()` once before calling any other exports to properly initialize the module first.

2. **Preparing memory pre-instantiation and importing it**

   An alternative is to create the `WebAssembly.Memory` object before instantiating the module, and using `--importMemory` to import it. This way around the memory is already known when the implicit start function executes.

## Memory regions

Internally, there are two regions of memory the compiler is aware of:

### Static memory

Memory starts with static data, like strings and arrays \(of constant values\) the compiler encountered while translating the program. Unlike in other languages, there is no concept of a stack in AssemblyScript and it instead relies on WebAssembly's execution stack exclusively.

A custom region of memory can be reserved using the `--memoryBase` option. For example, if one needs an image buffer of exactly N bytes, instead of allocating it one could reserve that space, telling the compiler to place its own static data afterwards, partitioning memory in this order:

| Region          | Description
| :-------------- | :----------
| Reserved memory | As specified with `--memoryBase`
| Static memory   | Starting right after reserved memory, ends at `__heap_base`
| Dynamic memory  | Starting right after static memory, starts at `__heap_base`

### Dynamic memory

Dynamic memory, commonly known as the heap, is managed by the [garbage collector](./garbage-collection.md), at runtime. When space for a new object is requested by the program, the runtime's memory manager reserves a suitable region and returns a pointer to it to the program. Once an object is not needed anymore and becomes unreachable, the garbage collector returns the object's memory to the memory manager for reuse.

The memory manager guarantees an alignment of 16 bytes, so an `ArrayBuffer`, which can be the backing buffer of multiple views, always fits up to `v128` values with natural  alignment.

## Internals

[WebAssembly is specified to use little-endian](https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions) and as a result, so is AssemblyScript.

Objects in AssemblyScript have a common hidden header used by the runtime to keep track of them. The header includes information about the block used by the memory manager, state information used by the garbage collector, a unique id per concrete class and the data's actual size. The length of a `String` \(id = 1\) is computed from that size for example. The header is "hidden" in that the reference to an object points right after it, at the first byte of the object's actual data.



#### Common header layout

| Name     | Offset | Type  | Description
| :------- | -----: | :---- | :----------
| #mmInfo  |    -20 | usize | Memory manager info
| #gcInfo  |    -16 | usize | Garbage collector info
| #gcInfo2 |    -12 | usize | Garbage collector info
| #rtId    |     -8 | u32   | Unique id of the concrete class
| #rtSize  |     -4 | u32   | Size of the data following the header
|          |      0 |       | Payload starts here

In Wasm32, the header is aligned to 16 bytes right after `mmInfo` and `rtSize`, with 16 bytes of managed information in between. The object's payload starts at 16 bytes alignment again.

The most basic objects using the common header are `ArrayBuffer` and `String`. These do not have any fields but are just data:

#### ArrayBuffer layout

| Name  | Offset | Type          | Description
| :---- | -----: | :------------ | :----------
|       |    -20 | See above     | Common header
| \[0\] |      0 | 8-bit untyped | The first byte
| \[1\] |      1 | 8-bit untyped | The second byte
| ...   |        |               |
| \[N\] |      N | 8-bit untyped | The N-th byte

#### String layout

| Name  | Offset | Type      | Description
| :---- | -----: | :-------- | :----------
|       |    -20 | See above | Common header
| \[0\] |      0 | u16       | The first character
| \[1\] |      2 | u16       | The second character
| ...   |        |           |
| \[N\] | N << 1 | u16       | The N-th character

### Collections

Collections like `Array`, `Map` and `Set` use one or multiple `ArrayBuffer`s to store their data, but their backing buffers are only exposed for typed arrays, as it is the case in JavaScript. This is because collections can grow automatically, which would otherwise lead to no longer valid references to buffers sticking around.

#### ArrayBufferView layout

This is not an actual class but a helper to simplify the implementation of the typed array views. Each typed array view like `Uint8Array` is like a subclass of `ArrayBufferView` with a static value type attached.

| Name        | Offset | Type        | Description
| :---------- | -----: | :---------- | :----------
|             |    -20 | See above   | Common header
| #data       |      0 | ArrayBuffer | Backing buffer reference
| #dataStart  |      4 | usize       | Start of the data within .data
| #dataLength |      8 | u32         | Length of the data from .dataStart

#### Array layout

| Name    | Offset | Type      | Description
| :------ | -----: | :-------- | :----------
|         |    -20 | See above | Common header
|         |      0 | See above | ArrayBufferView
| .length |     12 | i32       | Mutable length of the data the user is interested in

The layouts of `Set` and `Map` are a bit more sophisticated and therefore not mentioned here, but feel free to take a look at their sources.

---

## File: src/peculiarities.md

---
---

# Peculiarities

Special features that exist for internal implementation purposes or are otherwise nice to have.

## Annotations

Decorators work more like actual compiler annotations in AssemblyScript.

| Annotation          | Description
| :------------------ | :----------
| `@inline`           | Requests inlining of a constant or function.
| `@lazy`             | Requests lazy compilation of a variable. Useful to avoid unnecessary globals.
| `@global`           | Registers an element to be part of the global scope.
| `@external`         | Changes the external name of an imported element. `@external(module, name)` changes both the module and element name, `@external(name)` changes the element name only.
| `@operator`         | Annotates a method as a binary operator overload. See below.
| `@operator.binary`  | Alias of `@operator`.
| `@operator.prefix`  | Annotates a method as a unary prefix operator overload. See below.
| `@operator.postfix` | Annotates a method as a unary postfix operator overload. See below.

Custom decorators can be given meaning by using a [transform](./transforms.md).

## Operator overloads

Operator overloads can only be used on class methods. The respective argument types must match the class type.

### Binary operations

```ts
@operator(OP)
static __op(left: T, right :T): T { ... }

@operator(OP)
__op(right: T): T  { ... }
```

| OP      | Description
| :------ | :----------
| `"[]"`  | Checked indexed get
| `"[]="` | Checked indexed set
| `"{}"`  | Unchecked indexed get
| `"{}="` | Unchecked indexed set
| `"=="`  | Equality
| `"!="`  | Inequality
| `">"`   | Greater than
| `">="`  | Greater than or equal
| `"<"`   | Less than
| `"<="`  | Less than or equal
| `">>"`  | Arithmetic right shift
| `">>>"` | Logical right shift
| `"<<"`  | Left shift
| `"&"`   | Bitwise AND
| `"|"`   | Bitwise OR
| `"^"`   | Bitwise XOR
| `"+"`   | Addition
| `"-"`   | Subtraction
| `"*"`   | Multiplication
| `"/"`   | Division
| `"**"`  | Exponentiation
| `"%"`   | Remainder

The `===` operation cannot be overloaded \(is identity equality\).

### Unary prefix operations

```ts
@operator.prefix(OP)
static __op(self: T): T { ... }

@operator.prefix(OP)
__op(): T { ... }
```

| OP     | Description      | Notes
| :----- | :--------------- | :-----
| `"!"`  | Logical NOT      | 
| `"~"`  | Bitwise NOT      | 
| `"+"`  | Unary plus       | 
| `"-"`  | Unary negation   | 
| `"++"` | Prefix increment | Instance overload reassigns
| `"--"` | Prefix decrement | Instance overload reassigns

::: tip
Note that increment and decrement overloads can have slightly different semantics. If the overload is declared as an instance method, on `++a` the compiler does emit code that reassigns the resulting value to `a` while if the overload is declared static, the overload behaves like any other overload, skipping the otherwise implicit assignment.
:::

### Unary postfix operations

```ts
@operator.postfix(OP)
static __op(self: T): T { ... }

@operator.postfix(OP)
__op(): T { ... }
```

| OP     | Description       | Notes
| :----- | :---------------- | :---
| `"++"` | Postfix increment | Instance overload reassigns
| `"--"` | Postfix decrement | Instance overload reassigns

::: tip
Overloaded postfix operations do not preserve the original value automatically.
:::

## Range limits

The following range limits are present as global constants for convenience:

* ```ts
  const i8.MIN_VALUE: i8 = -128
  const i8.MAX_VALUE: i8 = 127
  ```

* ```ts
  const i16.MIN_VALUE: i16 = -32768
  const i16.MAX_VALUE: i16 = 32767
  ```

* ```ts
  const i32.MIN_VALUE: i32 = -2147483648
  const i32.MAX_VALUE: i32 = 2147483647
  ```

* ```ts
  const i64.MIN_VALUE: i64 = -9223372036854775808
  const i64.MAX_VALUE: i64 = 9223372036854775807
  ```

* ```ts
  const isize.MIN_VALUE: isize // WASM32: i32.MIN_VALUE, WASM64: i64.MIN_VALUE
  const isize.MAX_VALUE: isize // WASM32: i32.MAX_VALUE, WASM64: i64.MAX_VALUE
  ```

* ```ts
  const u8.MIN_VALUE: u8 = 0
  const u8.MAX_VALUE: u8 = 255
  ```

* ```ts
  const u16.MIN_VALUE: u16 = 0
  const u16.MAX_VALUE: u16 = 65535
  ```

* ```ts
  const u32.MIN_VALUE: u32 = 0
  const u32.MAX_VALUE: u32 = 4294967295
  ```

* ```ts
  const u64.MIN_VALUE: u64 = 0
  const u64.MAX_VALUE: u64 = 18446744073709551615
  ```

* ```ts
  const usize.MIN_VALUE: usize = 0
  const usize.MAX_VALUE: usize // WASM32: u32.MAX_VALUE, WASM64: u64.MAX_VALUE
  ```

* ```ts
  const bool.MIN_VALUE: bool = 0
  const bool.MAX_VALUE: bool = 1
  ```

* ```ts
  const f32.MIN_VALUE: f32 = -3.40282347e+38
  const f32.MAX_VALUE: f32 = 3.40282347e+38
  const f32.MIN_SAFE_INTEGER: f32 = -16777215
  const f32.MAX_SAFE_INTEGER: f32 = 16777215
  const f32.EPSILON: f32 = 1.19209290e-07
  ```

* ```ts
  const f64.MIN_VALUE: f64 = -1.7976931348623157e+308
  const f64.MAX_VALUE: f64 = 1.7976931348623157e+308
  const f64.MIN_SAFE_INTEGER: f64 = -9007199254740991
  const f64.MAX_SAFE_INTEGER: f64 = 9007199254740991
  const f64.EPSILON: f64 = 2.2204460492503131e-16
  ```

## Tree-shaking

### Module-level

The compiler only compiles elements reachable from the entry file and ignores everything that remains unused. This is very similar to a JavaScript VM's behavior when running a JavaScript file, but unlike in TypeScript it also affects checking of types. Helps to reduce compilation times and binary sizes significantly.

### Branch-level

In addition to module-level tree-shaking, the compiler ignores branches that it can prove won't be taken. Works with constants, built-ins that compile to a constant, expressions that can be precomputed to a constant, plus the following globals to detect specific compiler flags or features:

* ```ts
  const ASC_TARGET: i32
  ```
  Indicates the compilation target. Possible values are 0 = JS (portable), 1 = WASM32, 2 = WASM64.

* ```ts
  const ASC_NO_ASSERT: bool
  ```
  Whether `--noAssert` has been set.

* ```ts
  const ASC_MEMORY_BASE: usize
  ```
  The value of `--memoryBase`.

* ```ts
  const ASC_OPTIMIZE_LEVEL: i32
  ```
  The value of `--optimizeLevel`. Possible values are 0, 1, 2 and 3.

* ```ts
  const ASC_SHRINK_LEVEL: i32
  ```
  The value of `--shrinkLevel`. Possible values are 0, 1 and 2.

* ```ts
  const ASC_LOW_MEMORY_LIMIT: i32
  ```
  The value of `--lowMemoryLimit`.

* ```ts
  const ASC_EXPORT_RUNTIME: i32
  ```
  Whether `--exportRuntime` has been set.

* ```ts
  const ASC_FEATURE_SIGN_EXTENSION: bool
  const ASC_FEATURE_MUTABLE_GLOBALS: bool
  const ASC_FEATURE_NONTRAPPING_F2I: bool
  const ASC_FEATURE_BULK_MEMORY: bool
  const ASC_FEATURE_SIMD: bool
  const ASC_FEATURE_THREADS: bool
  const ASC_FEATURE_EXCEPTION_HANDLING: bool
  const ASC_FEATURE_TAIL_CALLS: bool
  const ASC_FEATURE_REFERENCE_TYPES: bool
  const ASC_FEATURE_MULTI_VALUE: bool
  const ASC_FEATURE_GC: bool
  const ASC_FEATURE_MEMORY64: bool
  ```
  Whether the respective feature is enabled.

  For example, if a library supports SIMD but also wants to provide a fallback when being compiled without SIMD support:

  ```ts
  if (ASC_FEATURE_SIMD) {
    // compute with SIMD operations
  } else {
    // fallback without SIMD operations
  }
  ```

* ```ts
  const ASC_WASI: i32
  ```
  A constant only being defined when WASI bindings are used via `import "wasi"`. Can be checked with `isDefined(ASC_WASI)`.

---

## File: src/portability.md

---
---

# Portability

With AssemblyScript using a stricter variant of TypeScript's syntax with a few semantic differences, there comes the opportunity to compile the same code to JavaScript with `tsc` and WebAssembly with `asc`. The AssemblyScript compiler itself is portable code.

## Portable Stdlib

Besides the full standard library, AssemblyScript provides a portable variant of the functionality that is present in both JavaScript and WebAssembly. In addition to that, the portable library lifts some of the functionality that is only available with `asc` to JavaScript, like the portable conversions mentioned below.

To use the portable library, add the following somewhere along your build step so the portable features are present in the environment

```js
require("assemblyscript/std/portable")
```

and extend `assemblyscript/std/portable.json` instead of `assemblyscript/std/assembly.json` within your `tsconfig.json`. The AssemblyScript compiler itself is an example of how this can be done.

::: tip
The portable standard library is still pretty much a work in progress and we are extending it as we go while working on the compiler. If you need something specific, feel free to improve [its definitions and feature set](https://github.com/AssemblyScript/assemblyscript/tree/master/std/portable).
:::

## Differences

There are a few semantics differences that must be taken care of.

### Conversions

While `asc` understands the meaning of

```ts
// non-portable
let someFloat: f32 = 1.5
let someInt: i32 = <i32>someFloat
```

and then inserts the correct conversion steps, `tsc` does not because all numeric types are just aliases of `number`. Hence, when targeting JavaScript with `tsc`, the above will result in

```js
var someFloat = 1.5
var someInt = someFloat
```

which is obviously wrong. To account for this, portable conversions can be used, resulting in actually portable code. For example

```ts
// portable
let someFloat: f32 = 1.5
let someInt: i32 = i32(someFloat)
```

will essentially result in

```js
var someFloat = 1.5
var someInt = someFloat | 0
```

which is correct. The best way of dealing with this is asking yourself the question: What would this code do when compiled to JavaScript?

### Overflows

Likewise, again because `asc` knows the meaning but `tsc` does not, overflows must be handled explicitly:

```ts
// non-portable
let someU8: u8 = 255
let someOtherU8: u8 = someU8 + 1
```

```ts
// portable
let someU8: u8 = 255
let someOtherU8: u8 = u8(someU8 + 1)
```

essentially resulting in

```js
let someU8 = 255
let someOtherU8 = (someU8 + 1) & 0xff
```

### API features

In JavaScript, some parts of the standard library function a little more loosely than how they would when compiling to WebAssembly. While the portable definitions try to take care of this, one example where this can happen is `Map#get` returning `undefined` when a key cannot be found in JavaScript, while resulting in an abort in WebAssembly, where it is necessary to first check that the key exists using `Map#has`. The best way of dealing with this is asking yourself the question: What would this code do when compiled to WebAssembly?

## Limitations

In JavaScript, all numeric values are IEEE754 doubles that cannot represent the full range of values fitting in a 64-bit integer \([max. safe integer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) is `2^53 - 1`\). Hence `i64` and `u64` are not portable and not present in `std/portable`. There are several ways to deal with this. One is to use an i64 polyfill like [in this example](https://github.com/AssemblyScript/examples/tree/master/i64).

Other than that, portable code \(JavaScript\) does not have a concept of memory, so there are no `load` and `store` implementations. Technically this can be polyfilled in various ways, but no default is provided since actual implementations are expected to be relatively specific \(for instance: the portable compiler accesses Binaryen's memory\).

---

## File: src/quick-start.md

---
sidebarDepth: 0
---

# Quick Start

Paving the way to what might be your first AssemblyScript module.

## Prerequisites

The following assumes that a [recent version of Node.js](https://nodejs.org) and its package manager [npm](https://www.npmjs.com) \(comes with Node.js\) are installed, with the commands below executed in a command prompt. Basic knowledge about writing and working with TypeScript modules, which is very similar, is a plus.

## Setting up a new project

To get started with AssemblyScript, switch to a new directory and initialize a new node module:

```sh
npm init
```

Now install both the [loader](./loader.md) and the [compiler](./compiler.md) using npm. Let's assume that the compiler is not required in production and make it a development dependency:

```sh
npm install --save @assemblyscript/loader
npm install --save-dev assemblyscript
```

::: tip
If you need a [specific version](https://github.com/AssemblyScript/assemblyscript/releases) of the loader and/or the compiler, append the respective version number as usual.
:::

Once installed, the compiler provides a handy scaffolding utility to quickly set up a new AssemblyScript project, for example in the directory of the just initialized node module:

```sh
npx asinit .
```

It automatically creates the recommended directory structure and configuration files:

```
This command will make sure that the following files exist in the project
directory '/path/to/mymodule':

  ./assembly
  Directory holding the AssemblyScript sources being compiled to WebAssembly.

  ./assembly/tsconfig.json
  TypeScript configuration inheriting recommended AssemblyScript settings.

  ./assembly/index.ts
  Example entry file being compiled to WebAssembly to get you started.

  ./build
  Build artifact directory where compiled WebAssembly files are stored.

  ./build/.gitignore
  Git configuration that excludes compiled binaries from source control.

  ./index.js
  Main file loading the WebAssembly module and exporting its exports.

  ./tests/index.js
  Example test to check that your module is indeed working.

  ./asconfig.json
  Configuration file defining both a 'debug' and a 'release' target.

  ./package.json
  Package info containing the necessary commands to compile to WebAssembly.

Do you want to proceed? [Y/n]
```

Once initialized, edit the sources in `assembly/`, tweak [compiler options](./compiler.md) in [`asconfig.json`](./compiler.md#asconfig-json) to fit your needs, and run the build command to compile your module to WebAssembly:

```sh
npm run asbuild
```

## Next steps

Once compiled, you may run the tests in `tests/index.js`:

```sh
npm test
```

add [imports](./exports-and-imports.md#imports) to the generated `index.js` (instantiates the module and re-exports it):

```js
...
const imports = {
  "assembly/index": {
    declaredImportedFunction: function(...) { ... }
  }
};
...
```

and ultimately use your WebAssembly module like a normal node module:

```js
const myModule = require("path/to/mymodule");
myModule.add(1, 2);
```

::: tip NOTE
Your module's exports only understand integers and floats for now, with strings and objects being passed as pointers, but we'll get into that later when covering the [loader](/loader.md).
:::

Read on to [learn more](/basics.md)!

---

## File: src/runtime.md

---
---

# Runtime

::: danger WARNING
This section is **OUTDATED** and covers version 0.17 of the AssemblyScript compiler. It has been superseded by the new runtime introduced in 0.18 that is now described under [Garbage collection](./garbage-collection.md).

**Migration from AssemblyScript 0.17 to 0.18** requires re-evaluating uses of `__retain` and `__release`, since these have been replaced with `__pin` and `__unpin` with slightly different semantics. An object can now be exactly pinned or not pinned, but cannot be pinned multiple times, and WebAssembly exports do not have a special case of pre-retaining objects for the caller anymore. Also, runtime names have changed, and instead of distinguishing between `full` (runtime exported) and `half` (runtime not exported), there's now an option `--exportRuntime` to achieve the effect with any runtime variant.
:::

**Documentation for AssemblyScript 0.17:**

AssemblyScript's runtime takes care of all the ins and outs of memory management and garbage collection, yet the compiler lets a developer choose the ideal runtime variant for their use case.

## Variants

| Variant | Description
| :------ | :----------
| full    | A proper memory manager and reference-counting based garbage collector, with runtime interfaces being exported to the host for being able to create managed objects externally.
| half    | The same as `full` but without any exports, i.e. where creating objects externally is not required. This allows the optimizer to eliminate parts of the runtime that are not needed.
| stub    | A minimalist arena memory manager without any means of freeing up memory again, but the same external interface as `full`. Useful for very short-lived programs or programs with hardly any memory footprint, while keeping the option to switch to `full` without any further changes. No garbage collection.
| none    | The same as `stub` but without any exports, for the same reasons as explained in `half`. Essentially evaporates entirely after optimizations.

The default runtime included in a program is the `full` runtime, but deciding for another variant using the `--runtime` option can help to reduce binary size significantly. The `full` runtime adds about 2KB of additional optimized code to your module, which is not that much considering what it brings to the table, but might still be overkill for simple programs.

::: tip
Previous versions of the compiler \(pre 0.7\) did not include any runtime functionality by default but instead required `import`ing an allocator and potentially an experimental tracing collector. This is not supported anymore by recent versions of the compiler.
:::

## Interface

The following paragraphs are relevant in low-level code respectively when working with objects externally only. In normal high-level code, the compiler utilizes these mechanisms automatically.

### Allocating managed objects

When allocating a managed object, it is necessary to also provide its unique class id so the runtime can properly recognize it. The unique id of any managed type can be obtained via `idof()`. Each concrete class \(like `String`, `Array`, `Array<f32>`\) has its own id. The ids of ArrayBuffer \(id=0\), String \(id=1\) and ArrayBufferView \(id=2\) are always the same, while all other ids are generated sequentially on first use of a class and differ between modules. Hence, it is usually necessary to `export Uint8Array_ID = idof()` for example when allocating one externally. The relevant interface is:

* ```ts
  function __new(size: usize, id: u32): usize
  ```
  Dynamically allocates an object represented by the specified id of at least the given size in bytes and returns its address. Alignment is guaranteed to be 16 bytes to fit up to v128 values naturally. Does not zero memory.

The [loader](./loader.md) provides some additional functionality for convenience, like `__newString`.

### Managing lifetimes

The concept is simple: If a reference to an object is established, the reference count of the object is increased by 1 \(a reference is retained\), and when a reference to an object is deleted, the reference count of the object is decreased by 1 \(a reference is released\). If the reference count of an object reaches 0, it is considered for collection and its memory ultimately returned to the memory manager for reuse. The relevant interface is:

* ```ts
  function __retain(ptr: usize): usize
  ```
  Retains a reference to the object pointed to by `ptr`. The object doesn't become collected as long as there's at least one retained reference to it. Returns the pointer.

* ```ts
  function __release(ptr: usize): void
  ```
  Releases a reference to the object pointer to by `ptr`. The object is considered for collection once all references to it have been released.

The compiler inserts retain and release calls automatically and this is opaque to a user on a higher level. On a lower level, for instance when dealing with managed objects externally, it is necessary to understand and adhere to the rules the compiler applies.

{% hint style="info" %}
Technically, both `__retain` and `__release` are nops when using the `stub`runtime, so one can either decide to skip the following for good or spend a little extra time to account for the possibility of upgrading to `full` later on.
{% endhint %}

#### Rules

1. A reference to an object **is retained** when assigning it to a target \(local, global, field or otherwise inserting it into a structure\) of a reference type, with the exceptions stated in \(3\).
2. A reference to an object **is released** when assigning another object to a target of a reference type previously retaining a reference to it, or if the lifetime of the local or structure currently retaining a reference to an object ends.
3. A reference to an object **is not released** but **remains retained** when returning a reference typed object from a call \(function, getter, constructor or operator overload\). Instead, the caller is expected to perform the release. This also means: 
   * If a reference to the object **would be immediately retained** by assigning the object to a target of a reference type, the compiler will not retain it twice, but skip retaining it on assignment.
   * If a reference to the object **will not be immediately retained**, the compiler will insert a temporary local into the current scope that autoreleases the reference to the object at the end of the scope.

::: tip
Objects created by calling `__new` start with a reference count of 0. This is not the case for constructors, these behave like calls. Built-ins like `store<T>` emit instructions directly and don't behave like calls.
:::

### Working with references externally

Working with objects through imports and exports, like when using [the loader](./loader.md), is _relatively_ straight-forward. However, if not handled properly, the program will either leak memory, free objects prematurely or even break. So here's some advice:

* Always `__retain` a reference to manually `__new`'ed objects and `__release` the reference again when done with the object.
* Always `__release` the reference to an object that was a return value of a call \(see above\) when done with it. It is not necessary to `__retain` a reference to returned objects.
* Always `__retain` a reference to an object read from memory, and `__release` the reference again when done with the object.

### Working with references internally

Working with objects internally, like when creating custom standard library components or otherwise writing low-level code, requires special care because switching between pointers and reference types can become quite tricky. The internal interface also provides [additional utility](https://github.com/AssemblyScript/assemblyscript/tree/master/std/assembly/rt) that is only relevant in very specific cases.

::: tip
One common point of confusion here is that the rules above **operate on types, not values**. Means: If the target is of a reference-type, the rules apply, but if the target is of an `usize` type, the rules do not apply, even if the value is a `changetype(..)`'d object.
:::

```ts
{
  let ref = new ArrayBuffer(10) // retains (reference type)
  let buf = changetype<usize>(ref) // does not retain (usize)
  ...
  // compiler will automatically __release(ref)
}
```

```ts
{
  let buf = changetype<usize>(new ArrayBuffer(10)) // does not retain (usize)
  // inserts a temporary, because _the object_ is not immediately assigned
  ...
  // compiler will automatically __release(theTemp)
}
```

```ts
{
  let ref = changetype<ArrayBuffer>(__new(10, idof<ArrayBuffer>())
  // retains on ref, because after changetype an object is assigned
  ...
  // compiler will automatically __release(ref)
}
```

### Collecting garbage

By default, the full and half runtime will automatically try to collect cyclic garbage when memory must be grown. This behavior can be disabled by setting `gc.auto = false` in performance critical code. Likewise, if there is a good opportunity to collect cyclic garbage at a given point in time, like if the application is idle, `gc.collect()` can be called to force a full garbage collection cycle. Protip: If no cyclic structures are used, no garbage must be collected.

## Implementation

The memory manager used by AssemblyScript is a variant of TLSF \([Two-Level Segregate Fit memory allocator](http://www.gii.upv.es/tlsf/)\) and it is accompanied by PureRC \(a variant of [A Pure Reference Counting Garbage Collector](https://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon03Pure.pdf)\) with [slight modifications of assumptions](https://github.com/dcodeIO/purerc) to avoid unnecessary work. Essentially, TLSF is responsible for partitioning [dynamic memory](./memory.md#dynamic-memory) into chunks that can be used by the various objects, while PureRC keeps track of their lifetimes.

## Performance considerations

Both the TLSF memory manager and the concept of reference counting are a good fit for _predictable performance_ scenarios. Remember: WebAssembly is about exactly that. It is not necessarily the fastest choice in every possible scenario, though.

It is also likely that our implementations are not as optimized yet as ultimately possible. If you are smarter than us, please let us know of your thoughts and findings.

## Internals

If you are interested in the inner workings, the internal APIs are explained in [the runtime's README file](https://github.com/AssemblyScript/assemblyscript/tree/master/std/assembly/rt) and of course in its sources - feel free to take a look!

#### Runtime type information \(RTTI\)

Every module using managed objects contains a memory segment with basic type information, that [the loader](./loader.md) for example uses when allocating new arrays. Internally, RTTI is used to perform dynamic `instanceof` checks and to determine whether a class is inherently acyclic. The memory offset of RTTI can be obtained by reading the `__rtti_base` global. Essentially, the compiler maps every concrete class to a unique id, starting with 0 \(=ArrayBuffer\), 1 \(=String\) and 2 \(=ArrayBufferView\) . For each such class, the compiler remembers the id of the respective base class, if any, and a set of flags describing the class. Flags for example contain information about key and value alignments, whether a class is managed and so on. Structure is like this:

| Name        | Offset | Type | Description
| :---------- | -----: | :--- | :----------
| #count      |      0 | u32  | Number of concrete classes
| #flags\[0\] |      4 | u32  | Flags describing the class with id=0
| #base\[0\]  |      8 | u32  | Base class id of the class with id=0
| #flags\[1\] |     12 | u32  | ... etc. ...

Flag values are currently still in flux, but if you are interested in these, feel free to take a look at the sources.

#### Notes

Unlike other reference counting implementions, allocating an object starts with a reference count of 0. This is useful in standard library code where memory is first allocated and then assigned to a variable, establishing the first reference.

The compiler does some extra work to evaluate whether an object can potentially become part of a reference cycle. Any object that cannot directly or indirectly reference another object of its kind is considered _inherently acyclic_, so it does not have to be added to the cycle buffer for further evaluation by deferred garbage collection.

Due to the lack of random access to WebAssembly's execution stack \(remember: AssemblyScript does not have a stack on its own\), values returned from a function become pre-retained for the caller, expecting that it will release the reference at the end, or give the reference to its own caller. This also leads to situations where sometimes a reference must be retained on assignment, and sometimes it must not. It also leads to situations where two branches must be unified, for example if there is a pre-retained value in one arm and one that is not in the other. The compiler is taking care of these situations, but it also requires special care when dealing with the reference counting internals within the standard library.

The compiler also utilizes a concept of so called autorelease locals. Essentially, if a reference enters a block of code from somewhere else, is pre-retained but not immediately assigned, such a local is added to the current scope to postpone the necessary release until the scope is exited.

One thing not particularly ideal at this point is that each function is expected to retain the reference-type arguments it is given, and release them again at the end. This is necessary because the compiler does just a single pass and doesn't know whether a variable becomes reassigned beforehand \(no SSA or similar, that's left to Binaryen in an attempt to avoid duplicating its code\). It does already skip this for certain variables like `this` that cannot be reassigned, but there are definitely more optimization opportunities along the way. Due to AssemblyScript essentially being a compiler on top of another compiler, it is somewhat unclear however where to perform such optimizations.

---

## File: src/status.md

---
sidebarDepth: 2
---

# Status

Not all language features are equally viable to implement on top of WebAssembly's current capabilities, and while AssemblyScript is already useful today, there is also still a lot to do. Keep in mind that WebAssembly is an evolving technology, and so is AssemblyScript.

## Philosophy

The original idea which made AssemblyScript attractive is that it aims to be a thin and efficient layer on top of WebAssembly with a familiar syntax, ultimately producing lean and mean binaries. This idea is composed of two components, however, that are sometimes orthogonal: **Lean and mean** implies that we have to stay close to WebAssembly's capabilities, i.e. not going too far already where implementations of certain language features would be inefficient or increase binary size disproportionately, while a **familiar syntax** naturally begs for supporting more of the original language right now.

As such, while AssemblyScript wants to stay as close as possible to being a language that feels very familiar with JavaScript and TypeScript developers, and aims to preserve compatiblity with existing tooling, it ultimately is a language compiling to WebAssembly and will prioritize language features that allow developers to write fast and small WebAssembly modules on top of the features that WebAssembly already provides.

## WebAssembly features

Some crucial language features rely on [future WebAssembly functionality](https://github.com/WebAssembly/proposals) to be efficient. The following table aims to give an overview from a WebAssembly perspective:

| WebAssembly spec               | Engines                       | AssemblyScript (flag)   | What's the plan?
|--------------------------------|-------------------------------|-------------------------|------------------------------------
| ✔️ **Finished proposal**
| Import/export mutable globals  | <Ch/> <Fi/> <Sa/> <No/> <Wa/> | ✔️                     | Global variable interop
| BigInt integration             | <Ch/> <Fi/>             <Wa/><sup>1</sup> | ✔️         | 64-bit integer interop
| Non-trapping F2I               | <Ch/> <Fi/>       <No/> <Wa/> | ⏳                      | Checked and unchecked casts
| Sign-extension                 | <Ch/> <Fi/>       <No/> <Wa/> | ⏳ `sign-extension`     | Efficient small integer casts
| Multi-value                    | <Ch/> <Fi/> <Sa/>       <Wa/> |                         | Tuple return values?
||
| 🏁 **Standardize the feature**
| Reference Types                |       <Fi/>             <Wa/> | ⏳ `reference-types`    | Prerequisite for garbage collection
| Bulk memory                    | <Ch/> <Fi/>             <Wa/> | ⏳ `bulk-memory`        | Replace `memcpy`, `memset`
||
| 🔨 **Implementation phase**
| Tail call                      |                               |                         |
| Fixed-width SIMD               |                               | ⏳ `simd`               | Expose as built-ins; Auto-vectorize?
| Multiple memories              |                               |                         |
| Custom annotations             |                               |                         |
||
| 📖 **Spec text available** 
| Threads                        | <Ch/> <Fi/>                   | ⏳ `threads`            | Expose as built-ins; WebWorker?
| ESM integration                |                               |                         | Natural web interop
| Exception handling             |                               | ⏳ `exception-handling` | Implement exceptions
| Function references            |                               |                         | Implement closures
| Memory64                       |                               | ⏳                      | Provide a Wasm64 target
||
| 💡 **Feature proposal**
| Type Imports                   |                               |                         | Web interop?
| Garbage collection             |                               |                         | Reuse host GC; Share objects?
| Interface Types                |                               |                         | Non-web interop?
| Feature detection              |                               |                         |
| Extended name section          |                               | ⏳                      | Debug names for locals etc.
| Flexible vectors               |                               |                         | Expose as built-ins
| Call Tags                      |                               |                         |
| Module Linking                 |                               |                         | Linking pre-compiled modules
| Branch hinting                 |                               |                         | `likely(x)`, `unlikely(x)`?

<Ch/> Chrome &nbsp;
<Fi/> Firefox &nbsp;
<Sa/> Safari &nbsp;
<No/> Node.js &nbsp;
<Wa/> Wasmtime (<sup>1</sup> native i64 support)

## Language features

As such, certain higher-level language features still have their limitations or are not yet available. From a language perspective:

| Feature                                           | What to expect?
|---------------------------------------------------|-----------------
| 🐤 **Functional**
| [Bootstrap](#bootstrap)                           | The compiler can compile itself to WebAssembly, passing the test suite.
| [Classes and interfaces](#classes-and-interfaces) | Largely implemented in linear memory. Some caveats. (needs GC 🦄)
| [Standard library](#standard-library)             | Largely implemented in linear memory. Some caveats.
| [Generics](#generics)                             | Monomorphized templates for now. (maybe post-MVP GC 🦄)
| [Garbage collection](#garbage-collection)         | Implemented in linear memory for now. (needs GC 🦄)
| [Interop with JS](#interop-with-js)               | Enabled by the loader package. (needs Type imports / Interface Types 🦄)
||
| 🐣 **Limited**
| [Union types](#union-types)                       | Nullable class types only. Can use generics with static type checks instead. (No proposal so far)
| [Symbols](#symbols)                               | Implemented, but no deep compiler integration yet.
| [JSON](#json)                                     | Third-party library available.
| [RegExp](#regexp)                                 | Third-party library available.
||
| 🥚 **Not implemented**
| [Closures](#closures)                             | Perhaps implement in linear memory. (needs Function references 🦄)
| [Iterators](#iterators)                           | Not implemented yet. Depends on symbols.
| [Rest parameters](#rest-parameters)               | Perhaps implement in linear memory. (No proposal so far)
| [Exceptions](#exceptions)                         | Throwing currently aborts the program. (needs Exception handling 🦄)
| [Promises](#promises)                             | There is no concept of async/await yet due to the lack of an event loop. (No proposal so far)
| [BigInt](#bigint)                                 | There are no BigInts yet, but there are i64s.
||
| 🕳️ **Not supported**
| [Dynamicness](#dynamicness)                       | AssemblyScript avoids overly dynamic JavaScript features by design.

### Bootstrap

The first release able to bootstrap itself and pass the test suite is v0.18, released in January 2021. Note that the compiler is not technically "self hosted" in WebAssembly still, as it currently uses a JavaScript frontend for I/O and links to Binaryen (C++ with Emscripten), which also requires some JavaScript glue code. As such, to make the compiler work in a WebAssembly-only engine like Wasmtime, the next steps would be to work towards a WebAssembly-only build of Binaryen, and replace the I/O parts provided by `asc` with WASI.

### Classes and interfaces

These mostly work, with a a few caveats.

* Access modifiers like `private` and `protected` are not currently enforced. Likely to be enforced in the future.
* Interface fields must be implemented as getters and setters. Likely to be lifted in the future.
* Note that WebAssembly doesn't magically neglect the runtime cost of making extensive use of managed classes, so there are often faster alternatives.

### Standard library

Some [standard library APIs](./stdlib/globals.md) function a little different than in JavaScript to account for differences introduced by static typing or missing WebAssembly features. We are also maintaining a [separate status document](https://github.com/AssemblyScript/assemblyscript/wiki/Status-and-Roadmap) specific to the standard library.

### Generics

AssemblyScript compiles generics to one concrete method or function per set of unique contextual type arguments, also known as [monomorphisation](https://en.wiktionary.org/wiki/monomorphisation). Implications are that a module only includes and exports concrete functions for sets of type arguments actually used and that concrete functions can be shortcutted with [static type checks](./environment.md#static-type-checks) at compile time, which turned out to be quite useful.

* The compiler does not currently enforce `extends Y` clauses on type parameters. Likely to be enforced in the future.
* WebAssembly GC 🦄 may introduce more sophisticated mechanisms like reified generics, potentially post-MVP.
* Concrete functions compiling to the exact same code are de-duplicated during optimization.

### Garbage collection

[Garbage collection](./garbage-collection.md) is currently implemented in linear memory, independent from the host, and is best paired with [the loader](./loader.md) for interop.

### Interop with JS

WebAssembly only understands numeric values as of today and cannot easily exchange objects with JavaScript. Hence, when an object is returned from WebAssembly to JavaScript, what the caller passes and the callee receives is a pointer to the object in linear memory. Note that WebAssembly does not know what to do with JavaScript objects passed to it, as the VM will implicitly convert the object to a number when it crosses the boundary, which is typically not what you want.

For example, to pass a string to a WebAssembly export, one first has to allocate the string in the WebAssembly module's linear memory, and then pass the resulting pointer to the WebAssembly export. The same is true for arrays and other objects.

For now, [the loader](./loader.md) provides the utility necessary to translate between objects in linear memory and JavaScript objects (e.g. with `__newString` and `__getString`), and our hopes are on Type Imports 🦄, Interface Types 🦄 and perhaps Garbage collection 🦄 to make interop more convenient eventually.

See also: [Will interop between AssemblyScript and JavaScript become better?](./frequently-asked-questions.md#will-interop-between-assemblyscript-and-javascript-become-better)

### Union types

WebAssembly cannot efficiently represent locals or globals of dynamic types, so union types are not supported in AssemblyScript. One can however take advantage of the fact that AssemblyScript is a static compiler, with monomorphized generics and [static type checks](./environment.md#static-type-checks), to achieve a similar effect:

```ts
function addOrConcat<T>(a: T, b: T): T {
  return a + b; // concats if a string, otherwise adds
}

function addOrSomethingElse<T>(a: T, b: T): T {
  if (isString<T>()) {
    return "something else"; // eliminated if T is not a string
  } else {
    return a + b; // eliminated if T is a string
  }
}
```

Another effect of the above is that AssemblyScript does not have an `any` type or `undefined` value.

### Symbols

The standard library implements [`Symbol`](./stdlib/symbol.md), and it is possible to work with and create new symbols, but there is no deep compiler integration like registration of `Symbol.iterator` etc. yet.

### JSON

JSON integration in the compiler itself is still an open question due to its untyped nature. May require a mix of reflection and schema-specific code generation for natural integration.

Solutions being developed by the community:

* [nearprotocol/assemblyscript-json](https://github.com/nearprotocol/assemblyscript-json)

### RegExp

Regular expressions have been on our todo list for quite a while. It's mostly that a good implementation becomes complicated pretty quickly with special Unicode cases, exponential behavior and so on. Also, an ideal RegExp implementation would be compatible with the ECMAScript specification, reasonably fast and integrate deeply with the compiler, so RegExp literals can be pre-compiled (to WebAssembly code or an intermediate bytecode), making it unnecessary most of the time to ship the entire engine with a module.

Solutions being developed by the community:

* [ColinEberhardt/assemblyscript-regex](https://github.com/ColinEberhardt/assemblyscript-regex)

### Closures

Closures (functions with a captured environment) are not yet supported and we are waiting for the Function References 🦄 and Garbage collection 🦄 (captured environments are GC'ed) proposals to land. However, since this is a crucial language feature, we may end up with a filler implementation using linear memory. Not available yet, though.

In the meantime we recommend to restructure code so closures are not necessary, i.e. instead of writing

```ts
function computeSum(arr: i32[]): i32 {
  var sum = 0
  arr.forEach(value => {
    sum += value // fails
  })
  return sum
}
```

restructure to

```ts
var sum: i32 // becomes a WebAssembly Global
function computeSum(arr: i32[]): i32 {
  sum = 0
  arr.forEach(value => {
    sum += value // works
  })
  return sum
}
```

or to

```ts
function computeSum(arr: i32[]): i32 {
  var sum = 0
  for (let i = 0, k = arr.length; i < k; ++i) {
    sum += arr[i] // works
  }
  return sum
}
```

### Iterators

It has not been attempted to implement iterators due to uncertainty how efficient iterators will be using frequent dynamic allocation. Also requires symbols for deep integration. Therefore `for ... of` loops are not currently supported. To work around the limitation of not having iterators, otherwise non-functional standard library APIs return an array for now:

#### Map\<K,V>

* ```ts
  function keys(): Array<K>
  ```

* ```ts
  function values(): Array<V>
  ```

#### Set\<T>

* ```ts
  function values(): Array<T>
  ```

### Rest parameters

It has not yet been attempted to implement variadic functions due to uncertainty how efficient it will be without random stack access. The risk is that doing dynamic allocations instead may introduce an unfortunate hidden cost to function calls.

In the meantime, optional function arguments, which do not have such a hidden cost, may be able to help:

```ts
function handleGiven(a: i32, b: i32 = -1, c: i32 = -1): void {
  handle(a);
  if (~b) {
    handle(b);
    if (~c) {
      handle(c);
    }
  }
}
```

### Exceptions

Exceptions are not yet supported and we are waiting for the Exception handling 🦄 proposal to land. It is not yet feasible to implement exceptions without the help of the proposal as throwing and catching an exception requires stack unwinding, so the following will currently crash the program with a call to `abort("message", ...)`:

```ts
function doThrow(): void {
  throw new Error("message")
}
```

In the meantime we recommend to do as they did in the olden days and return an error code or `null` to indicate an exception.

### Promises

The concept of async execution requires an underlying concept of an event loop, which browsers and Node.js have but WebAssembly does not. In the meantime, it is recommended to stick to synchronous code within WebAssembly or call back into WebAssembly when an external async operation completes.

### BigInt

We have favored the use of WebAssembly's native 64-bit integers over `BigInt`s and their `INTn` notation so far, since `BigInt`s can represent values > 64-bits and as such would have to be implemented as less-efficient heap allocated objects. There are certain use cases relying on representing more than 64-bits, of course, but we still have to figure out how to support both types without introducing conflicts.

### Dynamicness

AssemblyScript intentionally avoids very dynamic JavaScript features that cannot be compiled efficiently, like for example:

* Assigning any value to any variable.
* Compare values of incompatible types.
* Implicitly convert from a non-string to a string without using `x.toString()`.
* Assign a new property, that has not been statically declared, to a class or object.
* Assign a class to a variable (e.g. `var clazz = MyClass`) since classes are static constructs without a runtime representation.
* Patch class `.prototype`s since there are none.
* Access `arguments` to dynamically obtain function arguments.
* Dynamically obtain the name of a function at runtime or otherwise use reflection.

Some of these restrictions, like implicit conversion to strings when concatenating with a string, may be lifted in the future, while others, like prototypes, may never be viable in ahead-of-time compilation. For instance, some features would work in an interpreter and may become efficient with a JIT compiler, yet going down that rabbit hole runs counter to WebAssembly's, and by definition AssemblyScript's, goals.

## Tooling features

| Feature                 | What to expect?
|-------------------------|-----------------
| 🐤 **Functional**
| [Debugging](#debugging) | Support for debug information and source maps. (needs DWARF support)
| [Testing](#testing)     | With assertions. Third-party library available.
||
| 🐣 **Limited**
| [Linting](#linting)     | Re-used TypeScript tooling. Third-party tooling available.

### Debugging

Debugging of AssemblyScript modules is not as convenient as it should be, but [possible with debug information and accompanying source maps](./debugging.md). For a better debugging experience, we may eventually want to integrate with the [DWARF](http://dwarfstd.org) format used by for example LLVM, ideally through Binaryen.

### Testing

The standard library provides the [`assert`](./environment.md#utility) built-in, which does not decide on a particular flavor of testing, yet is often sufficient to write basic tests.

Solutions being developed by the community:

* [jtenner/as-pect](https://github.com/jtenner/as-pect)

### Linting

AssemblyScript piggy-backs on top of TypeScript's excellent infrastructure currently, making it trivial to get started, but could need more sophisticated checking (as one types) for where code is valid TypeScript but not valid AssemblyScript or vice-versa with `// @ts-ignore`. It is still an open question whether a custom language server is needed (potentially with a separate file extension), or if a plugin on top of existing TypeScript tooling would be an equally viable option. The latter would imply having to reinvent fewer wheels, like code navigation and refactoring etc., while the former may feel more polished once all the wheels have been reinvented.

Solutions being developed by the community:

* [Shopify/asls](https://github.com/Shopify/asls)

---

## File: src/transforms.md

---
---

# Transforms

AssemblyScript is compiled statically, so code transformation cannot be done at runtime but must instead be performed at compile-time. To enable this, the compiler frontend \(asc\) provides a mechanism to hook into the compilation process before, while and after the module is being compiled.

Specifying `--transform ./myTransform` on the command line will load the node module pointed to by `./myTransform`.

```js
const { Transform } = require("assemblyscript/cli/transform")
const assemblyscript = require("assemblyscript")
class MyTransform extends Transform {
  ...
}
module.exports = MyTransform
```

## Properties

A transform is an ES6 class/node module with the following inherited properties:

* ```ts
  readonly program: Program
  ```
  Reference to the `Program` instance.

* ```ts
  readonly baseDir: string
  ```
  Base directory used by the compiler.

* ```ts
  readonly stdout: OutputStream
  ```
  Output stream used by the compiler.

* ```ts
  readonly stderr: OutputStream
  ```
  Error stream uses by the compiler.

* ```ts
  readonly log: typeof console.log
  ```
  Logs a message to console.

* ```ts
  function writeFile(filename: string, contents: string | Uint8Array, baseDir: string): boolean
  ```
  Writes a file to disk.

* ```ts
  function readFile(filename: string, baseDir: string): string | null
  ```
  Reads a file from disk.

* ```ts
  function listFiles(dirname: string, baseDir: string): string[] | null
  ```
  Lists all files in a directory.

## Hooks

The frontend will call several hooks, if present on the transform, during the compilation process:

* ```ts
  function afterParse(parser: Parser): void
  ```
  Called when parsing is complete, before a program is initialized from the AST. Note that types are not yet known at this stage and there is no easy way to obtain them.

* ```ts
  function afterInitialize(program: Program): void
  ```
  Called once the program is initialized, before it is being compiled. Types are known at this stage, respectively can be resolved where necessary.

* ```ts
  function afterCompile(module: Module): void
  ```
  Called with the resulting module before it is being emitted. Useful to modify the IR before writing any output, for example to replace imports with actual functionality or to add custom sections.

Transforms are a very powerful feature, but may require profound knowledge of the compiler to utilize them to their full extent, so reading through the compiler sources is a plus.

---

## File: src/types.md

---
---

# Types

Instead of using the `number` type for all sorts of numeric values, AssemblyScript inherits WebAssembly's more specific integer and floating point types:

| AssemblyScript Type | WebAssembly type | Description
| :------------------ | :--------------- | :-----------
| `i32`               | i32              | A 32-bit signed integer.
| `u32`               | i32              | A 32-bit unsigned integer.
| `i64`               | i64              | A 64-bit signed integer.
| `u64`               | i64              | A 64-bit unsigned integer.
| `f32`               | f32              | A 32-bit float.
| `f64`               | f64              | A 64-bit float.
| `v128`              | v128             | A 128-bit vector 🦄.
| `anyref`            | anyref           | An opaque host reference 🦄.
| **Small integer types**                |
| `i8`                | i32              | An 8-bit signed integer.
| `u8`                | i32              | An 8-bit unsigned integer.
| `i16`               | i32              | A 16-bit signed integer.
| `u16`               | i32              | A 16-bit unsigned integer.
| `bool`              | i32              | A 1-bit unsigned integer.
| **Variable integer types**             |
| `isize`             | i32 or i64       | A 32-bit signed integer in WASM32.A 64-bit signed integer in WASM64 🦄.
| `usize`             | i32 or i64       | A 32-bit unsigned integer in WASM32.A 64-bit unsigned integer in WASM64 🦄.
| **Special types**                      |
| `void`              | -                | Indicates no return value.
| `auto`              | ?                | Makes an educated guess. Internal only.

## Type rules

AssemblyScript will complain when it sees an implicit conversion that might not actually be intended, quite similar to what a C compiler would do.

### Casting

In AssemblyScript, the type assertions `<T>expression` and `expression as T` known from TypeScript become explicit type conversions, essentially telling the compiler that the conversion is intended. In addition, each of the type names mentioned above, except aliases, also act as portable conversion built-ins that can be used just like `i32(expression)`. Using portable conversions is especially useful where the exact same code is meant to be compiled to JavaScript with the TypeScript compiler \([see](./portability.md)\), that otherwise would require the insertion of asm.js-style type coercions like `expression | 0`.

### Inference

Compared to TypeScript, type inference in AssemblyScript is limited because the type of each expression must be known in advance. This means that variable and parameter declarations must either have their type annotated or have an initializer. Without a type annotation and only an initializer, AssemblyScript will assume `i32` at first and only reconsider another type if the value doesn't fit \(becomes `i64`\), is a float \(becomes `f64`\) or irrefutably has another type than these, like the type of a variable, the return type of a function or a class type. Furthermore, functions must be annotated with a return type to help the compiler make the correct decisions, for example where a literal is returned or multiple return statements are present.

### Nullability

Basic types cannot be nullable, but class and function types can. Appending `| null` declares a nullable type.

### Assignability

Assigning a value of one type to a target of another type can be performed without explicit casts where the full range of possible values can be represented in the target type, regardless of interpretation/signedness:

| ↱       | bool | i8/u8 | i16/u16 | i32/u32 | i64/u64 | f32 | f64 |
| :------ | :--- | :---- | :------ | :------ | :------ | :-- | :-- |
| bool    | ✓ | ✓   | ✓ | ✓ | ✓ | ✓ | ✓ |
| i8/u8   |  | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| i16/u16 |  |  | ✓ | ✓ | ✓ | ✓ | ✓ |
| i32/u32 |  |  |  | ✓ | ✓ |  | ✓ |
| i64/u64 |  |  |  |  | ✓ |  |  |
| f32     |  |  |  |  |  | ✓ | ✓ |
| f64     |  |  |  |  |  |  | ✓ |

Note that `isize` and `usize` are aliases of either `i32` and `u32` in WASM32 respectively `i64` and `u64` in WASM64 🦄.

```ts
var  i8val: i8  = -128  // 0x80
var  u8val: u8  = i8val // becomes 128 (0x80)
var i16val: i16 = i8val // becomes -128 through sign-extension (0xFF80)
var u16val: u16 = i8val // becomes 65408 through masking (0xFF80)
var f32val: f32 = i8val // becomes -128.0
```

### Comparability

Comparing two values of different types can be performed without an explicit cast under the same rules as outlined in assignability above

1. if the comparison is absolute \(`==`, `!=`\)
2. if the comparison is relative \(`>`, `<`, `>=`, `<=`\) and **both types have the same signedness**

because WebAssembly has distinct operations for signed and unsigned comparisons. The comparison uses the larger type and returns `bool`.

### Bit shifts

The result of a bit shift \(`<<`, `>>`\) is the left type, with the right type implicitly converted to the left type, performing an arithmetic shift if the left type is signed and a logical shift if the left type is unsigned.

The result of an unsigned right shift \(`>>>`\) is the left type \(signedness is retained\), with the right type implicitly converted to the left type, but always performing a logical shift.

Note that only the `log2(sizeof<T>())` least signficant bits of the shift affect the result:

| Type      | Significant bits | Example
| :-------- | :--------------: | :------------------------
| i8 / u8   | 3                | `x & y` ≡ `x & (y & 7)`
| i16 / u16 | 4                | `x & y` ≡ `x & (y & 15)`
| i32 / u32 | 5                | `x & y` ≡ `x & (y & 31)`
| i64 / u64 | 6                | `x & y` ≡ `x & (y & 63)`

If the left type is a float, an error is emitted.

## Macro types

The following macro types provide access to related types that would otherwise be impossible to obtain.

| Macro type    | Description
| :------------ | :----------
| `native<T>`   | Obtains the underlying native type of `T`, e.g. `u32` if `T` is a class \(in WASM32\).
| `indexof<T>`  | Obtains the index type of a collection based on the indexed access overload.
| `valueof<T>`  | Obtains the value type of a collection based on the indexed access overload.
| `returnof<T>` | Obtains the return type of a function type.

---

## File: src/examples/arrays.md

# Arrays example

Shows how to exchange and work with arrays either created in WebAssembly or in JavaScript.

## Contents

* Using the loader and the full runtime to work with managed objects.
* Creating arrays in WebAssembly and using them in JavaScript.
* Creating arrays in JavaScript and using them in WebAssembly.
* Using both copies of and live views on arrays.
* Performing `unchecked` accesses where the length of an array is known.
* Pinning objects externally to prevent premature garbage collection.

## Example

```editor
#!optimize=speed&runtime=default&exportRuntime
/** Creates a new array and returns it to JavaScript. */
export function createArray(length: i32): Int32Array {
  return new Int32Array(length)
}

/** Randomizes the specified array's values. */
export function randomizeArray(arr: Int32Array): void {
  for (let i = 0, k = arr.length; i < k; ++i) {
    let value = i32((Math.random() * 2.0 - 1.0) * i32.MAX_VALUE)
    unchecked(arr[i] = value)
  }
}

/** Computes the sum of an array's values and returns the sum to JavaScript. */
export function sumArray(arr: Int32Array): i32 {
  let total = 0
  for (let i = 0, k = arr.length; i < k; ++i) {
    total += unchecked(arr[i])
  }
  return total
}

// We'll need the unique Int32Array id when allocating one in JavaScript
export const Int32Array_ID = idof<Int32Array>()

#!html
<textarea id="output" style="width: 100%; height: 100%" readonly></textarea>
<script>
loader.instantiate(module_wasm).then(({ exports }) => {
  const output = document.getElementById('output')

  /** Logs a message to the textarea. */
  function log(message = '') {
    output.value += `${message}\n`
  }

  // A simple example using an array created in WebAssembly.
  function example1() {
    log('=== Example1 ===')

    // Obtain the necessary runtime helpers
    const { __pin, __unpin, __getArray } = exports

    // Create a new array in WebAssembly and get a reference to it. Note that
    // the array is not reachable from within WebAssembly, only externally, so
    // we should pin it to prevent it from becoming garbage collected too early.
    let arrayPtr = __pin(exports.createArray(5))
    log(`Array pointer: ${arrayPtr}`)

    // Log its elements to make sure these are zero
    log('Initial values: ' + __getArray(arrayPtr).join(', '))

    // Randomize the array in WebAssembly and log it again
    exports.randomizeArray(arrayPtr)
    log('Randomized values: ' + __getArray(arrayPtr).join(', '))

    // Compute the array values' sum and log it. This will overflow i32 range.
    let total = exports.sumArray(arrayPtr)
    log(`Sum (likely overflown): ${total}`)

    // We are done with the array, so __unpin it so it can become collected.
    __unpin(arrayPtr)

    log()
  }
  example1()

  // A slightly more advanced example allocating the array in JavaScript instead
  // of WebAssembly, and utilizing a live view to modify it in WebAssembly memory.
  function example2() {
    log('=== Example2 ===')

    // Obtain the necessary runtime helpers
    const { __pin, __unpin, __newArray, __getArray, __getArrayView } = exports

    // Create a new array, but this time in JavaScript. Note that the array is
    // again not reachable from within WebAssembly, only externally, so we
    // should pin it to prevent it from becoming garbage collected too early.
    let arrayPtr = __pin(__newArray(exports.Int32Array_ID, [
      3, 4, 5, 6, 7, 8, 9
    ]))
    log('Array pointer: ' + arrayPtr)

    // Log its elements to make sure these are the provided values
    log('Initial values: ' + __getArray(arrayPtr).join(', '))

    // Compute the array values' sum and log it
    let total = exports.sumArray(arrayPtr)
    log('Sum: ' + total)

    // Instead of copying, let's obtain a live view on the array and modify its
    // values right in WebAssembly memory.
    let view = __getArrayView(arrayPtr)
    view.reverse()

    // Log the array's elements, now reversed
    log('Reversed values: ' + __getArray(arrayPtr).join(', '))

    // We are done with the array, so __unpin it so it can become collected.
    __unpin(arrayPtr)

    log()
  }
  example2()
})
</script>
```

::: tip NOTE
This example utilizes the loader to work with managed objects, hence requires `--exportRuntime` to be set to expose the runtime helpers to JavaScript.
:::

## Resources

Further information on using the loader and the runtime helpers is available as part of the [loader's](../loader.md#counting-references) and the [garbage collection documentation](../garbage-collection.md).

---

## File: src/examples/game-of-life.md

---
---

# Game of Life example

Continuously updates a slightly modified variant of [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway's_Game_of_Life) and visualizes its state on a canvas.

## Contents

* Exporting functions from a WebAssembly module.
* Calling functions exported from WebAssembly.
* Importing configuration values from JavaScript.
* Instantiating the module's memory in JavaScript and import it using `--importMemory`.
* Speeding up a program by forcing helper functions in a hot path to always `@inline`.
* Utilizing JavaScript's `Math` instead of native libm to reduce module size via `--use Math=JSMath`.
* Reacting to user input by directly modifying an input image buffer.
* Finding out about WebAssembly's unintuitive byte order.
* And finally: Continuously updating an input to an output image buffer and rendering the output image buffer.
* Featuring: Clicking and drawing lots of *stuff*.

## Example

```editor
#!optimize=speed&runtime=stub&importMemory&use=Math=JSMath
// Configuration imported from JS
declare const BGR_ALIVE: u32;
declare const BGR_DEAD: u32;
declare const BIT_ROT: u32;

var width: i32, height: i32, offset: i32;

/** Gets an input pixel in the range [0, s]. */
@inline
function get(x: u32, y: u32): u32 {
  return load<u32>((y * width + x) << 2);
}

/** Sets an output pixel in the range [s, 2*s]. */
@inline
function set(x: u32, y: u32, v: u32): void {
  store<u32>((offset + y * width + x) << 2, v);
}

/** Sets an output pixel in the range [s, 2*s] while fading it out. */
@inline
function rot(x: u32, y: u32, v: u32): void {
  var alpha = max<i32>((v >> 24) - BIT_ROT, 0);
  set(x, y, (alpha << 24) | (v & 0x00ffffff));
}

/** Initializes width and height. Called once from JS. */
export function init(w: i32, h: i32): void {
  width  = w;
  height = h;
  offset = w * h;

  // Start by filling output with random live cells.
  for (let y = 0; y < h; ++y) {
    for (let x = 0; x < w; ++x) {
      let c = Math.random() > 0.1
        ? BGR_DEAD  & 0x00ffffff
        : BGR_ALIVE | 0xff000000;
      set(x, y, c);
    }
  }
}

/** Performs one step. Called about 30 times a second from JS. */
export function step(): void {
  var w = width,
      h = height;

  var hm1 = h - 1, // h - 1
      wm1 = w - 1; // w - 1

  // The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square
  // "cells", each of which is in one of two possible states, alive or dead.
  for (let y = 0; y < h; ++y) {
    let ym1 = y == 0 ? hm1 : y - 1,
        yp1 = y == hm1 ? 0 : y + 1;
    for (let x = 0; x < w; ++x) {
      let xm1 = x == 0 ? wm1 : x - 1,
          xp1 = x == wm1 ? 0 : x + 1;

      // Every cell interacts with its eight neighbours, which are the cells that are horizontally,
      // vertically, or diagonally adjacent. Least significant bit indicates alive or dead.
      let aliveNeighbors = (
        (get(xm1, ym1) & 1) + (get(x, ym1) & 1) + (get(xp1, ym1) & 1) +
        (get(xm1, y  ) & 1)                     + (get(xp1, y  ) & 1) +
        (get(xm1, yp1) & 1) + (get(x, yp1) & 1) + (get(xp1, yp1) & 1)
      );

      let self = get(x, y);
      if (self & 1) {
        // A live cell with 2 or 3 live neighbors rots on to the next generation.
        if ((aliveNeighbors & 0b1110) == 0b0010) rot(x, y, self);
        // A live cell with fewer than 2 or more than 3 live neighbors dies.
        else set(x, y, BGR_DEAD | 0xff000000);
      } else {
        // A dead cell with exactly 3 live neighbors becomes a live cell.
        if (aliveNeighbors == 3) set(x, y, BGR_ALIVE | 0xff000000);
        // A dead cell with fewer or more than 3 live neighbors just rots.
        else rot(x, y, self);
      }
    }
  }
}

/** Fills the row and column indicated by `x` and `y` with random live cells. */
export function fill(x: u32, y: u32, p: f64): void {
  for (let ix = 0; ix < width; ++ix) {
    if (Math.random() < p) set(ix, y, BGR_ALIVE | 0xff000000);
  }
  for (let iy = 0; iy < height; ++iy) {
    if (Math.random() < p) set(x, iy, BGR_ALIVE | 0xff000000);
  }
}

#!html
<canvas id="canvas" style="width: 100%; height: 100%; background: #000; cursor: crosshair"></canvas>
<script>
// Configuration
const RGB_ALIVE = 0xD392E6;
const RGB_DEAD  = 0xA61B85;
const BIT_ROT   = 10;

// Set up the canvas with a 2D rendering context
const canvas = document.getElementById("canvas");
const boundingRect = canvas.getBoundingClientRect();
const ctx = canvas.getContext("2d");

// Compute the size of the universe (2 pixels per cell)
const width = boundingRect.width >>> 1;
const height = boundingRect.height >>> 1;
const size = width * height;
const byteSize = (size + size) << 2; // input & output (4 bytes per cell)

canvas.width = width;
canvas.height = height;
canvas.style.imageRendering = "pixelated";
ctx.imageSmoothingEnabled = false;

// Compute the size of and instantiate the module's memory
const memory = new WebAssembly.Memory({ initial: ((byteSize + 0xffff) & ~0xffff) >>> 16 });

// Fetch and instantiate the module
loader.instantiate(module_wasm, {
  env: {
    memory
  },
  module: {
    BGR_ALIVE : rgb2bgr(RGB_ALIVE) | 1, // LSB set indicates alive
    BGR_DEAD  : rgb2bgr(RGB_DEAD) & ~1, // LSB not set indicates dead
    BIT_ROT
  }
}).then(({ exports }) => {
  // Initialize the module with the universe's width and height
  exports.init(width, height);

  var buffer = new Uint32Array(memory.buffer);

  // Update about 30 times a second
  (function update() {
    setTimeout(update, 1000 / 30);
    buffer.copyWithin(0, size, size + size);   // copy output to input
    exports.step();                            // perform the next step
  })();

  // Keep rendering the output at [size, 2*size]
  var imageData = ctx.createImageData(width, height);
  var argb = new Uint32Array(imageData.data.buffer);
  (function render() {
    requestAnimationFrame(render);
    argb.set(buffer.subarray(size, size + size)); // copy output to image buffer
    ctx.putImageData(imageData, 0, 0);            // apply image buffer
  })();

  // When clicked or dragged, fill the current row and column with random live cells
  var down = false;
  [ [canvas, "mousedown"],
    [canvas, "touchstart"]
  ].forEach(eh => eh[0].addEventListener(eh[1], e => down = true));
  [ [document, "mouseup"],
    [document, "touchend"]
  ].forEach(eh => eh[0].addEventListener(eh[1], e => down = false));
  [ [canvas, "mousemove"],
    [canvas, "touchmove"],
    [canvas, "mousedown"]
  ].forEach(eh => eh[0].addEventListener(eh[1], e => {
    if (!down) return;
    var loc;
    if (e.touches) {
      if (e.touches.length > 1) return;
      loc = e.touches[0];
    } else {
      loc = e;
    }
    const currentBoundingRect = canvas.getBoundingClientRect();
    exports.fill(
      ((loc.clientX - currentBoundingRect.left) / currentBoundingRect.width * boundingRect.width) >>> 1,
      ((loc.clientY - currentBoundingRect.top) / currentBoundingRect.height * boundingRect.height) >>> 1,
      0.5
    );
  }));
});

/** Bitshifts an RGB color to BGR instead (WebAssembly is little endian). */
function rgb2bgr(rgb) {
  return ((rgb >>> 16) & 0xff) | (rgb & 0xff00) | (rgb & 0xff) << 16;
}
</script>
```

::: tip NOTE
The example makes a couple assumptions. For instance, using the entire memory of the program as the image buffer as in this example is only possible because we know that no interferring static memory segments will be created, which is achieved by

* using JavaScript's Math instead of native libm (usually adds lookup tables),
* not using a more sophisticated runtime (typically adds bookkeeping) and
* the rest of the example being relatively simple (i.e. no strings or similar).

As soon as these conditions are no longer met, one would instead either reserve some space by specifying a suitable `--memoryBase` or export a dynamically instantiated chunk of memory, like an `Uint32Array`, and utilize it as the input and output image buffers both in WebAssembly and in JavaScript.
:::

## Running locally

Instructions are identical to [those of the Mandelbrot example](./mandelbrot.md#running-locally).

---

## File: src/examples/interference.md

---
---

# Interference example

Colin Eberhardt's and Ben Smith's [WebAssembly interference effect](https://github.com/ColinEberhardt/wasm-interference), if it was written in AssemblyScript.

## Contents

* Exporting functions and variables from a WebAssembly module.
* Calling functions and reading variables exported from WebAssembly.
* Utilizing 32-bit floating point math to speed up calculations by utilizing `Mathf`.
* Keeping an image buffer within the module's memory and copying it to a canvas.
* Manually growing memory depending on the size of the viewport on the browser side.
* And finally: Continuously updating and rendering the image buffer.

## Example

::: danger EPILEPSY WARNING
A very small percentage of individuals may experience epileptic seizures when exposed to certain light patterns or flashing lights. Exposure to certain patterns or backgrounds on a computer screen may induce an epileptic seizure in these individuals. Certain conditions may induce previously undetected epileptic symptoms even in persons who have no history of prior seizures or epilepsy.

If you experience any of the following symptoms while viewing - dizziness, altered vision, eye or muscle twitches, loss of awareness, disorientation, any involuntary movement, or convulsions - IMMEDIATELY discontinue use and consult your physician.
:::

```editor
#!optimize=speed&runtime=stub
var width  = 320;
var height = 200;

// Let's utilize the entire heap as our image buffer
export const offset = __heap_base;

/** Sets a single pixel's color. */
function set(x: i32, y: i32, v: f32): void {
  var vi = <i32>v;
  store<i32>(offset + ((width * y + x) << 2), ~vi << 24 | vi << 8);
}

/** Computes the distance between two pixels. */
function distance(x1: i32, y1: i32, x2: f32, y2: f32): f32 {
  var dx = <f32>x1 - x2;
  var dy = <f32>y1 - y2;
  return Mathf.sqrt(dx * dx + dy * dy);
}

/** Performs one tick. */
export function update(tick: f32): void {
  var w = <f32>width;
  var h = <f32>height;
  var hw = w * 0.5,
      hh = h * 0.5;
  var cx1 = (Mathf.sin(tick * 2) + Mathf.sin(tick      )) * hw * 0.3 + hw,
      cy1 = (Mathf.cos(tick)                            ) * hh * 0.3 + hh,
      cx2 = (Mathf.sin(tick * 4) + Mathf.sin(tick + 1.2)) * hw * 0.3 + hw,
      cy2 = (Mathf.sin(tick * 3) + Mathf.cos(tick + 0.1)) * hh * 0.3 + hh;
  var res = <f32>48 / Mathf.max(w, h);
  var y = 0;
  do {
    let x = 0;
    do {
      set(x, y, Mathf.abs(
        Mathf.sin(distance(x, y, cx1, cy1) * res) +
        Mathf.sin(distance(x, y, cx2, cy2) * res)
      ) * 120);
    } while (++x != width)
  } while (++y != height)
}

/** Recomputes and potentially grows memory on resize of the viewport. */
export function resize(w: i32, h: i32): void {
  width = w; height = h;
  // Pages are 64kb. Rounds up using mask 0xffff before shifting to pages.
  var needed = <i32>((offset + (w * h * sizeof<i32>() + 0xffff)) & ~0xffff) >>> 16;
  var actual = memory.size();
  if (needed > actual) memory.grow(needed - actual);
}

#!html
<canvas id="canvas" style="width: 100%; height: 100%; background: #aff"></canvas>
<script>
var step = 0.012;
loader.instantiate(module_wasm).then(({ exports }) => {
  const canvas = document.getElementById("canvas");
  const context = canvas.getContext("2d");

  // Upscale the image to speed up calculations
  const upscaleFactor = 4;

  var width, height, image;

  // Inform the module about the viewport's size, incl. on resize
  function onresize() {
    width = (canvas.offsetWidth / upscaleFactor) | 0;
    height = (canvas.offsetHeight / upscaleFactor) | 0;
    canvas.width = width;
    canvas.height = height;
    image = context.createImageData(width, height);
    exports.resize(width, height);
  }
  onresize();
  new ResizeObserver(onresize).observe(canvas);

  // Keep updating the image
  var tick = 0.0;
  (function update() {
    requestAnimationFrame(update);
    exports.update(tick += step);
    new Uint32Array(image.data.buffer).set(new Uint32Array(exports.memory.buffer, exports.offset, width * height));
    context.putImageData(image, 0, 0);
  })();
});
</script>
```

::: tip NOTE
The example makes one important assumption: Since we are not using a sophisticated runtime, we can instead repurpose the entire heap, starting at `__heap_base`, as our image buffer.

As soon as this condition is no longer met, one would instead either reserve some space by specifying a suitable `--memoryBase` or export a dynamically instantiated chunk of memory, like an `Uint32Array`, and utilize it as the image buffer both in WebAssembly and in JavaScript.
:::


## Running locally

Set up a new AssemblyScript project as described in [Quick start](../quick-start.md) and copy `module.ts` to `assembly/index.ts` and `index.html` to the project's top-level directory. Edit the build commands in `package.json` to include

```
--runtime none
```

The example can now be compiled with

```sh
npm run asbuild
```

To view the example, one can modify the instantiation in `index.html` from

```js
loader.instantiate(module_wasm).then(({ exports }) => {
```

to

```js
WebAssembly.instantiateStreaming(fetch('./build/optimized.wasm'), {
  JSMath: Math
}).then(({ exports }) => {
```

because using the [loader](../loader.md) is not ultimately necessary here (no managed objects are exchanged). If the loader is used instead, it will automatically provide `JSMath`.

Some browsers may restrict `fetch`ing local resources when just opening `index.html` now, but one can set up a local server as a workaround:

```sh
npm install --save-dev http-server
http-server . -o -c-1
```

---

## File: src/examples/mandelbrot.md

---
---

# Mandelbrot example

Renders the [Mandelbrot set](https://en.wikipedia.org/wiki/Mandelbrot_set) to a canvas using 2048 discrete color values computed on the JS side.

## Contents

* Exporting functions from a WebAssembly module.
* Calling functions exported from WebAssembly.
* Instantiating the module's memory in JavaScript and import it using `--importMemory`.
* Utilizing JavaScript's `Math` instead of native libm to reduce module size via `--use Math=JSMath`.
* And finally: Reading and translating data from WebAssembly memory to colors rendered to a canvas.

## Example

```editor
#!optimize=speed&runtime=stub&importMemory&use=Math=JSMath
/** Number of discrete color values on the JS side. */
const NUM_COLORS = 2048;

/** Updates the rectangle `width` x `height`. */
export function update(width: u32, height: u32, limit: u32): void {
  var translateX = width  * (1.0 / 1.6);
  var translateY = height * (1.0 / 2.0);
  var scale      = 10.0 / min(3 * width, 4 * height);
  var realOffset = translateX * scale;
  var invLimit   = 1.0 / limit;

  var minIterations = min(8, limit);

  for (let y: u32 = 0; y < height; ++y) {
    let imaginary = (y - translateY) * scale;
    let yOffset   = (y * width) << 1;

    for (let x: u32 = 0; x < width; ++x) {
      let real = x * scale - realOffset;

      // Iterate until either the escape radius or iteration limit is exceeded
      let ix = 0.0, iy = 0.0, ixSq: f64, iySq: f64;
      let iteration: u32 = 0;
      while ((ixSq = ix * ix) + (iySq = iy * iy) <= 4.0) {
        iy = 2.0 * ix * iy + imaginary;
        ix = ixSq - iySq + real;
        if (iteration >= limit) break;
        ++iteration;
      }

      // Do a few extra iterations for quick escapes to reduce error margin
      while (iteration < minIterations) {
        let ixNew = ix * ix - iy * iy + real;
        iy = 2.0 * ix * iy + imaginary;
        ix = ixNew;
        ++iteration;
      }

      // Iteration count is a discrete value in the range [0, limit] here, but we'd like it to be
      // normalized in the range [0, 2047] so it maps to the gradient computed in JS.
      // see also: http://linas.org/art-gallery/escape/escape.html
      let colorIndex = NUM_COLORS - 1;
      let distanceSq = ix * ix + iy * iy;
      if (distanceSq > 1.0) {
        let fraction = Math.log2(0.5 * Math.log(distanceSq));
        colorIndex = <u32>((NUM_COLORS - 1) * clamp<f64>((iteration + 1 - fraction) * invLimit, 0.0, 1.0));
      }
      store<u16>(yOffset + (x << 1), colorIndex);
    }
  }
}

/** Clamps a value between the given minimum and maximum. */
function clamp<T>(value: T, minValue: T, maxValue: T): T {
  return min(max(value, minValue), maxValue);
}

#!html
<canvas id="canvas" style="width: 100%; height: 100%"></canvas>
<script>

// Set up the canvas with a 2D rendering context
const canvas = document.getElementById("canvas");
const boundingRect = canvas.getBoundingClientRect();
const ctx = canvas.getContext("2d");

// Compute the size of the viewport
const ratio  = window.devicePixelRatio || 1;
const width  = (boundingRect.width  | 0) * ratio;
const height = (boundingRect.height | 0) * ratio;
const size = width * height;
const byteSize = size << 1; // discrete color indices in range [0, 2047] (2 bytes per pixel)

canvas.width  = width;
canvas.height = height;

ctx.scale(ratio, ratio);

// Compute the size (in pages) of and instantiate the module's memory.
// Pages are 64kb. Rounds up using mask 0xffff before shifting to pages.
const memory = new WebAssembly.Memory({ initial: ((byteSize + 0xffff) & ~0xffff) >>> 16 });
const buffer = new Uint16Array(memory.buffer);
const imageData = ctx.createImageData(width, height);
const argb = new Uint32Array(imageData.data.buffer);

loader.instantiate(module_wasm, {
  env: {
    memory
  }
}).then(({ exports }) => {

  // Update state
  exports.update(width, height, 40);

  // Translate 16-bit color indices to colors
  for (let y = 0; y < height; ++y) {
    const yx = y * width;
    for (let x = 0; x < width; ++x) {
      argb[yx + x] = colors[buffer[yx + x]];
    }
  }

  // Render the image buffer.
  ctx.putImageData(imageData, 0, 0);
});

/** Computes a nice set of colors using a gradient. */
function computeColors() {
  const canvas = document.createElement("canvas");
  canvas.width = 2048;
  canvas.height = 1;
  const ctx = canvas.getContext("2d");
  const grd = ctx.createLinearGradient(0, 0, 2048, 0);
  grd.addColorStop(0.00, "#000764");
  grd.addColorStop(0.16, "#2068CB");
  grd.addColorStop(0.42, "#EDFFFF");
  grd.addColorStop(0.6425, "#FFAA00");
  grd.addColorStop(0.8575, "#000200");
  ctx.fillStyle = grd;
  ctx.fillRect(0, 0, 2048, 1);
  return new Uint32Array(ctx.getImageData(0, 0, 2048, 1).data.buffer);
}

const colors = computeColors();
</script>
```

::: tip NOTE
The example makes a couple assumptions. For instance, using the entire memory of the program as the image buffer as in this example is only possible because we know that no interferring static memory segments will be created, which is achieved by

* using JavaScript's Math instead of native libm (usually adds lookup tables),
* not using a more sophisticated runtime (typically adds bookkeeping) and
* the rest of the example being relatively simple (i.e. no strings or similar).

As soon as these conditions are no longer met, one would instead either reserve some space by specifying a suitable `--memoryBase` or export a dynamically instantiated chunk of memory, like an `Uint16Array`, and utilize it as the color index buffer both in WebAssembly and in JavaScript.
:::

## Running locally

Set up a new AssemblyScript project as described in [Quick start](../quick-start.md) and copy `module.ts` to `assembly/index.ts` and `index.html` to the project's top-level directory. Edit the build commands in `package.json` to include

```
--runtime none --use Math=JSMath --importMemory
```

The example can now be compiled with

```sh
npm run asbuild
```

To view the example, one can modify the instantiation in `index.html` from

```js
loader.instantiate(module_wasm, {
  env: {
    memory
  }
}).then(({ exports }) => {
```

to

```js
WebAssembly.instantiateStreaming(fetch('./build/optimized.wasm'), {
  env: {
    memory
  },
  JSMath: Math
}).then(({ exports }) => {
```

because using the [loader](../loader.md) is not ultimately necessary here (no managed objects are exchanged). If the loader is used instead, it will automatically provide `JSMath`.

Some browsers may restrict `fetch`ing local resources when just opening `index.html` now, but one can set up a local server as a workaround:

```sh
npm install --save-dev http-server
http-server . -o -c-1
```

---

## File: src/examples/snippets.md

# Snippets

Small, copy-pastable AssemblyScript examples using common syntax and patterns.

## Class

An AssemblyScript snippet on using Classes, their instantiation, and their static properties.

```editor
#!runtime=stub
class Animal<T> {
  static ONE: i32 = 1;
  static add(a: i32, b: i32): i32 { return a + b + Animal.ONE; }

  two: i16 = 2; // 6
  instanceSub<T>(a: T, b: T): T { return a - b + <T>Animal.ONE; } // tsc does not allow this
}

export function staticOne(): i32 {
  return Animal.ONE;
}

export function staticAdd(a: i32, b: i32): i32 {
  return Animal.add(a, b);
}

export function instanceTwo(): i32 {
  let animal = new Animal<i32>();
  return animal.two;
}

export function instanceSub(a: f32, b: f32): f32 {
  let animal = new Animal<f32>();
  return animal.instanceSub<f32>(a, b);
}


#!html
<script>
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

loader.instantiate(module_wasm, { /* imports */ })
  .then(({ exports }) => {
    console.log(exports.staticOne());
    console.log(exports.staticAdd(1, 2));
    console.log(exports.instanceTwo());
    console.log(exports.instanceSub(3.0, 1.0));
  })
</script>
```

## Extending Classes

Extending classes and general Object Orientated Programming (OOP) in AssemblyScript

```editor
#!runtime=stub

class BaseClass {
  static staticProp: i32 = 24;
  instanceProp: i32;

  constructor(value: i32) {
    this.instanceProp = value;
  }

  add(a: i32, b: i32): i32 {
    return a + b;
  }
}

class ExtendedClass extends BaseClass {

  extendedProp: i32;

  constructor(extendedValue: i32) {
    super(1);

    this.extendedProp = extendedValue;
  }

  add(a: i32): i32 {
    return super.add(a, this.extendedProp + super.instanceProp);
  }
}

export function getStaticProp(): i32 {
  return ExtendedClass.staticProp;
}

export function overloadAdd(value: i32): i32 {
  let extendedClass = new ExtendedClass(value);
  return extendedClass.add(24);
}

#!html
<script>
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg === 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

loader.instantiate(module_wasm, { /* imports */ })
.then(({ exports }) => {
  console.log(`getStaticProp: ${exports.getStaticProp()}`);
  console.log(`overloadAdd: ${exports.overloadAdd(24)}`);
})
</script>
```

## Handling Null

Handling Null as a union type for optional return values and simulating `try/catch` for errors in AssemblyScript

```editor
#!runtime=stub
class MyValue {
  value: i32;

  constructor(value: i32) {
    this.value = value;
  }
}

// Using a class type here, as some types are not nullable
function getMyValue(isAble: boolean): MyValue | null {
  let myValue = new MyValue(24);
  if (isAble) {
    return myValue;
  } else {
    return null;
  }
}

export function positiveAddWithMyValue(a: i32): i32 {
  let myValue = getMyValue(a > 0);
  if (myValue == null) {
    return -1;
  } else {
    return a + myValue.value;
  }
}

#!html
<script>
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

loader.instantiate(module_wasm, { /* imports */ })
.then(({ exports }) => {
  if(exports.positiveAddWithMyValue(24) > -1) {
    console.log("Add was successful")
  } else {
    console.log("Could not add 24");
  }

  if(exports.positiveAddWithMyValue(-1) > -1) {
  console.log("Add was successful")
  } else {
  console.log("Could not add -1");
  }
});
</script>
```

## Switch Case

Using `switch case` statements in AssemblyScript.

::: tip NOTE
Currently, the switch conditions (case values) are implicitly converted to u32, i.e. switching over strings or similar is not yet supported.
:::

```editor
#!runtime=stub
export function switchSurprise(a: i32): i32 {
  let response = -1;

  // Using a mix of braces and not using braces
  // to show that both syntaxes are supported here.
  switch (a) {
    case 1:
      response = 100;
      break;
    case 2: {   // Cases can also use braces
      response = 200;
      break;
    }
    case 3:
      // Fall Through to the next case
    case 4:
      response = 400;
      break;
    default: {
      response = 0;
    }
  }

  return response;
}

#!html
<script>
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

loader.instantiate(module_wasm, { /* imports */ })
.then(({ exports }) => {
  console.log(`switchSurprise(1) : ${exports.switchSurprise(1)}`);
  console.log(`switchSurprise(2) : ${exports.switchSurprise(2)}`);
  console.log(`switchSurprise(3) : ${exports.switchSurprise(3)}`);
  console.log(`switchSurprise(4) : ${exports.switchSurprise(4)}`);
  console.log(`switchSurprise(57) : ${exports.switchSurprise(57)}`);
});
</script>
```

## Ternary if-else

Using Ternary if-else in AssemblyScript

```editor
#!runtime=stub
export function isTrue(a: i32): i32 {
  let response = a > 0 ? 1 : 0;
  return response;
}

#!html
<script>
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

loader.instantiate(module_wasm, { /* imports */ })
.then(({ exports }) => {
  console.log(`is 24 greater than 0? ${exports.isTrue(24) > 0 ? true : false}`);
  console.log(`is -3 greater than 0? ${exports.isTrue(-3) > 0 ? true : false}`);
});
</script>
```

---

## File: src/stdlib/array.md

---
---

# Array

A randomly accessible sequence of values of a generic type.

The Array API is very similar to JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)\), with the notable difference that one must make sure that there are no `null`  values if `T` is a non-nullable reference type. Example:

```ts
var arr = new Array<string>(10)
// arr[0]; // would error 😢
for (let i = 0; i < arr.length; ++i) {
  arr[i] = ""
}
arr[0]; // now it works 😊
```

## Constructor

* ```ts
  new Array<T>(capacity?: i32)
  ```
  Constructs a new array.

## Static members

* ```ts
  function isArray<U>(value: U): bool
  ```
  Tests if a value is an array.

## Instance members

### Fields

* ```ts
  var length: i32
  ```
  The length of this array. Setting the length to a value larger than internal capacity will automatically grow the array.

### Methods

* ```ts
  function concat(other: Array<T>): Array<T>
  ```
  Concatenates the values of this and the other array to a new array, in this order.

* ```ts
  function copyWithin(target: i32, start: i32, end?: i32): this
  ```
  Copies a region of an array's values over the respective values starting at the target location.

* ```ts
  function every(fn: (value: T, index: i32, array: Array<T>) => bool): bool
  ```
  Calls the specified function with every value of the array until it finds the first value for which the function returns `false`. Returns `true` if all functions returned `true` or the array is empty, otherwise `false`.

* ```ts
  function fill(value: T, start?: i32, end?: i32): this
  ```
  Replaces the values of the array from `start` inclusive to `end` exclusive in place with the specified value, returning the array.

* ```ts
  function filter(fn: (value: T, index: i32, array: Array<T>) => bool): Array<T>
  ```
  Calls the specified function with every value of the array, returning a new array with all values for which the function returned `true`.

* ```ts
  function findIndex(fn: (value: T, index: i32, array: Array<T>) => bool): i32
  ```
  Calls the specified function with every value of the array until it finds the first value for which the function returns `true`, returning its index. Returns `-1` if that's never the case.

* ```ts
  function flat(): valueof<T>[]
  ```
  Flattens an array of arrays to a one-dimensional array. `null` entries are ignored.

* ```ts
  function forEach(fn: (value: T, index: i32, array: Array<T>) => void): void
  ```
  Calls the specified function with every value of the array.

* ```ts
  function includes(value: T, fromIndex?: i32): bool
  ```
  Tests if the array includes the specified value, optionally providing a starting index.

* ```ts
  function indexOf(value: T, fromIndex?: i32): i32
  ```
  Gets the first index where the specified value can be found in the array. Returns `-1` if not found.

* ```ts
  function join(separator?: string): string
  ```
  Concatenates all values of the array to a string, separated by the specified separator \(default: `,`\).

* ```ts
  function lastIndexOf(value: T, fromIndex?: i32): i32
  ```
  Gets the last index where the specified value can be found in the array. Returns `-1` if not found.

* ```ts
  function map<U>(fn: (value: T, index: i32, array: Array<T>) => U): Array<U>
  ```
  Calls the specified function with every value of the array, returning a new array of the function's return values.

* ```ts
  function pop(): T
  ```
  Removes and returns the last value of the array. Modifies `Array#length`.

* ```ts
  function push(value: T): i32
  ```
  Adds one more value to the end of the array and returns the Array's new length. Modifies `Array#length`.

* ```ts
  function reduce<U>(
    fn: (acc: U, cur: T, idx: i32, src: Array) => U,
    initialValue: U
  ): U
  ```
  Calls the specified reducer function with each value of the array, resulting in a single return value. The respective previous reducer function's return value is remembered in `acc`, starting with `initialValue`, becoming the final return value in the process.

* ```ts
  function reduceRight<U>(
    fn: (acc: U, cur: T, idx: i32, src: Array) => U,
    initialValue: U
  ): U
  ```
  Calls the specified reducer function with each value of the array, from right to left, resulting in a single return value. See `Array#reduce` for the reducer function's signature.

* ```ts
  function reverse(): this
  ```
  Reverses an array's values in place, modifying the array before returning it.

* ```ts
  function shift(): T
  ```
  Removes and returns the first value of the array. Modifies `Array#length`.

* ```ts
  function slice(start?: i32, end?: i32): Array<T>
  ```
  Returns a shallow copy of the array's values from `begin` inclusive to `end` exclusive, as a new array. If omitted, `end` defaults to the end of the array.

* ```ts
  function some(fn: (value: T, index: i32, array: Array<T>) => bool): bool
  ```
  Calls the specified function with every value of the array until it finds the first value for which the function returns `true`, returning `true`. Returns `false` otherwise or if the array is empty.

* ```ts
  function sort(fn?: (a: T, b: T) => i32): this
  ```
  Sorts the values of the array in place, using the specified comparator function, modifying the array before returning it. The comparator returning a negative value means `a < b`, a positive value means `a > b` and `0` means that both are equal. Unlike in JavaScript, where an implicit conversion to strings is performed, the comparator defaults to compare two values of type `T`.

* ```ts
  function splice(start: i32, deleteCount?: i32): Array<T>
  ```
  Removes `deleteCount` \(defaults to all remaining\) values from the array, starting at index `start`, modifying the array in place, returning the removed values.

* ```ts
  function toString(): string
  ```
  Returns the result of `Array#join()`.

* ```ts
  function unshift(value: T): i32
  ```
  Adds one more value to the start of the array and returns the Array's new length. Modifies `Array#length`.

---

## File: src/stdlib/arraybuffer.md

---
---

# ArrayBuffer

A fixed-length raw binary buffer.

The ArrayBuffer API is exactly as in JavaScript \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)\).

## Constructor

* ```ts
  new ArrayBuffer(length: i32)
  ```
  Constructs a new buffer of the given length in bytes.

## Static members

* ```ts
  function isView<T>(value: T): bool
  ```
  Returns true if `value` is one of the buffer views, such as one of the [typed arrays](./typedarray.md) or a [DataView](./dataview.md).

## Instance members

### Fields

* ```ts
  readonly byteLength: i32
  ```
  The buffer's length, in bytes.

### Methods

* ```ts
  function slice(begin?: i32, end?: i32): ArrayBuffer
  ```
  Returns a copy of this buffer from begin, inclusive, up to end, exclusive.

* ```ts
  function toString(): string
  ```
  Returns a string representation of this buffer.

---

## File: src/stdlib/console.md

---
---

# console

An implementation of the `console` global on top of WASI. Requires a WASI-enabled host and opting into WASI in the entry file with

```ts
import "wasi";
```

## Static members

* ```ts
  function assert<T>(assertion: T, message: string): void
  ```
  Logs `message` to console if `assertion` is false-ish.

* ```ts
  function log(message: string): void
  ```
  Outputs `message` to the console.

* ```ts
  function debug(message: string): void
  function info(message: string): void
  function warn(message: string): void
  function error(message: string): void
  ```
  Outputs `message` to the console, prefixed with "Debug:", "Info:", "Warning:" or "Error:" respectively.

* ```ts
  function time(label: string): void
  ```
  Starts a new timer using the specified `label`.

* ```ts
  function timeLog(label: string): void
  ```
  Logs the current value of a timer previously started with `console.time`.

* ```ts
  function timeEnd(label: string): void
  ```
  Logs the current value of a timer previously started with `console.time` and discards the timer.

---

## File: src/stdlib/crypto.md

---
---

# crypto

An implementation of the `crypto` global on top of WASI. Requires a WASI-enabled host and opting into WASI in the entry file with

```ts
import "wasi";
```

## Static members

* ```ts
  function getRandomValues(array: Uint8Array): void
  ```
  Fills `array` with cryptographically strong random values.

---

## File: src/stdlib/dataview.md

---
---

# DataView

An interface for working with a raw binary buffer.

The DataView API is exactly as in JavaScript \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView)\).

## Constructor

* ```ts
  new DataView(buffer: ArrayBuffer, byteOffset?: i32, byteLength?: i32)
  ```
  Constructs a new DataView on the specified buffer and region.

## Instance members

### Fields

* ```ts
  readonly buffer: ArrayBuffer
  ```
  The backing buffer.

* ```ts
  readonly byteLength: i32
  ```
  The length of this view from the start of its buffer.

* ```ts
  readonly byteOffset: i32
  ```
  The offset of this view from the start of its buffer.

### Methods

* ```ts
  function getFloat32(byteOffset: i32, littleEndian?: bool): f32
  ```
  Gets the 32-bit float value at the specified offset from the start of the view.

* ```ts
  function getFloat64(byteOffset: i32, littleEndian?: bool): f64
  ```
  Gets the 64-bit float value at the specified offset from the start of the view.

* ```ts
  function getInt8(byteOffset: i32): i8
  ```
  Gets the signed 8-bit integer value at the specified offset from the start of the view.

* ```ts
  function getInt16(byteOffset: i32, littleEndian?: bool): i16
  ```
  Gets the signed 16-bit integer value at the specified offset from the start of the view.

* ```ts
  function getInt32(byteOffset: i32, littleEndian?: bool): i32
  ```
  Gets the signed 32-bit integer value at the specified offset from the start of the view.

* ```ts
  function getInt64(byteOffset: i32, littleEndian?: bool): i64
  ```
  Gets the signed 64-bit integer value at the specified offset from the start of the view.

* ```ts
  function getUint8(byteOffset: i32, littleEndian?: bool): u8
  ```
  Gets the unsigned 8-bit integer value at the specified offset from the start of the view.

* ```ts
  function getUint16(byteOffset: i32, littleEndian?: bool): u16
  ```
  Gets the unsigned 16-bit integer value at the specified offset from the start of the view.

* ```ts
  function getUint32(byteOffset: i32, littleEndian?: bool): u32
  ```
  Gets the unsigned 32-bit integer value at the specified offset from the start of the view.

* ```ts
  function getUint64(byteOffset: i32, littleEndian?: bool): u64
  ```
  Gets the unsigned 64-bit integer value at the specified offset from the start of the view.

* ```ts
  function setFloat32(byteOffset: i32, value: f32, littleEndian?: bool): void
  ```
  Sets the 32-bit float value at the specified offset from the start of the view.

* ```ts
  function setFloat64(byteOffset: i32, value: f64, littleEndian?: bool): void
  ```
  Sets the 64-bit float value at the specified offset from the start of the view.

* ```ts
  function setInt8(byteOffset: i32, value: i8): void
  ```
  Sets the signed 8-bit integer value at the specified offset from the start of the view.

* ```ts
  function setInt16(byteOffset: i32, value: i16, littleEndian?: bool): void
  ```
  Sets the signed 16-bit integer value at the specified offset from the start of the view.

* ```ts
  function setInt32(byteOffset: i32, value: i32, littleEndian?: bool): void
  ```
  Sets the signed 32-bit integer value at the specified offset from the start of the view.

* ```ts
  function setInt64(byteOffset: i32, value: i64, littleEndian?: bool): void
  ```
  Sets the signed 64-bit integer value at the specified offset from the start of the view.

* ```ts
  function setUint8(byteOffset: i32, value: u8, littleEndian?: bool): void
  ```
  Sets the unsigned 8-bit integer value at the specified offset from the start of the view.

* ```ts
  function setUint16(byteOffset: i32, value: u16, littleEndian?: bool): void
  ```
  Sets the unsigned 16-bit integer value at the specified offset from the start of the view.

* ```ts
  function setUint32(byteOffset: i32, value: u32, littleEndian?: bool): void
  ```
  Sets the unsigned 32-bit integer value at the specified offset from the start of the view.

* ```ts
  function setUint64(byteOffset: i32, value: u64, littleEndian?: bool): void
  ```
  Sets the unsigned 64-bit integer value at the specified offset from the start of the view.

* ```ts
  function toString(): string
  ```
  Returns a string representation of this object.

Endianness defaults to `littleEndian = false`.

---

## File: src/stdlib/date.md

---
---

# Date

Represents timestamps.

The Date API is still preliminary and requires importing the `Date` object from the host \(as `Date`\).

## Constructor

* ```ts
  new Date(value: i64)
  ```
  Constructs a new date object from an UTC timestamp in milliseconds.

## Static members

* ```ts
  function now(): i64
  ```
  Returns the current UTC timestamp in milliseconds.

* ```ts
  function UTC(
    year: i32,
    month?: i32,
    day?: i32,
    hour?: i32,
    minute?: i32,
    second?: i32,
    millisecond?: i64
  ): i64
  ```
  Returns the UTC timestamp in milliseconds of the specified date.

## Instance members

* ```ts
  function getTime(): i64
  ```
  Gets the UTC timestamp of this date in milliseconds.

* ```ts
  function setTime(value: i64): i64
  ```
  Sets the UTC timestamp of this date in milliseconds and returns the timestamp.

---

## File: src/stdlib/error.md

---
---

# Error

Represents a runtime error.

The Error API is very similar to JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)\), with some properties not being implemented yet.

## Variants

| Variant     | Description
| :---------- | :----------
| Error       | Represents a general error.
| RangeError  | Represents an error where a value is not in the range of allowed values.
| TypeError   | Represents an error where a value is not of the expected type.
| SyntaxError | Represents an error where the syntax of the input in invalid.

The `Error`class can also be sub-classed by forwarding `message` and setting the `name` property in the overloaded constructor.

## Constructor

* ```ts
  new Error(message?: string)
  ```
  Constructs a new error object.

## Instance members

### Fields

* ```ts
  var message: string
  ```
  The message of this error.

* ```ts
  var name: string
  ```
  The name of this error. In case of `Error`, this is `"Error"`.

* ```ts
  var stack: string
  ```
  The stack trace of this error. Not supported yet, hence an empty string.

### Methods

* ```ts
  function toString(): string
  ```
  Returns a string representation of this error in the form `name: message`.

---

## File: src/stdlib/globals.md

---
---

# Globals

In addition to the [general environment with its WebAssembly-focused built-ins](../environment.md), the following global constants and functions are present alongside the standard library's classes.

## Constants

* ```ts
  const NaN: auto // f32 or f64
  ```
  Not a number as a 32-bit or 64-bit float depending on context. Compiles to a constant.

* ```ts
  const Infinity: auto // f32 or f64
  ```
  Positive infinity as a 32-bit or 64-bit float depending on context. Compiles to a constant.

## Functions

* ```ts
  function isNaN<T>(value: T): bool
  ```
  Tests if a 32-bit or 64-bit float is `NaN`.

* ```ts
  function isFinite<T>(value: T): bool
  ```
  Tests if a 32-bit or 64-bit float is finite, that is not `NaN` or +/-`Infinity`.

* ```ts
  function parseInt(str: string, radix?: i32): i64
  ```
  Parses a string to a 64-bit integer. Returns `0` on invalid inputs.

* ```ts
  function parseFloat(str: string): f64
  ```
  Parses a string to a 64-bit float. Returns `NaN` on invalid inputs.

---

## File: src/stdlib/map.md

---
---

# Map

A mapping of generic keys to generic values.

The Map API is very similar to JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)\), with the notable difference that a `.get` with a key that does not exist results in an error, because `undefined` cannot be represented. Example:

```ts
var map = new Map<i32,string>()

// Because `undefined` cannot be represented if a key is not found, this will error:
var str = map.get(1) // ERROR

// The error can be avoided by first making sure that the key exists, so this works:
var str: string | null = map.has(1) ? map.get(1) : null // OK
```

## Constructor

* ```ts
  new Map<K,V>()
  ```
  Constructs a new map mapping keys of type `K` to values of type `V`.

## Instance members

### Fields

* ```ts
  readonly size: i32
  ```
  The current number of key-value pairs in this map.

### Methods

* ```ts
  function clear(): void
  ```
  Clears the map, deleting all key-value pairs.

* ```ts
  function delete(key: K): bool
  ```
  Deletes the key-value pair for the corresponding key. Returns `true` if the key did exist, otherwise `false`.

* ```ts
  function get(key: K): V
  ```
  Gets the value corresponding to the specified key. Traps if the key does not exist because "not found" cannot be represented in all cases \(use `Map#has` to check\).

* ```ts
  function has(key: K): bool
  ```
  Tests if the specified key exists.

* ```ts
  function keys(): Array<K>
  ```
  Gets the keys contained in this map as an array, in insertion order. This is preliminary while iterators are not supported.

* ```ts
  function set(key: K, value: V): this
  ```
  Sets the value for the specified key. Creates a new key-value pair if the key did not exist.

* ```ts
  function values(): Array<V>
  ```
  Gets the values contained in this map as an array, in insertion order. This is preliminary while iterators are not supported.

* ```ts
  function toString(): string
  ```
  Returns a string representation of this map.

---

## File: src/stdlib/math.md

---
---

# Math

Mathematical operations as known from JavaScript.

The Math API is very much like JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math)\), with the notable exceptions stated above and rest parameters not being supported yet.

## Variants

Math in AssemblyScript is available in multiple variants.

| Variant     | Description
| :---------- | :----------
| NativeMath  | WebAssembly implementation for `f64`
| NativeMathf | WebAssembly implementation for `f32`
| JSMath      | JavaScript implementation for `f64` (imported from the host)

By default, the global `Math` object is an alias of `NativeMath` and `Mathf` is an alias of `NativeMathf` .

### Using NativeMath

This is the default, so no additional configuration options are required. Note, however, that `Math.random` needs a way to seed the random number generator in this scenario, which WebAssembly alone cannot do, hence a function `env.seed()` is imported from the host \([see also](../exports-and-imports.md#anatomy-of-a-module)\) that must return an `f64` value \(the seed\). The [loader](../loader.md) and `import "WASI"` automatically take care of providing the seed function in this scenario, but one can always implement their own, for example to make the PRNG deterministic by returning a fixed seed value.

### Using JSMath

Where small module size is more important than performance, one can opt to override the default by adding `--use Math=JSMath` on the command line, essentially aliasing `Math` with `JSMath` instead, which maps to an import of the browser's math implementation. Naturally, this option requires importing the browser's `Math` object as a whole, but does not require seeding / is not seedable. The [loader](../loader.md) automatically takes care of importing the browser's math in this scenario.

## Static members

The type `T` below substitutes either `f32` or `f64` depending on the implementation used.

### Constants

* ```ts
  const E: T
  ```
  The base of natural logarithms, e, approximately 2.718.

* ```ts
  const LN2: T
  ```
  The natural logarithm of 2, approximately 0.693.

* ```ts
  const LN10: T
  ```
  The natural logarithm of 10, approximately 2.302.

* ```ts
  const LOG2E: T
  ```
  The base 2 logarithm of e, approximately 1.442.

* ```ts
  const LOG10E: T
  ```
  The base 10 logarithm of e, approximately 0.434.

* ```ts
  const PI: T
  ```
  The ratio of the circumference of a circle to its diameter, approximately 3.14159.

* ```ts
  const SQRT1_2: T
  ```
  The square root of 1/2, approximately 0.707.

* ```ts
  const SQRT2: T
  ```
  The square root of 2, approximately 1.414.

### Functions

* ```ts
  function abs(x: T): T
  ```
  Returns the absolute value of `x`.

* ```ts
  function acos(x: T): T
  ```
  Returns the arccosine \(in radians\) of `x`.

* ```ts
  function acosh(x: T): T
  ```
  Returns the hyperbolic arc-cosine of `x`.

* ```ts
  function asin(x: T): T
  ```
  Returns the arcsine \(in radians\) of `x.`

* ```ts
  function asinh(x: T): T
  ```
  Returns the hyperbolic arcsine of `x`.

* ```ts
  function atan(x: T): T
  ```
  Returns the arctangent \(in radians\) of `x`.

* ```ts
  function atan2(y: T, x: T): T
  ```
  Returns the arctangent of the quotient of its arguments.

* ```ts
  function atanh(x: T): T
  ```
  Returns the hyperbolic arctangent of `x`.

* ```ts
  function cbrt(x: T): T
  ```
  Returns the cube root of `x`.

* ```ts
  function ceil(x: T): T
  ```
  Returns the smallest integer greater than or equal to `x`.

* ```ts
  function clz32(x: T): T
  ```
  Returns the number of leading zero bits in the 32-bit binary representation of `x`.

* ```ts
  function cos(x: T): T
  ```
  Returns the cosine \(in radians\) of `x`.

* ```ts
  function cosh(x: T): T
  ```
  Returns the hyperbolic cosine of `x`.

* ```ts
  function exp(x: T): T
  ```
  Returns e to the power of `x`.

* ```ts
  function expm1(x: T): T
  ```
  Returns e to the power of `x`, minus 1.

* ```ts
  function floor(x: T): T
  ```
  Returns the largest integer less than or equal to `x`.

* ```ts
  function fround(x: T): T
  ```
  Returns the nearest 32-bit single precision float representation of `x`.

* ```ts
  function hypot(value1: T, value2: T): T
  ```
  Returns the square root of the sum of squares of its arguments.

* ```ts
  function imul(a: T, b: T): T
  ```
  Returns the result of the C-like 32-bit multiplication of `a` and `b`.

* ```ts
  function log(x: T): T
  ```
  Returns the natural logarithm \(base e\) of `x`.

* ```ts
  function log10(x: T): T
  ```
  Returns the base 10 logarithm of `x`.

* ```ts
  function log1p(x: T): T
  ```
  Returns the natural logarithm \(base e\) of 1 + `x`.

* ```ts
  function log2(x: T): T
  ```
  Returns the base 2 logarithm of `x`.

* ```ts
  function max(value1: T, value2: T): T
  ```
  Returns the largest-valued number of its arguments.

* ```ts
  function min(value1: T, value2: T): T
  ```
  Returns the lowest-valued number of its arguments.

* ```ts
  function pow(base: T, exponent: T): T
  ```
  Returns `base` to the power of `exponent`.

* ```ts
  function random(): T
  ```
  Returns a pseudo-random number in the range from 0.0 inclusive up to but not including 1.0.
  
  ::: tip
  Seeding happens automatically in common scenarios. See the [notes on using NativeMath above](#using-nativemath) if it doesn't.
  :::

* ```ts
  function round(x: T): T
  ```
  Returns the value of `x` rounded to the nearest integer.

* ```ts
  function sign(x: T): T
  ```
  Returns the sign of `x`, indicating whether the number is positive, negative or zero.

* ```ts
  function signbit(x: T): bool
  ```
  Returns whether the sign bit of `x` is set.

* ```ts
  function sin(x: T): T
  ```
  Returns the sine of `x`.

* ```ts
  function sinh(x: T): T
  ```
  Returns the hyperbolic sine of `x`.

* ```ts
  function sqrt(x: T): T
  ```
  Returns the square root of `x`.

* ```ts
  function tan(x: T): T
  ```
  Returns the tangent of `x`.

* ```ts
  function tanh(x: T): T
  ```
  Returns the hyperbolic tangent of `x`.

* ```ts
  function trunc(x: T): T
  ```
  Returns the integer part of `x` by removing any fractional digits.

## Considerations

The Math implementations are meant as a drop-in replacement for JavaScript's Math so sometimes mimic special JavaScript semantics, like `Math.round` always rounding towards `+Infinity`. Also, functions like `Math.fround` or `Math.imul` do not return an `f32` respectively an `i32` as some might expect for the same reason. Hence, depending on the use case, using [WebAssembly's math instructions](../environment.md#math) directly can be a worthwhile alternative where portability is not a concern.

---

## File: src/stdlib/number.md

---
sidebarDepth: 2
---

# Number

Wrappers for basic numerical values.

The `Number` object has been split into one class per basic WebAssembly type as well. Unlike in JavaScript, these classes cannot have actual instances, hence it works a bit different than JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)\).

## Integers

The name `Number` below stands for one of the wrappers `I8`, `I16`, `I32`, `I64`, `U8`, `U16`, `U32` or `U64` representing their respective basic integer type `T`.

### Static members

* ```ts
  const MIN_VALUE: T
  ```
  The smallest representable value of the respective basic type. Differs from floating point values where it is the smallest representable positive value.

* ```ts
  const MAX_VALUE: T
  ```
  The largest representable value of the respective basic type.

* ```ts
  function parseInt(value: string, radix?: i32): T
  ```
  Parses a string to a value of the respective basic type.

### Instance members

* ```ts
  function toString(radix?: i32): string
  ```
  Returns the respective basic value converted to a string.

## Floats

The name `Number` below stands for one of the wrappers `F32` or `F64` representing their respective basic floating point type `T`.

### Static members

* ```ts
  const EPSILON: T
  ```
  The difference between `1.0` and the smallest number larger than `1.0`.

* ```ts
  const MAX_VALUE: T
  ```
  The largest representable positive value by the respective basic type.

* ```ts
  const MIN_VALUE: T
  ```
  The smallest representable positive value by the respective basic type.

* ```ts
  const MAX_SAFE_INTEGER: T
  ```
  The largest safe integer representable by the respective basic type.

* ```ts
  const MIN_SAFE_INTEGER: T
  ```
  The smallest safe integer representable by the respective basic type.

* ```ts
  const POSITIVE_INFINITY: T
  ```
  Positive infinity of the respective basic type.

* ```ts
  const NEGATIVE_INFINITY: T
  ```
  Negative infinity of the respective basic type.

* ```ts
  const NaN: T
  ```
  NaN \(Not A Number\) of the respective basic type.

* ```ts
  function isNan(value: T): bool
  ```
  Tests if the value is `NaN`.

* ```ts
  function isFinite(value: T): bool
  ```
  Tests if the value is finite, that is not `NaN` , `POSITIVE_INFINITY` or `NEGATIVE_INFINITY.`

* ```ts
  function isInteger(value: T): bool
  ```
  Tests if the value is an integer.

* ```ts
  function isSafeInteger(value: T): bool
  ```
  Tests if the value is a safe integer.

* ```ts
  function parseInt(value: string, radix?: i32): T
  ```
  Parses a string to an integer value of the respective basic type.

* ```ts
  function parseFloat(value: string): T
  ```
  Parses a string to a float value of the respective basic type.

### Instance members

* ```ts
  function toString(radix?: i32): string
  ```
  Returns the respective basic value converted to a string. The `radix` parameter is currently ignored here.

---

## File: src/stdlib/process.md

---
---

# process

An implementation of a Node.js-like `process` global on top of WASI. Requires a WASI-enabled host and opting into WASI in the entry file with

```ts
import "wasi";
```

## Static members

* ```ts
  const arch: string
  ```
  String representing the CPU architecture for which the binary was compiled. Either `wasm32` or `wasm64`.

* ```ts
  const platform: string
  ```
  String representing the operating system platform for which the binary was compiled. Always `wasm`.

* ```ts
  const argv: string[]
  ```
  Array of command line arguments passed to the binary upon instantiation.

* ```ts
  const env: Map<string,string>
  ```
  Map of variables in the binary's user environment.

* ```ts
  var exitCode: i32
  ```
  Process exit code to use when the process exits gracefully. Defaults to `0`.

* ```ts
  function exit(code?: i32): void
  ```
  Terminates the process with either the given exit code, or `process.exitCode` if omitted.

* ```ts
  const stdin: ReadableStream
  const stdout: WritableStream
  const stderr: WritableStream
  ```
  Streams connected to `stdin` (fd `0`), `stdout` (fd `1`) and `stderr` (fd `2`) respectively.

* ```ts
  function time(): i64
  ```
  Obtains the system's current time of day, in milliseconds since Unix epoch.

* ```ts
  function hrtime(): u64
  ```
  Obtains the system's monotonic high resolution time, in nanoseconds since an arbitrary time in the past.

---

## File: src/stdlib/set.md

---
---

# Set

A set of unique generic values.

The Set API is very similar to JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)\), but iterators are not implemented yet.

## Constructor

* ```ts
  new Set<T>()
  ```
  Constructs a new set of unique value of type `T`.

## Instance members

### Fields

* ```ts
  readonly size: i32
  ```
  The current number of unique values in the set.

### Methods

* ```ts
  function add(value: T): void
  ```
  Adds the specified value to the set. Does nothing if the value already exists.

* ```ts
  function delete(value: T): bool
  ```
  Deletes the specified value. Returns `true` if the value was found, otherwise `false`.

* ```ts
  function clear(): void
  ```
  Clears the set, deleting all values.

* ```ts
  function has(value: T): bool
  ```
  Tests if the specified value exists in the set.

* ```ts
  function values(): Array<T>
  ```
  Gets the values contained in this set as an array, in insertion order. This is preliminary while iterators are not supported.

* ```ts
  function toString(): string
  ```
  Returns a string representation of this map.

---

## File: src/stdlib/staticarray.md

---
---

# StaticArray

A randomly accessible sequence of values of a generic type with a fixed length.

The StaticArray API is similar to the [Array API](./array.md), with the important difference that it has a fixed length that cannot change. Unlike a normal Array, a StaticArray does not have a separate backing buffer, so no level of indirection, and as such can have minimal overhead and performance characteristics very similar to arrays in C.

## Constructor

* ```ts
  new StaticArray<T>(length: i32)
  ```
  Constructs a new static array.

## Static members

* ```ts
  function fromArray<T>(source: T[]): StaticArray<T>
  ```
  Creates a static array from a normal array.

* ```ts
  function concat<T>(source: StaticArray<T>, other: StaticArray<T>): StaticArray<T>
  ```
  Like the instance member `concat`, but taking and returning a `StaticArray`.

* ```ts
  function slice<T>(source: StaticArray<T>, start?: i32, end?: i32): StaticArray<T>
  ```
  Like the instance member `slice`, but returning a `StaticArray`.

## Instance members

### Fields

* ```ts
  readonly length: i32
  ```
  The fixed length of this static array.

### Methods

* ```ts
  function concat(other: T[]): T[]
  ```
  Concatenates the values of this static and the other normal array to a new normal array, in this order.

* ```ts
  function includes(value: T, fromIndex?: i32): bool
  ```
  Tests if the array includes the specified value, optionally providing a starting index.

* ```ts
  function indexOf(value: T, fromIndex?: i32): i32
  ```
  Gets the first index where the specified value can be found in the array. Returns `-1` if not found.

* ```ts
  function join(separator?: string): string
  ```
  Concatenates all values of the array to a string, separated by the specified separator \(default: `,`\).

* ```ts
  function lastIndexOf(value: T, fromIndex?: i32): i32
  ```
  Gets the last index where the specified value can be found in the array. Returns `-1` if not found.

* ```ts
  function slice(start?: i32, end?: i32): T[]
  ```
  Returns a shallow copy of this static array's values from `begin` inclusive to `end` exclusive, as a new normal array. If omitted, `end` defaults to the end of the array.

* ```ts
  function toString(): string
  ```
  Returns the result of `join()`.

---

## File: src/stdlib/string.md

---
---

# String

A fixed-length sequence of UTF-16 code units.

The String API works very much like JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\), with the notable difference that the `string` type is an actual alias of `String`.

## Static members

* ```ts
  function fromCharCode(unit: i32, surr?: i32): string
  ```
  Creates a one character long string from the specified UTF-16 code units.

* ```ts
  function fromCharCodes(units: u16[]): string
  ```
  Creates a string from a sequence of UTF-16 code units.

* ```ts
  function fromCodePoint(code: i32): string
  ```
  Creates a one character long string from the specified Unicode code point.

* ```ts
  function fromCodePoints(codes: i32[]): string
  ```
  Creates a string from a sequence of Unicode code points.

## Instance members

### Fields

* ```ts
  readonly length: i32
  ```
  The length of the string in UTF-16 code units.

### Methods

* ```ts
  function charAt(pos: i32): string
  ```
  Gets the UTF-16 code unit at the specified position as a single character string. Returns `""` \(empty string\) if out of bounds.

* ```ts
  function charCodeAt(pos: i32): i32
  ```
  Gets the UTF-16 code unit at the specified position as a number. Returns `-1` if out of bounds.

* ```ts
  function codePointAt(pos: i32): i32
  ```
  Gets the Unicode code point at the specified \(UTF-16 code unit\) position as a number, possibly combining multiple successive UTF-16 code units. Returns `-1` if out of bounds.

* ```ts
  function concat(other: string): string
  ```
  Concatenates this string with another string, in this order, and returns the resulting string.

* ```ts
  function endsWith(search: string, end?: i32): bool
  ```
  Tests if the strings ends with the specified string. If specified, `end` indicates the position at which to stop searching, acting as if it is the length of the string.

* ```ts
  function includes(search: string, start?: i32): bool
  ```
  Tests if the string includes the search string. If specified, `start` indicates the position at which to begin searching.

* ```ts
  function indexOf(search: string, start?: i32): i32
  ```
  Gets the first index of the specified search string within the string, or `-1` if not found. If specified, `start` indicates the position at which to begin searching.

* ```ts
  function lastIndexOf(search: string, start?: i32): i32
  ```
  Gets the last index of the specified search string within the string, or `-1` if not found. If specified, `pos` indicates the position at which to begin searching from right to left.

* ```ts
  function padStart(length: i32, pad: string): string
  ```
  Pads the string with the contents of another string, possibly multiple times, until the resulting string reaches the specified length, returning the resulting string.

* ```ts
  function padEnd(length: i32, pad: string): string
  ```
  Pads the string with the contents of another string, possibly multiple times, until the resulting string reaches the specified length, returning the resulting string.

* ```ts
  function repeat(count?: i32): string
  ```
  Repeats the string `count` times and returns the concatenated result.

* ```ts
  function replace(search: string, replacement: string): string
  ```
  Replaces the first occurrence of `search` with `replacement`.

* ```ts
  function replaceAll(search: string, replacement: string): string
  ```
  Replaces all occurrences of `search` with `replacement`.

* ```ts
  function slice(start: i32, end?: i32): string
  ```
  Returns the region of the string from `start` inclusive to `end` exclusive, as a new string. If omitted, `end` defaults to the end of the string.

* ```ts
  function split(separator?: string, limit?: i32): string[]
  ```
  Splits the string at each occurrence  of `separator` and returns the result as a new array of strings that has a maximum of `limit` values. If `limit` is omitted, no limit is assumed. If `separator` is omitted or not present in the string, the string becomes the sole element of the array. If `separator` is an empty string, the split is performed between code units \(not code points\), potentially destroying surrogate pairs.

* ```ts
  function startsWith(search: string, start?: i32): bool
  ```
  Tests if the string starts with the specified string. If specified, `pos` indicates the position at which to begin searching, acting as the start of the string.

* ```ts
  function substring(start: i32, end?: i32): string
  ```
  Gets the part of the string in between `start` inclusive and `end` exclusive as a new string.

* ```ts
  function toString(): this
  ```
  Returns the string.

* ```ts
  function trim(): string
  ```
  Removes white space characters from both the start and the end of the string, returning the resulting string.

* ```ts
  function trimStart(): string
  function trimLeft(): string
  ```
  Removes white space characters from the start of the string, returning the resulting string.

* ```ts
  function trimEnd(): string
  function trimRight(): string
  ```
  Removes white space characters from the end of the string, returning the resulting string.

## Encoding API

### UTF8

When integrating with an environment that uses UTF-8, the following helpers can be used to quickly re-encode String data.

* ```ts
  function String.UTF8.byteLength(str: string, nullTerminated?: bool): i32
  ```
  Calculates the byte length of the specified string when encoded as UTF-8, optionally null terminated.

* ```ts
  function String.UTF8.encode(str: string, nullTerminated?: bool): ArrayBuffer
  ```
  Encodes the specified string to UTF-8 bytes, optionally null terminated.

* ```ts
  function String.UTF8.encodeUnsafe(str: usize, len: i32, buf: usize, nullTerminated?: bool): usize
  ```
  Encodes the specified raw string to UTF-8 bytes, opionally null terminated. Returns the number of bytes written.

* ```ts
  function String.UTF8.decode(buf: ArrayBuffer, nullTerminated?: bool): string
  ```
  Decodes the specified buffer from UTF-8 bytes to a string, optionally null terminated.

* ```ts
  function String.UTF8.decodeUnsafe(
    buf: usize,
    len: usize,
    nullTerminated?: bool
  ): string
  ```
  Decodes raw UTF-8 bytes to a string, optionally null terminated.

::: tip
Note that any `ArrayBuffer` return value is a pointer to the buffer's data internally and thus can be passed to let's say a C-function directly. However, if the pointer is meant to live longer than the immediate external function call, the [lifetime of the buffer must be tracked](../runtime.md#managing-lifetimes) so it doesn't become collected prematurely with the data becoming invalid.
:::

### UTF16

The following mostly exist to have a safe way to copy between Strings and ArrayBuffers, but doesn't involve a re-encoding step.

* ```ts
  function String.UTF16.byteLength(str: string): i32
  ```
  Calculates the byte length of the specified string when encoded as UTF-16.

* ```ts
  function String.UTF16.encode(str: string): ArrayBuffer
  ```
  Encodes the specified string to UTF-16 bytes.

* ```ts
  function String.UTF16.encodeUnsafe(str: usize, len: i32, buf: usize): usize
  ```
  Encodes the specified raw string to UTF-16 bytes. Returns the number of bytes written.

* ```ts
  function String.UTF16.decode(buf: ArrayBuffer): string
  ```
  Decodes the specified buffer from UTF-16 bytes to a string.

* ```ts
  function String.UTF16.decodeUnsafe(buf: usize, len: usize): string
  ```
  Decodes raw UTF-16 bytes to a string.

## Considerations

Also see the notes on [string interoperability](../interoperability.md#strings).

---

## File: src/stdlib/symbol.md

---
---

# Symbol

A primitive data type representing a unique global symbol.

The symbol type is very similar to JavaScript's \([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)\), but is not deeply integrated with the compiler yet.

## Construction

* ```ts
  function Symbol(description?: string): symbol
  ```
  Creates a new unique symbol. Note that this is not a constructor (symbols are primitive data types) so cannot be invoked with `new`.

## Static members

* ```ts
  function for(key: string): symbol
  ```
  Obtains the existing unique symbol for the specified global key or creates a new unique symbol if the key does not exist.

* ```ts
  function keyFor(sym: symbol): string | null
  ```
  Obtains the global key of the specified unique symbol, if any.

## Instance members

* ```ts
  function toString(): string
  ```
  Returns a string representation of the symbol of the form `"Symbol(key?)"`.