Skip to content

feat: memory runtime, fixed collections & low-level stdlib primitives#7

Merged
BlobMaster41 merged 6 commits into
v0.29from
upgrade/deps
Mar 8, 2026
Merged

feat: memory runtime, fixed collections & low-level stdlib primitives#7
BlobMaster41 merged 6 commits into
v0.29from
upgrade/deps

Conversation

@BlobMaster41
Copy link
Copy Markdown

@BlobMaster41 BlobMaster41 commented Mar 8, 2026

Dep upgrades, memory runtime, fixed collections & low-level stdlib primitives

This branch builds on top of v0.29 with four things: bumped dev deps, a new GC-free memory runtime, fixed-capacity collections, and a set of zero-overhead low-level primitives for the standard library.


Dev dependency upgrades

Bumped all the dev tooling to current versions and regenerated every .wat test fixture to match the new output.

Package Old New
@eslint/js (new) ^10.0.1
eslint ^8.x ^10.0.3
@typescript-eslint/* ^5.62.0 ^8.56.1
@types/node ^18.x ^25.3.5
esbuild ^0.25.0 ^0.27.3
typescript-eslint (new) ^8.56.1
globals (new) ^17.4.0

Also tweaked .eslintrc.cjs and eslint.config.js to work with the new ESLint, and fixed 4 lint issues in the UMD bundles (indentation in lib/loader/umd/index.js, unused vars in both loader and rtrace UMD files).

Renamed the loader package from @assemblyscript/loader to @btc-vision/as-loader and updated the rtrace package metadata to match.

The .wat fixture regeneration accounts for the bulk of the diff (~300 files, ~400k lines changed). The actual code changes are about +1,800 lines.


Memory runtime (--runtime memory)

A new runtime option that gives you allocation without any garbage collector. Designed for blockchain contracts and embedded use cases where you want predictable memory behavior and zero GC overhead.

New files:

  • std/assembly/rt/memory-runtime.ts — bump allocator with alignment, auto memory.grow, no-op __free/__link/__visit
  • std/assembly/rt/index-memory.ts — entry point
  • std/assembly/shared/runtime.ts — added Runtime.Memory = 3

Compiler changes (src/compiler.ts, src/program.ts, src/passes/shadowstack.ts):

  • CLI accepts --runtime memory
  • Skips exporting runtime functions in this mode
  • Safer instance lookups
  • Shadow stack uses unreachable() when exception handling is on
  • Default stackSize: 65536 in asconfig.json

Stdlib conditional GC — seven modules now skip __link and __visit calls when ASC_RUNTIME == Runtime.Memory:

  • array.ts, map.ts, set.ts, staticarray.ts, typedarray.ts, string.ts, function.ts

Also changed the abort feature check in builtins.ts to use the ASC_FEATURE_EXCEPTION_HANDLING flag directly.


Fixed collections

Pre-allocated, fixed-capacity data structures. No dynamic growth, no GC pressure. They use __alloc under the memory runtime and __new otherwise.

FixedArray<T> (std/assembly/fixedarray.ts)

Contiguous buffer, manual length tracking. push/pop/swapDelete/indexOf/includes/fill/clear. Bounds-checked [], unchecked {}.

FixedMap<K,V> (std/assembly/fixedmap.ts)

Open-addressing hash map with linear probing and fixed bucket count. has/get/set/delete/clear/keys/values.

FixedSet<T> (std/assembly/fixedset.ts)

Same probing strategy as FixedMap. has/add/delete/clear/values.

All three have proper __visit implementations that only traverse managed elements when GC is active. Added E_CAPACITYEXCEEDED error constant.

Tests: tests/compiler/std/fixedarray.ts, fixedmap.ts, fixedset.ts with full fixture files.


Low-level primitives

Five new stdlib modules. All zero-overhead — inline functions and unmanaged types, no allocations, no GC.

Pointer<T> (std/assembly/pointer.ts)

Promoted from the old experiment in tests/compiler/std/pointer.ts. An @final @unmanaged class that IS a usize via changetype. Supports arithmetic (+, -, ++, --), indexing ([]), dereferencing (.value), plus new methods: isNull(), equals(), copyTo(), Pointer.null<T>().

Endian (std/assembly/endian.ts)

Inline wrappers for endian-aware memory access. loadBE/storeBE do bswap(load(...)), loadLE/storeLE are identity since wasm is LE. toBE/fromBE/toLE/fromLE for value conversion.

ByteSlice (std/assembly/byteslice.ts)

A (ptr, length) pair with bounds-checked, endian-aware reads and writes. Like DataView but doesn't own an ArrayBuffer — it views raw memory. Big-endian by default (matches protocol conventions). Constructor validates length >= 0, copyTo guards against negative count. Has getU8/16/32/64, signed variants, slice(), copyTo(), fill(), equals(), toPointer<T>().

BitFlags (std/assembly/bitflags.ts)

Inline generic functions for bit manipulation: has, hasAny, test, set, clear, toggle, popcount, isEmpty. Each compiles to 1-2 wasm instructions. Constrained to integer types via <T extends number> + compile-time isInteger<T>() guard — using BitFlags.has<f32>(...) gives you a clear error.

Encoding (std/assembly/encoding.ts)

Hex and varint codecs:

  • Hex: encode/decode (multi-byte), encodeByte/decodeByte (single), handles both upper and lowercase input
  • LEB128: encodeU32/decodeU32/encodeU64/decodeU64 with max byte guards (5 for u32, 10 for u64) to prevent infinite loops on malformed data
  • Bitcoin CompactSize: encodeCompact/decodeCompact, little-endian payloads per spec

All type declarations added to std/assembly/index.d.ts with JSDoc. Pointer gets operator overload declarations, ByteSlice documents be parameter defaulting to true.

Tests for all five in tests/compiler/std/ with debug + release WAT fixtures.


Other changes

  • Updated test.yml workflow
  • Loader/rtrace package.json metadata updates
  • lib/loader and lib/rtrace UMD bundles regenerated
  • rt.ts minor annotation cleanup

Numbers

What Count
Files changed 363
Actual source changes +1,789 / -102 (26 files)
Test fixtures regenerated ~320 .wat files
New stdlib modules 8
New compiler/runtime files 3

Testing

  • npm run build passes
  • All new tests pass — pointer, endian, bitflags, byteslice, encoding, fixedarray, fixedmap, fixedset (debug + release compile, fixture match, wasm instantiation)
  • No regressions on existing stdlib tests (array, map, set, string)
  • Lint clean (eslint --max-warnings 0)
  • BitFlags correctly rejects float types at compile time
  • Full npm test suite
  • Memory runtime integration with --runtime memory

@BlobMaster41 BlobMaster41 added the enhancement New feature or request label Mar 8, 2026
@BlobMaster41 BlobMaster41 changed the title Bump dev deps and update generated .wat tests upgrade: Bump dev deps and update generated .wat tests, upgraded to latest AS Mar 8, 2026
@BlobMaster41 BlobMaster41 changed the title upgrade: Bump dev deps and update generated .wat tests, upgraded to latest AS fix: Bump dev deps and update generated .wat tests, upgraded to latest AS Mar 8, 2026
Update development dependencies (notably @eslint/js -> 10.0.1, eslint -> 10.0.3, @typescript-eslint/* -> 8.56.1, @types/node -> 25.3.5, esbuild -> 0.27.3, and other tooling packages) and update package-lock.json accordingly. Regenerate a large set of compiler test outputs (.wat) so recorded test artifacts match the updated toolchain/formatting changes.

Add generated UMD bundle for rtrace

Add a generated UMD build for lib/rtrace (do not edit). The bundle exports Rtrace and overhead constants (BLOCK_OVERHEAD, OBJECT_OVERHEAD, TOTAL_OVERHEAD) and implements shadow-memory management, block bookkeeping, runtime instrumentation hooks (oninit, onalloc, onresize, onmove, onvisit, onfree, oninterrupt, onyield, oncollect, onstore, onload), GC profiling, and error/info reporting. This file is a generated wrapper intended for UMD consumers of the rtrace runtime.

Update test.yml

Revert "Update test.yml"

This reverts commit fd8d908.

Update eslint.config.js

Update eslint.config.js

Update .eslintrc.cjs

Update test.yml

Update test.yml

Rename loader package to @btc-vision/as-loader

Rebrand the loader package from @assemblyscript/loader to @btc-vision/as-loader. Update README references (root and loader README), import example, loader package.json and UMD entry, and related test build artifacts. Also update rtrace package metadata and UMD build, and add a package-lock for the rtrace package.

Support runtime 'none' and related fixes

Add support for a 'none' runtime option and adjust compiler/CLI behavior accordingly. CLI: map runtime 'none' and report compile diagnostics before crashing. Compiler: skip exporting runtime functions and managed runtime calls when runtime is None; improve instance lookup safety. Shadow stack: use unreachable() when exception handling is enabled, otherwise keep static abort. Program: emit diagnostics when required standard library elements are missing. asconfig: set a default stackSize of 65536.

Add 'none' runtime and simple allocator

Introduce a memory-only "none" runtime with basic allocation APIs and no GC: add std/assembly/rt/none.ts and an index file, and register Runtime.None in shared/runtime.ts. Implement __alloc/__realloc/__free and object helpers (__new/__renew) plus no-op __link/__visit; handle linear memory growth and allocation alignment. Also change abort feature check in builtins (use direct ASC_FEATURE_EXCEPTION_HANDLING flag) and tighten envOwners lookup in src/compiler.ts to return null when missing.

Add Memory runtime and conditional GC linking

Introduce a new Memory runtime (renamed from None) that provides a memory-only allocator without GC and update code to avoid GC hooks in this mode. Updated CLI to accept the "memory" runtime flag, adjusted compiler checks to compare against Runtime.Memory, and added a memory-only runtime implementation (std/assembly/rt/memory-runtime.ts and index-memory.ts). Multiple std/assembly modules now import Runtime and guard calls to __link and __visit so references and GC visitation are skipped when ASC_RUNTIME == Runtime.Memory.
Add several zero-overhead AssemblyScript utilities and types: Pointer, ByteSlice, Endian, Encoding (Hex/Varint/CompactSize) and BitFlags (new files std/assembly/pointer.ts, byteslice.ts, endian.ts, encoding.ts, bitflags.ts). Update std/assembly/index.d.ts to declare Pointer, ByteSlice, Endian, Encoding and BitFlags APIs. Make a small whitespace/annotation cleanup in std/assembly/rt.ts (__tostack signature). Note: lib/rtrace/umd/index.js was overwritten (the generated UMD runtime was removed and replaced with an installer prompt string); this looks accidental and should be reviewed.
Constrain bitflag generics to integer types and add runtime checks: BitFlags<T> functions now use T extends number and call isInteger<T>() to validate, emitting ERROR for non-integer usage. ByteSlice: remove unused Runtime import, import E_INVALIDLENGTH, validate constructor length (throws RangeError on negative), and tighten copyTo bounds-check by guarding count sign. Encoding: document and enforce LEB128 byte limits (max 5 bytes for u32, 10 for u64) to avoid infinite loops. index.d.ts: add Pointer operator overloads, annotate ByteSlice methods as big-endian by default and add be param docs/defaults, and update BitFlags declarations to require integer types. Add/modify compiler tests for bitflags, byteslice, encoding, endian, fixedarray, fixedmap, fixedset and adjust pointer tests to reflect changes.
Cleanup UMD bundle output: remove intermediate `var _default` and assign `._exports.default` directly in both loader and rtrace builds; move `TOTAL_OVERHEAD` assignment onto `_exports` (remove redundant `const`) in rtrace; fix indentation/initialization of the `off` variable in the loader string-decoding loop. Minor formatting and cleanup across the two UMD files.
Bump package version from 0.29.2 to 0.29.3 in package.json and update package-lock.json to reflect the new patch release.
@BlobMaster41 BlobMaster41 added the bug Something isn't working label Mar 8, 2026
@BlobMaster41 BlobMaster41 changed the title fix: Bump dev deps and update generated .wat tests, upgraded to latest AS feat: memory runtime, fixed collections & low-level stdlib primitives Mar 8, 2026
@BlobMaster41 BlobMaster41 merged commit 60793e6 into v0.29 Mar 8, 2026
19 checks passed
@BlobMaster41 BlobMaster41 deleted the upgrade/deps branch March 8, 2026 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant