From ce68ba361ffa697d040381a7161a3fa86e0c067c Mon Sep 17 00:00:00 2001 From: Hayden Date: Tue, 4 Nov 2025 21:31:35 -0700 Subject: [PATCH] Add auto-generated documentation --- docs/autogenerated_docs/1-overview.md | 326 +++++++++++++ .../2-compiler-architecture.md | 408 ++++++++++++++++ .../2.1-control-flow-analysis.md | 322 ++++++++++++ ...-module-system-and-binaryen-integration.md | 319 ++++++++++++ docs/autogenerated_docs/3-standard-library.md | 365 ++++++++++++++ .../3.1-array-and-string.md | 400 +++++++++++++++ docs/autogenerated_docs/3.2-math-library.md | 280 +++++++++++ docs/autogenerated_docs/3.3-typedarrays.md | 335 +++++++++++++ docs/autogenerated_docs/3.4-date.md | 335 +++++++++++++ .../3.5-string-and-number-utilities.md | 358 ++++++++++++++ .../4-command-line-interface-_cli_.md | 215 ++++++++ docs/autogenerated_docs/4.1-compiler-api.md | 407 ++++++++++++++++ .../5-javascript-integration.md | 459 ++++++++++++++++++ .../5.1-javascript-bindings-generator.md | 402 +++++++++++++++ .../autogenerated_docs/6-memory-management.md | 301 ++++++++++++ 15 files changed, 5232 insertions(+) create mode 100644 docs/autogenerated_docs/1-overview.md create mode 100644 docs/autogenerated_docs/2-compiler-architecture.md create mode 100644 docs/autogenerated_docs/2.1-control-flow-analysis.md create mode 100644 docs/autogenerated_docs/2.2-module-system-and-binaryen-integration.md create mode 100644 docs/autogenerated_docs/3-standard-library.md create mode 100644 docs/autogenerated_docs/3.1-array-and-string.md create mode 100644 docs/autogenerated_docs/3.2-math-library.md create mode 100644 docs/autogenerated_docs/3.3-typedarrays.md create mode 100644 docs/autogenerated_docs/3.4-date.md create mode 100644 docs/autogenerated_docs/3.5-string-and-number-utilities.md create mode 100644 docs/autogenerated_docs/4-command-line-interface-_cli_.md create mode 100644 docs/autogenerated_docs/4.1-compiler-api.md create mode 100644 docs/autogenerated_docs/5-javascript-integration.md create mode 100644 docs/autogenerated_docs/5.1-javascript-bindings-generator.md create mode 100644 docs/autogenerated_docs/6-memory-management.md diff --git a/docs/autogenerated_docs/1-overview.md b/docs/autogenerated_docs/1-overview.md new file mode 100644 index 0000000000..37c3a9861f --- /dev/null +++ b/docs/autogenerated_docs/1-overview.md @@ -0,0 +1,326 @@ +# Overview + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [README.md](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/README.md) +- [bin/asc.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/bin/asc.js) +- [package-lock.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package-lock.json) +- [package.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json) +- [src/glue/binaryen.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/glue/binaryen.d.ts) +- [src/module.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts) + +
+ + + +AssemblyScript is a TypeScript-like language that compiles to WebAssembly. This document provides a high-level overview of the AssemblyScript repository architecture and its key components, serving as an entry point to understand the codebase. + +For detailed information about specific components, refer to their respective wiki pages: +- For compiler architecture details, see [Compiler Architecture](#2) +- For standard library information, see [Standard Library](#3) +- For CLI usage, see [Command Line Interface](#4) +- For JavaScript integration, see [JavaScript Integration](#5) +- For memory management, see [Memory Management](#6) + +## What is AssemblyScript? + +AssemblyScript compiles a strict variant of TypeScript (essentially TypeScript with precise numeric types) to WebAssembly. It leverages the Binaryen compiler infrastructure to generate optimized WebAssembly modules while providing a familiar developer experience through TypeScript-like syntax. + +```mermaid +flowchart LR + subgraph "Development Environment" + TS["TypeScript-like\nSource Code"] + end + + subgraph "AssemblyScript Compiler" + ASC["asc CLI"] + Compiler["Compiler Pipeline"] + Binaryen["Binaryen\nWebAssembly Backend"] + end + + subgraph "Output" + WASM["WebAssembly Module\n(.wasm)"] + JS["JavaScript Bindings\n(.js)"] + TSD["TypeScript Definitions\n(.d.ts)"] + end + + TS --> ASC + ASC --> Compiler + Compiler --> Binaryen + Binaryen --> WASM + Compiler --> JS + Compiler --> TSD +``` + +Sources: [package.json:2-4](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L2-L4), [README.md:13-14](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/README.md#L13-L14) + +## Repository Architecture + +The AssemblyScript codebase is organized into several major components that work together to compile TypeScript-like code to WebAssembly. + +```mermaid +graph TD + subgraph "Core Components" + CLI["Command Line Interface\n(bin/asc.js)"] + Parser["Parser\n(src/parser.ts)"] + Compiler["Compiler\n(src/compiler.ts)"] + Module["Module System\n(src/module.ts)"] + Bindings["JavaScript Bindings\n(src/bindings)"] + end + + subgraph "Standard Library" + StdLib["Standard Library\n(std/assembly/*.ts)"] + CoreTypes["Core Types\n(std/assembly/index.d.ts)"] + DataStructures["Data Structures\n(array, string, map, etc.)"] + Utilities["Utilities\n(math, date, etc.)"] + end + + subgraph "Runtime" + Loader["AssemblyScript Loader\n(lib/loader)"] + GC["Garbage Collection\n(itcms)"] + MemoryManager["Memory Management\n(tlsf)"] + end + + CLI --> Parser + Parser --> Compiler + Compiler --> Module + Module --> Bindings + Module <--> BinaryenAPI["Binaryen API\n(src/glue/binaryen.d.ts)"] + + Compiler --- StdLib + StdLib --> CoreTypes + StdLib --> DataStructures + StdLib --> Utilities + + Module --> WebAssembly["WebAssembly Output"] + WebAssembly --> Loader + Loader --> GC + Loader --> MemoryManager +``` + +Sources: [package.json:42-67](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L42-L67), [src/module.ts:1-10](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L1-L10), [bin/asc.js:1-36](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/bin/asc.js#L1-L36) + +## Compilation Pipeline + +The AssemblyScript compiler converts TypeScript-like source code into WebAssembly modules in several stages. The entire pipeline integrates closely with Binaryen for WebAssembly generation and optimization. + +```mermaid +flowchart TD + subgraph "Input" + TSSource["TypeScript-like\nSource Files"] + Config["Configuration\n(asconfig.json)"] + end + + subgraph "AssemblyScript Compiler" + Parser["Parser"] --> AST["Abstract Syntax Tree"] + AST --> TypeChecker["Type Checker"] + TypeChecker --> Resolver["Resolver"] + Resolver --> ControlFlow["Control Flow Analysis"] + ControlFlow --> CodeGen["WebAssembly Code Generation"] + CodeGen --> Optimizer["Optimizer (Binaryen)"] + end + + subgraph "Output" + WasmModule["WebAssembly Module (.wasm)"] + WasmText["WebAssembly Text (.wat)"] + JSBindings["JavaScript Bindings (.js)"] + TSDefinitions["TypeScript Definitions (.d.ts)"] + end + + TSSource --> Parser + Config --> Parser + + Optimizer --> WasmModule + Optimizer --> WasmText + CodeGen --> JSBindings + CodeGen --> TSDefinitions +``` + +Sources: [bin/asc.js:29-33](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/bin/asc.js#L29-L33), [package.json:72-96](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L72-L96) + +## Module System and Binaryen Integration + +The AssemblyScript module system is a core part of the compiler that interfaces with Binaryen to generate WebAssembly. It acts as a thin wrapper around Binaryen's C-API. + +```mermaid +graph TD + subgraph "AssemblyScript Module System" + ModuleTS["src/module.ts"] + TypeRefs["Type References"] + ExprRefs["Expression References"] + FuncRefs["Function References"] + end + + subgraph "Binaryen Interface" + BinaryenGlue["src/glue/binaryen.d.ts"] + BinaryenAPI["Binaryen API"] + WasmFeatures["WebAssembly Features"] + WasmOps["WebAssembly Operations"] + end + + ModuleTS --> BinaryenGlue + BinaryenGlue --> BinaryenAPI + TypeRefs <--> BinaryenAPI + ExprRefs <--> BinaryenAPI + FuncRefs <--> BinaryenAPI + + BinaryenAPI --> WasmFeatures + BinaryenAPI --> WasmOps + + BinaryenAPI --> WasmOutput["WebAssembly Output"] +``` + +Sources: [src/module.ts:1-20](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L1-L20), [src/glue/binaryen.d.ts:1-11](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/glue/binaryen.d.ts#L1-L11), [package.json:27-29](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L27-L29) + +## JavaScript Integration and Interoperability + +AssemblyScript provides seamless integration with JavaScript through generated bindings and a loader. This enables efficient communication between WebAssembly modules and JavaScript host environments. + +```mermaid +flowchart TD + subgraph "WebAssembly Module" + WasmCode["WebAssembly Code"] + Exports["Exported Functions"] + Memory["Memory"] + end + + subgraph "AssemblyScript Integration" + JSBindings["JavaScript Bindings"] + Loader["AssemblyScript Loader"] + TypeConversion["Type Conversion\n(lifting/lowering)"] + end + + subgraph "JavaScript Application" + ImportObj["Import Object"] + API["JavaScript API"] + MemoryAccess["Memory Access"] + end + + WasmCode --> Exports + Exports --> JSBindings + Memory <--> TypeConversion + + JSBindings --> API + Loader --> instantiate["instantiate()"] + instantiate --> WasmCode + ImportObj --> WasmCode + + TypeConversion --> StringConv["String Conversion"] + TypeConversion --> ArrayConv["Array Conversion"] + TypeConversion --> NumericConv["Numeric Conversion"] + + API <--> TypeConversion + MemoryAccess <--> Memory +``` + +Sources: [package.json:42-60](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L42-L60) + +## Standard Library + +AssemblyScript includes a comprehensive standard library that provides essential data structures and utilities similar to TypeScript's standard library but optimized for WebAssembly. + +```mermaid +graph TD + subgraph "AssemblyScript Standard Library" + CoreTypes["Core Types\n(std/assembly/index.d.ts)"] + + subgraph "Data Structures" + Array["Array"] + String["String"] + Map["Map"] + Set["Set"] + TypedArrays["TypedArrays"] + end + + subgraph "Utilities" + Math["Math"] + Date["Date"] + DataView["DataView"] + StringUtils["String Utilities"] + end + + subgraph "Memory Management" + GC["Garbage Collection"] + Allocator["Memory Allocator"] + RefCount["Reference Counting"] + end + end + + CoreTypes --> Array + CoreTypes --> String + CoreTypes --> Map + CoreTypes --> Set + CoreTypes --> TypedArrays + CoreTypes --> Math + CoreTypes --> Date + CoreTypes --> DataView + + Array --> GC + String --> GC + Map --> GC + Set --> GC + + GC --> Allocator + GC --> RefCount +``` + +Sources: [package.json:98-106](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L98-L106) + +## Project Requirements and Development + +AssemblyScript requires Node.js 18+ and npm 10+ for development. The project uses: + +| Dependency | Purpose | +|------------|---------| +| Binaryen | WebAssembly compiler infrastructure | +| Long | 64-bit integer support | +| TypeScript | Type checking and development | +| ESBuild | Bundling | +| ESLint | Code quality | + +To set up a development environment: + +1. Clone the repository +2. Install dependencies with `npm install` +3. Optionally link globally with `npm link` +4. Build the compiler with `npm run build` + +Sources: [package.json:22-39](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L22-L39), [README.md:37-52](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/README.md#L37-L52) + +## Command Line Interface + +The AssemblyScript compiler is accessible through the `asc` command-line interface, which provides various options for compiling AssemblyScript code. + +```mermaid +flowchart TD + subgraph "Command Line Interface" + ASC["bin/asc.js"] + Args["Process Arguments"] + Options["Compiler Options"] + end + + subgraph "Compilation Process" + API["AssemblyScript API"] + Compile["Compile Source Files"] + Transform["Apply Transforms"] + Output["Generate Output"] + end + + InputFiles["Source Files"] --> ASC + ASC --> Args + Args --> Options + Options --> API + API --> Compile + Compile --> Transform + Transform --> Output + Output --> OutputFiles["Output Files\n(.wasm, .js, .d.ts)"] +``` + +Sources: [bin/asc.js:1-36](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/bin/asc.js#L1-L36), [package.json:68-71](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json#L68-L71) + +## Summary + +AssemblyScript provides a TypeScript-like development experience for WebAssembly, bridging the gap between high-level TypeScript and low-level WebAssembly. Its architecture is designed to leverage the strengths of both languages while providing efficient compilation and runtime performance. \ No newline at end of file diff --git a/docs/autogenerated_docs/2-compiler-architecture.md b/docs/autogenerated_docs/2-compiler-architecture.md new file mode 100644 index 0000000000..b42f8a02aa --- /dev/null +++ b/docs/autogenerated_docs/2-compiler-architecture.md @@ -0,0 +1,408 @@ +# Compiler Architecture + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [src/ast.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/ast.ts) +- [src/builtins.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/builtins.ts) +- [src/common.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/common.ts) +- [src/compiler.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/compiler.ts) +- [src/diagnosticMessages.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/diagnosticMessages.json) +- [src/diagnostics.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/diagnostics.ts) +- [src/extra/ast.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/extra/ast.ts) +- [src/parser.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/parser.ts) +- [src/program.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/program.ts) +- [src/resolver.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/resolver.ts) +- [src/tokenizer.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/tokenizer.ts) +- [src/types.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/types.ts) + +
+ + + +The AssemblyScript compiler transforms TypeScript code into WebAssembly binary modules. This page documents the architecture of the compiler, its core components, and how they interact to transform source code into executable WebAssembly. For information about using the compiler API programmatically, see [Compiler API](#4.1). + +## Core Components + +The AssemblyScript compiler is composed of several key components that work together in a pipeline: + +```mermaid +graph TD + Source["Source Code"] --> Parser["Parser"] + Parser --> AST["Abstract Syntax Tree"] + AST --> Resolver["Resolver"] + + subgraph "Program" + Resolver --> IR["Intermediate Representation"] + end + + IR --> Compiler["Compiler"] + Compiler --> BinaryenModule["Binaryen Module"] + BinaryenModule --> Outputs["WebAssembly & Bindings"] +``` + +- **Parser**: Transforms source code into an Abstract Syntax Tree (AST) +- **Resolver**: Resolves types, symbols, and references from the AST +- **Program**: Holds the intermediate representation (IR) of the code +- **Compiler**: Transforms the IR into WebAssembly via Binaryen +- **Module**: Interface to Binaryen for WebAssembly generation + +Sources: [src/parser.ts:103-443](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/parser.ts:103-443#L103-L443), [src/resolver.ts:118-177](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/resolver.ts:118-177#L118-L177), [src/program.ts:429-481](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/program.ts:429-481#L429-L481), [src/compiler.ts:429-1084](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/compiler.ts:429-1084#L429-L1084) + +## Compilation Pipeline + +The compilation process involves multiple stages, from parsing to output generation: + +```mermaid +flowchart TD + ParseOptions["Parse Options"] --> ParseSource["Parse Source Files"] + ParseSource --> CreateProgram["Create Program Object"] + CreateProgram --> InitProgram["Initialize Program"] + InitProgram --> CompileEntry["Compile Entry Files"] + CompileEntry --> CompileRuntime["Compile Runtime if Needed"] + CompileRuntime --> CompileLazy["Compile Lazy Functions"] + CompileLazy --> SetupStubs["Setup Override Stubs"] + SetupStubs --> CompileInstanceOf["Compile InstanceOf Helpers"] + CompileInstanceOf --> FinalizeRuntime["Finalize Runtime Features"] + FinalizeRuntime --> FinalizeMemory["Finalize Memory & Heap"] + FinalizeMemory --> SetupMemory["Setup Memory & Table"] + SetupMemory --> CompileStart["Compile Start Function"] + CompileStart --> RunCustomPasses["Run Custom Passes"] + RunCustomPasses --> ReturnModule["Return WebAssembly Module"] +``` + +The pipeline starts with parsing options and source files, creates a Program object, and then proceeds through various compilation stages before producing a WebAssembly module. + +Sources: [src/compiler.ts:480-756](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/compiler.ts:480-756#L480-L756) + +## Parser + +The Parser transforms source code into an Abstract Syntax Tree (AST) that represents the structure of the program. The AssemblyScript parser is specialized for the AssemblyScript subset of TypeScript. + +Key responsibilities: +- Tokenizing source code +- Building AST nodes +- Handling imports and exports +- Parsing declarations, expressions, and statements + +```mermaid +flowchart TD + Source["Source Code"] --> Tokenizer["Tokenizer"] + Tokenizer --> Tokens["Token Stream"] + Tokens --> Parser["Parser"] + Parser --> AST["Abstract Syntax Tree"] + + subgraph "AST Node Types" + Expressions["Expressions"] + Statements["Statements"] + Types["Type Nodes"] + Declarations["Declarations"] + end + + AST --> Expressions + AST --> Statements + AST --> Types + AST --> Declarations +``` + +The parser uses a tokenizer to break source code into tokens, which are then combined into AST nodes. The AST represents the syntactic structure of the program and forms the basis for further compilation steps. + +Sources: [src/parser.ts:103-443](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/parser.ts:103-443#L103-L443), [src/ast.ts:47-428](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/ast.ts:47-428#L47-L428), [src/tokenizer.ts:41-177](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/tokenizer.ts:41-177#L41-L177) + +## Program + +The Program class serves as the intermediate representation container, holding all the elements, types, and signatures used during compilation. + +Key responsibilities: +- Managing source files +- Maintaining the element hierarchy +- Storing type information +- Providing lookups for elements and types + +```mermaid +graph TD + Program --> Module["Binaryen Module"] + Program --> Parser["Parser Instance"] + Program --> Resolver["Resolver Instance"] + Program --> Sources["Source Files"] + Program --> LookupMaps["Lookup Maps"] + + subgraph "Lookup Maps" + FilesByName["Files by Name"] + ElementsByName["Elements by Name"] + ElementsByDecl["Elements by Declaration"] + InstancesByName["Instances by Name"] + WrapperClasses["Wrapper Classes"] + ManagedClasses["Managed Classes"] + UniqueSignatures["Unique Signatures"] + ModuleImports["Module Imports"] + end + + LookupMaps --> FilesByName + LookupMaps --> ElementsByName + LookupMaps --> ElementsByDecl + LookupMaps --> InstancesByName + LookupMaps --> WrapperClasses + LookupMaps --> ManagedClasses + LookupMaps --> UniqueSignatures + LookupMaps --> ModuleImports +``` + +The Program maintains various lookup maps for efficient access to elements and types. It also holds references to the Parser, Resolver, and Binaryen Module, serving as the central hub of the compilation process. + +Sources: [src/program.ts:429-481](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/program.ts:429-481#L429-L481) + +## Resolver + +The Resolver is responsible for resolving names, types, and expressions from the AST, turning symbolic references into concrete element references. + +Key responsibilities: +- Resolving type nodes to types +- Resolving expressions +- Looking up elements +- Handling type parameters + +```mermaid +flowchart TD + AST["AST Node"] --> Resolver + + subgraph "Resolver" + ResolveType["Resolve Type"] + ResolveExpr["Resolve Expression"] + ResolveName["Resolve Name"] + ResolveElement["Resolve Element"] + end + + Resolver --> TypeInfo["Type Information"] + Resolver --> ElementRefs["Element References"] + + ResolveType --> Type["Concrete Type"] + ResolveExpr --> ExprType["Expression Type"] + ResolveName --> Element["Named Element"] + ResolveElement --> ConcreteElement["Concrete Element"] +``` + +The Resolver works closely with the Program, looking up elements by name and resolving types based on type nodes in the AST. + +Sources: [src/resolver.ts:118-177](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/resolver.ts:118-177#L118-L177), [src/types.ts:136-332](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/types.ts:136-332#L136-L332) + +## Compiler + +The Compiler transforms the Program's intermediate representation into a WebAssembly module using Binaryen. + +Key responsibilities: +- Compiling functions, classes, and exports +- Managing memory layout +- Setting up the runtime +- Emitting WebAssembly code + +```mermaid +flowchart TD + Program --> Compiler + + subgraph "Compiler" + CompileFunc["Compile Functions"] + CompileExpr["Compile Expressions"] + CompileStmt["Compile Statements"] + SetupRuntime["Setup Runtime"] + ManageMemory["Manage Memory"] + end + + Compiler --> Module["Binaryen Module"] + + CompileFunc --> WasmFunc["WebAssembly Functions"] + CompileExpr --> WasmExpr["WebAssembly Expressions"] + CompileStmt --> WasmInstr["WebAssembly Instructions"] + SetupRuntime --> RuntimeFeatures["Runtime Features"] + ManageMemory --> MemoryLayout["Memory Layout"] +``` + +The Compiler uses the Resolver to resolve types and elements while generating WebAssembly code. It manages memory layout, sets up the runtime, and handles exports. + +Sources: [src/compiler.ts:429-1084](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/compiler.ts:429-1084#L429-L1084) + +## Type System + +AssemblyScript's type system bridges TypeScript's static typing with WebAssembly's runtime types. The compiler represents types using the Type class, which contains information about type size, flags, and relationships. + +Type kinds include primitive types (like i32, f64), reference types (for classes and interfaces), and function types. + +```mermaid +graph TD + Types --> Primitives["Primitive Types"] + Types --> References["Reference Types"] + Types --> Functions["Function Types"] + + subgraph "Primitive Types" + Integers["Integers (i8, i16, i32, i64)"] + Floats["Floats (f32, f64)"] + Bool["Boolean"] + Vector["Vector (v128)"] + end + + subgraph "Reference Types" + ClassTypes["Class Types"] + InterfaceTypes["Interface Types"] + ArrayTypes["Array Types"] + end + + subgraph "Function Types" + FunctionSignatures["Function Signatures"] + end +``` + +Each type has flags indicating its capabilities (signed, unsigned, integer, float, reference, etc.) and information about its size and alignment. + +Sources: [src/types.ts:28-332](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/types.ts:28-332#L28-L332) + +## Built-ins + +The compiler incorporates built-in elements that provide core WebAssembly functionality. These include operations like memory access, arithmetic, comparisons, and conversions. + +```mermaid +graph TD + Builtins --> CoreBuiltins["Core Builtins"] + Builtins --> Aliases["Builtin Aliases"] + + subgraph "Core Builtins" + Memory["Memory Operations"] + Arithmetic["Arithmetic Operations"] + Comparisons["Comparison Operations"] + Conversions["Type Conversions"] + SIMD["SIMD Operations"] + end + + subgraph "Aliases" + TypedOps["Typed Operations"] + IntrinsicOps["Intrinsic Operations"] + end +``` + +When the compiler encounters a built-in function call, it recognizes the `@builtin` decorator, looks up the handler, and emits the appropriate WebAssembly instructions. + +Sources: [src/builtins.ts:117-463](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/builtins.ts:117-463#L117-L463) + +## Diagnostics + +The compiler uses a diagnostic system to report errors, warnings, and informational messages. Each diagnostic has a code, category, message, and optional source range. + +Diagnostics are categorized as: +- Errors: Prevent compilation +- Warnings: Indicate potential issues +- Info: Provide information +- Pedantic: Highly strict warnings + +The compiler collects diagnostics during parsing, resolution, and compilation, and reports them to the user. + +Sources: [src/diagnostics.ts:34-442](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/diagnostics.ts:34-442#L34-L442), [src/diagnosticMessages.json:2-212](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/diagnosticMessages.json:2-212#L2-L212) + +## Memory Management + +The compiler handles memory management for the generated WebAssembly module, including: + +- Static memory layout +- Memory segments for constants +- String segments +- Function table setup + +It also supports various memory-related options like initial/maximum memory, shared memory, and memory import/export. + +```mermaid +flowchart TD + MemoryOffset["Memory Offset"] --> MemorySegments["Memory Segments"] + MemorySegments --> StringSegments["String Segments"] + MemorySegments --> StaticData["Static Data"] + + MemorySetup["Memory Setup"] --> InitialPages["Initial Pages"] + MemorySetup --> MaximumPages["Maximum Pages"] + MemorySetup --> SharedMemory["Shared Memory Flag"] + + FunctionTable["Function Table"] --> TableEntries["Table Entries"] + FunctionTable --> TableSize["Table Size"] +``` + +The compiler aligns memory properly and ensures that the memory layout adheres to WebAssembly's requirements. + +Sources: [src/compiler.ts:758-885](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/compiler.ts:758-885#L758-L885) + +## Compilation Flags and Options + +The compiler's behavior is controlled by various flags and options: + +| Category | Options | Description | +|----------|---------|-------------| +| Target | `target` | WebAssembly target (Wasm32/Wasm64) | +| Runtime | `runtime` | Runtime type (Incremental GC) | +| Debug | `debugInfo` | Whether to emit debug information | +| Memory | `initialMemory`, `maximumMemory` | Memory size in pages | +| Memory | `sharedMemory`, `importMemory`, `exportMemory` | Memory configuration | +| Table | `importTable`, `exportTable` | Function table configuration | +| Features | `features` | WebAssembly features to enable | +| Optimization | `optimizeLevelHint`, `shrinkLevelHint` | Optimization levels | + +These options can be set via the command line interface or programmatically. + +Sources: [src/compiler.ts:234-300](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/compiler.ts:234-300#L234-L300) + +## Common Flags + +Elements in the compiler can have various flags that indicate their characteristics: + +| Flag | Description | +|------|-------------| +| `Export` | Exported to the WebAssembly module | +| `Import` | Imported from the host environment | +| `Const` | Immutable value | +| `Static` | Static member | +| `Readonly` | Read-only property | +| `Private` | Private member | +| `Protected` | Protected member | +| `Instance` | Instance member | +| `Generic` | Generic type or function | +| `Compiled` | Successfully compiled | +| `Inlined` | Inlined at call sites | +| `Closure` | Part of a closure | + +These flags help the compiler determine how to handle each element during compilation. + +Sources: [src/common.ts:7-86](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/common.ts:7-86#L7-L86) + +## Integration with Binaryen + +AssemblyScript uses Binaryen as its backend for WebAssembly code generation and optimization. The Module class provides an interface to Binaryen's API. + +```mermaid +flowchart TD + Compiler --> Module["AssemblyScript Module"] + Module --> BinaryenModule["Binaryen Module"] + BinaryenModule --> Optimize["Binaryen Optimizer"] + Optimize --> Output["WebAssembly Output"] + + subgraph "Binaryen Operations" + CreateFunc["Create Functions"] + CreateExpr["Create Expressions"] + CreateGlobal["Create Globals"] + SetupMemory["Setup Memory"] + SetupTable["Setup Table"] + end + + Module --> CreateFunc + Module --> CreateExpr + Module --> CreateGlobal + Module --> SetupMemory + Module --> SetupTable +``` + +Binaryen provides a C-like API for WebAssembly code generation and optimization. The Module class wraps this API to make it easier to use from AssemblyScript. + +Sources: [src/compiler.ts:480-756](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/compiler.ts:480-756#L480-L756), [src/module.ts:referenced in other files](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts) + +## Summary + +The AssemblyScript compiler architecture follows a traditional compiler design with a frontend (Parser), middle-end (Resolver, Program), and backend (Compiler, Module). + +It transforms TypeScript code into an AST, resolves types and symbols, builds an intermediate representation, compiles to WebAssembly via Binaryen, and produces WebAssembly binaries along with JavaScript bindings and TypeScript definitions. + +The compiler's modular design allows for various optimizations and extensions while maintaining a clean separation of concerns between different compilation phases. \ No newline at end of file diff --git a/docs/autogenerated_docs/2.1-control-flow-analysis.md b/docs/autogenerated_docs/2.1-control-flow-analysis.md new file mode 100644 index 0000000000..1d24da3160 --- /dev/null +++ b/docs/autogenerated_docs/2.1-control-flow-analysis.md @@ -0,0 +1,322 @@ +# Control Flow Analysis + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [src/flow.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts) +- [src/util/collections.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/util/collections.ts) + +
+ + + +## Purpose and Scope + +Control Flow Analysis in AssemblyScript is responsible for tracking compilation state and analyzing code paths during the compilation process. It sits between type resolution and code generation in the compilation pipeline, providing crucial information about how code executes and the states of variables throughout program execution. + +This system keeps track of conditions such as whether code paths always terminate, whether local variables are guaranteed to be non-null, and whether expressions might overflow their value ranges. This information is used for optimizations, error checking, and generating appropriate WebAssembly code. + +Sources: [src/flow.ts:1-16](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L1-L16) + +## Flow Class Overview + +The core of Control Flow Analysis is the `Flow` class, which represents a branch in the program's control flow graph. Each function compilation begins with a clean flow that is populated with initial local states. As compilation progresses, statements and expressions update flow state while control structures (if/else, loops) create additional branched flows that are forked and later merged. + +```mermaid +classDiagram + class Flow { + +targetFunction: Function + +inlineFunction: Function|null + +parent: Flow|null + +outer: Flow|null + +flags: FlowFlags + +localFlags: LocalFlags[] + +thisFieldFlags: Map~Property,FieldFlags~ + +fork() + +forkThen() + +forkElse() + +inherit() + +mergeBranch() + +inheritAlternatives() + +canOverflow() + } + + class FlowFlags { + <> + +None + +Returns + +Throws + +Breaks + +Continues + +Terminates + +AccessesThis + +CallsSuper + +ConditionallyReturns + +ConditionallyThrows + } + + class LocalFlags { + <> + +None + +Constant + +Wrapped + +NonNull + +Initialized + } + + Flow --> FlowFlags : uses + Flow --> LocalFlags : uses +``` + +Sources: [src/flow.ts:17-205](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L17-L205), [src/flow.ts:206-217](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L206-L217) + +## Flow Creation and Lifecycle + +Each function being compiled receives a new flow instance. Control flow analysis begins with creating the default flow for a function using `Flow.createDefault()`. For optimization purposes, when inlining is performed, a special inline flow is created with `Flow.createInline()`. + +As compilation progresses through the source code, the flow instance tracks program state, including: + +1. Which code paths terminate (return, throw, break, continue) +2. The state of local variables (initialized, non-null, constant, etc.) +3. In constructors, which fields of `this` have been initialized +4. Whether potential integer overflows might occur + +```mermaid +flowchart TD + Start["Start Function\nCompilation"] --> DefaultFlow["Create Default Flow\nFlow.createDefault()"] + DefaultFlow --> ProcessBody["Process Function Body"] + + ProcessBody --> IfStatement["If Statement\nfork() two branches"] + ProcessBody --> Loop["Loop\nfork() with new break context"] + ProcessBody --> TryCatch["Try/Catch\ntrack exception flow"] + + IfStatement --> MergeBranches["Merge Branches\ninheritAlternatives()"] + Loop --> LoopExit["Loop Exit\nmergeBranch()"] + TryCatch --> CatchFlow["Catch Flow\nhandle exceptions"] + + MergeBranches --> Continue["Continue Compilation"] + LoopExit --> Continue + CatchFlow --> Continue + + Continue --> EndCompilation["End Function\nCompilation"] +``` + +Sources: [src/flow.ts:206-242](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L206-L242), [src/flow.ts:329-365](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L329-L365) + +## Flow Flags + +The flow analyzer uses a set of flags to track the characteristics of each control flow branch. These flags indicate conditions such as whether a branch always returns, throws an exception, or terminates in some other way. + +Key flow flags include: + +| Flag | Description | +|------|-------------| +| `Returns` | This flow always returns | +| `ReturnsWrapped` | This flow always returns a properly wrapped value (relevant for small integers) | +| `ReturnsNonNull` | This flow always returns a non-null value | +| `Throws` | This flow always throws an exception | +| `Breaks` | This flow always breaks out of a loop or switch | +| `Continues` | This flow always continues to the next loop iteration | +| `Terminates` | This flow always terminates (returns, throws, etc.) | +| `ConditionallyReturns` | This flow conditionally returns in a child flow | +| `ConditionallyThrows` | This flow conditionally throws in a child flow | + +These flags help the compiler determine: +- When code is unreachable +- Whether values need null checking +- If specific optimizations can be applied + +Sources: [src/flow.ts:103-171](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L103-L171) + +## Local Variable Tracking + +A critical function of Control Flow Analysis is tracking the state of local variables throughout a function's execution. The `Flow` class maintains an array of `LocalFlags` that correspond to each local variable in a function. + +### Local Flags + +The following flags track the state of each local variable: + +| Flag | Description | +|------|-------------| +| `Constant` | The local variable is a constant value | +| `Wrapped` | The local is properly wrapped (relevant for small integer types) | +| `NonNull` | The local is guaranteed to be non-null | +| `Initialized` | The local has been initialized | + +### Local Tracking Example + +For example, when an if-statement checks if a variable is non-null and then executes a branch only if that condition is true, the `Flow` class will automatically mark that variable as `NonNull` in the true branch: + +```mermaid +flowchart TD + Start["var x: string | null = ..."] --> Check["if (x !== null)"] + Check -->|"True Branch"| TrueBranch["x is marked NonNull\nin this flow"] + Check -->|"False Branch"| FalseBranch["x remains possibly null\nin this flow"] + TrueBranch --> MergePoint["Merge point:\nx might be null again"] + FalseBranch --> MergePoint +``` + +The flow analyzer tracks this information by using methods like `inheritNonnullIfTrue()` and `inheritNonnullIfFalse()` which update local states based on conditions. + +Sources: [src/flow.ts:173-186](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L173-L186), [src/flow.ts:547-574](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L547-L574), [src/flow.ts:979-1181](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L979-L1181) + +## Branch Handling + +Control flow analysis relies on creating, forking, and merging flows to handle branching code paths correctly. The `Flow` class provides sophisticated mechanisms for this purpose. + +### Forking Flows + +When the compiler encounters a branching statement (like an if/else), it forks the current flow into separate branches: + +- `fork()`: Creates a new child flow for a generic branch +- `forkThen()`: Creates a flow where a specific condition is true +- `forkElse()`: Creates a flow where a specific condition is false + +### Merging Flows + +After processing different branches, the compiler needs to merge their states: + +- `mergeBranch()`: Merges a branch (like a then-block without an else) with the current flow +- `inheritAlternatives()`: Merges two alternative branches (then and else) into the current flow +- `inherit()`: Inherits flags from another flow into this one + +When merging, the system must carefully determine which properties are guaranteed across all paths. For example, a variable is only considered non-null after merging if it's non-null in all merged branches. + +```mermaid +flowchart TD + ParentFlow["Parent Flow"] --> |"fork()"| ThenFlow["Then Flow"] + ParentFlow --> |"fork()"| ElseFlow["Else Flow"] + + ThenFlow --> |"process\nthen block"| ProcessedThen["Then Flow\nwith updated flags"] + ElseFlow --> |"process\nelse block"| ProcessedElse["Else Flow\nwith updated flags"] + + ProcessedThen --> |"merge"| MergedFlow["Merged Flow\nkeeps only guaranteed properties"] + ProcessedElse --> |"merge"| MergedFlow +``` + +Sources: [src/flow.ts:329-411](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L329-L411), [src/flow.ts:651-915](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L651-L915) + +## Integer Overflow Analysis + +A unique feature of AssemblyScript's control flow analysis is its ability to track potential integer overflows for small integer types (i8, u8, i16, u16, bool). The `canOverflow()` method analyzes expressions to determine if they might overflow their value range. + +The analyzer considers various factors: + +1. The type of the expression (only small integer types can overflow) +2. The operations being performed +3. Whether operands are constants or wrapped values +4. The specific values of constants where applicable + +This analysis helps the compiler: +- Insert appropriate value wrapping operations when needed +- Optimize out unnecessary wrapping when an operation can't overflow +- Ensure types behave as expected without unexpected overflow behavior + +The system is particularly sophisticated in how it analyzes different operations. For example, it knows that: +- Comparisons never overflow (result is always 0 or 1) +- Multiplying by 0 or 1 has special overflow properties +- Bit shifts by certain amounts can eliminate overflow possibilities + +Sources: [src/flow.ts:1183-1443](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L1183-L1443), [src/flow.ts:1472-1479](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L1472-L1479) + +## Scoped Variables + +The Control Flow Analysis system tracks scoped variables (variables defined within blocks) through dedicated mechanisms: + +- `addScopedLocal()`: Adds a new scoped local variable +- `getScopedLocal()`: Gets a scoped local by name +- `lookupLocal()`: Searches up the flow hierarchy for a local variable +- `addScopedTypeAlias()`: Adds a scoped type alias + +This tracking is crucial for proper variable scoping, especially in blocks like loops and if statements where variables might only exist within that scope. + +```mermaid +flowchart TD + GlobalScope["Function Scope"] --> BlockScope1["Block Scope 1"] + GlobalScope --> BlockScope2["Block Scope 2"] + BlockScope1 --> NestedBlock["Nested Block"] + + GlobalScope -->|"contains"| GlobalVars["Global Variables\n- accessible everywhere"] + BlockScope1 -->|"contains"| BlockVars1["Scoped Variables\n- only in Block 1\n- and nested blocks"] + BlockScope2 -->|"contains"| BlockVars2["Scoped Variables\n- only in Block 2"] + NestedBlock -->|"contains"| NestedVars["Nested Variables\n- only in Nested Block"] + + LookupVar["lookupLocal()"] -->|"searches up"| NestedBlock + LookupVar -->|"then"| BlockScope1 + LookupVar -->|"then"| GlobalScope +``` + +Sources: [src/flow.ts:413-537](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L413-L537) + +## Constructor Analysis + +Flow Analysis has special handling for class constructors, tracking which fields of `this` have been initialized. This helps enforce initialization requirements and detect potential errors like accessing uninitialized fields. + +When analyzing a constructor, the system: +1. Creates a map of field flags to track each field's state +2. Sets the `Initialized` flag for fields that have initializers or are initialized as constructor parameters +3. Updates field initialization states as the constructor executes +4. Detects accesses to `this` and calls to `super()` +5. Enforces language rules about field initialization before use + +Sources: [src/flow.ts:189-192](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L189-L192), [src/flow.ts:577-631](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L577-L631) + +## Integration with the Compiler + +Control Flow Analysis is tightly integrated with the AssemblyScript compiler. It appears at the "Flow Analysis" step in the compilation pipeline, between type resolution and WebAssembly code generation. + +The information collected during flow analysis directly influences: + +1. Code generation strategy +2. Optimization opportunities +3. Error and warning generation +4. Runtime checks insertion (null checks, bounds checks) + +```mermaid +flowchart TD + subgraph "AssemblyScript Compilation Pipeline" + ParseSource["Parse Source Files"] --> CreateProgram["Create Program Object"] + CreateProgram --> Resolve["Resolve Types and Symbols"] + Resolve --> FlowAnalysis["Control Flow Analysis\n(src/flow.ts)"] + FlowAnalysis --> GenerateWASM["Generate WebAssembly"] + GenerateWASM --> ApplyTransforms["Apply Custom Transforms"] + ApplyTransforms --> Optimize["Optimize (Binaryen)"] + end + + FlowAnalysis -->|"provides info on"| TerminatingPaths["Terminating Paths"] + FlowAnalysis -->|"provides info on"| NonNullVars["Non-null Variables"] + FlowAnalysis -->|"provides info on"| IntegerOverflows["Potential Integer Overflows"] + FlowAnalysis -->|"provides info on"| UnreachableCode["Unreachable Code"] + + TerminatingPaths --> GenerateWASM + NonNullVars --> GenerateWASM + IntegerOverflows --> GenerateWASM + UnreachableCode --> GenerateWASM +``` + +Sources: [src/flow.ts:1-16](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L1-L16) + +## Performance Considerations + +Flow Analysis includes mechanisms to handle performance challenges: + +1. **Recompilation detection**: The `resetIfNeedsRecompile()` method determines if recompilation is needed due to incompatible local flags between loops, and resets if necessary. + +2. **Loop analysis**: Special handling is provided for loops, as their analysis can be more complex due to the potential for multiple iterations with changing variable states. + +3. **Efficient collection operations**: Use of utility functions like `cloneMap()` ensures efficient operations when working with collections of state data. + +Sources: [src/flow.ts:917-956](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/flow.ts#L917-L956), [src/util/collections.ts:1-23](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/util/collections.ts#L1-L23) + +## Summary + +Control Flow Analysis in AssemblyScript provides a sophisticated system for tracking program state throughout compilation. By analyzing how code flows and how variables change state, it enables the compiler to: + +1. Generate more efficient WebAssembly code +2. Detect potential errors at compile time +3. Eliminate unnecessary runtime checks +4. Make informed optimization decisions + +The system's ability to track variable states (null/non-null, wrapped/unwrapped, initialized/uninitialized) and flow termination (returns, throws, breaks) provides the foundation for AssemblyScript's ability to generate safe, efficient WebAssembly code. \ No newline at end of file diff --git a/docs/autogenerated_docs/2.2-module-system-and-binaryen-integration.md b/docs/autogenerated_docs/2.2-module-system-and-binaryen-integration.md new file mode 100644 index 0000000000..2c4adee79e --- /dev/null +++ b/docs/autogenerated_docs/2.2-module-system-and-binaryen-integration.md @@ -0,0 +1,319 @@ +# Module System and Binaryen Integration + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [package-lock.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package-lock.json) +- [package.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/package.json) +- [src/glue/binaryen.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/glue/binaryen.d.ts) +- [src/module.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts) + +
+ + + +This document describes how AssemblyScript interfaces with Binaryen to generate WebAssembly code. The module system is a critical component of the compilation pipeline, responsible for transforming AssemblyScript's internal representation into optimized WebAssembly modules. + +## Overview + +AssemblyScript uses Binaryen as its WebAssembly backend. While Binaryen provides both a C API and JavaScript API, AssemblyScript intentionally uses the C API directly through a thin wrapper layer. This integration enables the compiler to leverage Binaryen's powerful optimization capabilities while maintaining precise control over the generated WebAssembly. + +```mermaid +flowchart TD + subgraph "AssemblyScript Compiler" + Parser["Parser\nsrc/parser.ts"] + Resolver["Resolver\nsrc/resolver.ts"] + TypeChecker["Type Checker"] + ModuleSystem["Module System\nsrc/module.ts"] + end + + subgraph "Binaryen" + BinaryenAPI["Binaryen C API\nsrc/glue/binaryen.d.ts"] + Optimizer["WebAssembly Optimizer"] + CodeGen["WebAssembly Code Generator"] + end + + Parser --> Resolver + Resolver --> TypeChecker + TypeChecker --> ModuleSystem + ModuleSystem --> BinaryenAPI + BinaryenAPI --> Optimizer + Optimizer --> CodeGen + CodeGen --> WebAssemblyModule["WebAssembly Module (.wasm)"] +``` + +*Diagram: High-level integration between AssemblyScript and Binaryen* + +Sources: [src/module.ts:1-10](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L1-L10), [src/glue/binaryen.d.ts:1-10](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/glue/binaryen.d.ts#L1-L10) + +## Module System Architecture + +The module system acts as a bridge between AssemblyScript's high-level representation and Binaryen's lower-level WebAssembly operations. It maintains references to Binaryen entities and provides an API to construct WebAssembly modules programmatically. + +```mermaid +classDiagram + class Module { + +ModuleRef ref + +bool useShadowStack + +TypeRef sizeType + +create(bool, TypeRef) Module + +createFrom(Uint8Array, bool, TypeRef) Module + +addFunction(name, params, results, vars, body) + +addGlobal(name, type, mutable, init) + +addMemory(initial, maximum, exportName, segments) + +optimize() + +validate() + +emitText() + +emitBinary() + } + + class TypeRef { + +None + +Unreachable + +I32 + +I64 + +F32 + +F64 + +V128 + +Funcref + +Externref + +Anyref + +... + } + + class HeapTypeRef { + +Extern + +Func + +Any + +Eq + +I31 + +Struct + +Array + +String + +... + +isSubtype(ht, superHt) + +leastUpperBound(a, b) + } + + class ExpressionRef { + <> + } + + Module --> TypeRef : uses + Module --> HeapTypeRef : uses + Module --> ExpressionRef : manipulates +``` + +*Diagram: Core classes in the module system* + +Sources: [src/module.ts:32-172](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L32-L172), [src/module.ts:1375-1392](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L1375-L1392) + +## Binaryen Integration + +AssemblyScript's module system is designed as a thin wrapper around Binaryen's C API. This approach simplifies integration while ensuring efficient operations for WebAssembly code generation. + +### Key Integration Points + +1. **Type Mapping**: AssemblyScript maps its types to Binaryen's type system +2. **Expression Building**: All WebAssembly instructions are created through Binaryen +3. **Module Operations**: Module-level operations (functions, globals, memory) use Binaryen APIs +4. **Optimization**: AssemblyScript leverages Binaryen's optimization passes + +```mermaid +flowchart LR + subgraph "AssemblyScript Types" + ASType["Type System\nsrc/types.ts"] + end + + subgraph "Module System" + TypeRef["TypeRef\nsrc/module.ts"] + HeapTypeRef["HeapTypeRef\nsrc/module.ts"] + Module["Module\nsrc/module.ts"] + end + + subgraph "Binaryen" + BinaryenType["_BinaryenType*\nsrc/glue/binaryen.d.ts"] + BinaryenHeapType["_BinaryenHeapType*\nsrc/glue/binaryen.d.ts"] + BinaryenModule["_BinaryenModule*\nsrc/glue/binaryen.d.ts"] + end + + ASType --> TypeRef + TypeRef --> BinaryenType + HeapTypeRef --> BinaryenHeapType + Module --> BinaryenModule +``` + +*Diagram: Type mapping between AssemblyScript and Binaryen* + +Sources: [src/module.ts:61-87](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L61-L87), [src/module.ts:90-172](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L90-L172), [src/glue/binaryen.d.ts:45-98](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/glue/binaryen.d.ts#L45-L98) + +## Core Components + +### Module Class + +The `Module` class is the primary interface to Binaryen. It encapsulates a Binaryen module reference (`ModuleRef`) and provides methods to build and manipulate the WebAssembly module. + +Key features of the Module class: + +| Method | Purpose | +|--------|---------| +| `create` | Creates a new module instance | +| `createFrom` | Creates a module from existing WebAssembly binary data | +| `addFunction` | Adds a function declaration to the module | +| `addFunctionImport` | Adds an imported function | +| `addFunctionExport` | Exports a function to the host environment | +| `addGlobal` | Adds a global variable | +| `addMemory` | Configures the module's memory | +| `addTable` | Adds a WebAssembly table | +| `optimize` | Runs Binaryen's optimization passes | +| `validate` | Validates the WebAssembly module | +| `emitText` | Produces WebAssembly text format (.wat) | +| `emitBinary` | Produces WebAssembly binary format (.wasm) | + +Sources: [src/module.ts:1375-1392](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L1375-L1392) + +### Type System + +AssemblyScript's module system maps its types to Binaryen's type system through the `TypeRef` and `HeapTypeRef` namespaces: + +- **TypeRef**: Represents WebAssembly value types (i32, i64, f32, f64, v128) and reference types (externref, funcref) +- **HeapTypeRef**: Represents types for GC proposals, including structs and arrays + +The module system includes special handling for type operations like subtyping checks and least upper bound computations. + +```typescript +// Example of type constants in TypeRef +export namespace TypeRef { + export const None: TypeRef = 0; // No value + export const Unreachable: TypeRef = 1; // Unreachable + export const I32: TypeRef = 2; // 32-bit integer + export const I64: TypeRef = 3; // 64-bit integer + export const F32: TypeRef = 4; // 32-bit float + export const F64: TypeRef = 5; // 64-bit float + export const V128: TypeRef = 6; // 128-bit vector + export const Funcref = binaryen._BinaryenTypeFuncref(); + export const Externref = binaryen._BinaryenTypeExternref(); + // ... +} +``` + +Sources: [src/module.ts:61-87](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L61-L87), [src/module.ts:90-172](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L90-L172) + +### Expression System + +The module system provides a comprehensive set of functions to create WebAssembly expressions: + +- **Basic operations**: Constants, variables, memory access +- **Control flow**: Blocks, loops, if statements, branches +- **Function calls**: Direct and indirect calls +- **Memory operations**: Load, store, grow, size +- **SIMD operations**: Vector instructions +- **Reference types**: Reference manipulation operations +- **GC operations**: Struct and array operations for the GC proposal + +These operations are represented through constants and enums that map directly to Binaryen's operation codes: + +| Category | Examples | +|----------|----------| +| Expression IDs | `ExpressionId.Block`, `ExpressionId.Call`, `ExpressionId.LocalGet` | +| Unary Operations | `UnaryOp.ClzI32`, `UnaryOp.NegF32`, `UnaryOp.ExtendI32ToI64` | +| Binary Operations | `BinaryOp.AddI32`, `BinaryOp.MulF64`, `BinaryOp.ShlI32` | +| SIMD Operations | `SIMDExtractOp`, `SIMDReplaceOp`, `SIMDShiftOp` | + +Sources: [src/module.ts:229-323](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L229-L323), [src/module.ts:335-619](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L335-L619), [src/module.ts:622-1090](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L622-L1090) + +## Code Generation Flow + +When generating WebAssembly code, AssemblyScript follows a systematic process of building expressions and combining them into functions, which are then added to the module. + +```mermaid +flowchart TD + AST["AST Nodes"] --> ExprGen["Expression Generation"] + ExprGen --> Expressions["Binaryen Expressions"] + Expressions --> FunctionBuilder["Function Builder"] + + TypeInfo["Type Information"] --> FunctionBuilder + LocalVars["Local Variables"] --> FunctionBuilder + + FunctionBuilder --> Function["Binaryen Function"] + Function --> Module["Module"] + + Module --> Optimization["Binaryen Optimization"] + Optimization --> BinaryOutput["WebAssembly Binary"] + + subgraph "Module System" + ExprGen + FunctionBuilder + Module + Optimization + end +``` + +*Diagram: Code generation flow through the module system* + +Sources: [src/module.ts:1375-1392](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L1375-L1392) + +### Expression Building + +The module system provides a rich API for building WebAssembly expressions. Each expression type has a corresponding creation function and accessor methods: + +1. **Constants**: Creation of constant values (`i32.const`, `f64.const`, etc.) +2. **Variables**: Local and global variable access +3. **Memory operations**: Load and store operations with various types +4. **Control flow**: Blocks, loops, branches, and conditionals +5. **Function calls**: Direct and indirect function invocation + +Example flow for creating a simple addition: + +1. Create local.get expressions for two variables +2. Create a binary.add expression with the two local.get expressions +3. Use the result in a function body or other composite expression + +Sources: [src/module.ts:229-323](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L229-L323), [src/module.ts:335-619](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L335-L619), [src/module.ts:622-1090](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L622-L1090) + +## Feature Flags and WebAssembly Proposals + +AssemblyScript supports various WebAssembly proposals through Binaryen. The module system exposes these as feature flags: + +| Feature Flag | WebAssembly Proposal | +|--------------|----------------------| +| `FeatureFlags.MVP` | Minimum Viable Product (base WebAssembly) | +| `FeatureFlags.Atomics` | Atomic operations | +| `FeatureFlags.MutableGlobals` | Mutable global variables | +| `FeatureFlags.SIMD` | 128-bit SIMD operations | +| `FeatureFlags.BulkMemory` | Bulk memory operations | +| `FeatureFlags.ReferenceTypes` | Reference types | +| `FeatureFlags.GC` | Garbage collection | +| `FeatureFlags.Stringref` | String references | + +These flags can be combined to enable multiple features: + +```typescript +// Enable GC, reference types and string references +module.setFeatures( + FeatureFlags.GC | + FeatureFlags.ReferenceTypes | + FeatureFlags.Stringref +); +``` + +Sources: [src/module.ts:207-226](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L207-L226) + +## Shadow Stack Support + +AssemblyScript's module system can optionally use a shadow stack for function calls, which is important for supporting certain advanced features like exception handling. This is controlled through the `useShadowStack` parameter when creating a module: + +```typescript +// Create a module with shadow stack enabled +const module = Module.create(true, TypeRef.I32); +``` + +The shadow stack affects how function calls are generated and how certain operations like exceptions are handled. + +Sources: [src/module.ts:1380](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/module.ts#L1380) + +## Conclusion + +The module system is a critical component of AssemblyScript's compiler, serving as the bridge between AssemblyScript's high-level representation and Binaryen's WebAssembly generation capabilities. By wrapping Binaryen's C API directly, AssemblyScript achieves efficient and flexible WebAssembly code generation with precise control over the output. \ No newline at end of file diff --git a/docs/autogenerated_docs/3-standard-library.md b/docs/autogenerated_docs/3-standard-library.md new file mode 100644 index 0000000000..479ce04f24 --- /dev/null +++ b/docs/autogenerated_docs/3-standard-library.md @@ -0,0 +1,365 @@ +# Standard Library + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [NOTICE](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/NOTICE) +- [std/assembly/builtins.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts) +- [std/assembly/index.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts) +- [std/portable/index.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/portable/index.d.ts) +- [std/portable/index.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/portable/index.js) +- [tests/compiler/builtins.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/builtins.ts) + +
+ + + +The AssemblyScript Standard Library provides fundamental types, data structures, and utility functions necessary for writing WebAssembly applications. It serves as the foundation for AssemblyScript programs, offering functionality comparable to standard libraries in other languages while being specifically optimized for WebAssembly's needs. + +This document provides a comprehensive overview of the AssemblyScript standard library's core types, built-in functions, and components. For information about specific library components such as Array and String, see [Array and String](#3.1), and for memory management details, see [Memory Management](#6). + +## Core Types and Type System + +AssemblyScript's type system is designed to provide static type safety while targeting WebAssembly's limited set of primitive types. The type system is defined in `index.d.ts` under the standard library. + +```mermaid +graph TD + subgraph "AssemblyScript Type System" + subgraph "Integer Types" + I8["i8 (-128 to 127)"] + I16["i16 (-32768 to 32767)"] + I32["i32 (-2^31 to 2^31-1)"] + I64["i64 (-2^63 to 2^63-1)"] + U8["u8 (0 to 255)"] + U16["u16 (0 to 65535)"] + U32["u32 (0 to 2^32-1)"] + U64["u64 (0 to 2^64-1)"] + ISIZE["isize (i32/i64 depend on target)"] + USIZE["usize (u32/u64 depend on target)"] + end + + subgraph "Floating Point Types" + F32["f32 (32-bit float)"] + F64["f64 (64-bit float)"] + end + + subgraph "Special Types" + BOOL["bool (true/false)"] + V128["v128 (128-bit vector)"] + end + + subgraph "Reference Types" + ARRAYT["Array Types"] + STRINGT["String Type"] + OBJECTT["Object Types"] + FUNCT["Function References"] + end + end +``` + +Sources: [std/assembly/index.d.ts:10-81](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L10-L81) + +### Integer Types + +AssemblyScript provides a comprehensive set of integer types with explicit bit widths: + +| Type | Description | Size | Range | +|---------|-----------------------------------|---------|----------------------------------------| +| `i8` | 8-bit signed integer | 1 byte | -128 to 127 | +| `i16` | 16-bit signed integer | 2 bytes | -32,768 to 32,767 | +| `i32` | 32-bit signed integer | 4 bytes | -2,147,483,648 to 2,147,483,647 | +| `i64` | 64-bit signed integer | 8 bytes | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | +| `u8` | 8-bit unsigned integer | 1 byte | 0 to 255 | +| `u16` | 16-bit unsigned integer | 2 bytes | 0 to 65,535 | +| `u32` | 32-bit unsigned integer | 4 bytes | 0 to 4,294,967,295 | +| `u64` | 64-bit unsigned integer | 8 bytes | 0 to 18,446,744,073,709,551,615 | +| `isize` | Pointer-sized signed integer | 4/8 bytes | Depends on target (32-bit or 64-bit) | +| `usize` | Pointer-sized unsigned integer | 4/8 bytes | Depends on target (32-bit or 64-bit) | + +Each integer type has associated `MIN_VALUE` and `MAX_VALUE` constants defining their ranges, as well as helpful utility functions like `parse()` for string conversion. + +Sources: [std/assembly/index.d.ts:10-29](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L10-L29), [std/assembly/builtins.ts:277-295](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L277-L295), [std/assembly/builtins.ts:303-317](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L303-L317), [std/assembly/builtins.ts:323-337](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L323-L337), [std/assembly/builtins.ts:841-858](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L841-L858), [std/assembly/builtins.ts:864-880](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L864-L880), [std/assembly/builtins.ts:886-921](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L886-L921), [std/assembly/builtins.ts:927-942](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L927-L942), [std/assembly/builtins.ts:948-965](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L948-L965) + +### Floating-Point Types + +AssemblyScript provides two floating-point types: + +| Type | Description | Size | Precision | +|---------|---------------------------------|---------|-------------------------| +| `f32` | 32-bit IEEE 754 floating point | 4 bytes | ~7 decimal digits | +| `f64` | 64-bit IEEE 754 floating point | 8 bytes | ~15-16 decimal digits | + +Floating-point types include useful constants such as: +- `MIN_VALUE`: Smallest representable value +- `MAX_VALUE`: Largest representable value +- `EPSILON`: Difference between 1 and the smallest value greater than 1 +- `NaN`: Not a Number value +- `POSITIVE_INFINITY` and `NEGATIVE_INFINITY` +- `MIN_SAFE_INTEGER` and `MAX_SAFE_INTEGER`: Integer values that can be represented exactly + +Sources: [std/assembly/index.d.ts:31-35](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L31-L35), [std/assembly/builtins.ts:993-1035](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L993-L1035), [std/assembly/builtins.ts:1111-1156](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L1111-L1156) + +### Boolean Type + +The `bool` type represents a boolean value (true or false), but unlike in JavaScript, it's not directly interchangeable with numbers. When necessary, AssemblyScript does implicit conversions following WebAssembly's conventions. + +Sources: [std/assembly/index.d.ts:30](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L30), [std/assembly/builtins.ts:969-986](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L969-L986) + +### Special Types + +AssemblyScript also provides special types for specific use cases: + +| Type | Description | +|--------------|-----------------------------------------------------------| +| `v128` | 128-bit vector type for SIMD operations | +| `funcref` | Nullable function reference | +| `externref` | Nullable external reference | +| `anyref` | Nullable any reference | +| `stringref` | Nullable string reference | + +Sources: [std/assembly/index.d.ts:36-81](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L36-L81) + +## Built-in Functions and Constants + +AssemblyScript provides a rich set of built-in functions and constants. Many of these map directly to WebAssembly instructions, offering efficient operations with a familiar syntax. + +```mermaid +graph TD + subgraph "Built-in Functions" + subgraph "Mathematical Operations" + ABS["abs"] + MAX["max"] + MIN["min"] + SQRT["sqrt"] + CEIL["ceil"] + FLOOR["floor"] + TRUNC["trunc"] + NEAREST["nearest"] + end + + subgraph "Bit Manipulation" + CLZ["clz"] + CTZ["ctz"] + POPCNT["popcnt"] + ROTL["rotl"] + ROTR["rotr"] + BSWAP["bswap"] + end + + subgraph "Memory Operations" + LOAD["load"] + STORE["store"] + MEMORY["memory"] + end + + subgraph "Type Helpers" + SIZEOF["sizeof()"] + ALIGNOF["alignof()"] + OFFSETOF["offsetof()"] + NAMEOF["nameof()"] + IDOF["idof()"] + end + end +``` + +Sources: [std/assembly/index.d.ts:142-170](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L142-L170), [std/assembly/index.d.ts:197-282](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L197-L282), [std/assembly/builtins.ts:4-217](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L4-L217) + +### Math Functions + +The standard library includes a comprehensive set of mathematical functions: + +| Function | Description | +|-------------------|---------------------------------------------------------------| +| `abs` | Computes the absolute value of an integer or float | +| `max` | Determines the maximum of two integers or floats | +| `min` | Determines the minimum of two integers or floats | +| `ceil` | Performs the ceiling operation (round up to nearest integer) | +| `floor` | Performs the floor operation (round down to nearest integer) | +| `nearest` | Rounds to the nearest integer tied to even | +| `sqrt` | Calculates the square root | +| `trunc` | Rounds to the nearest integer towards zero | +| `copysign` | Composes a float from the magnitude of x and the sign of y | + +Sources: [std/assembly/index.d.ts:154-175](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L154-L175), [std/assembly/builtins.ts:91-127](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L91-L127) + +### Bit Manipulation Functions + +Efficient bit-level operations are crucial for many algorithms: + +| Function | Description | +|-------------------|---------------------------------------------------------------| +| `clz` | Counts leading zero bits | +| `ctz` | Counts trailing zero bits | +| `popcnt` | Counts the number of 1 bits | +| `rotl` | Rotates bits left | +| `rotr` | Rotates bits right | +| `bswap` | Reverses the byte order (endianness swap) | + +Sources: [std/assembly/index.d.ts:143-153](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L143-L153), [std/assembly/builtins.ts:71-87](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L71-L87) + +### Memory Operations + +Direct memory manipulation functions: + +| Function | Description | +|-----------------|----------------------------------------------------------------| +| `load` | Loads a value of the specified type from memory | +| `store` | Stores a value of the specified type to memory | + +These low-level operations allow direct access to the linear memory. They're generally considered unsafe and should be used carefully. + +Sources: [std/assembly/index.d.ts:190-193](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L190-L193), [std/assembly/builtins.ts:158-163](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L158-L163) + +### Atomic Operations + +For applications using threads, the standard library provides atomic operations through the `atomic` namespace: + +| Function | Description | +|------------------------|----------------------------------------------------------| +| `atomic.load` | Atomically loads a value from memory | +| `atomic.store` | Atomically stores a value to memory | +| `atomic.add` | Atomically adds a value in memory | +| `atomic.sub` | Atomically subtracts a value in memory | +| `atomic.and` | Atomically performs a bitwise AND operation | +| `atomic.or` | Atomically performs a bitwise OR operation | +| `atomic.xor` | Atomically performs a bitwise XOR operation | +| `atomic.xchg` | Atomically exchanges a value in memory | +| `atomic.cmpxchg` | Atomically compares and exchanges a value in memory | +| `atomic.wait` | Waits on a memory address | +| `atomic.notify` | Notifies waiting agents | +| `atomic.fence` | Ensures ordering of operations | + +Sources: [std/assembly/index.d.ts:284-310](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L284-L310), [std/assembly/builtins.ts:219-267](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L219-L267) + +### Type Information Functions + +AssemblyScript provides useful functions for type introspection: + +| Function | Description | +|-------------------|---------------------------------------------------------------| +| `sizeof()` | Determines the byte size of the specified type | +| `alignof()` | Determines the alignment (log2) of the specified type | +| `offsetof()` | Determines the offset of fields within a class type | +| `nameof()` | Determines the name of a given type | +| `idof()` | Determines the unique runtime id of a class type | + +Sources: [std/assembly/index.d.ts:208-220](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L208-L220), [std/assembly/builtins.ts:167-183](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L167-L183) + +### Type Testing Functions + +The library provides a rich set of type checking functions: + +| Function | Description | +|-----------------------|-----------------------------------------------------------| +| `isBoolean()` | Tests if the type is a boolean | +| `isInteger()` | Tests if the type is an integer | +| `isSigned()` | Tests if the type can represent negative numbers | +| `isFloat()` | Tests if the type is a float | +| `isReference()` | Tests if the type is a reference type | +| `isString()` | Tests if the type can be used as a string | +| `isArray()` | Tests if the type can be used as an array | +| `isFunction()` | Tests if the type is a function | +| `isNullable()` | Tests if the type is nullable | + +Sources: [std/assembly/index.d.ts:234-263](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L234-L263), [std/assembly/builtins.ts:7-59](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/builtins.ts#L7-L59) + +### Compiler Constants + +The standard library also exposes various compiler constants, which provide information about the compilation environment: + +| Constant | Description | +|------------------------------|-------------------------------------------------------| +| `ASC_TARGET` | Compiler target (0=JS, 1=WASM32, 2=WASM64) | +| `ASC_RUNTIME` | Runtime type (0=Stub, 1=Minimal, 2=Incremental) | +| `ASC_MEMORY_BASE` | Provided memoryBase option | +| `ASC_TABLE_BASE` | Provided tableBase option | +| `ASC_OPTIMIZE_LEVEL` | Provided optimizeLevel option | +| `ASC_SHRINK_LEVEL` | Provided shrinkLevel option | +| `ASC_FEATURE_*` | Various feature flags (e.g., SIMD, threads, etc.) | + +These constants are particularly useful for conditional compilation or optimizing code based on target environment and available features. + +Sources: [std/assembly/index.d.ts:85-138](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L85-L138) + +## Standard Library Structure + +The AssemblyScript standard library is organized in a modular fashion, with core types and functions defined in the root namespace and additional functionality organized into specific components. + +```mermaid +graph TD + subgraph "Standard Library Components" + CORE["Core Types & Functions
(index.d.ts, builtins.ts)"] + + CORE --> ARRAY["Array
(array.ts)"] + CORE --> STRING["String
(string.ts)"] + CORE --> TYPEDARRAY["TypedArrays
(typedarray.ts)"] + CORE --> MATH["Math
(math.ts)"] + CORE --> DATE["Date
(date.ts)"] + CORE --> MAP["Map
(map.ts)"] + CORE --> SET["Set
(set.ts)"] + + ARRAY --> ARRAYBUFFER["ArrayBuffer"] + ARRAY --> DATAVIEW["DataView"] + + TYPEDARRAY --> INT8ARRAY["Int8Array"] + TYPEDARRAY --> UINT8ARRAY["Uint8Array"] + TYPEDARRAY --> INT16ARRAY["Int16Array"] + TYPEDARRAY --> UINT16ARRAY["Uint16Array"] + TYPEDARRAY --> INT32ARRAY["Int32Array"] + TYPEDARRAY --> UINT32ARRAY["Uint32Array"] + TYPEDARRAY --> FLOAT32ARRAY["Float32Array"] + TYPEDARRAY --> FLOAT64ARRAY["Float64Array"] + + STRING --> STRINGUTILS["String Utilities
(util/string.ts)"] + + MATH --> MATHCONST["Math Constants"] + MATH --> MATHFUNC["Math Functions"] + end +``` + +Sources: [std/assembly/index.d.ts:1-283](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/index.d.ts#L1-L283) + +## Portable Environment + +The AssemblyScript standard library includes a portable environment that enables code to be compiled to both WebAssembly and JavaScript. This is provided through two main files: + +1. `std/portable/index.d.ts` - TypeScript definitions for the portable environment +2. `std/portable/index.js` - JavaScript implementations of the AssemblyScript standard library + +The portable environment defines the same types and functions as the WebAssembly environment but implements them in JavaScript, allowing code to be shared between WebAssembly and JavaScript execution contexts. + +```mermaid +graph TD + subgraph "Portable Environment" + ASC["AssemblyScript Code"] + + ASC --> COMPILER["AssemblyScript Compiler"] + ASC --> TSCCOMPILER["TypeScript Compiler"] + + COMPILER --> WASM["WebAssembly Module"] + TSCCOMPILER --> JS["JavaScript Module"] + + WASM --> STDLIB["AssemblyScript Standard Library
(std/assembly/*)"] + JS --> PORTABLE["Portable Standard Library
(std/portable/*)"] + end +``` + +Sources: [std/portable/index.d.ts:1-462](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/portable/index.d.ts#L1-L462), [std/portable/index.js:1-415](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/portable/index.js#L1-L415) + +The portable environment is particularly useful for: +- Testing AssemblyScript code in JavaScript environments +- Developing libraries that can be used in both WebAssembly and JavaScript +- Creating fallback implementations for browsers without WebAssembly support + +Key differences in the portable environment: +- 64-bit integers are emulated using JavaScript numbers or BigInt (with limitations) +- Some WebAssembly-specific optimizations are not available +- Memory model differs (JavaScript garbage collection vs. AssemblyScript's memory management) + +Sources: [std/portable/index.d.ts:15-28](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/portable/index.d.ts#L15-L28), [std/portable/index.js:4-17](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/portable/index.js#L4-L17) + +## Conclusion + +The AssemblyScript standard library provides a rich set of types, functions, and utilities that form the foundation for AssemblyScript applications. With its familiar TypeScript-like syntax and WebAssembly-specific optimizations, it strikes a balance between developer ergonomics and performance. \ No newline at end of file diff --git a/docs/autogenerated_docs/3.1-array-and-string.md b/docs/autogenerated_docs/3.1-array-and-string.md new file mode 100644 index 0000000000..08fef4518d --- /dev/null +++ b/docs/autogenerated_docs/3.1-array-and-string.md @@ -0,0 +1,400 @@ +# Array and String + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [std/assembly/array.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts) +- [std/assembly/string.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/string.ts) +- [tests/compiler/std/array.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/array.ts) +- [tests/compiler/std/string.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/string.ts) + +
+ + + +This page documents the Array and String implementations in the AssemblyScript standard library, which provide fundamental data structures for collections and text manipulation. These classes are core building blocks for most AssemblyScript applications and are implemented with careful attention to memory efficiency and runtime safety. + +## Memory Structure + +Both Array and String have carefully designed memory layouts to optimize performance while ensuring type safety. + +```mermaid +classDiagram + class Array~T~ { + buffer: ArrayBuffer + dataStart: usize + byteLength: i32 + length_: i32 + [key: number]: T + } + + class String { + <> + +MAX_LENGTH: i32 + +length: i32 + +Various string methods... + } + + note for Array~T~ "Memory layout mimics ArrayBufferView" + note for String "Internally stores UTF-16 code units" +``` + +### Array Memory Layout + +The Array class has a specific memory structure that intentionally mimics the ArrayBufferView interface: + +```mermaid +flowchart LR + subgraph "Array Memory Structure" + A["Array Instance"] --> B["Header (OBJECT)"] + A --> C["buffer: ArrayBuffer"] + A --> D["dataStart: usize"] + A --> E["byteLength: i32"] + A --> F["length_: i32"] + + C --> G["ArrayBuffer"] + G --> H["Element 0"] + G --> I["Element 1"] + G --> J["..."] + G --> K["Element n-1"] + + D -.-> H + end +``` + +Sources: [std/assembly/array.ts:41-56](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:41-56#L41-L56) + +Key characteristics: +- `buffer`: Points to an ArrayBuffer containing the actual data +- `dataStart`: Provides direct memory access to the start of the array data +- `byteLength`: Tracks the capacity of the array in bytes +- `length_`: Stores the actual number of elements + +Arrays have a minimum capacity (8 elements) and grow by doubling their capacity when needed to amortize allocation costs. + +### String Memory Layout + +Strings in AssemblyScript are final abstract classes that store UTF-16 encoded text: + +```mermaid +flowchart LR + subgraph "String Memory Structure" + A["String Instance"] --> B["Header (OBJECT)"] + A --> C["UTF-16 Code Units"] + C --> D["Code Unit 0"] + C --> E["Code Unit 1"] + C --> F["..."] + C --> G["Code Unit n-1"] + end +``` + +Sources: [std/assembly/string.ts:10-86](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/string.ts:10-86#L10-L86) + +Key characteristics: +- Implemented as a final abstract class +- Internally stores a sequence of 16-bit code units (UTF-16) +- Provides the `length` property that returns the number of code units +- Defines a maximum length based on block size constraints +- All string operations create new instances (immutable design) + +## Array Implementation + +### Creation and Capacity Management + +Arrays dynamically manage their capacity as elements are added: + +```mermaid +flowchart TD + subgraph "Array Capacity Management" + A["Array Creation"] --> B["new Array(length)"] + A --> C["Array.create(capacity)"] + + D["Growth Management"] --> E["push()/unshift()"] + E --> F["ensureCapacity()"] + F --> G["Current capacity sufficient?"] + G -->|"Yes"| H["Use existing buffer"] + G -->|"No"| I["Calculate new capacity"] + I --> J["Allocate new buffer"] + J --> K["Copy old elements"] + K --> L["Update internal pointers"] + end +``` + +Sources: [std/assembly/array.ts:15-38](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:15-38#L15-L38), [std/assembly/array.ts:69-86](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:69-86#L69-L86) + +Key implementation details: +- Arrays start with a minimum capacity of 8 elements +- The `ensureCapacity` function handles dynamic resizing: + - Checks if current capacity is sufficient + - Typically doubles capacity when growing + - Allocates new memory with `__new`/`__renew` + - Copies existing elements to the new buffer + - Updates internal pointers +- Capacity is constrained by `BLOCK_MAXSIZE` + +### Element Access and Mutation + +Array provides methods for accessing and manipulating elements: + +```mermaid +flowchart TD + subgraph "Array Element Operations" + A["Element Access"] --> B["array[index]"] + A --> C["array.at(index)"] + + D["Element Mutation"] --> E["array[index] = value"] + + F["Array Modification"] --> G["End Operations"] + F --> H["Start Operations"] + F --> I["Middle Operations"] + + G --> J["push()/pop()"] + H --> K["unshift()/shift()"] + I --> L["splice()"] + end +``` + +Sources: [std/assembly/array.ts:113-151](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:113-151#L113-L151), [std/assembly/array.ts:206-371](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:206-371#L206-L371) + +Implementation characteristics: +- Direct indexing (`array[index]`) includes bounds checking and throws a RangeError when out of bounds +- `at` method supports negative indices (counting from the end) +- For non-nullable reference types, accessing an uninitialized (null) element throws an error +- `push` ensures capacity before adding elements +- `shift`/`unshift` use `memory.copy` to move elements +- `splice` extracts elements and adjusts the array + +### Iteration and Higher-Order Functions + +Array implements numerous higher-order functions: + +```mermaid +flowchart TD + subgraph "Array Higher-Order Functions" + A["Iteration"] --> B["forEach()"] + + C["Transformation"] --> D["map()"] + C --> E["filter()"] + + F["Reduction"] --> G["reduce()"] + F --> H["reduceRight()"] + + I --> K["findLastIndex()"] + + L["Conditions"] --> M["every()"] + L --> N["some()"] + end +``` + +Sources: [std/assembly/array.ts:92-352](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:92-352#L92-L352) + +Key implementation patterns: +- Iterations are based on the initial length to prevent infinite loops if the array is modified during iteration +- Safe handling of reference types with proper runtime linking +- Optimization for common operation patterns +- Support for early termination in functions like `some` and `every` + +### Transformation and Utilities + +Arrays include methods for data transformation: + +```mermaid +flowchart TD + subgraph "Array Transformation" + A["Transformation"] --> B["sort()"] + A --> C["reverse()"] + A --> D["concat()"] + A --> E["slice()"] + A --> F["flat()"] + + G["Utilities"] --> H["join()"] + G --> I["includes()"] + G --> J["indexOf()/lastIndexOf()"] + G --> K["copyWithin()"] + end +``` + +Sources: [std/assembly/array.ts:153-511](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:153-511#L153-L511) + +Implementation highlights: +- `sort` implements a stable sorting algorithm that handles various edge cases +- `reverse` modifies the array in place using efficient memory operations +- `concat` creates a new array with combined elements +- `slice` extracts a portion of the array into a new instance +- `flat` flattens nested arrays +- Special handling for floating-point types (e.g., `includes` treats NaN as equal to itself) + +## String Implementation + +### Creation and Character Access + +Strings can be created and accessed through various methods: + +```mermaid +flowchart TD + subgraph "String Creation and Access" + A["Creation"] --> B["String literal"] + A --> C["String.fromCharCode()"] + A --> D["String.fromCharCodes()"] + A --> E["String.fromCodePoint()"] + + F["Character Access"] --> G["charAt()/at()"] + F --> H["charCodeAt()"] + F --> I["codePointAt()"] + end +``` + +Sources: [std/assembly/string.ts:14-83](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/string.ts:14-83#L14-L83) + +Implementation details: +- `fromCharCode` creates a string from UTF-16 code units +- `fromCharCodes` converts an array of code units to a string +- `fromCodePoint` handles surrogate pairs for Unicode code points above 0xFFFF +- Character access methods handle bounds checking appropriately +- `codePointAt` properly combines surrogate pairs + +### String Operations + +Strings provide comprehensive functionality for text manipulation: + +```mermaid +flowchart TD + subgraph "String Operations" + A["Concatenation"] --> B["concat()"] + A --> C["operator +"] + + D["Substring Extraction"] --> E["slice()"] + D --> F["substring()"] + D --> G["substr()"] + + H["Search"] --> I["indexOf()"] + H --> J["lastIndexOf()"] + H --> K["includes()"] + H --> L["startsWith()/endsWith()"] + + M["Modification"] --> N["replace()"] + M --> O["replaceAll()"] + M --> P["trim()/trimStart()/trimEnd()"] + M --> Q["padStart()/padEnd()"] + M --> R["repeat()"] + + S["Splitting"] --> T["split()"] + + U["Case Conversion"] --> V["toLowerCase()"] + U --> W["toUpperCase()"] + end +``` + +Sources: [std/assembly/string.ts:89-646](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/string.ts:89-646#L89-L646) + +Implementation characteristics: +- String operations create new string instances (immutability) +- Memory is explicitly managed using `__new` and `__renew` +- Operations optimize for common cases (e.g., empty strings) +- Case conversion handles: + - ASCII as a fast path + - Full Unicode case mapping + - Special cases like Greek sigma at the end of words + - Surrogate pairs and character expansion + +### String Encoding and Decoding + +The String class provides specialized namespaces for encoding/decoding: + +```mermaid +flowchart LR + subgraph "String Encoding Utilities" + A["String"] --> B["UTF8 Namespace"] + A --> C["UTF16 Namespace"] + + B --> D["encode()"] + B --> E["decode()"] + B --> F["byteLength()"] + B --> G["encodeUnsafe()/decodeUnsafe()"] + + C --> H["encode()"] + C --> I["decode()"] + C --> J["byteLength()"] + C --> K["encodeUnsafe()/decodeUnsafe()"] + end +``` + +Sources: [std/assembly/string.ts:661-843](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/string.ts:661-843#L661-L843) + +Key functionality: +- UTF-8 encoding handles proper code point conversion to 1-4 bytes +- Surrogate pair detection and handling +- Error modes for invalid sequences (WTF8, REPLACE, ERROR) +- Optimized encoding/decoding paths for common patterns +- Support for null termination + +## Integration with Runtime + +Both Array and String interact with AssemblyScript's runtime system: + +```mermaid +flowchart LR + subgraph "Runtime Integration" + A["Array/String Implementation"] --> B["Memory Management"] + A --> C["Reference Tracking"] + A --> D["Garbage Collection"] + + B --> E["__new / __renew"] + C --> F["__link"] + D --> G["__visit"] + end +``` + +Sources: [std/assembly/array.ts:514-525](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/array.ts:514-525#L514-L525) + +Integration points: +- Memory allocation via `__new` and `__renew` +- Arrays use `__link` to establish ownership of references they contain +- The `__visit` method supports garbage collection +- Efficient memory operations with `memory.copy` and `memory.fill` + +## Performance Considerations + +### Array Performance + +- Arrays start with a minimum capacity of 8 elements +- Capacity doubles on reallocation to amortize costs +- Operations at the end of the array (`push`/`pop`) are more efficient than operations at the beginning (`unshift`/`shift`) +- Arrays with non-nullable reference types include null checking for type safety +- Methods that mutate the array in place are generally more efficient than those creating new arrays + +### String Performance + +- Strings are immutable, so all operations create new instances +- Comparison operations optimize common cases (same instance, different lengths) +- Case transformations use ASCII fast paths when possible +- String methods balance correctness (Unicode handling) with performance +- For extensive string building, concatenating multiple strings at once is more efficient than sequential concatenation + +## Common Usage Patterns + +Arrays and strings are fundamental data structures used throughout most applications: + +```mermaid +flowchart TD + subgraph "Common Usage Patterns" + A["Collection Management"] --> B["Arrays for data storage"] + A --> C["Arrays for algorithm implementation"] + + D["Text Processing"] --> E["String parsing and validation"] + D --> F["Text transformation"] + D --> G["String searching"] + + H["Data Conversion"] --> I["Array.join() for serialization"] + H --> J["String.split() for parsing"] + H --> K["String.UTF8 for encoding/decoding"] + end +``` + +Sources: [tests/compiler/std/array.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/array.ts), [tests/compiler/std/string.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/string.ts) + +## Summary + +The Array and String implementations in AssemblyScript provide essential functionality while maintaining memory efficiency and type safety. They are designed with careful attention to memory management, offering comprehensive APIs for data manipulation and transformation. \ No newline at end of file diff --git a/docs/autogenerated_docs/3.2-math-library.md b/docs/autogenerated_docs/3.2-math-library.md new file mode 100644 index 0000000000..57854bdd40 --- /dev/null +++ b/docs/autogenerated_docs/3.2-math-library.md @@ -0,0 +1,280 @@ +# Math Library + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [std/assembly/math.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts) +- [tests/compiler/std/math.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/math.ts) + +
+ + + +The AssemblyScript Math Library provides mathematical operations and constants for both single-precision (f32) and double-precision (f64) floating-point arithmetic. It implements standard mathematical functions similar to JavaScript's Math object, but with native WebAssembly performance and precision characteristics. The library is part of the AssemblyScript standard library. + +## Overview + +The Math Library is implemented in [std/assembly/math.ts](). It consists of two main namespaces: + +1. `NativeMath` - Double-precision (f64) mathematical functions +2. `NativeMathf` - Single-precision (f32) mathematical functions + +Many implementations are based on the musl C library, with adaptations for WebAssembly, as noted in the source code comments. The library also includes specialized look-up tables for improved performance of certain functions. + +Sources: [std/assembly/math.ts:1-2764](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1-L2764) + +## Library Architecture + +The Math Library is organized into namespaces with parallel implementations for different precision levels: + +```mermaid +graph TD + subgraph "AssemblyScript Math Library" + MathLib["Math Library
std/assembly/math.ts"] + + subgraph "Double Precision" + NativeMath["NativeMath Namespace
(f64 operations)"] + Constants64["Mathematical Constants
(PI, E, LN2, etc.)"] + CoreFuncs64["Core Math Functions
(sin, cos, exp, log, etc.)"] + HelperFuncs64["Internal Helper Functions"] + LUTs64["Look-up Tables
(pow_lut, exp_lut, etc.)"] + end + + subgraph "Single Precision" + NativeMathf["NativeMathf Namespace
(f32 operations)"] + Constants32["Mathematical Constants
(PI, E, LN2, etc.)"] + CoreFuncs32["Core Math Functions
(sin, cos, exp, log, etc.)"] + HelperFuncs32["Internal Helper Functions"] + LUTs32["Look-up Tables
(powf_lut, expf_lut, etc.)"] + end + + MathLib --> NativeMath + MathLib --> NativeMathf + + NativeMath --> Constants64 + NativeMath --> CoreFuncs64 + CoreFuncs64 --> HelperFuncs64 + CoreFuncs64 --> LUTs64 + + NativeMathf --> Constants32 + NativeMathf --> CoreFuncs32 + CoreFuncs32 --> HelperFuncs32 + CoreFuncs32 --> LUTs32 + + JSMath["JavaScript Math Object
imported via bindings/dom"] + MathLib --> JSMath + end +``` + +Sources: [std/assembly/math.ts:1-7](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1-L7), [std/assembly/math.ts:415-1765](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L415-L1765), [std/assembly/math.ts:1946-2764](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1946-L2764) + +## Mathematical Constants + +Both `NativeMath` and `NativeMathf` provide the following constants: + +| Constant | Description | Value (approx.) | +|-----------|---------------------------------------------------|---------------------| +| E | Euler's number (base of natural logarithm) | 2.718281828459045 | +| LN2 | Natural logarithm of 2 | 0.6931471805599453 | +| LN10 | Natural logarithm of 10 | 2.302585092994046 | +| LOG2E | Base-2 logarithm of E | 1.4426950408889634 | +| LOG10E | Base-10 logarithm of E | 0.4342944819032518 | +| PI | Ratio of the circumference to the diameter of a circle | 3.141592653589793 | +| SQRT1_2 | Square root of 1/2 | 0.7071067811865476 | +| SQRT2 | Square root of 2 | 1.4142135623730951 | + +The constants are implemented using the `@lazy` decorator and precise bit representations to ensure accuracy: + +``` +@lazy +export const PI = reinterpret(0x400921FB54442D18); // 3.14159265358979323846 +``` + +Sources: [std/assembly/math.ts:417-447](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L417-L447), [std/assembly/math.ts:1949-1978](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1949-L1978) + +## Function Categories + +The Math Library implements the following categories of functions for both f32 and f64: + +```mermaid +graph TD + subgraph "Math Library Functions" + Basic["Basic Functions"] + Trig["Trigonometric Functions"] + InvTrig["Inverse Trigonometric Functions"] + Hyperbolic["Hyperbolic Functions"] + InvHyperbolic["Inverse Hyperbolic Functions"] + ExpLog["Exponential and Logarithmic"] + PowerRoot["Power and Root Functions"] + Special["Special Functions"] + Random["Random Number Generation"] + end + + Basic --> |"abs, ceil, floor, trunc, round, sign"| Implementation + Trig --> |"sin, cos, tan, sincos"| Implementation + InvTrig --> |"asin, acos, atan, atan2"| Implementation + Hyperbolic --> |"sinh, cosh, tanh"| Implementation + InvHyperbolic --> |"asinh, acosh, atanh"| Implementation + ExpLog --> |"exp, exp2, expm1, log, log2, log10, log1p"| Implementation + PowerRoot --> |"pow, sqrt, cbrt"| Implementation + Special --> |"hypot, fround, imul, clz32, mod, rem"| Implementation + Random --> |"random, seedRandom"| Implementation + + Implementation["Implementation Details:
- Lookup tables
- Special case handling
- Performance optimizations"] +``` + +Sources: [std/assembly/math.ts:415-1765](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L415-L1765), [std/assembly/math.ts:1946-2764](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1946-L2764) + +## Implementation Techniques + +The Math Library uses several techniques to balance precision, performance, and code size: + +### 1. Lookup Tables + +For computationally expensive functions like `exp`, `log`, and `pow`, lookup tables are used to improve performance: + +```mermaid +flowchart LR + Function["Math Function
(e.g., exp, log, pow)"] + Check["Check ASC_SHRINK_LEVEL"] + LUT["Use Lookup Table Implementation
(exp_lut, log_lut, pow_lut)"] + Direct["Use Direct Implementation"] + Result["Return Result"] + + Function --> Check + Check -->|"ASC_SHRINK_LEVEL < 1"| LUT + Check -->|"ASC_SHRINK_LEVEL >= 1"| Direct + LUT --> Result + Direct --> Result +``` + +The lookup tables are imported from `./util/math`: + +``` +import { + pow_lut, exp_lut, exp2_lut, log_lut, log2_lut, + powf_lut, expf_lut, exp2f_lut, logf_lut, log2f_lut +} from "./util/math"; +``` + +Sources: [std/assembly/math.ts:4-7](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L4-L7), [std/assembly/math.ts:781-826](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L781-L826), [std/assembly/math.ts:1128-1185](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1128-L1185), [std/assembly/math.ts:1199-1416](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1199-L1416) + +### 2. Special Case Handling + +Mathematical functions handle special cases like NaN, Infinity, zero, and specific input ranges for correctness and performance: + +```mermaid +flowchart TD + Function["Mathematical Function"] + SpecialCase1["Check for NaN/Infinity"] + SpecialCase2["Check for Zero"] + SpecialCase3["Check for Common Values
(1, -1, 0.5, etc.)"] + RangeCheck["Check Value Ranges"] + Calculate["Perform Calculation"] + Result["Return Result"] + + Function --> SpecialCase1 + SpecialCase1 -->|"Is special"| Result + SpecialCase1 -->|"Not special"| SpecialCase2 + SpecialCase2 -->|"Is zero"| Result + SpecialCase2 -->|"Not zero"| SpecialCase3 + SpecialCase3 -->|"Is common"| Result + SpecialCase3 -->|"Not common"| RangeCheck + RangeCheck --> Calculate + Calculate --> Result +``` + +Sources: [std/assembly/math.ts:462-1764](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L462-L1764) + +### 3. Optimization Levels + +The library uses the `ASC_SHRINK_LEVEL` constant to provide different implementations based on code size requirements: + +```typescript +if (ASC_SHRINK_LEVEL < 1) { + return exp_lut(x); // Optimized with lookup tables +} else { + // Direct calculation implementation + // ... +} +``` + +Sources: [std/assembly/math.ts:781-826](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L781-L826), [std/assembly/math.ts:967-1014](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L967-L1014), [std/assembly/math.ts:1128-1185](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1128-L1185), [std/assembly/math.ts:1199-1416](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1199-L1416) + +## Random Number Generation + +The Math Library includes a pseudo-random number generator: + +1. `random()` - Returns a random number between 0 (inclusive) and 1 (exclusive) +2. `seedRandom(value: i64)` - Seeds the random number generator + +The implementation uses a xorshift algorithm for f64 and xoroshiro64starstar for f32: + +```mermaid +flowchart TD + CheckSeed["Check if PRNG is seeded"] + GetSeed["Get seed from system"] + UpdateState["Update internal state"] + Generate["Generate random number"] + NormalizeToRange["Normalize to [0,1) range"] + Result["Return result"] + + CheckSeed -->|"Not seeded"| GetSeed + GetSeed --> UpdateState + CheckSeed -->|"Already seeded"| UpdateState + UpdateState --> Generate + Generate --> NormalizeToRange + NormalizeToRange --> Result +``` + +Sources: [std/assembly/math.ts:390-398](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L390-L398), [std/assembly/math.ts:1418-1442](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1418-L1442), [std/assembly/math.ts:2727-2740](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L2727-L2740) + +## Usage Examples + +The Math Library can be used in AssemblyScript code like this: + +```typescript +// Using double precision (f64) functions +import { NativeMath } from "./math"; + +function calculateDistance(x1: f64, y1: f64, x2: f64, y2: f64): f64 { + const dx = x2 - x1; + const dy = y2 - y1; + return NativeMath.sqrt(dx * dx + dy * dy); +} + +// Using single precision (f32) functions +import { NativeMathf } from "./math"; + +function normalizeVector(x: f32, y: f32): void { + const length = NativeMathf.sqrt(x * x + y * y); + return { x: x / length, y: y / length }; +} +``` + +## Performance Considerations + +1. **Precision vs. Size Trade-offs**: Use the appropriate precision (f32 or f64) based on your needs. Single-precision operations are generally faster but less precise. + +2. **Optimization Levels**: The `ASC_SHRINK_LEVEL` compiler option affects which implementations are used: + - Lower levels use lookup tables for better performance + - Higher levels use direct calculations for smaller code size + +3. **Special Cases**: Functions include optimizations for common cases (like `x = 0`, `x = 1`, etc.) that bypass expensive calculations. + +4. **Implementation Details**: Many functions are based on the musl C library, with adaptations for WebAssembly to ensure efficiency. + +Sources: [std/assembly/math.ts:371-388](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L371-L388), [std/assembly/math.ts:781-826](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L781-L826), [std/assembly/math.ts:967-1014](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L967-L1014), [std/assembly/math.ts:1128-1185](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1128-L1185), [std/assembly/math.ts:1199-1416](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/math.ts#L1199-L1416) + +## Relationship with JavaScript Math + +The AssemblyScript Math Library imports the JavaScript Math object for compatibility: + +```typescript +import { Math as JSMath } from "./bindings/dom"; +export { JSMath }; +``` + +This allows existing JavaScript code to be more easily ported to AssemblyScript, while the `NativeMath` and `NativeMathf` namespaces provide native WebAssembly implementations for better performance. \ No newline at end of file diff --git a/docs/autogenerated_docs/3.3-typedarrays.md b/docs/autogenerated_docs/3.3-typedarrays.md new file mode 100644 index 0000000000..22ff2511a1 --- /dev/null +++ b/docs/autogenerated_docs/3.3-typedarrays.md @@ -0,0 +1,335 @@ +# TypedArrays + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [std/assembly/typedarray.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts) +- [tests/compiler/std/typedarray.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts) + +
+ + + +TypedArrays in AssemblyScript provide fixed-length array-like objects that store numeric values of specific types in WebAssembly memory. These typed arrays offer memory-efficient storage and operations compared to regular arrays and are essential for binary data manipulation, interfacing with external systems, and optimizing memory usage in AssemblyScript applications. + +## TypedArray Hierarchy and Structure + +TypedArrays in AssemblyScript extend the `ArrayBufferView` class, which provides a view into an underlying `ArrayBuffer` that holds the actual data. + +```mermaid +classDiagram + ArrayBufferView <|-- Int8Array + ArrayBufferView <|-- Uint8Array + ArrayBufferView <|-- Uint8ClampedArray + ArrayBufferView <|-- Int16Array + ArrayBufferView <|-- Uint16Array + ArrayBufferView <|-- Int32Array + ArrayBufferView <|-- Uint32Array + ArrayBufferView <|-- Int64Array + ArrayBufferView <|-- Uint64Array + ArrayBufferView <|-- Float32Array + ArrayBufferView <|-- Float64Array + + class ArrayBufferView { + +buffer: ArrayBuffer + +dataStart: usize + +byteLength: i32 + +byteOffset: i32 + } + + class Int8Array { + +static BYTES_PER_ELEMENT: i32 + +length: i32 + +constructor(length: i32) + } + + class Float64Array { + +static BYTES_PER_ELEMENT: i32 + +length: i32 + +constructor(length: i32) + } +``` + +Sources: [std/assembly/typedarray.ts:8-1569](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L8-L1569) + +## Available TypedArray Types + +AssemblyScript provides several TypedArray implementations for different numeric types: + +| TypedArray | Element Type | Bytes Per Element | Value Range | +|------------|--------------|-------------------|-------------| +| Int8Array | i8 | 1 | -128 to 127 | +| Uint8Array | u8 | 1 | 0 to 255 | +| Uint8ClampedArray | u8 | 1 | 0 to 255 (with clamping) | +| Int16Array | i16 | 2 | -32,768 to 32,767 | +| Uint16Array | u16 | 2 | 0 to 65,535 | +| Int32Array | i32 | 4 | -2,147,483,648 to 2,147,483,647 | +| Uint32Array | u32 | 4 | 0 to 4,294,967,295 | +| Int64Array | i64 | 8 | -2^63 to 2^63-1 | +| Uint64Array | u64 | 8 | 0 to 2^64-1 | +| Float32Array | f32 | 4 | 32-bit IEEE floating point | +| Float64Array | f64 | 8 | 64-bit IEEE floating point | + +Sources: [std/assembly/typedarray.ts:8-1569](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L8-L1569), [tests/compiler/std/typedarray.ts:1-11](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts#L1-L11) + +## Memory Layout + +TypedArrays provide structured access to binary data in memory. Each TypedArray maintains a reference to its underlying `ArrayBuffer` and uses low-level memory operations to access and modify elements efficiently. + +```mermaid +graph TD + subgraph "Memory Model" + AB["ArrayBuffer (raw memory)"] + TA["TypedArray"] + + TA -->|references| AB + + subgraph "Memory Layout" + E1["Element[0]"] --- E2["Element[1]"] --- E3["Element[2]"] --- E4["..."] + end + + AB -->|contains| E1 + end + + subgraph "Key Properties" + BP["BYTES_PER_ELEMENT"] --> |"sizeof()"|S["Element Size"] + DS["dataStart"] --> |"Memory Pointer"|P["Start Address"] + BL["byteLength"] --> |"Total Bytes"|TB["Total Memory"] + L["length"] --> |"byteLength / BYTES_PER_ELEMENT"|C["Element Count"] + end +``` + +Sources: [std/assembly/typedarray.ts:8-147](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L8-L147), [std/assembly/typedarray.ts:287-432](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L287-L432) + +## Creating TypedArrays + +There are multiple ways to create TypedArrays in AssemblyScript: + +1. Creating a new TypedArray with a specified length: + ```typescript + let array = new Int32Array(5); // 5 elements, each initialized to 0 + ``` + +2. Using the `wrap` static method to create a view over an existing `ArrayBuffer`: + ```typescript + let buffer = new ArrayBuffer(20); + let array = Int32Array.wrap(buffer); // View into buffer with 5 Int32 elements + ``` + +3. Creating a slice (copy) or subarray (view) from an existing TypedArray: + ```typescript + let original = new Int32Array(10); + let slice = original.slice(2, 5); // New copy with elements 2, 3, 4 + let subarray = original.subarray(2, 5); // View into original with elements 2, 3, 4 + ``` + +Sources: [std/assembly/typedarray.ts:15-147](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L15-L147), [std/assembly/typedarray.ts:1571-1883](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L1571-L1883), [tests/compiler/std/typedarray.ts:29-85](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts#L29-L85) + +## Key Operations + +### Element Access + +Each TypedArray provides methods for accessing and modifying elements: + +```typescript +// Element access +let value = array[2]; // Get element at index 2 +array[2] = 42; // Set element at index 2 +let lastValue = array.at(-1); // Get last element using negative index +``` + +The `at()` method supports negative indices, where `-1` refers to the last element. + +Sources: [std/assembly/typedarray.ts:23-50](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L23-L50), [std/assembly/typedarray.ts:319-334](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L319-L334) + +### Searching + +TypedArrays include methods for searching elements: + +```typescript +let hasElement = array.includes(42); // Check if array contains a value +let indexOfElement = array.indexOf(42); // Find index of first occurrence +let lastIndexOfElement = array.lastIndexOf(42); // Find index of last occurrence +let evenNumberIndex = array.findIndex(x => x % 2 === 0); // Find first element satisfying a condition +let lastEvenNumberIndex = array.findLastIndex(x => x % 2 === 0); // Find last element satisfying a condition +``` + +Sources: [std/assembly/typedarray.ts:52-62](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L52-L62), [std/assembly/typedarray.ts:1746-1808](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L1746-L1808) + +### Transformation + +TypedArrays offer methods to transform data: + +```typescript +// Map, filter, reduce +let doubled = array.map(x => x * 2); // Create new array with transformed values +let evenNumbers = array.filter(x => x % 2 === 0); // Create new array with filtered values +let sum = array.reduce((acc, val) => acc + val, 0); // Reduce to a single value +let reverseSum = array.reduceRight((acc, val) => acc + val, 0); // Reduce from right to left +``` + +Sources: [std/assembly/typedarray.ts:100-121](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L100-L121), [std/assembly/typedarray.ts:1664-1717](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L1664-L1717) + +### Array Manipulation + +TypedArrays provide methods for manipulating array elements: + +```typescript +array.fill(0); // Fill entire array with 0 +array.fill(1, 2, 4); // Fill indices 2-3 with 1 +array.sort(); // Sort numerically +array.sort((a, b) => b - a); // Sort with custom comparator +array.reverse(); // Reverse the array in-place +array.copyWithin(0, 2, 4); // Copy elements from indices 2-3 to index 0 +``` + +Sources: [std/assembly/typedarray.ts:64-84](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L64-L84), [std/assembly/typedarray.ts:128-131](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L128-L131), [tests/compiler/std/typedarray.ts:140-202](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts#L140-L202) + +### Iteration and Aggregation + +TypedArrays support methods for iterating through elements and testing conditions: + +```typescript +let allPositive = array.every(x => x > 0); // Test if all elements pass predicate +let someEven = array.some(x => x % 2 === 0); // Test if any element passes predicate +array.forEach(x => console.log(x)); // Execute function for each element +``` + +Sources: [std/assembly/typedarray.ts:116-126](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L116-L126), [std/assembly/typedarray.ts:1809-1847](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L1809-L1847) + +### Interoperation + +TypedArrays allow copying values between arrays and converting to strings: + +```typescript +// Copy values from another array +array.set(sourceArray, offsetIndex); + +// Convert to string +let arrayString = array.join(','); // Join with separator +let arrayToString = array.toString(); // Default toString uses comma separator +``` + +Sources: [std/assembly/typedarray.ts:141-143](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L141-L143), [std/assembly/typedarray.ts:133-139](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L133-L139), [std/assembly/typedarray.ts:1886-1945](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L1886-L1945) + +## Special TypedArray Features + +### Uint8ClampedArray + +The `Uint8ClampedArray` has a unique behavior when assigning values: + +- Values less than 0 are clamped to 0 +- Values greater than 255 are clamped to 255 +- Non-finite values like `NaN` and `Infinity` become 0 + +This is useful for image processing where pixel values must be in the 0-255 range. + +```typescript +let clampedArray = new Uint8ClampedArray(3); +clampedArray[0] = -32; // Clamped to 0 +clampedArray[1] = 2; // Remains 2 +clampedArray[2] = 256; // Clamped to 255 +``` + +Sources: [std/assembly/typedarray.ts:318-327](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L318-L327), [tests/compiler/std/typedarray.ts:130-138](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts#L130-L138) + +### Memory Efficiency + +TypedArrays provide memory-efficient storage by using the exact amount of memory needed for each element type: + +```typescript +let array = new Int32Array(1000); +// Exactly 4000 bytes (4 bytes × 1000 elements) +// Plus minimal overhead for the view object +``` + +This is more efficient than using regular arrays for numeric data. + +Sources: [tests/compiler/std/typedarray.ts:1-11](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts#L1-L11) + +## Implementation Details + +TypedArrays use low-level memory operations for efficient data access through the WebAssembly memory: + +```typescript +// Simplified example of element access in Int32Array +@operator("[]") +private __get(index: i32): i32 { + // Bounds check + if (index >= this.byteLength >>> alignof()) + throw new RangeError(E_INDEXOUTOFRANGE); + // Direct memory access + return load(this.dataStart + (index << alignof())); +} +``` + +Key implementation details: +- Use of `load` and `store` for direct memory access +- Alignment-aware calculations with `alignof()` +- Shared helper functions like `SLICE`, `SUBARRAY`, and `COPY_WITHIN` that implement common operations generically + +Sources: [std/assembly/typedarray.ts:734-754](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L734-L754), [std/assembly/typedarray.ts:1571-1589](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L1571-L1589) + +## Common Usage Patterns + +### Creating and Manipulating Pixel Data + +```typescript +// Create a pixel buffer with RGBA values +let pixels = new Uint8ClampedArray(width * height * 4); + +// Set RGBA values for a pixel at (x,y) +function setPixel(x: i32, y: i32, r: u8, g: u8, b: u8, a: u8): void { + const index = (y * width + x) * 4; + pixels[index + 0] = r; + pixels[index + 1] = g; + pixels[index + 2] = b; + pixels[index + 3] = a; +} +``` + +### Working with Binary Data + +```typescript +// Create a view into binary data +let buffer = new ArrayBuffer(16); +let int32View = Int32Array.wrap(buffer); +let uint8View = Uint8Array.wrap(buffer); + +// Modify data through one view affects the other +int32View[0] = 0x01020304; +// uint8View now contains [4, 3, 2, 1] or [1, 2, 3, 4] depending on endianness +``` + +### Data Processing + +```typescript +// Process array of sensor readings +let readings = new Float32Array(100); +// ... fill with data ... + +// Process the data +let average = readings.reduce((sum, val) => sum + val, 0) / readings.length; +let normalizedReadings = readings.map(val => val - average); +let peaks = normalizedReadings.filter(val => val > threshold); +``` + +Sources: [tests/compiler/std/typedarray.ts:317-436](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts#L317-L436), [tests/compiler/std/typedarray.ts:593-661](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.ts#L593-L661) + +## Performance Considerations + +1. **Direct Memory Access**: TypedArrays provide direct access to WebAssembly memory, making them much more efficient than regular arrays for numeric data. + +2. **Alignment and Padding**: Each TypedArray element is properly aligned in memory based on its type, which ensures optimal access patterns. + +3. **View vs. Copy**: Using `subarray()` creates a view into the existing memory (no copy), while `slice()` creates a new copy of the data. Choose wisely based on whether you need to modify the original data. + +4. **Memory Management**: TypedArrays are managed by the AssemblyScript garbage collector, but their tight memory representation reduces pressure on the GC. + +Sources: [std/assembly/typedarray.ts:1571-1610](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/typedarray.ts#L1571-L1610) + +## Compatibility with JavaScript + +The AssemblyScript TypedArray implementation follows the same API as JavaScript TypedArrays, making it easier to port code between the two environments and interact with JavaScript through WebAssembly exports and imports. \ No newline at end of file diff --git a/docs/autogenerated_docs/3.4-date.md b/docs/autogenerated_docs/3.4-date.md new file mode 100644 index 0000000000..77a0dc1ffa --- /dev/null +++ b/docs/autogenerated_docs/3.4-date.md @@ -0,0 +1,335 @@ +# Date + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [std/assembly/date.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts) +- [std/assembly/util/error.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/error.ts) +- [tests/compiler/std/date.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/date.debug.wat) +- [tests/compiler/std/date.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/date.json) +- [tests/compiler/std/date.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/date.release.wat) +- [tests/compiler/std/date.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/date.ts) +- [tests/compiler/std/date.untouched.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/date.untouched.wat) + +
+ + + +This document describes the `Date` class in AssemblyScript, which provides functionality for working with dates and times. The Date class represents moments in time as milliseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC) and provides methods for creating, manipulating, and formatting dates. + +## Overview + +The `Date` class in AssemblyScript's standard library supports UTC-based date and time operations. It provides functionality similar to JavaScript's Date object but with implementation details specific to AssemblyScript. + +```mermaid +classDiagram + class Date { + -year: i32 + -month: i32 + -day: i32 + -epochMillis: i64 + +UTC(year, month, day, hour, minute, second, millisecond): i64 + +now(): i64 + +parse(dateString): Date + +fromString(dateTimeString): Date + +getTime(): i64 + +setTime(time): i64 + +getUTC methods... + +setUTC methods... + +format methods... + } +``` + +Sources: [std/assembly/date.ts:20-296](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L20-L296) + +## Data Model and Constants + +The `Date` class uses key constants for time calculations: + +```mermaid +flowchart TD + subgraph "Date Time Units" + A["MILLIS_PER_DAY\n1000 * 60 * 60 * 24"] + B["MILLIS_PER_HOUR\n1000 * 60 * 60"] + C["MILLIS_PER_MINUTE\n1000 * 60"] + D["MILLIS_PER_SECOND\n1000"] + end + + subgraph "Epoch Constants" + E["YEARS_PER_EPOCH\n400"] + F["DAYS_PER_EPOCH\n146097"] + G["EPOCH_OFFSET\n719468"] + H["MILLIS_LIMIT\n8640000000000000"] + end +``` + +Sources: [std/assembly/date.ts:5-14](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L5-L14) + +Internally, the Date object stores: +- Milliseconds since epoch (`epochMillis`) +- Cached year, month, and day components to avoid recalculation + +## Creating Date Objects + +The Date class provides several methods for creating date objects: + +### Constructor + +The basic constructor accepts milliseconds since epoch: + +```typescript +constructor(private epochMillis: i64) +``` + +Example: +```typescript +// January 1, 2020 00:00:00 UTC +let date = new Date(1577836800000); +``` + +If the provided value is invalid (outside the valid range), the constructor throws a `RangeError` with "Invalid Date" message. + +Sources: [std/assembly/date.ts:128-136](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L128-L136) + +### Static Methods + +The Date class provides several static methods for date creation: + +1. **Date.UTC**: + ```typescript + static UTC(year: i32, month: i32 = 0, day: i32 = 1, + hour: i32 = 0, minute: i32 = 0, second: i32 = 0, + millisecond: i32 = 0): i64 + ``` + + Creates a timestamp in milliseconds for the specified UTC date/time. Month is 0-based (0 = January). + +2. **Date.now**: + ```typescript + static now(): i64 + ``` + + Returns the current time in milliseconds since epoch. + +3. **Date.parse/fromString**: + ```typescript + static parse(dateString: string): Date + static fromString(dateTimeString: string): Date + ``` + + Parses ISO 8601 date strings (e.g., "YYYY-MM-DDTHH:MM:SS.sssZ"). + +Sources: [std/assembly/date.ts:25-126](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L25-L126) + +```mermaid +flowchart TD + A["Date Creation Methods"] --> B["new Date(milliseconds)"] + A --> C["Date.now()"] + A --> D["Date.UTC(year, month, ...)"] + A --> E["Date.fromString(dateString)"] + + B --> F["Date Object"] + C --> B + D --> B + E --> F +``` + +## Accessing Date Components + +The Date class provides methods to access various date components: + +```typescript +getTime(): i64 // Milliseconds since epoch +getUTCFullYear(): i32 // Year (e.g., 2020) +getUTCMonth(): i32 // Month (0-11) +getUTCDate(): i32 // Day of month (1-31) +getUTCDay(): i32 // Day of week (0-6, 0=Sunday) +getUTCHours(): i32 // Hour (0-23) +getUTCMinutes(): i32 // Minute (0-59) +getUTCSeconds(): i32 // Second (0-59) +getUTCMilliseconds(): i32 // Millisecond (0-999) +``` + +Sources: [std/assembly/date.ts:138-183](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L138-L183) + +## Modifying Date Components + +The Date class provides methods to modify date components: + +```typescript +setTime(time: i64): i64 // Set milliseconds since epoch +setUTCMilliseconds(millis: i32): void // Set milliseconds (0-999) +setUTCSeconds(seconds: i32): void // Set seconds (0-59) +setUTCMinutes(minutes: i32): void // Set minutes (0-59) +setUTCHours(hours: i32): void // Set hour (0-23) +setUTCDate(day: i32): void // Set day of month (1-31) +setUTCMonth(month: i32, day?: i32): void // Set month (0-11) and optionally day +setUTCFullYear(year: i32): void // Set year +``` + +When changing date components: +- Values outside the valid range (like month=12) will overflow properly (becomes next year, month=0) +- The internal year/month/day cache is automatically updated + +Sources: [std/assembly/date.ts:142-214](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L142-L214) + +## Date Formatting Methods + +The Date class offers several formatting methods: + +```typescript +toISOString(): string // "YYYY-MM-DDTHH:MM:SS.sssZ" +toUTCString(): string // "Ddd, DD Mmm YYYY HH:MM:SS GMT" +toDateString(): string // "Ddd Mmm DD YYYY" +toTimeString(): string // "HH:MM:SS" +toString(): string // "Ddd Mmm DD YYYY HH:MM:SS" +``` + +Sources: [std/assembly/date.ts:216-295](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L216-L295) + +Example: +```typescript +let date = new Date(Date.UTC(2020, 0, 1)); +date.toISOString(); // "2020-01-01T00:00:00.000Z" +date.toUTCString(); // "Wed, 01 Jan 2020 00:00:00 GMT" +date.toDateString(); // "Wed Jan 01 2020" +``` + +## Parsing ISO 8601 Date Strings + +The `fromString` method parses ISO 8601 date strings with extensive support for various formats: + +```mermaid +flowchart TD + A["Date.fromString(input)"] --> B{"Contains 'T'?"} + B -->|Yes| C["Split into date and time"] + B -->|No| D["Parse as date only"] + + C --> E["Parse time components"] + C --> F{"Contains timezone?"} + F -->|"Z"| G["Set timezone to UTC"] + F -->|"+/-"| H["Parse timezone offset"] + F -->|No| I["Assume UTC"] + + D --> J["Parse YYYY-MM-DD"] + E --> K["Parse HH:MM:SS.sss"] + + G --> L["Create date object"] + H --> L + I --> L + J --> L + K --> L +``` + +The parser supports: +- Basic date: `YYYY`, `YYYY-MM`, `YYYY-MM-DD` +- Time components: `THH:MM`, `THH:MM:SS`, `THH:MM:SS.sss` +- UTC indicator: `Z` +- Timezone offsets: `+HH:MM`, `-HH:MM` + +Sources: [std/assembly/date.ts:49-126](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L49-L126) + +## Date Calculations + +The Date implementation uses efficient algorithms for date calculations: + +### Key Helper Functions + +```typescript +// Convert date components to milliseconds +epochMillis(year, month, day, hour, minute, second, milliseconds): i64 + +// Convert milliseconds to date components (populates _month, _day globals) +dateFromEpoch(ms: i64): i32 // Returns year + +// Calculate days since epoch for date +daysSinceEpoch(y: i32, m: i32, d: i32): i64 + +// Calculate day of week (0=Sunday) +dayOfWeek(year: i32, month: i32, day: i32): i32 +``` + +Sources: [std/assembly/date.ts:298-375](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L298-L375) + +The implementation uses the Euclidean Affine Functions algorithm for date calculations, as noted in the source code comments: + +> Based on "Euclidean Affine Functions and Applications to Calendar Algorithms" +> Paper: https://arxiv.org/pdf/2102.06959.pdf + +Sources: [std/assembly/date.ts:332-334](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L332-L334) + +## Date Limitations + +The Date class has the following limitations: + +- Valid date range: -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds from epoch +- This corresponds approximately to years -271821 to 275760 +- Attempting to create a Date with values outside this range will throw a RangeError + +The validation occurs in the `invalidDate` function: + +```typescript +function invalidDate(millis: i64): bool { + return (millis < -MILLIS_LIMIT) | (millis > MILLIS_LIMIT); +} +``` + +Sources: [std/assembly/date.ts:327-330](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/date.ts#L327-L330) + +## Examples + +### Basic Date Creation and Formatting + +```typescript +// Create date from timestamp +let date1 = new Date(1577836800000); // 2020-01-01T00:00:00.000Z + +// Create date from components (month is 0-based) +let date2 = new Date(Date.UTC(2020, 0, 1)); + +// Get current time +let now = new Date(Date.now()); + +// Format date +let isoString = date1.toISOString(); // "2020-01-01T00:00:00.000Z" +``` + +### Date Component Manipulation + +```typescript +let date = new Date(Date.UTC(2020, 0, 1)); + +// Get components +let year = date.getUTCFullYear(); // 2020 +let month = date.getUTCMonth(); // 0 (January) +let day = date.getUTCDate(); // 1 + +// Set components +date.setUTCFullYear(2021); // Change year to 2021 +date.setUTCMonth(11); // Change to December +date.setUTCDate(31); // Change to the 31st +``` + +### Date Parsing + +```typescript +// Parse ISO date strings +let date1 = Date.fromString("2020-01-01"); // Date only +let date2 = Date.fromString("2020-01-01T12:30:45"); // Date and time +let date3 = Date.fromString("2020-01-01T12:30:45Z"); // With UTC indicator +let date4 = Date.fromString("2020-01-01T12:30:45-08:00"); // With timezone offset +``` + +Sources: [tests/compiler/std/date.ts:288-340](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/date.ts#L288-L340) + +## Implementation Notes + +The Date implementation in AssemblyScript: + +1. Emphasizes efficiency with cached date components +2. Uses optimized algorithms for date calculations +3. Provides UTC-based methods only (no local timezone support) +4. Handles the full range of date scenarios including leap years, different month lengths, etc. +5. Throws appropriate errors for invalid dates instead of returning special values \ No newline at end of file diff --git a/docs/autogenerated_docs/3.5-string-and-number-utilities.md b/docs/autogenerated_docs/3.5-string-and-number-utilities.md new file mode 100644 index 0000000000..1085e687ae --- /dev/null +++ b/docs/autogenerated_docs/3.5-string-and-number-utilities.md @@ -0,0 +1,358 @@ +# String and Number Utilities + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [std/assembly/util/number.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/number.ts) +- [std/assembly/util/string.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts) +- [tests/compiler/resolve-binary.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/resolve-binary.debug.wat) +- [tests/compiler/resolve-elementaccess.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/resolve-elementaccess.debug.wat) +- [tests/compiler/resolve-elementaccess.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/resolve-elementaccess.release.wat) +- [tests/compiler/resolve-ternary.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/resolve-ternary.debug.wat) +- [tests/compiler/std/array.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/array.debug.wat) +- [tests/compiler/std/array.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/array.release.wat) +- [tests/compiler/std/string.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/string.debug.wat) +- [tests/compiler/std/string.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/string.release.wat) +- [tests/compiler/std/typedarray.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.debug.wat) +- [tests/compiler/std/typedarray.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/typedarray.release.wat) +- [tests/compiler/templateliteral.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/templateliteral.debug.wat) +- [tests/compiler/templateliteral.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/templateliteral.release.wat) + +
+ + + +## Purpose and Scope + +The String and Number Utilities in AssemblyScript provide essential functionality for string manipulation and number conversion. This document covers the character classification and manipulation functions, string comparison utilities, string-to-number parsing, and number-to-string formatting capabilities found in the standard library. For information about the core String type implementation, see [Array and String](#3.1). + +## Character Classification and Manipulation + +AssemblyScript provides several utility functions for classifying and manipulating characters: + +| Function | Purpose | +|----------|---------| +| `isAscii(c: u32): bool` | Determines if a character is an ASCII character (code point < 128) | +| `isLower8(c: u32): bool` | Checks if a character is a lowercase ASCII letter (a-z) | +| `isUpper8(c: u32): bool` | Checks if a character is an uppercase ASCII letter (A-Z) | +| `isSpace(c: u32): bool` | Identifies whitespace characters | +| `isAlpha(c: u32): bool` | Detects alphabetic characters (both ASCII and Unicode) | +| `isCased(c: u32): bool` | Determines if a character has case (uppercase, lowercase, or titlecase) | +| `isCaseIgnorable(c: u32): bool` | Identifies characters that should be ignored when determining case | +| `toLower8(c: u32): u32` | Converts an ASCII character to lowercase | +| `toUpper8(c: u32): u32` | Converts an ASCII character to uppercase | + +These functions are implemented using efficient lookup tables and bitwise operations. + +Sources: [std/assembly/util/string.ts:506-662](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L506-L662) + +## Character Classification System + +```mermaid +graph TD + charInput["Character Input"] + + subgraph "ClassificationFunctions" + isAscii["isAscii\nChecks if c < 128"] + isLower["isLower8\nChecks if c is a-z"] + isUpper["isUpper8\nChecks if c is A-Z"] + isSpace["isSpace\nChecks for whitespace"] + isAlpha["isAlpha\nChecks for letters"] + isCased["isCased\nChecks for case property"] + isCaseIgnorable["isCaseIgnorable"] + toLower8["toLower8"] + toUpper8["toUpper8"] + end + + subgraph "LookupTables" + alphaTable["ALPHA_TABLE\nSize: 3904 bytes"] + casedTable["CASED\nSize: 1568 bytes"] + ignorableTable["CASE_IGNORABLES\nSize: 2976 bytes"] + lower127["LOWER127\nASCII lowercase mapping"] + upper127["UPPER127\nASCII uppercase mapping"] + end + + charInput --> isAscii + charInput --> isLower + charInput --> isUpper + charInput --> isSpace + charInput --> isAlpha + charInput --> isCased + charInput --> isCaseIgnorable + + isAlpha --> alphaTable + isCased --> casedTable + isCaseIgnorable --> ignorableTable + toLower8 --> lower127 + toUpper8 --> upper127 +``` + +Sources: [std/assembly/util/string.ts:26-462](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L26-L462) + +## String Comparison + +The `compareImpl` function compares two strings character by character: + +```typescript +export function compareImpl(str1: string, index1: usize, str2: string, index2: usize, len: usize): i32 +``` + +This function returns: +- A negative value if the first string is lexicographically less than the second +- A positive value if the first string is lexicographically greater than the second +- Zero if the strings are equal for the specified length + +The implementation includes an optimization for aligned pointers to improve performance on sequences of 4 or more characters. + +Sources: [std/assembly/util/string.ts:621-642](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L621-L642) + +## String to Number Conversion + +### Integer Parsing + +The `strtol` function parses a string to an integer: + +```typescript +export function strtol(str: string, radix: i32 = 0): T +``` + +This generic function handles various integer formats: +- Optional leading whitespace +- Optional sign (+ or -) +- Automatic detection of number prefixes when `radix` is 0: + - `0x` or `0X` for hexadecimal (base 16) + - `0o` or `0O` for octal (base 8) + - `0b` or `0B` for binary (base 2) +- Conversion of characters to numeric values based on the specified radix + +Sources: [std/assembly/util/string.ts:665-781](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L665-L781) + +### Floating-Point Parsing + +The `strtod` function parses a string to a floating-point number: + +```typescript +export function strtod(str: string): f64 +``` + +This function handles: +- Optional leading whitespace +- Optional sign (+ or -) +- Special values like "Infinity" +- Decimal points and fractional parts +- Scientific notation with exponents (e.g., "1.23e-45") + +Sources: [std/assembly/util/string.ts:783-856](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L783-L856) + +## String-Number Conversion Flow + +```mermaid +flowchart TD + subgraph "StringToNumber" + strInput["String Input\n(e.g., '123', '0xFF', '3.14')"] + strtol["strtol\nParse integer with radix"] + strtod["strtod\nParse floating-point"] + numOutput["Number Output\n(i32, f64, etc.)"] + end + + subgraph "NumberToString" + numInput["Number Input\n(e.g., 123, 255, 3.14)"] + itoa["itoa32/itoa64\nFormat signed integer"] + utoa["utoa32/utoa64\nFormat unsigned integer"] + dtoa["dtoa\nFormat floating-point"] + strOutput["String Output"] + end + + subgraph "BufferedFormatting" + buffer["Memory Buffer"] + itoa_buffered["itoa_buffered\nFormat to buffer"] + dtoa_buffered["dtoa_buffered\nFormat to buffer"] + end + + strInput --> strtol + strInput --> strtod + strtol --> numOutput + strtod --> numOutput + + numInput --> itoa + numInput --> utoa + numInput --> dtoa + itoa --> strOutput + utoa --> strOutput + dtoa --> strOutput + + numInput --> itoa_buffered + numInput --> dtoa_buffered + itoa_buffered --> buffer + dtoa_buffered --> buffer + buffer --> strOutput +``` + +Sources: [std/assembly/util/string.ts:665-856](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L665-L856), [std/assembly/util/number.ts:1-700](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/number.ts#L1-L700) + +## Number to String Conversion + +AssemblyScript provides several functions for converting numbers to strings: + +| Function | Purpose | +|----------|---------| +| `itoa32(value: i32, radix: i32 = 10): string` | Converts a 32-bit signed integer to a string | +| `utoa32(value: u32, radix: i32 = 10): string` | Converts a 32-bit unsigned integer to a string | +| `itoa64(value: i64, radix: i32 = 10): string` | Converts a 64-bit signed integer to a string | +| `utoa64(value: u64, radix: i32 = 10): string` | Converts a 64-bit unsigned integer to a string | +| `dtoa(value: f64): string` | Converts a double-precision floating-point number to a string | + +These functions support different radixes (bases) for integer formatting, including decimal, hexadecimal, octal, and binary. + +Sources: [std/assembly/util/number.ts:300-700](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/number.ts#L300-L700) + +## Buffered Formatting + +For efficient string building, the library provides buffered formatting functions that write directly to a memory buffer: + +```typescript +export function itoa_buffered(buffer: usize, offset: usize, value: i32, radix: i32 = 10): usize +export function dtoa_buffered(buffer: usize, offset: usize, value: f64, precision: i32 = 0): usize +``` + +These functions are useful when building complex strings as they: +- Avoid creating intermediate string objects +- Allow fine control over the formatting process +- Return the new offset in the buffer after writing + +The maximum length needed for double-precision floating-point formatting is defined as: + +```typescript +export const MAX_DOUBLE_LENGTH = 28; +``` + +Sources: [std/assembly/util/number.ts:8-250](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/number.ts#L8-L250) + +## Unicode and Character Set Handling + +AssemblyScript uses space-efficient lookup tables for character handling: + +```mermaid +flowchart LR + subgraph "UnicodeCharacterHandling" + direction TB + charInput["Character Input"] + + subgraph "LookupTables" + direction LR + alphaTable["ALPHA_TABLE\nSize: 3904 bytes"] + casedTable["CASED\nSize: 1568 bytes"] + ignorableTable["CASE_IGNORABLES\nSize: 2976 bytes"] + end + + subgraph "ClassificationFunctions" + direction LR + isAlpha["isAlpha(c: u32): bool"] + isCased["isCased(c: u32): bool"] + isCaseIgnorable["isCaseIgnorable(c: u32): bool"] + isFinalSigma["isFinalSigma(buffer, index, len): bool"] + end + + charInput --> isAlpha + charInput --> isCased + charInput --> isCaseIgnorable + + isAlpha --> alphaTable + isCased --> casedTable + isCaseIgnorable --> ignorableTable + isFinalSigma --> isCased + isFinalSigma --> isCaseIgnorable + end +``` + +These tables use a space-efficient "two-staged lookup table" structure that allows for efficient storage and lookup: + +```typescript +function stagedBinaryLookup(table: usize, c: u32): bool { + return ((load(table + (load(table + (c >>> 8)) << 5) + ((c & 255) >> 3)) >>> (c & 7)) & 1); +} +``` + +For ASCII characters, simpler tables are provided for case conversion: +- `LOWER127`: Maps ASCII characters to their lowercase equivalents +- `UPPER127`: Maps ASCII characters to their uppercase equivalents + +Additionally, the `POWERS10` table in the number utilities stores powers of 10 for efficient number formatting. + +Sources: [std/assembly/util/string.ts:26-619](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L26-L619), [std/assembly/util/number.ts:10-22](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/number.ts#L10-L22) + +## Special Case Handling + +The library includes specialized functions for handling Unicode case transformations: + +- `isFinalSigma`: Determines if a Greek sigma is in final position (requiring special case transformations) +- `codePointBefore`: Gets the code point before a given position in a string buffer + +These functions support correct handling of Unicode characters in various contexts. + +For number formatting, special handling is provided for: +- NaN and Infinity +- Zero values (positive and negative) +- Very large or small numbers requiring scientific notation +- Precision control for floating-point numbers + +Sources: [std/assembly/util/string.ts:565-614](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L565-L614), [std/assembly/util/number.ts:300-700](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/number.ts#L300-L700) + +## Performance Optimizations + +The string and number utilities include several performance optimizations: + +1. Two-staged lookup tables for space-efficient character classification +2. Fast path for ASCII characters in case conversion +3. Optimized comparison for aligned memory in `compareImpl` +4. Buffered formatting to avoid intermediate string allocations +5. Pre-computed lookup tables for commonly used values: + +```typescript +@lazy @inline const POWERS10 = memory.data([ + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 +]); +``` + +6. Lookup tables for efficiently formatting pairs of digits: + +```typescript +@lazy @inline const DIGITS = memory.data([ + 0x00300030, 0x00310030, 0x00320030, ... // "00", "01", "02", etc. +]); +``` + +Sources: [std/assembly/util/string.ts:26-642](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L26-L642), [std/assembly/util/number.ts:10-50](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/number.ts#L10-L50) + +## Character Codes Constants + +The library defines common character codes as an enum for improved code readability: + +```typescript +@inline +export const enum CharCode { + PERCENT = 0x25, + PLUS = 0x2B, + MINUS = 0x2D, + DOT = 0x2E, + _0 = 0x30, + // Additional character codes... + z = 0x7A +} +``` + +This enum allows for clearer code when working with specific character codes in the string and number utilities. + +Sources: [std/assembly/util/string.ts:472-503](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/util/string.ts#L472-L503) + +## Usage Examples + +The string and number utility functions are used extensively throughout the AssemblyScript standard library and in user code for tasks such as: + +- Parsing user input +- Formatting values for display +- Serializing data to string formats +- Processing text +- Implementing higher-level string operations \ No newline at end of file diff --git a/docs/autogenerated_docs/4-command-line-interface-_cli_.md b/docs/autogenerated_docs/4-command-line-interface-_cli_.md new file mode 100644 index 0000000000..762bc1b5c9 --- /dev/null +++ b/docs/autogenerated_docs/4-command-line-interface-_cli_.md @@ -0,0 +1,215 @@ +# Command Line Interface (CLI) + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [src/index.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/index.ts) +- [tests/cli/options.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/cli/options.js) +- [tests/compiler/import.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/import.ts) +- [tests/compiler/issues/1699.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/issues/1699.ts) +- [util/options.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js) + +
+ + + +This document provides a comprehensive guide to using the AssemblyScript command line interface (CLI), which serves as the primary entry point for compiling AssemblyScript code to WebAssembly. For information about programmatic compilation using the Compiler API, see [Compiler API](#4.1). + +## Overview + +The AssemblyScript CLI provides a command-line tool for compiling `.ts` files to WebAssembly modules (`.wasm`), along with optional JavaScript bindings and TypeScript definitions. The CLI offers extensive configuration options for controlling the compilation process, optimizations, and output formats. + +```mermaid +flowchart TD + subgraph "AssemblyScript CLI Flow" + ASC["asc (CLI Entry Point)"] --> OptionsParsing["Parse Command Line Options\noptions.parse()"] + OptionsParsing --> ConfigLoad["Load Configuration\n(asconfig.json)"] + ConfigLoad --> OptionsMerge["Merge Options\noptions.merge()"] + OptionsMerge --> Compilation["Compile\nAssemblyScript Sources"] + Compilation --> OutputGen["Generate Output Files\n(.wasm, .js, .d.ts)"] + end +``` + +Sources: [util/options.js:22-96](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js#L22-L96) + +## Basic Usage + +The basic syntax for using the AssemblyScript CLI is: + +``` +asc [options] [entry files] +``` + +For example, to compile a simple AssemblyScript file: + +``` +asc assembly/index.ts -o build/output.wasm +``` + +This compiles `assembly/index.ts` to WebAssembly and writes the output to `build/output.wasm`. + +## CLI Options + +The AssemblyScript CLI supports various types of options for configuring the compilation process. Options can be specified in the command line or in a configuration file. + +### Option Types + +The CLI supports the following option types: + +| Type | Description | Example | +|------|-------------|---------| +| `b` | Boolean flag | `--optimize` | +| `i` | Integer value | `--optimizeLevel 3` | +| `f` | Float value | `--converge 0.01` | +| `s` | String value | `--outFile output.wasm` | +| `I` | Integer array | `--target 99` (multiple times) | +| `F` | Float array | `--rates 0.1,0.2` | +| `S` | String array | `--importMemory external,mutable` | + +Sources: [util/options.js:12-19](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js#L12-L19) + +### Option Parsing + +When you run the CLI, it processes command line arguments according to the following flow: + +```mermaid +flowchart TD + subgraph "Option Parsing Mechanism" + Args["Command Line Arguments"] --> Parse["options.parse()"] + Parse --> Format{Is Argument\nan Option?} + Format -- Yes --> Match["Match option pattern\n(--option, -o, etc.)"] + Format -- No --> CollectArg["Collect as input argument"] + Match --> Lookup{Found in Config?} + Lookup -- Yes --> ProcessType["Process according to type\n(b,i,f,s,I,F,S)"] + Lookup -- No --> Unknown["Add to unknown options"] + ProcessType --> AddToOpts["Add to options object"] + CollectArg --> ReturnResult["Return parsed result\n{options, unknown, arguments, trailing}"] + Unknown --> ReturnResult + AddToOpts --> ReturnResult + end +``` + +Sources: [util/options.js:22-96](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js#L22-L96) + +## Configuration File + +The AssemblyScript CLI supports a configuration file named `asconfig.json` that can be used to specify compiler options. This is particularly useful for projects with many compiler options or for maintaining consistent configurations across builds. + +Example `asconfig.json`: + +```json +{ + "targets": { + "debug": { + "outFile": "build/debug.wasm", + "textFile": "build/debug.wat", + "sourceMap": true, + "debug": true + }, + "release": { + "outFile": "build/release.wasm", + "textFile": "build/release.wat", + "sourceMap": true, + "optimize": true + } + }, + "options": { + "bindings": "esm", + "importMemory": true + } +} +``` + +### Option Merging + +When both command line arguments and a configuration file are present, the CLI merges these options with command line options taking precedence. This process handles array types, mutually exclusive options, and path resolution. + +```mermaid +flowchart TD + subgraph "Option Merging Process" + CLI["Command Line Options"] --> Merge["options.merge()"] + Config["Configuration File Options"] --> Merge + Merge --> Process["Process Each Option"] + Process --> TypeCheck["Check Option Type"] + TypeCheck --> ArrayCheck{Is Array Type?} + ArrayCheck -- Yes --> MergeArrays["Merge Arrays\nwith Deduplication"] + ArrayCheck -- No --> TakeCLI["Take CLI Value\nif Present"] + MergeArrays --> HandleExclusions["Handle Mutually\nExclusive Options"] + TakeCLI --> HandlePaths["Resolve Paths\nif isPath=true"] + HandleExclusions --> Final["Final Options"] + HandlePaths --> Final + Final --> Defaults["Add Default Values\noptions.addDefaults()"] + end +``` + +Sources: [util/options.js:174-235](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js#L174-L235), [util/options.js:256-262](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js#L256-L262) + +## Path Resolution + +The CLI handles paths in options specially, resolving relative paths against the base directory of the configuration file or the current working directory. + +### Node Resolution + +For certain options, the CLI can use Node.js module resolution to resolve non-relative imports. This is controlled by the `useNodeResolution` property of the option configuration. + +Sources: [util/options.js:247-253](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js#L247-L253) + +## Common CLI Options + +While the specific options available in the CLI are not directly visible in the provided code, here are some common options: + +| Option | Description | +|--------|-------------| +| `--outFile, -o` | Specifies the WebAssembly output file | +| `--textFile, -t` | Specifies the WebAssembly text format output | +| `--bindings` | Generates JavaScript bindings (raw, esm, js) | +| `--optimize, -O` | Enables optimizations | +| `--optimizeLevel` | Sets the optimization level (0-3) | +| `--shrinkLevel` | Sets the shrink level (0-2) | +| `--importMemory` | Imports the memory from the environment | +| `--exportMemory` | Exports the memory to the environment | +| `--debug` | Enables debug information | +| `--sourceMap` | Enables source maps | +| `--target` | Sets the WebAssembly target version | + +## Examples + +### Basic Compilation + +``` +asc assembly/index.ts -o build/output.wasm --optimize +``` + +### Using a Configuration File + +``` +asc --config asconfig.json +``` + +### Compiling with a Specific Target + +``` +asc assembly/index.ts --target release +``` + +### Generating JavaScript Bindings + +``` +asc assembly/index.ts -o build/output.wasm --bindings esm +``` + +## Help Text + +The CLI provides detailed help text that can be accessed using: + +``` +asc --help +``` + +This displays all available options with their descriptions, grouped by categories if the option has a `category` property. + +Sources: [util/options.js:98-141](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/util/options.js#L98-L141) + +## Summary \ No newline at end of file diff --git a/docs/autogenerated_docs/4.1-compiler-api.md b/docs/autogenerated_docs/4.1-compiler-api.md new file mode 100644 index 0000000000..fa0a4b08f6 --- /dev/null +++ b/docs/autogenerated_docs/4.1-compiler-api.md @@ -0,0 +1,407 @@ +# Compiler API + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [.gitignore](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/.gitignore) +- [cli/index.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts) +- [cli/index.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js) +- [dist/asc.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/dist/asc.d.ts) +- [dist/assemblyscript.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/dist/assemblyscript.d.ts) +- [dist/transform.cjs](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/dist/transform.cjs) +- [dist/transform.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/dist/transform.d.ts) +- [dist/transform.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/dist/transform.js) +- [scripts/build-dts.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/scripts/build-dts.js) +- [src/index-wasm.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/index-wasm.ts) + +
+ + + +The AssemblyScript Compiler API provides programmatic access to the AssemblyScript compiler, allowing developers to integrate the compilation process into their own applications or tools. This page documents the main interfaces and functions that make up the Compiler API. + +For information about using the command line interface (CLI) instead, see [Command Line Interface (CLI)](#4). + +## Overview + +The AssemblyScript Compiler API enables you to compile AssemblyScript code to WebAssembly programmatically from JavaScript applications. The API is exposed through the AssemblyScript package and provides functions to parse AssemblyScript source code, compile it to WebAssembly, and generate JavaScript bindings. + +```mermaid +flowchart TD + subgraph "Compiler API Entry Points" + main["main()"] + compileString["compileString()"] + end + + subgraph "Configuration" + CompilerOptions["CompilerOptions Interface"] + APIOptions["APIOptions Interface"] + end + + subgraph "Output" + APIResult["APIResult Interface"] + Stats["Stats Class"] + end + + subgraph "Extensibility" + Transform["Transform Class"] + end + + main --> CompilerOptions + main --> APIOptions + compileString --> CompilerOptions + + CompilerOptions --> main + APIOptions --> main + + main --> APIResult + compileString --> APIResult + Stats --> APIResult + + Transform --> APIOptions +``` + +Sources: [cli/index.js:178-139](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L178-L139), [cli/index.d.ts:79-156](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L79-L156), [cli/index.d.ts:159-175](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L159-L175), [cli/index.d.ts:177-187](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L177-L187) + +## Key Functions + +### Main Compilation Functions + +The API provides two primary functions for compiling AssemblyScript code: + +1. **main** - Runs the compiler with specified arguments and options +2. **compileString** - Compiles source strings directly (convenience function) + +#### main + +The `main` function is the primary entry point for the API. It accepts an array of arguments (similar to command line arguments) or a configuration object, along with additional API options. + +```typescript +function main( + argv: string[] | CompilerOptions, + options?: APIOptions +): Promise +``` + +#### compileString + +The `compileString` function provides a simplified interface for compiling AssemblyScript source code directly from strings. + +```typescript +function compileString( + sources: { [key: string]: string } | string, + options?: CompilerOptions +): Promise +``` + +Sources: [cli/index.js:133-1019](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L133-L1019), [cli/index.js:116-130](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L116-L130), [cli/index.d.ts:190-191](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L190-L191), [cli/index.d.ts:192-198](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L192-L198) + +## Compilation Process + +The following diagram illustrates the compilation process when using the Compiler API: + +```mermaid +flowchart TB + Source["Source Code"] --> Parse + CompilerOptions["CompilerOptions"] --> Configure + + subgraph "Compiler API Workflow" + Configure["Configure Compiler"] --> Parse["Parse Source"] + Parse --> Compile["Compile to IR"] + Compile --> Transform["Apply Transforms"] + Transform --> Optimize["Optimize"] + Optimize --> Validate["Validate"] + Validate --> EmitOutput["Emit Output"] + end + + EmitOutput --> Binary["WebAssembly Binary"] + EmitOutput --> Text["WebAssembly Text"] + EmitOutput --> JSBindings["JavaScript Bindings"] + EmitOutput --> TSDefs["TypeScript Definitions"] +``` + +Sources: [cli/index.js:400-1008](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L400-L1008) + +## Configuration Options + +The Compiler API provides extensive configuration options through the `CompilerOptions` interface. + +### Core Compiler Options + +| Option | Type | Description | +|--------|------|-------------| +| `optimize` | boolean | Optimizes the module | +| `optimizeLevel` | number | How much to focus on optimizing code (0-3) | +| `shrinkLevel` | number | How much to focus on shrinking code size (0-2) | +| `noAssert` | boolean | Replaces assertions with just their value without trapping | +| `debug` | boolean | Enables debug information in emitted binaries | +| `noEmit` | boolean | Performs compilation without emitting code | +| `runtime` | string | Specifies the runtime variant to include | +| `noUnsafe` | boolean | Disallows unsafe features in user code | + +### Output Options + +| Option | Type | Description | +|--------|------|-------------| +| `outFile` | string | WebAssembly output file (.wasm) | +| `textFile` | string | WebAssembly text output file (.wat) | +| `sourceMap` | boolean \| string | Enables source map generation | +| `bindings` | string[] | Specifies the bindings to generate | + +### Memory Options + +| Option | Type | Description | +|--------|------|-------------| +| `importMemory` | boolean | Imports memory provided as 'env.memory' | +| `noExportMemory` | boolean | Does not export memory as 'memory' | +| `initialMemory` | number | Sets initial memory size in pages | +| `maximumMemory` | number | Sets maximum memory size in pages | +| `sharedMemory` | boolean | Declares memory as shared | +| `memoryBase` | number | Sets start offset of compiler-generated static memory | + +Sources: [cli/index.d.ts:79-156](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L79-L156), [cli/index.js:282-339](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L282-L339) + +## API Options + +The `APIOptions` interface provides additional options for the API, allowing customization of I/O operations and other aspects of the compilation process. + +```typescript +interface APIOptions { + stdout?: OutputStream; + stderr?: OutputStream; + readFile?: (filename: string, baseDir: string) => (string | null) | Promise; + writeFile?: (filename: string, contents: Uint8Array | string, baseDir: string) => void | Promise; + listFiles?: (dirname: string, baseDir: string) => (string[] | null) | Promise; + reportDiagnostic?: DiagnosticReporter; + transforms?: Transform[]; +} +``` + +Sources: [cli/index.d.ts:159-175](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L159-L175), [cli/index.js:137-165](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L137-L165) + +## Transform API + +The Transform API allows extending the compilation process with custom transforms. Transforms can be applied at various stages of the compilation process. + +```mermaid +flowchart TD + subgraph "Transform Lifecycle Hooks" + afterParse["afterParse(parser)"] + afterInitialize["afterInitialize(program)"] + afterCompile["afterCompile(module)"] + end + + subgraph "Transform Process" + Parser["Program Parser"] --> afterParse + afterParse --> Program["Program Instance"] + Program --> afterInitialize + afterInitialize --> Compile["Compilation"] + Compile --> afterCompile + afterCompile --> BinaryenModule["Binaryen Module"] + end +``` + +### Transform Class + +The `Transform` abstract class provides the base for implementing custom transforms: + +```typescript +abstract class Transform { + readonly program: Program; + readonly binaryen: typeof binaryen; + readonly baseDir: string; + readonly stdout: OutputStream; + readonly stderr: OutputStream; + readonly log: typeof console.log; + + readFile(filename: string, baseDir: string): (string | null) | Promise; + writeFile(filename: string, contents: string | Uint8Array, baseDir: string): void | Promise; + listFiles(dirname: string, baseDir: string): (string[] | null) | Promise; + + afterParse?(parser: Parser): void | Promise; + afterInitialize?(program: Program): void | Promise; + afterCompile?(module: binaryen.Module): void | Promise; +} +``` + +Sources: [cli/index.d.ts:246-284](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L246-L284), [cli/index.js:405-468](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L405-L468), [cli/index.js:470-484](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L470-L484) + +## Diagnostics and Error Handling + +The API provides interfaces for diagnostic messages and functions for checking diagnostics: + +```typescript +interface DiagnosticMessage { + code: number; + category: number; + message: string; + range: Range | null; + relatedRange: Range | null; +} + +function checkDiagnostics( + emitter: Record, + stderr?: OutputStream, + reportDiagnostic?: DiagnosticReporter, + useColors?: boolean +): boolean; +``` + +Sources: [cli/index.d.ts:62-74](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L62-L74), [cli/index.d.ts:201](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L201) + +## Statistics + +The `Stats` class provides statistics about the compilation process: + +```typescript +class Stats { + readCount: number; + writeCount: number; + parseTime: number; + parseCount: number; + compileTime: number; + compileCount: number; + emitTime: number; + emitCount: number; + validateTime: number; + validateCount: number; + optimizeTime: number; + optimizeCount: number; + + begin(): number; + end(begin: number): number; + toString(): string; +} +``` + +Sources: [cli/index.d.ts:204-235](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.d.ts#L204-L235) + +## Usage Examples + +### Basic Compilation + +This example shows how to compile a simple AssemblyScript program using the `compileString` function: + +```javascript +import { compileString } from "assemblyscript/cli"; + +async function compile() { + const result = await compileString(` + export function add(a: i32, b: i32): i32 { + return a + b; + } + `); + + if (result.error) { + console.error(result.error); + } else { + console.log("Compilation successful!"); + // Access WebAssembly binary + const binary = result.binary; + // Access WebAssembly text format + const text = result.text; + } +} +``` + +### Advanced Compilation + +This example demonstrates using the `main` function with custom options and transforms: + +```javascript +import { main, Transform } from "assemblyscript/cli"; +import * as fs from "fs"; +import * as path from "path"; + +// Custom transform +class MyTransform extends Transform { + afterParse(parser) { + console.log("Parsing complete!"); + } + + afterCompile(module) { + console.log("Compilation complete!"); + } +} + +async function compile() { + const options = { + optimize: true, + optimizeLevel: 3, + shrinkLevel: 1, + outFile: "output.wasm", + textFile: "output.wat", + bindings: ["esm"], + sourceMap: true + }; + + const apiOptions = { + transforms: [new MyTransform()], + readFile: (filename, baseDir) => { + try { + return fs.readFileSync(path.join(baseDir, filename), "utf8"); + } catch (e) { + return null; + } + }, + writeFile: (filename, contents, baseDir) => { + const dir = path.dirname(path.join(baseDir, filename)); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + if (typeof contents === "string") { + fs.writeFileSync(path.join(baseDir, filename), contents); + } else { + fs.writeFileSync(path.join(baseDir, filename), Buffer.from(contents)); + } + } + }; + + const result = await main(["input.ts", ...Object.entries(options).flat()], apiOptions); + + if (result.error) { + console.error(result.error); + } else { + console.log("Compilation successful!"); + console.log(result.stats.toString()); + } +} +``` + +Sources: [cli/index.js:116-130](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L116-L130), [cli/index.js:133-139](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L133-L139) + +## Integration with Other Systems + +The Compiler API is designed to integrate with various development tools and build systems. Common integration scenarios include: + +1. **Build tools** (webpack, rollup, etc.) - Create plugins that use the Compiler API to compile AssemblyScript files during the build process +2. **IDEs and editors** - Provide in-editor compilation and error checking +3. **Online playgrounds** - Enable browser-based compilation and execution +4. **Custom tooling** - Develop specialized tools for AssemblyScript development + +The API's promise-based interface and customizable I/O operations make it well-suited for these integration scenarios. + +Sources: [cli/index.js:133-1019](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/cli/index.js#L133-L1019) + +## Underlying CompilerOptions Implementation + +The AssemblyScript compiler itself uses a more low-level API for setting compiler options as seen in the internal implementation. The Compiler API provides a high-level wrapper around these functions: + +```typescript +// Low-level API example (internal use) +function setTarget(options: Options, target: Target): void +function setRuntime(options: Options, runtime: Runtime): void +function setNoAssert(options: Options, noAssert: bool): void +// ...and many more option setters +``` + +Sources: [src/index-wasm.ts:54-238](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/index-wasm.ts#L54-L238) + +## Conclusion + +The AssemblyScript Compiler API provides a flexible and powerful way to integrate AssemblyScript compilation into JavaScript applications. With its extensive configuration options, transform capabilities, and customizable I/O operations, it enables developers to build sophisticated tooling around AssemblyScript. \ No newline at end of file diff --git a/docs/autogenerated_docs/5-javascript-integration.md b/docs/autogenerated_docs/5-javascript-integration.md new file mode 100644 index 0000000000..0c61d7b29d --- /dev/null +++ b/docs/autogenerated_docs/5-javascript-integration.md @@ -0,0 +1,459 @@ +# JavaScript Integration + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [lib/loader/README.md](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/README.md) +- [lib/loader/index.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.d.ts) +- [lib/loader/index.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js) +- [lib/loader/package.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/package.json) +- [lib/loader/tests/assembly/index.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/tests/assembly/index.ts) +- [lib/loader/tests/build/default.wasm](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/tests/build/default.wasm) +- [lib/loader/tests/build/legacy.wasm](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/tests/build/legacy.wasm) +- [lib/loader/tests/index.html](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/tests/index.html) +- [lib/loader/tests/index.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/tests/index.js) + +
+ + + +This page documents how AssemblyScript modules can be integrated with JavaScript environments, focusing on the mechanisms for instantiating WebAssembly modules and managing data transfer between JavaScript and WebAssembly. For information about JavaScript bindings generation, see [JavaScript Bindings Generator](#5.1). + +## Overview + +AssemblyScript's JavaScript integration layer provides a bridge between WebAssembly modules compiled from AssemblyScript and JavaScript host environments. This integration is primarily facilitated through the AssemblyScript loader, which handles module instantiation, memory management, and data conversions. + +**Note:** The AssemblyScript loader has been deprecated as of AssemblyScript 0.20. It will continue to work for a while, but it's recommended to switch to the new static bindings generation. + +The JavaScript integration system solves several key challenges: + +1. **Module Instantiation**: Simplifying the process of loading WebAssembly modules +2. **Memory Management**: Facilitating access to the WebAssembly module's memory +3. **Type Conversion**: Converting between JavaScript and AssemblyScript data types +4. **Object Lifetime**: Managing the lifetime of complex objects across the boundary + +Sources: [lib/loader/README.md:1-5](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/README.md#L1-L5) + +## AssemblyScript Loader Architecture + +The AssemblyScript loader provides a convenient API for working with AssemblyScript modules. It wraps the WebAssembly API and adds utilities for working with AssemblyScript types. + +```mermaid +flowchart TB + subgraph "JavaScript Environment" + JsApp["JavaScript Application"] + LoaderModule["AssemblyScript Loader"] + WebAssemblyAPI["WebAssembly API"] + end + + subgraph "WebAssembly Module" + WasmInstance["WebAssembly Instance"] + WasmMemory["WebAssembly Memory"] + WasmTable["WebAssembly Table"] + Exports["Module Exports"] + end + + JsApp --> LoaderModule + LoaderModule --> WebAssemblyAPI + WebAssemblyAPI --> WasmInstance + WasmInstance --> WasmMemory + WasmInstance --> WasmTable + WasmInstance --> Exports + + LoaderModule --> |"instantiate()"|WasmInstance + LoaderModule --> |"__getString(), __newString()"|WasmMemory + LoaderModule --> |"__getArray(), __newArray()"|WasmMemory + LoaderModule --> |"__getFunction()"|WasmTable + + JsApp --> |"Use Enhanced Exports"|Exports +``` + +Sources: [lib/loader/index.js:332-365](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L332-L365), [lib/loader/index.d.ts:102-118](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.d.ts#L102-L118) + +### Key Components + +The loader consists of the following key components: + +1. **Instantiation Methods**: Functions for instantiating WebAssembly modules +2. **Memory Access Utilities**: Functions for working with the module's memory +3. **Type Conversion Utilities**: Functions for converting between JavaScript and AssemblyScript types +4. **Export Demangling**: Logic for creating a friendly object structure from module exports + +Sources: [lib/loader/index.js:70-446](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L70-L446) + +## Module Instantiation + +The loader provides several methods for instantiating AssemblyScript modules: + +```mermaid +flowchart LR + subgraph "Input Sources" + Binary["WebAssembly Binary"] + Module["WebAssembly.Module"] + Response["Response (fetch)"] + end + + subgraph "Loader Methods" + Instantiate["instantiate()"] + InstantiateSync["instantiateSync()"] + InstantiateStreaming["instantiateStreaming()"] + end + + subgraph "Result" + ResultObject["ResultObject"] + EnhancedExports["ASUtil & Module Exports"] + end + + Binary --> Instantiate + Binary --> InstantiateSync + Module --> Instantiate + Module --> InstantiateSync + Response --> InstantiateStreaming + Response --> Instantiate + + Instantiate --> ResultObject + InstantiateSync --> ResultObject + InstantiateStreaming --> ResultObject + + ResultObject --> EnhancedExports +``` + +The loader provides three primary methods for instantiating AssemblyScript modules: + +| Method | Description | Usage | +|--------|-------------|-------| +| `instantiate()` | Asynchronously instantiates a module from any source | `await loader.instantiate(fetch("module.wasm"))` | +| `instantiateSync()` | Synchronously instantiates a module from a binary or module | `loader.instantiateSync(wasmBinary)` | +| `instantiateStreaming()` | Asynchronously instantiates a module from a Response | `await loader.instantiateStreaming(fetch("module.wasm"))` | + +The instantiation process involves: + +1. Pre-instantiation setup (preparing imports) +2. WebAssembly instantiation +3. Post-instantiation processing (enhancing exports) +4. Export demangling (creating a friendly object structure) + +Sources: [lib/loader/index.js:332-365](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L332-L365), [lib/loader/index.d.ts:102-118](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.d.ts#L102-L118) + +### Example Usage + +```javascript +import loader from "@assemblyscript/loader"; + +// Asynchronous instantiation +loader.instantiate( + fetch("mymodule.wasm"), // WebAssembly binary source + { /* imports */ } // Optional imports +).then(({ exports }) => { + // Use the module's exports with enhanced functionality + const result = exports.myFunction(); +}); +``` + +Sources: [lib/loader/README.md:9-21](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/README.md#L9-L21) + +## Memory Management and Data Transfer + +One of the most important aspects of JavaScript integration is managing memory and transferring data between JavaScript and WebAssembly. + +```mermaid +flowchart LR + subgraph "JavaScript" + JsString["JavaScript String"] + JsArray["JavaScript Array"] + JsObject["JavaScript Object"] + end + + subgraph "AssemblyScript Loader" + NewString["__newString()"] + GetString["__getString()"] + NewArray["__newArray()"] + GetArray["__getArray()"] + Pin["__pin()"] + Unpin["__unpin()"] + end + + subgraph "WebAssembly Memory" + WasmPointer["Pointer (number)"] + WasmMemory["Memory Buffer"] + end + + JsString --> NewString + NewString --> WasmPointer + WasmPointer --> GetString + GetString --> JsString + + JsArray --> NewArray + NewArray --> WasmPointer + WasmPointer --> GetArray + GetArray --> JsArray + + JsObject --> |"Managed References"|Pin + Pin --> WasmPointer + WasmPointer --> Unpin + Unpin --> |"Release"|JsObject +``` + +### Memory Utilities + +The loader provides a set of utility functions for working with memory: + +| Function | Description | +|----------|-------------| +| `__new(size, id)` | Allocates a new instance of given size and id in the module's memory | +| `__pin(ptr)` | Prevents a managed object from being collected by the GC | +| `__unpin(ptr)` | Allows a managed object to be collected by the GC | +| `__collect()` | Performs a full garbage collection cycle | + +Sources: [lib/loader/index.js:95-103](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L95-L103), [lib/loader/index.d.ts:92-99](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.d.ts#L92-L99) + +## Working with Types + +### Strings + +Converting strings between JavaScript and AssemblyScript requires explicit allocation and retrieval: + +| Function | Description | +|----------|-------------| +| `__newString(str)` | Allocates a new string in module memory and returns its pointer | +| `__getString(ptr)` | Gets a string from a pointer in module memory | + +The string implementation handles different string sizes efficiently, using optimized approaches for small strings and a more general approach for larger strings: + +Sources: [lib/loader/index.js:54-67](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L54-L67), [lib/loader/index.js:137-147](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L137-L147), [lib/loader/index.js:161-167](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L161-L167) + +### Arrays + +Working with arrays requires knowing the array's type ID to properly interpret the memory: + +| Function | Description | +|----------|-------------| +| `__newArray(id, values)` | Allocates a new array with the given type ID and values | +| `__getArray(ptr)` | Copies an array's values from module memory | +| `__getArrayView(ptr)` | Gets a live view on an array's values in module memory | + +For typed arrays, specialized functions are available for each array type: + +```javascript +// For example, for Int32Array: +__getInt32Array(ptr) // Copies values +__getInt32ArrayView(ptr) // Gets a live view +``` + +Sources: [lib/loader/index.js:191-226](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L191-L226), [lib/loader/index.js:228-294](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L228-L294) + +### ArrayBuffers + +For working with raw binary data: + +| Function | Description | +|----------|-------------| +| `__newArrayBuffer(buf)` | Allocates a new ArrayBuffer in module memory | +| `__getArrayBuffer(ptr)` | Copies an ArrayBuffer from module memory | + +Sources: [lib/loader/index.js:149-158](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L149-L158), [lib/loader/index.js:256-261](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L256-L261) + +### Runtime Type Information (RTTI) + +The loader uses runtime type information stored in the module to properly interpret and convert between types: + +```mermaid +flowchart TD + subgraph "Type Information" + TypeInfo["getTypeinfo(id)"] + ArrayInfo["getArrayInfo(id)"] + ValueAlign["getValueAlign(info)"] + end + + subgraph "Type Constants" + ARRAYBUFFERVIEW["ARRAYBUFFERVIEW"] + ARRAY["ARRAY"] + STATICARRAY["STATICARRAY"] + VAL_SIGNED["VAL_SIGNED"] + VAL_FLOAT["VAL_FLOAT"] + VAL_MANAGED["VAL_MANAGED"] + end + + subgraph "Memory Operations" + GetView["getView(alignLog2, signed, float)"] + GetTypedArray["getTypedArray(Type, alignLog2, ptr)"] + GetTypedArrayView["getTypedArrayView(Type, alignLog2, ptr)"] + end + + TypeInfo --> ArrayInfo + ArrayInfo --> TypeConstants + TypeInfo --> ValueAlign + + TypeConstants --> |"Type Flags"|ARRAYBUFFERVIEW + TypeConstants --> |"Type Flags"|ARRAY + TypeConstants --> |"Type Flags"|STATICARRAY + TypeConstants --> |"Value Flags"|VAL_SIGNED + TypeConstants --> |"Value Flags"|VAL_FLOAT + TypeConstants --> |"Value Flags"|VAL_MANAGED + + ValueAlign --> GetView + GetView --> GetTypedArray + GetView --> GetTypedArrayView +``` + +Sources: [lib/loader/index.js:11-28](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L11-L28), [lib/loader/index.js:113-129](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L113-L129), [lib/loader/index.js:172-188](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L172-L188) + +## Working with Functions and Classes + +### Functions + +To work with functions exported from AssemblyScript: + +| Function | Description | +|----------|-------------| +| `__getFunction(ptr)` | Gets a function from a pointer containing the table index | + +Sources: [lib/loader/index.js:265-272](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L265-L272) + +### Classes and Objects + +The loader also handles class instantiation and method calls through a sophisticated export demangling process. This allows JavaScript code to interact with AssemblyScript classes in a more natural way. + +For instance, with a class in AssemblyScript: + +```typescript +// AssemblyScript +export class Example { + constructor(public value: i32) {} + getValue(): i32 { return this.value; } +} +``` + +The JavaScript code after demangling would be able to: + +```javascript +// JavaScript +const example = new exports.Example(42); +console.log(example.getValue()); // 42 +``` + +The demangling process handles: +- Constructor invocation +- Method calls +- Getters and setters +- Static methods + +Sources: [lib/loader/index.js:367-446](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L367-L446) + +## Export Demangling + +The loader's `demangle` function transforms the raw WebAssembly exports into a more user-friendly structure: + +```mermaid +flowchart LR + subgraph "Raw Exports" + RawExports["WebAssembly Exports"] + MangledNames["Mangled Names"] + end + + subgraph "Demangling Process" + DemangleFunction["demangle()"] + ProcessClassMethods["Process Class Methods"] + ProcessGetterSetters["Process Getters/Setters"] + WrapFunctions["Wrap Functions"] + end + + subgraph "Friendly Structure" + Namespaces["Namespaces"] + Classes["Classes"] + Methods["Methods"] + Properties["Properties"] + end + + RawExports --> DemangleFunction + MangledNames --> DemangleFunction + + DemangleFunction --> ProcessClassMethods + DemangleFunction --> ProcessGetterSetters + DemangleFunction --> WrapFunctions + + ProcessClassMethods --> Classes + ProcessClassMethods --> Methods + ProcessGetterSetters --> Properties + WrapFunctions --> Namespaces + + Classes --> FriendlyStructure + Methods --> FriendlyStructure + Properties --> FriendlyStructure + Namespaces --> FriendlyStructure +``` + +The demangling process: + +1. Processes the mangled export names (e.g., `Example#getValue`) +2. Creates class constructors and prototype methods +3. Sets up getters and setters +4. Wraps functions to handle argument length +5. Organizes everything into a hierarchical object structure + +Sources: [lib/loader/index.js:367-446](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.js#L367-L446), [lib/loader/index.d.ts:120-124](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/index.d.ts#L120-L124) + +## Advanced Usage and Best Practices + +### Managing Object Lifetimes + +When working with complex objects, it's important to manage their lifetimes to prevent memory leaks: + +```javascript +// Pin an object to prevent garbage collection +const ptr = exports.__pin(exports.createObject()); + +try { + // Work with the object... + const result = exports.processObject(ptr); +} finally { + // Always unpin when done to allow garbage collection + exports.__unpin(ptr); +} +``` + +Sources: [lib/loader/README.md:137-147](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/README.md#L137-L147) + +### Live Views vs. Copying + +When working with arrays, there are two approaches: + +1. **Copying**: Using `__getArray()` to create a JavaScript copy of the data +2. **Live Views**: Using `__getArrayView()` to get a direct view of the memory + +Live views are more efficient but also more dangerous: +- They may become detached if memory grows +- They may reference invalid memory if the array is resized + +Sources: [lib/loader/README.md:114-149](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/README.md#L114-L149) + +### TypeScript Integration + +For better type safety, the loader can be used with TypeScript definitions: + +```typescript +import type * as MyModule from "myModule"; // points to generated .d.ts +import loader from "@assemblyscript/loader"; + +loader.instantiate( + fetch("myModule.wasm") +).then(({ exports }) => { + // exports is now properly typed +}); +``` + +Sources: [lib/loader/README.md:304-318](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/lib/loader/README.md#L304-L318) + +## Conclusion + +The AssemblyScript loader provides a powerful bridge between JavaScript and WebAssembly modules compiled from AssemblyScript. While deprecated in favor of static bindings, it remains a useful tool for understanding how to integrate AssemblyScript with JavaScript environments. + +Key takeaways: +- Use the loader's instantiation methods to load AssemblyScript modules +- Use the provided utility functions to convert between JavaScript and AssemblyScript types +- Manage object lifetimes to prevent memory leaks +- Consider the tradeoffs between convenience and efficiency + +For more advanced integration needs, consider using static bindings generation or specialized tools like as-bind. \ No newline at end of file diff --git a/docs/autogenerated_docs/5.1-javascript-bindings-generator.md b/docs/autogenerated_docs/5.1-javascript-bindings-generator.md new file mode 100644 index 0000000000..93d6b87c66 --- /dev/null +++ b/docs/autogenerated_docs/5.1-javascript-bindings-generator.md @@ -0,0 +1,402 @@ +# JavaScript Bindings Generator + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [src/bindings/js.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/js.ts) +- [src/bindings/tsd.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/tsd.ts) +- [tests/compiler/bindings/esm.debug.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.d.ts) +- [tests/compiler/bindings/esm.debug.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.js) +- [tests/compiler/bindings/esm.release.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.release.d.ts) +- [tests/compiler/bindings/esm.release.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.release.js) +- [tests/compiler/bindings/esm.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.ts) +- [tests/compiler/bindings/noExportRuntime.debug.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/noExportRuntime.debug.js) +- [tests/compiler/bindings/noExportRuntime.release.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/noExportRuntime.release.js) +- [tests/compiler/bindings/raw.debug.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/raw.debug.d.ts) +- [tests/compiler/bindings/raw.debug.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/raw.debug.js) +- [tests/compiler/bindings/raw.release.d.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/raw.release.d.ts) +- [tests/compiler/bindings/raw.release.js](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/raw.release.js) + +
+ + + +## Purpose and Scope + +The JavaScript Bindings Generator is a core component of AssemblyScript that automatically generates JavaScript code to interface between WebAssembly modules compiled from AssemblyScript and JavaScript applications. It handles type conversions, memory management, and provides a natural JavaScript API for interacting with AssemblyScript-compiled code. This page documents the structure, functionality, and use of the bindings generator. + +For information about integrating AssemblyScript modules with JavaScript applications in general, see [JavaScript Integration](#5). + +## Architecture Overview + +The JavaScript Bindings Generator consists of two main components: + +1. **JSBuilder** - Generates JavaScript code for binding to WebAssembly modules +2. **TSDBuilder** - Generates TypeScript definition files for type safety + +### Binding Generation System + +```mermaid +flowchart TB + subgraph "AssemblyScript Compiler" + SourceCode["AssemblyScript Source"] + Program["Program Object"] + ASModule["WebAssembly Module"] + JSBuilder["JSBuilder Class"] + TSDBuilder["TSDBuilder Class"] + end + + subgraph "Generated Files" + JSBindings[".js Bindings"] + TSDefinitions[".d.ts Definitions"] + WasmModule[".wasm Binary"] + end + + subgraph "Runtime" + JSApp["JavaScript Application"] + Instantiate["instantiate()"] + WasmInstance["WebAssembly Instance"] + AdaptedExports["Adapted Exports"] + end + + SourceCode --> Program + Program --> ASModule + Program --> JSBuilder + Program --> TSDBuilder + JSBuilder --> JSBindings + TSDBuilder --> TSDefinitions + ASModule --> WasmModule + + JSBindings --> Instantiate + WasmModule --> Instantiate + Instantiate --> WasmInstance + WasmInstance --> AdaptedExports + AdaptedExports --> JSApp + TSDefinitions -.-> JSApp +``` + +Sources: [src/bindings/js.ts:113-1025](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/js.ts#L113-L1025), [src/bindings/tsd.ts:37-408](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/tsd.ts#L37-L408) + +## JSBuilder Class + +The `JSBuilder` class is the primary implementation of the JavaScript bindings generator. It extends the `ExportsWalker` class to traverse the AssemblyScript program's exports and generate appropriate JavaScript code. + +```mermaid +classDiagram + ExportsWalker <|-- JSBuilder + + class JSBuilder { + -esm: bool + -sb: string[] + -needsLiftBuffer: bool + -needsLowerBuffer: bool + -needsLiftString: bool + -needsLowerString: bool + -needsRetain: bool + -needsRelease: bool + +static build(program, esm) + +build() + -visitGlobal(name, element) + -visitFunction(name, element) + -visitEnum(name, element) + -makeLiftFromValue(valueExpr, type, sb) + -makeLowerToValue(valueExpr, type, sb) + } +``` + +Sources: [src/bindings/js.ts:113-168](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/js.ts#L113-L168) + +## Binding Generation Process + +The binding generation process follows these key steps: + +1. Instantiate the `JSBuilder` with the AssemblyScript program and ESM option +2. Walk through all exports in the program +3. Generate code for each export based on its type (function, global, enum) +4. Generate helper functions for type conversions and memory management +5. Assemble all generated code into a JavaScript file + +### Generated Structure + +The generated JavaScript file follows this basic structure: + +```javascript +async function instantiate(module, imports = {}) { + // 1. Set up adapted imports with instrumentation + const adaptedImports = { /* ... */ }; + + // 2. Instantiate the WebAssembly module + const { exports } = await WebAssembly.instantiate(module, adaptedImports); + + // 3. Create an object wrapping the raw exports + const adaptedExports = Object.setPrototypeOf({ + // Exported functions, globals, etc. with proper JavaScript bindings + }, exports); + + // 4. Helper functions for type conversions + function __liftString(pointer) { /* ... */ } + function __lowerString(value) { /* ... */ } + // ...more helper functions + + // 5. Return the adapted exports + return adaptedExports; +} + +// For ESM modules: export the bindings +export const { + // Named exports +} = await instantiate(/* ... */); +``` + +Sources: [src/bindings/js.ts:520-1025](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/js.ts#L520-L1025), [tests/compiler/bindings/esm.debug.js:1-562](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.js#L1-L562) + +## Type Conversions + +A crucial aspect of the bindings is converting between WebAssembly and JavaScript value representations. This is handled through two primary operations: + +1. **Lifting** - Converting WebAssembly values to JavaScript values +2. **Lowering** - Converting JavaScript values to WebAssembly values + +```mermaid +flowchart LR + subgraph "JavaScript Types" + JSString["String"] + JSNumber["Number"] + JSArray["Array"] + JSObject["Object"] + JSBigInt["BigInt"] + JSTypedArray["TypedArray"] + end + + subgraph "WebAssembly Memory" + WASMString["String Pointer"] + WASMNumber["Integer/Float"] + WASMArray["Array Pointer"] + WASMObject["Object Pointer"] + WASMBigInt["i64/u64"] + WASMTypedArray["TypedArray Pointer"] + end + + JSString -- "__lowerString" --> WASMString + WASMString -- "__liftString" --> JSString + + JSNumber -- "direct conversion" --> WASMNumber + WASMNumber -- "direct or >>> 0" --> JSNumber + + JSArray -- "__lowerArray" --> WASMArray + WASMArray -- "__liftArray" --> JSArray + + JSObject -- "__lowerRecord" --> WASMObject + WASMObject -- "__liftRecord" --> JSObject + + JSBigInt -- "direct" --> WASMBigInt + WASMBigInt -- "direct or BigInt.asUintN" --> JSBigInt + + JSTypedArray -- "__lowerTypedArray" --> WASMTypedArray + WASMTypedArray -- "__liftTypedArray" --> JSTypedArray +``` + +### Supported Type Conversions + +| AssemblyScript Type | JavaScript Type | Lifting Function | Lowering Function | +|--------------------|-----------------|------------------|-------------------| +| `i8`, `i16`, `i32`, `f32`, `f64` | `number` | Direct | Direct | +| `u32` | `number` | `value >>> 0` | Direct | +| `i64`, `u64` | `bigint` | `BigInt.asIntN/asUintN` | Direct | +| `bool` | `boolean` | `!!value` | `value ? 1 : 0` | +| `string` | `string` | `__liftString` | `__lowerString` | +| `ArrayBuffer` | `ArrayBuffer` | `__liftBuffer` | `__lowerBuffer` | +| `Array` | `Array` | `__liftArray` | `__lowerArray` | +| `TypedArray` | `TypedArray` | `__liftTypedArray` | `__lowerTypedArray` | +| `StaticArray` | `ArrayLike` | `__liftStaticArray` | `__lowerStaticArray` | +| Plain objects | Plain objects | `__liftRecord` | `__lowerRecord` | +| Other objects | `Internref` | `__liftInternref` | `__lowerInternref` | + +Sources: [src/bindings/js.ts:692-846](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/js.ts#L692-L846), [tests/compiler/bindings/esm.debug.js:262-367](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.js#L262-L367) + +## Memory Management + +The JavaScript bindings include a reference counting mechanism to manage object lifetimes across the JavaScript/WebAssembly boundary: + +```mermaid +sequenceDiagram + participant JS as "JavaScript" + participant Bindings as "JS Bindings" + participant Wasm as "WebAssembly" + + JS->>Bindings: Call function with object parameter + Bindings->>Bindings: Lower object to WebAssembly + Bindings->>Wasm: __pin(pointer) + Bindings->>Bindings: __retain(pointer) + Bindings->>Wasm: Call AssemblyScript function + Wasm-->>Bindings: Return result + Bindings->>Bindings: Lift result to JavaScript + Bindings->>Bindings: __release(pointer) + Bindings->>Wasm: __unpin(pointer) if refcount=0 + Bindings-->>JS: Return JavaScript value +``` + +### Memory Management Helpers + +The bindings generator includes these key memory management functions: + +- `__retain(pointer)` - Increments reference count for a pointer +- `__release(pointer)` - Decrements reference count and unpins if zero +- `__pin(pointer)` - Pins an object in memory to prevent garbage collection +- `__unpin(pointer)` - Unpins an object, allowing garbage collection + +For JavaScript objects that reference AssemblyScript objects, the bindings use `FinalizationRegistry` to automatically release the reference when the JavaScript object is garbage collected. + +Sources: [src/bindings/js.ts:853-894](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/js.ts#L853-L894), [tests/compiler/bindings/esm.debug.js:371-387](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.js#L371-L387) + +## TypeScript Definition Generation + +The `TSDBuilder` class generates TypeScript definition files (.d.ts) that provide type information for the JavaScript bindings: + +```mermaid +flowchart TD + subgraph "TSDBuilder" + Program["Program Object"] + Exports["Exports Analysis"] + TypeMapping["AS to TS Type Mapping"] + Interfaces["Interface Generation"] + Classes["Class Generation"] + end + + subgraph "Generated .d.ts" + Functions["Function Declarations"] + GlobalVars["Global Declarations"] + Enums["Enum Declarations"] + RecordTypes["Interface Definitions"] + ClassTypes["Class Definitions"] + end + + Program --> Exports + Exports --> Functions + Exports --> GlobalVars + Exports --> Enums + TypeMapping --> Functions + TypeMapping --> GlobalVars + TypeMapping --> RecordTypes + TypeMapping --> ClassTypes + Interfaces --> RecordTypes + Classes --> ClassTypes +``` + +### Type Mapping + +The `toTypeScriptType` method maps AssemblyScript types to TypeScript types: + +| AssemblyScript Type | TypeScript Type | +|---------------------|-----------------| +| `bool` | `boolean` | +| `i8`, `i16`, `i32`, `u8`, `u16`, `u32`, `f32`, `f64` | `number` | +| `i64`, `u64` | `bigint` | +| `string` | `string` | +| `ArrayBuffer` | `ArrayBuffer` | +| `Array` | `Array` | +| `StaticArray` | `ArrayLike` | +| TypedArrays | Corresponding TypeScript TypedArrays | +| Plain classes | Interfaces (`__RecordN`) | +| Other classes | Class declarations (`__InternrefN`) | + +Sources: [src/bindings/tsd.ts:262-350](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/tsd.ts#L262-L350), [tests/compiler/bindings/esm.debug.d.ts:1-209](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.d.ts#L1-L209) + +## Examples + +### Basic Example + +```javascript +// AssemblyScript code +export function add(a: i32, b: i32): i32 { + return a + b; +} + +// Generated JavaScript binding +export function add(a, b) { + // Direct conversion for numeric types + return exports.add(a, b); +} +``` + +### String Handling Example + +```javascript +// AssemblyScript code +export function concat(a: string, b: string): string { + return a + b; +} + +// Generated JavaScript binding +export function concat(a, b) { + // Convert JS strings to WebAssembly strings + a = __retain(__lowerString(a) || __notnull()); + b = __lowerString(b) || __notnull(); + try { + // Call the WebAssembly function and convert result back to JS string + return __liftString(exports.concat(a, b) >>> 0); + } finally { + // Release the retained reference + __release(a); + } +} +``` + +### Object Example + +```javascript +// AssemblyScript code +export class Point { + x: i32; + y: i32; +} + +export function createPoint(x: i32, y: i32): Point { + const pt = new Point(); + pt.x = x; + pt.y = y; + return pt; +} + +// Generated TypeScript definition +declare interface __Record1 { + /** @type `i32` */ + x: number | TOmittable; + /** @type `i32` */ + y: number | TOmittable; +} + +// Generated JavaScript binding function +export function createPoint(x, y) { + return __liftRecord1(exports.createPoint(x, y) >>> 0); +} +``` + +Sources: [tests/compiler/bindings/esm.debug.js:83-213](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.js#L83-L213), [tests/compiler/bindings/esm.debug.d.ts:55-198](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/bindings/esm.debug.d.ts#L55-L198) + +## Limitations and Considerations + +1. **Class Support**: Complex class hierarchies with inheritance are not fully supported. Plain classes are represented as interfaces, while classes with constructors or private members are represented as opaque reference types. + +2. **Memory Management**: Care must be taken when working with object references. The reference counting system helps manage memory, but circular references between JavaScript and WebAssembly can cause leaks. + +3. **Internref Handling**: Objects that can't be directly represented as plain JavaScript objects are exposed as opaque references through a custom `Internref` class. + +4. **Performance**: Type conversions add overhead compared to direct WebAssembly calls. For performance-critical code, consider using simpler types or raw WebAssembly exports. + +5. **Module Linking**: Linking two instrumented modules produces intermediate garbage. A native mechanism for direct communication between modules would improve efficiency. + +Sources: [src/bindings/js.ts:52-99](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/src/bindings/js.ts#L52-L99) + +## Integration with AssemblyScript Compiler + +The binding generator is integrated into the AssemblyScript compiler pipeline and can be configured through compiler options: + +- `--bindings esm` - Generate ECMAScript module bindings (default) +- `--bindings raw` - Generate CommonJS bindings +- `--exportStart` - Specify a function to call upon module instantiation +- `--exportRuntime` - Export runtime functions like `__new`, `__pin`, etc. + +The binding generator will automatically detect which helper functions are needed based on the types used in exports and generate only the necessary code. \ No newline at end of file diff --git a/docs/autogenerated_docs/6-memory-management.md b/docs/autogenerated_docs/6-memory-management.md new file mode 100644 index 0000000000..4ecf676fcf --- /dev/null +++ b/docs/autogenerated_docs/6-memory-management.md @@ -0,0 +1,301 @@ +# Memory Management + +
+Relevant source files + +The following files were used as context for generating this wiki page: + +- [std/assembly/polyfills.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/std/assembly/polyfills.ts) +- [tests/compiler/builtins.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/builtins.debug.wat) +- [tests/compiler/builtins.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/builtins.release.wat) +- [tests/compiler/issues/2622.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/issues/2622.debug.wat) +- [tests/compiler/issues/2622.json](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/issues/2622.json) +- [tests/compiler/issues/2622.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/issues/2622.release.wat) +- [tests/compiler/issues/2622.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/issues/2622.ts) +- [tests/compiler/issues/2622/_a.ts](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/issues/2622/_a.ts) +- [tests/compiler/std/dataview.debug.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/dataview.debug.wat) +- [tests/compiler/std/dataview.release.wat](https://github.com/AssemblyScript/assemblyscript/blob/4e7734b8/tests/compiler/std/dataview.release.wat) + +
+ + + +This wiki page describes how memory is organized, allocated, tracked, and reclaimed in AssemblyScript. It covers the core memory management systems that enable safe and efficient memory usage in AssemblyScript programs. For information about specific memory operations like `memcpy` and logical operations, see [Memory Operations](#6.1). + +## Overview + +AssemblyScript's memory management consists of several integrated components: + +1. **WebAssembly Linear Memory Model**: The fundamental memory architecture +2. **Memory Layout**: Organization of data, stack, and heap regions +3. **Memory Allocation**: Two-Level Segregated Fit (TLSF) algorithm for efficient allocation +4. **Garbage Collection**: Incremental Tri-Color Mark and Sweep (ITCMS) for automatic memory reclamation +5. **Runtime Safety Features**: Bounds checking and reference tracking + +Sources: `tests/compiler/std/dataview.release.wat`, `tests/compiler/builtins.debug.wat` + +## WebAssembly Memory Model + +AssemblyScript, like all WebAssembly modules, uses a linear memory model - a contiguous array of bytes addressable from 0 to the memory size. + +### Memory Layout Diagram + +```mermaid +graph TD + subgraph "WebAssembly Linear Memory" + Data["Data Region"] + Stack["Stack Region"] + Heap["Heap Region"] + end + + Data --> DataEnd["__data_end\nEnd of static data"] + Stack --> StackPtr["__stack_pointer\nCurrent stack top"] + Heap --> HeapBase["__heap_base\nStart of heap"] + + StackPtr -- "Stack grows down" --> HeapBase + HeapBase -- "Heap grows up" --> MemEnd["memory.size limit"] +``` + +The memory consists of three main regions: +- **Data Region**: Contains static data such as string literals and constants +- **Stack Region**: Used for local variables and function call frames +- **Heap Region**: Used for dynamic allocations (objects, arrays, etc.) + +Key global variables track memory boundaries: +- `__data_end`: End of the static data section +- `__stack_pointer`: Current top of the stack, updated during function calls +- `__heap_base`: Start of the heap region, where dynamic allocations begin + +Sources: `tests/compiler/builtins.debug.wat:60-62` + +## Memory Allocation System (TLSF) + +AssemblyScript uses the Two-Level Segregated Fit (TLSF) algorithm for memory allocation, providing O(1) time complexity for allocation and deallocation operations. + +### TLSF Architecture Diagram + +```mermaid +graph TD + TLSF["TLSF Allocator (~lib/rt/tlsf)"] + TLSF --> ROOT["ROOT\nGlobal allocator instance"] + + ROOT --> FLMap["First Level Map\nBitmap tracking non-empty size classes"] + ROOT --> FreeLists["Free Lists"] + + FreeLists --> FL0["FL[0]"] + FreeLists --> FL1["FL[1]"] + FreeLists --> FLn["FL[n]"] + + FL0 --> SLMap0["Second Level Map"] + FL0 --> SL00["SL[0,0]"] + FL0 --> SL01["SL[0,1]"] + FL0 --> SL0m["SL[0,m]"] + + SL00 --> Block1["Free Block"] + Block1 --> Block2["Free Block"] + Block2 --> null["null\n(end of list)"] + + Block1 --> Header["Header\n- size\n- prev/next\n- flags"] + Block1 --> Payload["Payload\n(user data)"] +``` + +The key components of the TLSF allocator: + +1. **ROOT**: The global allocator instance that manages all memory +2. **First Level**: Divides memory into major size classes (powers of 2) +3. **Second Level**: Further divides each size class into smaller ranges +4. **Free Lists**: Linked lists of available memory blocks for each size class +5. **Blocks**: Memory chunks with headers containing metadata + +Primary operations: +- `removeBlock`: Removes a block from the free lists +- `insertBlock`: Inserts a block into the appropriate free list +- `allocateBlock`: Finds and allocates a suitable memory block +- `freeBlock`: Returns a block to the free lists + +Sources: `tests/compiler/std/dataview.release.wat:257-648` + +## Garbage Collection (ITCMS) + +AssemblyScript uses an Incremental Tri-Color Mark and Sweep (ITCMS) garbage collector to automatically reclaim memory that's no longer in use. + +### ITCMS Architecture Diagram + +```mermaid +graph TD + GC["ITCMS Garbage Collector"] + + GC --> Spaces["Memory Spaces"] + GC --> States["GC States"] + GC --> Operations["GC Operations"] + + Spaces --> White["White Space\n(Potentially unreachable)"] + Spaces --> Gray["Gray Space\n(Being processed)"] + Spaces --> Black["Black Space\n(Known reachable)"] + Spaces --> Pin["Pin Space\n(Manually managed)"] + + States --> Idle["Idle State"] + States --> Mark["Mark State"] + States --> Sweep["Sweep State"] + + Operations --> VisitRoots["visitRoots\nVisit all root objects"] + Operations --> Visit["__visit\nMark object as reachable"] + Operations --> MakeGray["makeGray\nMove to gray space"] + Operations --> Step["step\nPerform incremental work"] +``` + +The ITCMS uses a tri-color marking scheme to track object reachability: +- **White**: Objects that might be garbage +- **Gray**: Objects being processed (marked but children not yet processed) +- **Black**: Objects known to be reachable + +Garbage collection proceeds through these phases: +1. **Mark Phase**: Starting from roots (globals, stack), identify all reachable objects +2. **Sweep Phase**: Free unreachable (white) objects +3. **Flip**: Swap white and black spaces for the next cycle + +The collector works incrementally to avoid long pauses, performing a small amount of work per step. + +Sources: `tests/compiler/std/dataview.release.wat:20-27`, `tests/compiler/std/dataview.release.wat:54-271` + +## Object Memory Layout + +All heap objects in AssemblyScript follow a consistent memory layout with a header followed by the object's data. + +### Object Memory Layout Diagram + +```mermaid +graph TD + Object["Memory Object"] + Object --> Header["Object Header (20 bytes)"] + Object --> Data["Object Data (type-specific)"] + + Header --> mmInfo["mmInfo (4 bytes)\nSize and GC flags"] + Header --> nextWithColor["nextWithColor (4 bytes)\nNext object + GC color"] + Header --> prev["prev (4 bytes)\nPrevious object"] + Header --> rtId["rtId (4 bytes)\nRuntime type ID"] + Header --> rtSize["rtSize (4 bytes)\nRuntime size"] +``` + +The 20-byte object header contains: +- Memory management information (size and GC flags) +- Doubly-linked list pointers for garbage collection +- Runtime type information for type checking and inheritance +- Size information used by the runtime + +Different types have specialized layouts after the header: +- **String**: Length followed by character data +- **Array**: Length followed by element data +- **ArrayBuffer**: ByteLength followed by raw bytes +- **Class**: Fields in declaration order + +Sources: `tests/compiler/std/dataview.debug.wat:224-227`, `tests/compiler/std/dataview.release.wat:111-116` + +## Runtime Memory Operations + +AssemblyScript provides low-level memory operations through WebAssembly instructions: + +| Operation | Description | Examples | +|-----------|-------------|----------| +| Load | Read from memory | `i32.load`, `i64.load`, `f32.load`, `f64.load` | +| Store | Write to memory | `i32.store`, `i64.store`, `f32.store`, `f64.store` | +| Size | Get memory size | `memory.size` | +| Grow | Increase memory | `memory.grow` | + +Example usage from builtins test: +```wat +// Load value from memory +i32.const 8 +i32.load +global.set $builtins/i + +// Store value to memory +i32.const 8 +global.get $builtins/i +i32.store +``` + +The runtime also provides specialized load/store variants for different sizes (8-bit, 16-bit, 32-bit, 64-bit) and signedness (signed, unsigned). + +Sources: `tests/compiler/builtins.release.wat:446-524` + +## Memory Safety Features + +AssemblyScript implements several memory safety features to prevent common memory-related bugs: + +### Bounds Checking + +Array and buffer accesses are automatically bounds-checked to prevent buffer overflows: + +```wat +// Simplified bounds check +local.get $index +local.get $array_length +i32.ge_u +if + // Throw "Index out of range" error + i32.const 1248 // Error message pointer + i32.const 1312 // File name pointer + i32.const 21 // Line number + i32.const 28 // Column number + call $~lib/builtins/abort + unreachable +end +``` + +### Stack Overflow Prevention + +The runtime checks for stack overflows before function execution: + +```wat +global.get $~lib/memory/__stack_pointer +global.get $~lib/memory/__data_end +i32.lt_s +if + // Throw stack overflow error + call $~lib/builtins/abort + unreachable +end +``` + +Sources: `tests/compiler/builtins.debug.wat:387-398` + +### Reference Counting and Type Safety + +The runtime maintains reference counts for objects and performs type checking operations to ensure type safety. This helps prevent issues like use-after-free and invalid casts. + +Sources: `tests/compiler/issues/2622.release.wat:42-78` + +## Memory Polyfills + +AssemblyScript provides polyfills for common memory operations that aren't natively available in WebAssembly: + +```typescript +// Byte swap implementation example +export function bswap(value: T): T { + if (isInteger()) { + if (sizeof() == 1) { + return value; + } + if (sizeof() == 2) { + return (value << 8 | (value >> 8)); + } + // Additional implementations for 4 and 8 bytes... + } + ERROR("Unsupported generic type"); +} +``` + +These polyfills provide optimized implementations of operations that would otherwise require multiple WebAssembly instructions. + +Sources: `std/assembly/polyfills.ts:1-27` + +## Integration with the Runtime + +The memory management system is tightly integrated with the AssemblyScript runtime. Programs compiled with AssemblyScript automatically have memory management code included, handling allocation, tracking, and deallocation without manual intervention. + +When objects are created (e.g., using `new`), the compiler generates code to: +1. Allocate the appropriate memory using TLSF +2. Initialize the object header with type information +3. Add the object to the garbage collection system +4. Initialize the object's fields \ No newline at end of file