From 561fd08254c45eb228b649724963342bff9a8a9d Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Wed, 6 Aug 2025 14:21:25 +0100 Subject: [PATCH 01/27] Skeleton UrWASM docs --- .../build-on-urbit/wasm-walkthrough/README.md | 18 + .../wasm-walkthrough/examples/README.md | 20 + .../wasm-walkthrough/examples/agent.md | 3 + .../wasm-walkthrough/examples/generator.md | 3 + .../wasm-walkthrough/examples/thread.md | 4 + .../wasm-walkthrough/overview.md | 25 ++ .../wasm-walkthrough/reference/README.md | 25 ++ .../wasm-walkthrough/reference/data-types.md | 18 + .../wasm-walkthrough/reference/wasm-libs.md | 389 ++++++++++++++++++ 9 files changed, 505 insertions(+) create mode 100644 content/build-on-urbit/wasm-walkthrough/README.md create mode 100644 content/build-on-urbit/wasm-walkthrough/examples/README.md create mode 100644 content/build-on-urbit/wasm-walkthrough/examples/agent.md create mode 100644 content/build-on-urbit/wasm-walkthrough/examples/generator.md create mode 100644 content/build-on-urbit/wasm-walkthrough/examples/thread.md create mode 100644 content/build-on-urbit/wasm-walkthrough/overview.md create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/README.md create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/data-types.md create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md diff --git a/content/build-on-urbit/wasm-walkthrough/README.md b/content/build-on-urbit/wasm-walkthrough/README.md new file mode 100644 index 00000000..70f09e5f --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/README.md @@ -0,0 +1,18 @@ +--- +description: "foobarbaz" +layout: + title: + visible: true + description: + visible: false + tableOfContents: + visible: true + outline: + visible: true + pagination: + visible: true +--- + +# WASM Walkthrough + +foobar diff --git a/content/build-on-urbit/wasm-walkthrough/examples/README.md b/content/build-on-urbit/wasm-walkthrough/examples/README.md new file mode 100644 index 00000000..d1d2bba1 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/examples/README.md @@ -0,0 +1,20 @@ +# UrWASM Examples + +foobar examples + +* What usage patterns are possible with UrWASM? + * WASM modules as libraries + * In generators + * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) + * Stateless UrWASM: `+run-once` + * Tutorial: sort a list of 64-bit atoms + * In threads + * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) + * Stateful UrWASM: `+run` + * Example: running Wasm in a thread + * In Gall agents + * You could do a Gall agent that tracks its state in the agent but delegates functionality to a JS library + * WASM calls as "userspace jets" + * I don’t think there’s an existing example for this + * Glicko-2 in JS or Python might be nice + * Would require finishing a Glicko-2 %telos which would be a pretty big job diff --git a/content/build-on-urbit/wasm-walkthrough/examples/agent.md b/content/build-on-urbit/wasm-walkthrough/examples/agent.md new file mode 100644 index 00000000..03fd04ff --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/examples/agent.md @@ -0,0 +1,3 @@ +# UrWASM Gall Agent Example + +foobar diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md new file mode 100644 index 00000000..a5ffb14f --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -0,0 +1,3 @@ +# UrWASM Generator Example + +foo diff --git a/content/build-on-urbit/wasm-walkthrough/examples/thread.md b/content/build-on-urbit/wasm-walkthrough/examples/thread.md new file mode 100644 index 00000000..b79756d6 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/examples/thread.md @@ -0,0 +1,4 @@ +# UrWASM Thread Example + +foo + diff --git a/content/build-on-urbit/wasm-walkthrough/overview.md b/content/build-on-urbit/wasm-walkthrough/overview.md new file mode 100644 index 00000000..d6b8f759 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/overview.md @@ -0,0 +1,25 @@ +# UrWASM Overview + +### Why +* The point of UrWASM is to compensate for deficiencies in the system, so that Hoon devs can… + * Do stuff like userspace jets for stuff that’s criminally slow in Hoon (fuzzy-find, userpsace jets, Glicko-2, etc.) + * Leverage existing JS and Rust libraries for functionality that doesn’t exist in Hoon (encryption, ripgrep, etc.) + +### How +* Why didn’t Urbit do this already? +* How did we solve the problems? + * UrWASM + * [urwasm.md](https://gist.github.com/Quodss/a1aaa81941e61707843a75d45d901ea0) + * Introduction + * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) + * WebAssembly primer + * UrWASM core structure + * Determinism solved by Lia + * [urwasm-jetting.md](https://gist.github.com/Quodss/196a4deb3e24a652c021469d2c4544fb) + * Jetting + * Motivation + * Bespoke WASM interpreter that operates on nouns + * Serializer / deserializer in the jet + * Serializer / deserializer in the Hoon spec + * Higher level interpreting function + * Lia interpreter diff --git a/content/build-on-urbit/wasm-walkthrough/reference/README.md b/content/build-on-urbit/wasm-walkthrough/reference/README.md new file mode 100644 index 00000000..0be38fa7 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/README.md @@ -0,0 +1,25 @@ +# UrWASM Reference + +foobar + +Urwasm is structured as a series of nested cores: + +/sur/wasm/wasm/hoon :: Wasm types definition +/sur/wasm/engine/hoon :: Wasm interpreter types +/sur/wasm/lia/hoon :: Lia [Language for Invocation of (web)Assembly] types +/lib/wasm/parser/hoon :: Wasm parser +/lib/wasm/validator/hoon :: Wasm validator +/lib/wasm/runner/op-def/hoon :: Wasm operator definitions +/lib/wasm/runner/engine/hoon :: Wasm interpreter +/lib/wasm/lia/hoon :: Lia interpreter + +All cores except for the topmost, defined in /lib/wasm/lia/hoon are additionally wrapped in one-armed cores to manage the namespace: + +/sur/wasm/wasm/hoon -> wasm-sur +/sur/wasm/engine/hoon -> engine-sur +/sur/wasm/lia/hoon -> lia-sur +/lib/wasm/parser/hoon -> parser +/lib/wasm/validator/hoon -> validator +/lib/wasm/runner/op-def/hoon -> op-def +/lib/wasm/runner/engine/hoon -> engine + diff --git a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md new file mode 100644 index 00000000..54fa0420 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md @@ -0,0 +1,18 @@ +# UrWASM Data Types + +nested core structure + +/sur/wasm/wasm/hoon :: Wasm types definition +/sur/wasm/engine/hoon :: Wasm interpreter types +/sur/wasm/lia/hoon :: Lia [Language for Invocation of (web)Assembly] types + +foobar + +## /sur/wasm/wasm/hoon +Wasm types definition + +## /sur/wasm/engine/hoon +Wasm interpreter types + +## /sur/wasm/lia/hoon +Lia [Language for Invocation of (web)Assembly] types diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md new file mode 100644 index 00000000..00e7138e --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md @@ -0,0 +1,389 @@ +# UrWASM Library Reference + +nested core structure + +/lib/wasm/parser/hoon :: Wasm parser +/lib/wasm/validator/hoon :: Wasm validator +/lib/wasm/runner/op-def/hoon :: Wasm operator definitions +/lib/wasm/runner/engine/hoon :: Wasm interpreter +/lib/wasm/lia/hoon :: Lia interpreter + +foobar + + * Stateless UrWASM: `+run-once` + * Stateful UrWASM: `+run` + +*** + +## /lib/wasm/runner/engine + +++ engine + ++ get-types + ++ mint + ++ make-export-map + ++ find-func-id + ++ conv + ++ import-upd + ++ prep + ++ instantiate + ++ init-globals + ++ init-table + ++ init-elems + ++ init-mem + ++ init-data + ++ start + ++ wasm-need + ++ wasm-bind + ++ invoke + ++ invoke-id + ++ call + ++ eval + ++ dec-br + ++ apply + + +## /lib/wasm/runner/op-def + +++ op-def + ++ mayb + ++ sure + ++ torn + ++ lane-size + ++ fuse :: from \~paldev + ++ chap + ++ page-size ^\~((bex 16)) + ++ place + ++ lim-min + ++ lim-max + ++ lte-lim + ++ change + ++ to-si + ++ en-si + ++ sat + ++ coin-to-val + ++ val-to-coin + ++ snug + ++ shot + ++ buy + ++ grab + ++ func + ++ table + ++ memo + ++ glob + ++ mem-store + ++ mem-load + ++ kind + ++ fetch-gate + ++ fetch + ++ dbug + ++ print-tee + ++ select + ++ null + ++ unreachable + ++ nop |=(local-state +<) + ++ return + ++ drop + ++ ref + ++ ref-null + ++ ref-is-null + ++ ref-func + ++ load + ++ store + ++ const + ++ get + ++ set + ++ branch + ++ table + ++ table-get + ++ table-set + ++ table-init + ++ elem-drop + ++ table-copy + ++ table-grow + ++ table-size + ++ table-fill + ++ memo + ++ memory-size + ++ memory-grow + ++ memory-init + ++ data-drop + ++ memory-copy + ++ memory-fill + ++ unar + ++ clz + ++ ctz + ++ popcnt + ++ abs + ++ neg + ++ sqrt + ++ ceil + ++ floor + ++ trunc + ++ nearest + ++ eqz + ++ wrap + ++ extend + ++ convert + ++ demote + ++ promote + ++ reinterpret + ++ bina + ++ add + ++ sub + ++ mul + ++ div + ++ rem + ++ and + ++ or + ++ xor + ++ shl + ++ shr + ++ rotl + ++ rotr + ++ min + ++ max + ++ copysign + ++ eq + ++ ne + ++ lt + ++ gt + ++ le + ++ ge + ++ simd + ++ rope + ++ fetch-vec + ++ load + ++ load-lane + ++ store + ++ store-lane + ++ const + ++ shuffle + ++ extract + ++ replace + ++ plain + ++ kind + ++ vec-unar + ++ vec-bina + ++ get-op-unar + ++ get-op-bina + ++ get-size + +## /lib/wasm/lia + +++ run-once + ++ init +++ run + ++ init + +++ arrows +* [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) + ++ m-sat (lia-state m-acc) + ++ call + ++ call-1 + ++ memread + ++ memwrite + ++ call-ext + ++ global-set + ++ global-get + ++ memory-size + ++ memory-grow :: returns old size in pages + ++ get-acc + ++ set-acc + ++ get-all-local-globals + ++ set-all-local-globals + +++ runnable (script (list lia-value) *) +++ cw-to-atom +++ types-atoms-to-coins +++ valtype-from-coin +++ page-size ^\~((bex 16)) +++ yield-need + +## /lib/wasm/parser + +++ parser + ++ main + ++ r + ++ womp + ++ bild + ++ bonk + ++ feel + ++ u-n + ++ s-n + ++ u32 (u-n 32) + ++ u64 (u-n 64) + ++ f32 + ++ f64 + ++ vec + ++ name (cook crip (vec next)) + ++ vec-u32 (vec u32) + ++ num-type + ++ vec-type (cold %v128 (just '\7b')) + ++ ref-type + ++ valtype + ++ func-type + ++ limits + ++ expr + ++ expr-pair + ++ end (just '\0b') + ++ else (just '\05') + ++ const-i32 (just '\41') + ++ const-i64 (just '\42') + ++ const-f32 (just '\43') + ++ const-f64 (just '\44') + ++ block-op (just '\02') + ++ loop-op (just '\03') + ++ if-op (just '\04') + ++ form-ranges + ++ instr + ++ select-vec + ++ br-table + ++ instr-zero (sear op-map next) + ++ block + ++ loop + ++ if + ++ block-type + ++ handle-one-arg-i32 + ++ handle-two-args-i32 + ++ handle-br-table + ++ handle-block + ++ get-valtype + ++ handle-loop + ++ handle-if + ++ handle-const-f64 + ++ handle-const-f32 + ++ handle-const-i32 + ++ handle-const-i64 + ++ fc + ++ zero-args (sear handle-zero u32) + ++ one-arg (sear handle-one ;\~(plug u32 u32)) + ++ two-args (sear handle-two ;\~(plug u32 u32 u32)) + ++ handle-zero + ++ handle-one + ++ handle-two + ++ fd + ++ memarg + ++ mem-lane + ++ const + ++ shuffle + ++ lane + ++ type-section + ++ import-section + ++ import + ++ import-desc + ++ import-func ;\~(plug (cold %func (just '\00')) u32) + ++ import-tabl ;\~(plug (cold %tabl (just '\01')) ref-type limits) + ++ import-memo ;\~(plug (cold %memo (just '\02')) limits) + ++ import-glob + ++ con-var + ++ function-section + ++ table-section + ++ table ;\~(plug ref-type limits) + ++ memory-section + ++ global-section + ++ global + ++ const-expr ;\~(sfix const-instr end) :: single instruction + ++ const-instr + ++ export-section + ++ export + ++ start-section + ++ elem-section + ++ elem + ++ elem-kind (just '\00') + ++ elem-0 + ++ elem-1 + ++ elem-2 + ++ elem-3 + ++ elem-4 + ++ elem-5 + ++ elem-6 + ++ elem-7 + ++ handle-elem-0 + ++ handle-elem-1 + ++ handle-elem-2 + ++ handle-elem-3 + ++ handle-elem-4 + ++ handle-elem-5 + ++ handle-elem-6 + ++ handle-elem-7 + ++ code-section + ++ code (bonk (vec next) ;\~(pfix u32 func)) + ++ func + ++ locals ;\~(plug u32 valtype) + ++ handle-locals + ++ data-section + ++ data + ++ to-octs + ++ datacnt-section + ++ module + ++ module-contents + ++ check + ++ customs + ++ magic (jest '\00asm') + ++ version + ++ op-map + ++ simd-map + ++ nearest + ++ sqrt + ++ div + ++ pmin + ++ pmax + ++ avgr + ++ ceil + ++ floor + ++ all-true + ++ bitmask + ++ narrow + ++ shl + ++ extadd + ++ convert + ++ mul + ++ splat + ++ eq + ++ ne + ++ abs + ++ neg + ++ trunc + ++ lt + ++ gt + ++ le + ++ ge + ++ shr + ++ min + ++ max + ++ add + ++ sub + ++ extend + ++ extmul + + +## /lib/wasm/validator + +++ validator + ++ output + ++ result-form + ++ result + ++ bind + ++ snug + ++ validate-module + ++ v-import-section + ++ validate-limits + ++ v-function-section + ++ v-table-section + ++ v-memory-section + ++ v-global-section + ++ v-export-section + ++ v-start-section + ++ v-elem-section + ++ v-datacnt-section + ++ v-code-section + ++ v-data-section + ++ validate-code + ++ validate-expr + ++ validate-instr + ++ get-type + ++ get-type-vec + ++ from-coin + ++ byte-width + ++ dim-lane + ++ unpack From 1c7bc0c9e4419c657332edef553728e9fd7f052f Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Wed, 6 Aug 2025 14:27:34 +0100 Subject: [PATCH 02/27] Draft intro --- content/build-on-urbit/wasm-walkthrough/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/content/build-on-urbit/wasm-walkthrough/README.md b/content/build-on-urbit/wasm-walkthrough/README.md index 70f09e5f..b47eb274 100644 --- a/content/build-on-urbit/wasm-walkthrough/README.md +++ b/content/build-on-urbit/wasm-walkthrough/README.md @@ -15,4 +15,10 @@ layout: # WASM Walkthrough -foobar +Urbit's WASM affordances (collectively known as "UrWASM") enables Hoon developers to leverage pre-existing libraries from any WASM-compatible language like Rust and Go. Using QuickJS as a WASM module, they can also run Javascript on the Urbit ship. + +These docs cover: +- UrWASM overview +- UrWASM examples +- UrWASM types and API + From 568b7cb8e08209d51d88bcb2de721cc3418b6eef Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Thu, 7 Aug 2025 13:35:02 +0100 Subject: [PATCH 03/27] Draft overview --- .../build-on-urbit/wasm-walkthrough/README.md | 2 +- .../wasm-walkthrough/overview.md | 93 ++++++++++++++----- 2 files changed, 72 insertions(+), 23 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/README.md b/content/build-on-urbit/wasm-walkthrough/README.md index b47eb274..b013741c 100644 --- a/content/build-on-urbit/wasm-walkthrough/README.md +++ b/content/build-on-urbit/wasm-walkthrough/README.md @@ -15,7 +15,7 @@ layout: # WASM Walkthrough -Urbit's WASM affordances (collectively known as "UrWASM") enables Hoon developers to leverage pre-existing libraries from any WASM-compatible language like Rust and Go. Using QuickJS as a WASM module, they can also run Javascript on the Urbit ship. +Urbit's WebAssembly affordances (collectively known as "UrWASM") enables Hoon developers to leverage pre-existing libraries from any WASM-compatible language like Rust, Python, and Go. Using QuickJS as a WASM module, they can also run Javascript on the Urbit ship. These docs cover: - UrWASM overview diff --git a/content/build-on-urbit/wasm-walkthrough/overview.md b/content/build-on-urbit/wasm-walkthrough/overview.md index d6b8f759..d9f493f5 100644 --- a/content/build-on-urbit/wasm-walkthrough/overview.md +++ b/content/build-on-urbit/wasm-walkthrough/overview.md @@ -1,25 +1,74 @@ # UrWASM Overview -### Why -* The point of UrWASM is to compensate for deficiencies in the system, so that Hoon devs can… - * Do stuff like userspace jets for stuff that’s criminally slow in Hoon (fuzzy-find, userpsace jets, Glicko-2, etc.) - * Leverage existing JS and Rust libraries for functionality that doesn’t exist in Hoon (encryption, ripgrep, etc.) - -### How -* Why didn’t Urbit do this already? -* How did we solve the problems? - * UrWASM - * [urwasm.md](https://gist.github.com/Quodss/a1aaa81941e61707843a75d45d901ea0) - * Introduction - * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) - * WebAssembly primer - * UrWASM core structure - * Determinism solved by Lia - * [urwasm-jetting.md](https://gist.github.com/Quodss/196a4deb3e24a652c021469d2c4544fb) - * Jetting - * Motivation - * Bespoke WASM interpreter that operates on nouns - * Serializer / deserializer in the jet - * Serializer / deserializer in the Hoon spec - * Higher level interpreting function +Onboarding new developers onto Urbit necessarily involves teaching them [Hoon](../../hoon/why-hoon.md). Whatever Hoon's merits as a systems programming language, the time commitment to understanding the language enough to be productive is an obvious barrier to entry. + +Urbit allows developers to run server-side code in languages like Rust and Python by compiling that code to [WebAssembly](https://webassembly.org/) (WASM). They can run Javascript on the Urbit ship with a JS interpreter like QuickJS. Today this still involves some knowledge of Hoon, but the developer can mostly use the examples here as boilerplate. + +Trivially, Urbit's WASM affordances (collectively "UrWASM") enable Hoon developers to leverage pre-existing libraries for functionality that doesn't already exist in Hoon, or would be prohibitively slow without writing a C [runtime jet](../runtime/jetting.md). But one can imagine more ambitious use-cases like running complete Next.js or Rust apps on the Urbit ship. + +## WebAssembly + +WebAssembly is a small, hardware-independent assembly language for a stack-based virtual machine, primarily intended to be deployed on the web for client- and server-side applications that may be written in one of many programming languages other than Javascript. WASM is supported out-of-the-box in all mainstream browsers, and it uses Web APIs wherever possible, but WASM may be executed in other runtimes. + +Compiled WASM code (a `.wasm` file) is structured as a module, which consists of import and export declarations, function definitions, global variable and memory declarations, etc. A WASM module describes the starting state of a WASM virtual machine, whose state is modified by calling its functions, writing directly to the memory of the module, or what have you. + +As a low-level language, WASM's functions only return 32/64 bit integers and floating-point numbers. Higher-level information like structs and function signatures are stripped away during compliation and must be restored via "host language bindings", which reimplement the source code functions as wrappers around calls to the WASM VM. These may be generated automatically by the WASM compiler in addition to the `.wasm` module, usually in Javascript if the code is targeting a browser. + +For example, the following Rust code... + +```rust +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn process(input: String) -> String { + let output_string: String = input.chars().rev().collect(); + output_string +} +``` + +...will produce a `.wasm` module alongside the following language binding... + +```javascript +export function process(input) { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + wasm.process(retptr, ptr0, len0); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + deferred2_0 = r0; + deferred2_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(deferred2_0, deferred2_1, 1); + } +} +``` + +...which a web app could invoke like so: + +```javascript +import init, { process } from './our_wasm_module.js'; + +await init(); // init our_wasm_module.wasm +const result = process("hello world"); // run process() +console.log(result); // "dlrow olleh" +``` + +In our case, we'll have to write our own bindings manually in Hoon. We'll cover this later in these docs. + +## Lia + +The main theortical blocker to executing non-Hoon code on Urbit was that doing so would violate Urbit's commitments to determinism and referential transparency. UrWASM solves this by executing compiled WASM in Lia, a tiny interpreter that manages WASM's handful of nondeterministic edge-cases such that the same inputs to a WASM function will always result in the same output. The interpreter itself is small enough to be [jetted](../runtime/jetting.md), such that Urbit can execute WASM code at near-native speeds. + +* Determinism solved by Lia + * [urwasm-jetting.md](https://gist.github.com/Quodss/196a4deb3e24a652c021469d2c4544fb) + * Jetting + * Motivation + * Higher level interpreting function * Lia interpreter + From 8e4f98de2fc6e63dccc3bf5d3be4dc2ef150628a Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Thu, 7 Aug 2025 14:21:49 +0100 Subject: [PATCH 04/27] Skeleton examples section --- .../wasm-walkthrough/examples/README.md | 22 ++++--------------- .../wasm-walkthrough/examples/agent.md | 4 ++++ .../wasm-walkthrough/examples/generator.md | 5 +++++ .../wasm-walkthrough/examples/thread.md | 4 ++++ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/examples/README.md b/content/build-on-urbit/wasm-walkthrough/examples/README.md index d1d2bba1..4bbdfc30 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/README.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/README.md @@ -1,20 +1,6 @@ # UrWASM Examples -foobar examples - -* What usage patterns are possible with UrWASM? - * WASM modules as libraries - * In generators - * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) - * Stateless UrWASM: `+run-once` - * Tutorial: sort a list of 64-bit atoms - * In threads - * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) - * Stateful UrWASM: `+run` - * Example: running Wasm in a thread - * In Gall agents - * You could do a Gall agent that tracks its state in the agent but delegates functionality to a JS library - * WASM calls as "userspace jets" - * I don’t think there’s an existing example for this - * Glicko-2 in JS or Python might be nice - * Would require finishing a Glicko-2 %telos which would be a pretty big job +What usage patterns are possible with WASM on Urbit? In this section we'll demonstrate several: +- WASM in a [generator](../../../hoon/generators.md). +- WASM in [threads](../../../urbit-os/base/threads/README.md). +- WASM in [Gall agents](../../app-school/README.md). diff --git a/content/build-on-urbit/wasm-walkthrough/examples/agent.md b/content/build-on-urbit/wasm-walkthrough/examples/agent.md index 03fd04ff..dbaf6fde 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/agent.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/agent.md @@ -1,3 +1,7 @@ # UrWASM Gall Agent Example foobar + +* In Gall agents + * You could do a Gall agent that tracks its state in the agent but delegates functionality to a JS library + diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index a5ffb14f..08834022 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -1,3 +1,8 @@ # UrWASM Generator Example foo + +* In generators + * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) + * Stateless UrWASM: `+run-once` + * Tutorial: sort a list of 64-bit atoms diff --git a/content/build-on-urbit/wasm-walkthrough/examples/thread.md b/content/build-on-urbit/wasm-walkthrough/examples/thread.md index b79756d6..e0e66d4f 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/thread.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/thread.md @@ -2,3 +2,7 @@ foo +* [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) + * Stateful UrWASM: `+run` + * Example: running Wasm in a thread + From 070de5de57ed14dbf85e6835c4e102a2d6d74b65 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Thu, 7 Aug 2025 15:08:43 +0100 Subject: [PATCH 05/27] Add UrWASM Structure to overview --- .../wasm-walkthrough/overview.md | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/content/build-on-urbit/wasm-walkthrough/overview.md b/content/build-on-urbit/wasm-walkthrough/overview.md index d9f493f5..3fa8523a 100644 --- a/content/build-on-urbit/wasm-walkthrough/overview.md +++ b/content/build-on-urbit/wasm-walkthrough/overview.md @@ -63,7 +63,7 @@ In our case, we'll have to write our own bindings manually in Hoon. We'll cover ## Lia -The main theortical blocker to executing non-Hoon code on Urbit was that doing so would violate Urbit's commitments to determinism and referential transparency. UrWASM solves this by executing compiled WASM in Lia, a tiny interpreter that manages WASM's handful of nondeterministic edge-cases such that the same inputs to a WASM function will always result in the same output. The interpreter itself is small enough to be [jetted](../runtime/jetting.md), such that Urbit can execute WASM code at near-native speeds. +The main theoretical blocker to executing non-Hoon code on Urbit was that doing so would violate Urbit's commitments to determinism and referential transparency. UrWASM solves this by executing compiled WASM in Lia ("Language for Invocation of (web)Assembly"), a tiny interpreter that manages WASM's handful of nondeterministic edge-cases such that the same inputs to a WASM function will always result in the same output. The interpreter itself is small enough to be [jetted](../runtime/jetting.md), such that Urbit can execute WASM code at near-native speeds. * Determinism solved by Lia * [urwasm-jetting.md](https://gist.github.com/Quodss/196a4deb3e24a652c021469d2c4544fb) @@ -72,3 +72,34 @@ The main theortical blocker to executing non-Hoon code on Urbit was that doing s * Higher level interpreting function * Lia interpreter +## UrWASM Structure + +UrWASM is structured as several nested cores, with each core in this list being in the [subject](../../hoon/why-hoon.md#subject-oriented-programming) of the core below. + +``` +/sur/wasm/wasm/hoon :: WASM types +/sur/wasm/engine/hoon :: WASM interpreter types +/sur/wasm/lia/hoon :: Lia types +/lib/wasm/parser/hoon :: WASM parser +/lib/wasm/validator/hoon :: WASM validator +/lib/wasm/runner/op-def/hoon :: WASM operator definitions +/lib/wasm/runner/engine/hoon :: WASM interpreter +/lib/wasm/lia/hoon :: Lia interpreter +``` + +All cores except `/lib/wasm/lia/hoon`, are additionally wrapped in one-armed cores for easy invocation: + +``` +/sur/wasm/wasm/hoon :: wasm-sur +/sur/wasm/engine/hoon :: engine-sur +/sur/wasm/lia/hoon :: lia-sur +/lib/wasm/parser/hoon :: parser +/lib/wasm/validator/hoon :: validator +/lib/wasm/runner/op-def/hoon :: op-def +/lib/wasm/runner/engine/hoon :: engine +``` + +Thus if you imported `/lib/wasm/lia/hoon` as `wasm`, you can get the core with Lia types as `lia-sur:wasm`. + +UrWASM's data types and functionality are covered in detail in the [reference](./reference/README.md) section. + From a06cc320c79108dcb85bced42a330edaaf74a250 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Fri, 8 Aug 2025 14:52:10 +0100 Subject: [PATCH 06/27] Draft generator docs --- .../wasm-walkthrough/examples/generator.md | 279 +++++++++++++++++- 1 file changed, 274 insertions(+), 5 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index 08834022..df0a74de 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -1,8 +1,277 @@ # UrWASM Generator Example -foo +Let's use UrWASM to write a generator that can quickly sort a large list of 64-bit integers in ascending order. + +## Benchmark without UrWASM + +In pure Hoon, we would write something like this: + +```hoon +:: XX check this compiles and runs +|= lit=(list @G) +^- (list @G) +~> %bout +(sort lit lth) +``` + +Let's run this and see how long it takes. (`__~` in the Dojo discards the product of the given expression and returns `~`). + +``` +> =l (flop (gulf 0 1.000)) +> +took ms/63.434 +> __~ +run l +~ +``` + +## Building the WASM module + +Now let's sort the list using UrWasm, with the source code written in Rust. Initialize a new library cargo with `cargo new wasm_sort --lib` and edit `Cargo.toml`: + +```toml +[package] +name = "wasm_sort" +version = "0.1.0" +edition = "2024" + +[dependencies] +wasm-bindgen = "0.2" + +[lib] +crate-type = ["cdylib"] +``` + +Paste this source code into `sort.rs`: + +```rust +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn sort_u64(mut input: Vec) -> Vec { + input.sort(); + input +} +``` + +Run `wasm-pack build` and `wasm-pack` will compile the `wasm_sort.wasm` module from this file. The `wasm_bindgen` Rust library will be used to create a corresponding JS bindings file named something like `wasm_sort_bg.js`. + +## Writing Hoon bindings + +Let's see how the JS bindings file calls `sort_u64()`. Remember, this is a generated wrapper function that would be called from the web app. This wrapper function is what we'll have to reimplement in our new Hoon generator to call out to the compiled `wasm_sort.wasm` module. + +```javascript +// ... + +let WASM_VECTOR_LEN = 0; + +function passArray64ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 8, 8) >>> 0; + getBigUint64ArrayMemory0().set(arg, ptr / 8); + WASM_VECTOR_LEN = arg.length; + return ptr; +} + +function getArrayU64FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getBigUint64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len); +} + +/** + * @param {BigUint64Array} input + * @returns {BigUint64Array} +**/ +export function sort_u64(input) { + const ptr0 = passArray64ToWasm0(input, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.sort_u64(ptr0, len0); + var v2 = getArrayU64FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 8, 8); + return v2; +} + +// ... +``` + +What's going on in this `sortu64()` wrapper function? We see that it does the following: +1. Allocates memory for the input vector by calling `__wbindgen_malloc`. +2. Writes the contents of the array to WASM memory. +3. Calls `sort_u64()` with the array pointer and length as parameters, which returns two values. +4. Uses those two values as the pointer and length of the resulting array, reads that from memory. +5. Frees the returned array from Wasm memory with `__wbindgen_free`. +6. Returns the sorted array. + +{TODO: better setup for yil-mold and acc-mold here.} + +We don't need to reimplement step 5, since the whole Wasm VM will be freed when we're done. + +Our generator with Hoon "bindings" will look like this in full. We'll examine each part in detail below. + +{% code title="/ted/sort.hoon" overflow="nowrap" lineNumbers="true" %} + +```hoon +/+ *wasm-lia +/* wasm-bin %wasm /sort/wasm +:: +:- %say +|= [* [lit=(list @G) ~] *] +:- %noun +^- (list @G) +~> %bout +:: +=> |% + +$ yil-mold (list @G) + +$ acc-mold * + -- +%- yield-need =< - +%^ (run-once yil-mold acc-mold) [wasm-bin [~ ~]] %$ +=/ m (script yil-mold acc-mold) +=/ arr (arrows acc-mold) +=, arr +=/ len-vec=@ (lent lit) +=/ len-bytes=@ (mul 8 len-vec) +=/ vec=@ (rep 6 lit) +:: +;< ptr=@ try:m (call-1 '__wbindgen_malloc' len-bytes 8 ~) +;< ~ try:m (memwrite ptr len-bytes vec) +;< ptr-len=(list @) try:m (call 'sort_u64' ptr len-vec ~) +;< vec-out=octs try:m (memread &1.ptr-len (mul 8 &2.ptr-len)) +:: +=/ lit-out=(list @) (rip 6 q.vec-out) +=/ lent-out=@ (lent lit-out) +?: =(len-vec lent-out) + (return:m lit-out) +%- return:m +%+ weld lit-out +(reap (sub len-vec lent-out) 0) +``` + +{% endcode %} + +What's going on here? + +First, we import the Lia interpreter and the `.wasm` module, which we've copied in to the root of our desk. (If you're working through this example, the `%base` desk on a fakeship would be fine.) + +```hoon +/+ *wasm-lia +/+ wasm-bin %wasm /sort/wasm +``` + +Mostly generator boilerplate, but note the `.lit` parameter and the output `(list @G)`. (That is, a `+list` of `@`s where `G` indicates a bitwidth of 64.) + +```hoon +:- %say +|= [* [lit=(list @G) ~] *] +:- %noun +^- (list @G) +``` + +We use the `%bout` runtime hint to time the computation that follows. + +```hoon +~> %bout +``` + +Now we'll define the types for our yield of the main script and the accumulator noun. We don't need the accumulator for this example but it's required for `+run-once`, so we'll just call it a noun `*`. + +{TODO: better intro to the yield concept} + +```hoon +=> |% + +$ yil-mold (list @G) :: type of the yield + +$ acc-mold * :: type of the accumulator + -- +``` + +Since Lia's `+run-once` returns a pair of \[yield accumulator], we grab the yield with [`=<`](../../../hoon/rune/tis.md#tisgal) to get the head (`-`) of the result. `+yield-need` is a Lia function that asserts that a yield is successful and returns the unwrapped result. The `%$` is where we'd specify a runtime hint like `%bout`, but we stub it out here as we don't need one. + +Below, we build Lia's `+run-once` gate and run it on our imported `.wasm-bin` module, which we give the empty initial state `[~ ~]`. (That is, a pair of the initial accumulator state and {foobar}). + +{TODO: not sure about this Lia `+run-once` verbiage above} + +{TODO: get clarity on (list coin-wasm) arg in wasm state} + +```hoon +:: run +yield-need on the head of the result +%- yield-need =< - +:: +:: build Lia's +run-once core with our .yil-mold +:: and .acc-mold and run it with our .wasm-bin, which +:: will be given the empty state [~ ~] +%^ (run-once yil-mold acc-mold) [wasm-bin [~ ~]] %$ +``` + +Some more boilerplate. Hoon developers will recognize `.m` by analogy to the `.m` from the boilerplate often seen in [threads](../../../urbit-os/base/threads/README.md). `.arrows` is our built `+arrows` core from Lia, and we expose that namespace with [`=,`](../../../hoon/rune/tis.md#tiscom) for convenient usage later. + +{TODO: link to `+arrows` documentation in the reference section once it exists} + +```hoon +:: define the monadic interface for the script +=/ m (script yil-mold acc-mold) +:: define basic operations +=/ arr (arrows acc-mold) +:: expose the .arr namespace +=, arr +``` + +We'll measure the input list and concatonate all of its elements into a single atom with [`+rep`](../../../hoon/stdlib/2c.md#rep). + +{TODO: amend generator code style and update all code blocks accordingly} + +```hoon +:: number of items in the list +=/ len-vec=@ (lent lit) +:: byte-length of the list +=/ len-bytes=@ (mul 8 len-vec) +:: 2^6 = 64 bits per list element +=/ vec=@ (rep 6 lit) +``` + +With that out of the way we can now interact with Wasm VM, replicating steps 1-4 of the JS binding we're using as a reference. We make heavy use of Hoon's [`;<`](../../../hoon/rune/mic.md#micgal) monadic pipeline builder, running expressions and piping the result directly into the one that follows. + +```hoon +:: allocate memory +;< ptr=@ try:m (call-1 '__wbindgen_malloc' len-bytes 8 ~) +:: write the input vector +;< ~ try:m (memwrite ptr len-bytes vec) +:: call the sort_u64 function in the module +;< ptr-len=(list @) try:m (call 'sort_u64' ptr len-vec ~) +:: read the resulting vector from memory +;< vec-out=octs try:m (memread &1.ptr-len (mul 8 &2.ptr-len)) +``` + +Now we split the resulting octets atom (`$octs`, a cell of byte length and data) into a list of 64-bit atoms with [`+rip`](../../../hoon/stdlib/2c.md) and add missing trailing zeroes if necessary. + +{TODO: why would trailing zeroes be missing?} + +```hoon +:: rip the octet stream into a list of 64-bit atoms +=/ lit-out=(list @) (rip 6 q.vec-out) +:: measure the length of the list +=/ lent-out=@ (lent lit-out) +:: +:: check if .lent-out equals the length of the +:: original list we passed into the generator +?: =(len-vec lent-out) + :: if so, return the output list + (return:m lit-out) +:: +:: if not, use +return from the .m +script core to +:: return the output list with enough trailing zeroes +:: to match the length of the input list +%- return:m +%+ weld lit-out +(reap (sub len-vec lent-out) 0) +``` + +Once you have the `sort.wasm` module and the `sort.hoon` generator in your `%base` desk, run `|commit %base` and run this generator in the Dojo, again timing it with the `%bout` in the generator. + +``` +took ms/5.012 +> __~ +sort l +~ +``` + +{TODO: get example data in there} + +A 10x speedup compared to pure Hoon for our test case (1.000 elements, reversed ordering). -* In generators - * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) - * Stateless UrWASM: `+run-once` - * Tutorial: sort a list of 64-bit atoms From f0c65fa5ba782bd5b9d17b51f397cb2126c9797e Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Fri, 8 Aug 2025 14:53:11 +0100 Subject: [PATCH 07/27] Add todo to generator --- content/build-on-urbit/wasm-walkthrough/examples/generator.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index df0a74de..b50170f9 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -7,13 +7,14 @@ Let's use UrWASM to write a generator that can quickly sort a large list of 64-b In pure Hoon, we would write something like this: ```hoon -:: XX check this compiles and runs |= lit=(list @G) ^- (list @G) ~> %bout (sort lit lth) ``` +{TODO: check the above compiles and runs} + Let's run this and see how long it takes. (`__~` in the Dojo discards the product of the given expression and returns `~`). ``` From 6bce6858eaab2072a2ab078d04c1a7bae63368d6 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Fri, 8 Aug 2025 14:54:19 +0100 Subject: [PATCH 08/27] Change /ted to /gen --- content/build-on-urbit/wasm-walkthrough/examples/generator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index b50170f9..85d3ecec 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -107,7 +107,7 @@ We don't need to reimplement step 5, since the whole Wasm VM will be freed when Our generator with Hoon "bindings" will look like this in full. We'll examine each part in detail below. -{% code title="/ted/sort.hoon" overflow="nowrap" lineNumbers="true" %} +{% code title="/gen/sort.hoon" overflow="nowrap" lineNumbers="true" %} ```hoon /+ *wasm-lia From d046f444b462110d7e1c16e0acd41e9d2546b33d Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Fri, 8 Aug 2025 15:20:40 +0100 Subject: [PATCH 09/27] Add l arg to dojo example --- content/build-on-urbit/wasm-walkthrough/examples/generator.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index 85d3ecec..cc9c512d 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -267,12 +267,12 @@ Now we split the resulting octets atom (`$octs`, a cell of byte length and data) Once you have the `sort.wasm` module and the `sort.hoon` generator in your `%base` desk, run `|commit %base` and run this generator in the Dojo, again timing it with the `%bout` in the generator. ``` +> =l (flop (gulf 0 1.000)) +> took ms/5.012 > __~ +sort l ~ ``` -{TODO: get example data in there} - A 10x speedup compared to pure Hoon for our test case (1.000 elements, reversed ordering). From 1dd8b0c1f8b4d39463b365e6f859f6eee3f1ba9b Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Fri, 8 Aug 2025 15:43:05 +0100 Subject: [PATCH 10/27] Fix conclusion --- content/build-on-urbit/wasm-walkthrough/examples/generator.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index cc9c512d..9d140555 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -264,7 +264,7 @@ Now we split the resulting octets atom (`$octs`, a cell of byte length and data) (reap (sub len-vec lent-out) 0) ``` -Once you have the `sort.wasm` module and the `sort.hoon` generator in your `%base` desk, run `|commit %base` and run this generator in the Dojo, again timing it with the `%bout` in the generator. +Once you have the `sort.wasm` module and `/gen/sort.hoon` in your `%base` desk, run `|commit %base` and run this `+sort` generator in the Dojo; again we'll see the timed computation with `%bout`. ``` > =l (flop (gulf 0 1.000)) @@ -274,5 +274,5 @@ took ms/5.012 ~ ``` -A 10x speedup compared to pure Hoon for our test case (1.000 elements, reversed ordering). +This is a ~10x speedup compared to the pure Hoon implementation. From 81a8f7edd743e66b1c44e299145d629b935ea70a Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Fri, 8 Aug 2025 15:57:45 +0100 Subject: [PATCH 11/27] UrWASM to UrWasm --- content/build-on-urbit/wasm-walkthrough/README.md | 8 ++++---- .../wasm-walkthrough/examples/README.md | 2 +- .../wasm-walkthrough/examples/agent.md | 2 +- .../wasm-walkthrough/examples/generator.md | 6 +++--- .../wasm-walkthrough/examples/thread.md | 4 ++-- content/build-on-urbit/wasm-walkthrough/overview.md | 12 ++++++------ .../wasm-walkthrough/reference/README.md | 2 +- .../wasm-walkthrough/reference/data-types.md | 2 +- .../wasm-walkthrough/reference/wasm-libs.md | 6 +++--- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/README.md b/content/build-on-urbit/wasm-walkthrough/README.md index b013741c..981b33bc 100644 --- a/content/build-on-urbit/wasm-walkthrough/README.md +++ b/content/build-on-urbit/wasm-walkthrough/README.md @@ -15,10 +15,10 @@ layout: # WASM Walkthrough -Urbit's WebAssembly affordances (collectively known as "UrWASM") enables Hoon developers to leverage pre-existing libraries from any WASM-compatible language like Rust, Python, and Go. Using QuickJS as a WASM module, they can also run Javascript on the Urbit ship. +Urbit's WebAssembly affordances (collectively known as "UrWasm") enables Hoon developers to leverage pre-existing libraries from any WASM-compatible language like Rust, Python, and Go. Using QuickJS as a WASM module, they can also run Javascript on the Urbit ship. These docs cover: -- UrWASM overview -- UrWASM examples -- UrWASM types and API +- UrWasm overview +- UrWasm examples +- UrWasm types and API diff --git a/content/build-on-urbit/wasm-walkthrough/examples/README.md b/content/build-on-urbit/wasm-walkthrough/examples/README.md index 4bbdfc30..b313cac5 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/README.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/README.md @@ -1,4 +1,4 @@ -# UrWASM Examples +# UrWasm Examples What usage patterns are possible with WASM on Urbit? In this section we'll demonstrate several: - WASM in a [generator](../../../hoon/generators.md). diff --git a/content/build-on-urbit/wasm-walkthrough/examples/agent.md b/content/build-on-urbit/wasm-walkthrough/examples/agent.md index dbaf6fde..1bbf0ff7 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/agent.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/agent.md @@ -1,4 +1,4 @@ -# UrWASM Gall Agent Example +# UrWasm Gall Agent Example foobar diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index 9d140555..b0c7dd08 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -1,8 +1,8 @@ -# UrWASM Generator Example +# UrWasm Generator Example -Let's use UrWASM to write a generator that can quickly sort a large list of 64-bit integers in ascending order. +Let's use UrWasm to write a generator that can quickly sort a large list of 64-bit integers in ascending order. -## Benchmark without UrWASM +## Benchmark without UrWasm In pure Hoon, we would write something like this: diff --git a/content/build-on-urbit/wasm-walkthrough/examples/thread.md b/content/build-on-urbit/wasm-walkthrough/examples/thread.md index e0e66d4f..aed205ad 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/thread.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/thread.md @@ -1,8 +1,8 @@ -# UrWASM Thread Example +# UrWasm Thread Example foo * [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) - * Stateful UrWASM: `+run` + * Stateful UrWasm: `+run` * Example: running Wasm in a thread diff --git a/content/build-on-urbit/wasm-walkthrough/overview.md b/content/build-on-urbit/wasm-walkthrough/overview.md index 3fa8523a..6e39c132 100644 --- a/content/build-on-urbit/wasm-walkthrough/overview.md +++ b/content/build-on-urbit/wasm-walkthrough/overview.md @@ -1,10 +1,10 @@ -# UrWASM Overview +# UrWasm Overview Onboarding new developers onto Urbit necessarily involves teaching them [Hoon](../../hoon/why-hoon.md). Whatever Hoon's merits as a systems programming language, the time commitment to understanding the language enough to be productive is an obvious barrier to entry. Urbit allows developers to run server-side code in languages like Rust and Python by compiling that code to [WebAssembly](https://webassembly.org/) (WASM). They can run Javascript on the Urbit ship with a JS interpreter like QuickJS. Today this still involves some knowledge of Hoon, but the developer can mostly use the examples here as boilerplate. -Trivially, Urbit's WASM affordances (collectively "UrWASM") enable Hoon developers to leverage pre-existing libraries for functionality that doesn't already exist in Hoon, or would be prohibitively slow without writing a C [runtime jet](../runtime/jetting.md). But one can imagine more ambitious use-cases like running complete Next.js or Rust apps on the Urbit ship. +Trivially, Urbit's WASM affordances (collectively "UrWasm") enable Hoon developers to leverage pre-existing libraries for functionality that doesn't already exist in Hoon, or would be prohibitively slow without writing a C [runtime jet](../runtime/jetting.md). But one can imagine more ambitious use-cases like running complete Next.js or Rust apps on the Urbit ship. ## WebAssembly @@ -63,7 +63,7 @@ In our case, we'll have to write our own bindings manually in Hoon. We'll cover ## Lia -The main theoretical blocker to executing non-Hoon code on Urbit was that doing so would violate Urbit's commitments to determinism and referential transparency. UrWASM solves this by executing compiled WASM in Lia ("Language for Invocation of (web)Assembly"), a tiny interpreter that manages WASM's handful of nondeterministic edge-cases such that the same inputs to a WASM function will always result in the same output. The interpreter itself is small enough to be [jetted](../runtime/jetting.md), such that Urbit can execute WASM code at near-native speeds. +The main theoretical blocker to executing non-Hoon code on Urbit was that doing so would violate Urbit's commitments to determinism and referential transparency. UrWasm solves this by executing compiled WASM in Lia ("Language for Invocation of (web)Assembly"), a tiny interpreter that manages WASM's handful of nondeterministic edge-cases such that the same inputs to a WASM function will always result in the same output. The interpreter itself is small enough to be [jetted](../runtime/jetting.md), such that Urbit can execute WASM code at near-native speeds. * Determinism solved by Lia * [urwasm-jetting.md](https://gist.github.com/Quodss/196a4deb3e24a652c021469d2c4544fb) @@ -72,9 +72,9 @@ The main theoretical blocker to executing non-Hoon code on Urbit was that doing * Higher level interpreting function * Lia interpreter -## UrWASM Structure +## UrWasm Structure -UrWASM is structured as several nested cores, with each core in this list being in the [subject](../../hoon/why-hoon.md#subject-oriented-programming) of the core below. +UrWasm is structured as several nested cores, with each core in this list being in the [subject](../../hoon/why-hoon.md#subject-oriented-programming) of the core below. ``` /sur/wasm/wasm/hoon :: WASM types @@ -101,5 +101,5 @@ All cores except `/lib/wasm/lia/hoon`, are additionally wrapped in one-armed cor Thus if you imported `/lib/wasm/lia/hoon` as `wasm`, you can get the core with Lia types as `lia-sur:wasm`. -UrWASM's data types and functionality are covered in detail in the [reference](./reference/README.md) section. +UrWasm's data types and functionality are covered in detail in the [reference](./reference/README.md) section. diff --git a/content/build-on-urbit/wasm-walkthrough/reference/README.md b/content/build-on-urbit/wasm-walkthrough/reference/README.md index 0be38fa7..8187c7d6 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/README.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/README.md @@ -1,4 +1,4 @@ -# UrWASM Reference +# UrWasm Reference foobar diff --git a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md index 54fa0420..069eee74 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md @@ -1,4 +1,4 @@ -# UrWASM Data Types +# UrWasm Data Types nested core structure diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md index 00e7138e..2c63980e 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md @@ -1,4 +1,4 @@ -# UrWASM Library Reference +# UrWasm Library Reference nested core structure @@ -10,8 +10,8 @@ nested core structure foobar - * Stateless UrWASM: `+run-once` - * Stateful UrWASM: `+run` + * Stateless UrWasm: `+run-once` + * Stateful UrWasm: `+run` *** From ea76720fa2ecaf11d79544234934c3dfd6c893f8 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Fri, 8 Aug 2025 15:59:53 +0100 Subject: [PATCH 12/27] WASM to Wasm --- .../build-on-urbit/wasm-walkthrough/README.md | 4 ++-- .../wasm-walkthrough/examples/README.md | 8 +++---- .../wasm-walkthrough/examples/generator.md | 4 ++-- .../wasm-walkthrough/overview.md | 24 +++++++++---------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/README.md b/content/build-on-urbit/wasm-walkthrough/README.md index 981b33bc..dd6e91fe 100644 --- a/content/build-on-urbit/wasm-walkthrough/README.md +++ b/content/build-on-urbit/wasm-walkthrough/README.md @@ -13,9 +13,9 @@ layout: visible: true --- -# WASM Walkthrough +# Wasm Walkthrough -Urbit's WebAssembly affordances (collectively known as "UrWasm") enables Hoon developers to leverage pre-existing libraries from any WASM-compatible language like Rust, Python, and Go. Using QuickJS as a WASM module, they can also run Javascript on the Urbit ship. +Urbit's WebAssembly affordances (collectively known as "UrWasm") enables Hoon developers to leverage pre-existing libraries from any Wasm-compatible language like Rust, Python, and Go. Using QuickJS as a Wasm module, they can also run Javascript on the Urbit ship. These docs cover: - UrWasm overview diff --git a/content/build-on-urbit/wasm-walkthrough/examples/README.md b/content/build-on-urbit/wasm-walkthrough/examples/README.md index b313cac5..28c591c0 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/README.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/README.md @@ -1,6 +1,6 @@ # UrWasm Examples -What usage patterns are possible with WASM on Urbit? In this section we'll demonstrate several: -- WASM in a [generator](../../../hoon/generators.md). -- WASM in [threads](../../../urbit-os/base/threads/README.md). -- WASM in [Gall agents](../../app-school/README.md). +What usage patterns are possible with Wasm on Urbit? In this section we'll demonstrate several: +- Wasm in a [generator](../../../hoon/generators.md). +- Wasm in [threads](../../../urbit-os/base/threads/README.md). +- Wasm in [Gall agents](../../app-school/README.md). diff --git a/content/build-on-urbit/wasm-walkthrough/examples/generator.md b/content/build-on-urbit/wasm-walkthrough/examples/generator.md index b0c7dd08..fb6186dd 100644 --- a/content/build-on-urbit/wasm-walkthrough/examples/generator.md +++ b/content/build-on-urbit/wasm-walkthrough/examples/generator.md @@ -25,7 +25,7 @@ took ms/63.434 ~ ``` -## Building the WASM module +## Building the Wasm module Now let's sort the list using UrWasm, with the source code written in Rust. Initialize a new library cargo with `cargo new wasm_sort --lib` and edit `Cargo.toml`: @@ -95,7 +95,7 @@ export function sort_u64(input) { What's going on in this `sortu64()` wrapper function? We see that it does the following: 1. Allocates memory for the input vector by calling `__wbindgen_malloc`. -2. Writes the contents of the array to WASM memory. +2. Writes the contents of the array to Wasm memory. 3. Calls `sort_u64()` with the array pointer and length as parameters, which returns two values. 4. Uses those two values as the pointer and length of the resulting array, reads that from memory. 5. Frees the returned array from Wasm memory with `__wbindgen_free`. diff --git a/content/build-on-urbit/wasm-walkthrough/overview.md b/content/build-on-urbit/wasm-walkthrough/overview.md index 6e39c132..db3eb53d 100644 --- a/content/build-on-urbit/wasm-walkthrough/overview.md +++ b/content/build-on-urbit/wasm-walkthrough/overview.md @@ -2,17 +2,17 @@ Onboarding new developers onto Urbit necessarily involves teaching them [Hoon](../../hoon/why-hoon.md). Whatever Hoon's merits as a systems programming language, the time commitment to understanding the language enough to be productive is an obvious barrier to entry. -Urbit allows developers to run server-side code in languages like Rust and Python by compiling that code to [WebAssembly](https://webassembly.org/) (WASM). They can run Javascript on the Urbit ship with a JS interpreter like QuickJS. Today this still involves some knowledge of Hoon, but the developer can mostly use the examples here as boilerplate. +Urbit allows developers to run server-side code in languages like Rust and Python by compiling that code to [WebAssembly](https://webassembly.org/) (Wasm). They can run Javascript on the Urbit ship with a JS interpreter like QuickJS. Today this still involves some knowledge of Hoon, but the developer can mostly use the examples here as boilerplate. -Trivially, Urbit's WASM affordances (collectively "UrWasm") enable Hoon developers to leverage pre-existing libraries for functionality that doesn't already exist in Hoon, or would be prohibitively slow without writing a C [runtime jet](../runtime/jetting.md). But one can imagine more ambitious use-cases like running complete Next.js or Rust apps on the Urbit ship. +Trivially, Urbit's Wasm affordances (collectively "UrWasm") enable Hoon developers to leverage pre-existing libraries for functionality that doesn't already exist in Hoon, or would be prohibitively slow without writing a C [runtime jet](../runtime/jetting.md). But one can imagine more ambitious use-cases like running complete Next.js or Rust apps on the Urbit ship. ## WebAssembly -WebAssembly is a small, hardware-independent assembly language for a stack-based virtual machine, primarily intended to be deployed on the web for client- and server-side applications that may be written in one of many programming languages other than Javascript. WASM is supported out-of-the-box in all mainstream browsers, and it uses Web APIs wherever possible, but WASM may be executed in other runtimes. +WebAssembly is a small, hardware-independent assembly language for a stack-based virtual machine, primarily intended to be deployed on the web for client- and server-side applications that may be written in one of many programming languages other than Javascript. Wasm is supported out-of-the-box in all mainstream browsers, and it uses Web APIs wherever possible, but Wasm may be executed in other runtimes. -Compiled WASM code (a `.wasm` file) is structured as a module, which consists of import and export declarations, function definitions, global variable and memory declarations, etc. A WASM module describes the starting state of a WASM virtual machine, whose state is modified by calling its functions, writing directly to the memory of the module, or what have you. +Compiled Wasm code (a `.wasm` file) is structured as a module, which consists of import and export declarations, function definitions, global variable and memory declarations, etc. A Wasm module describes the starting state of a Wasm virtual machine, whose state is modified by calling its functions, writing directly to the memory of the module, or what have you. -As a low-level language, WASM's functions only return 32/64 bit integers and floating-point numbers. Higher-level information like structs and function signatures are stripped away during compliation and must be restored via "host language bindings", which reimplement the source code functions as wrappers around calls to the WASM VM. These may be generated automatically by the WASM compiler in addition to the `.wasm` module, usually in Javascript if the code is targeting a browser. +As a low-level language, Wasm's functions only return 32/64 bit integers and floating-point numbers. Higher-level information like structs and function signatures are stripped away during compliation and must be restored via "host language bindings", which reimplement the source code functions as wrappers around calls to the Wasm VM. These may be generated automatically by the Wasm compiler in addition to the `.wasm` module, usually in Javascript if the code is targeting a browser. For example, the following Rust code... @@ -63,7 +63,7 @@ In our case, we'll have to write our own bindings manually in Hoon. We'll cover ## Lia -The main theoretical blocker to executing non-Hoon code on Urbit was that doing so would violate Urbit's commitments to determinism and referential transparency. UrWasm solves this by executing compiled WASM in Lia ("Language for Invocation of (web)Assembly"), a tiny interpreter that manages WASM's handful of nondeterministic edge-cases such that the same inputs to a WASM function will always result in the same output. The interpreter itself is small enough to be [jetted](../runtime/jetting.md), such that Urbit can execute WASM code at near-native speeds. +The main theoretical blocker to executing non-Hoon code on Urbit was that doing so would violate Urbit's commitments to determinism and referential transparency. UrWasm solves this by executing compiled Wasm in Lia ("Language for Invocation of (web)Assembly"), a tiny interpreter that manages Wasm's handful of nondeterministic edge-cases such that the same inputs to a Wasm function will always result in the same output. The interpreter itself is small enough to be [jetted](../runtime/jetting.md), such that Urbit can execute Wasm code at near-native speeds. * Determinism solved by Lia * [urwasm-jetting.md](https://gist.github.com/Quodss/196a4deb3e24a652c021469d2c4544fb) @@ -77,13 +77,13 @@ The main theoretical blocker to executing non-Hoon code on Urbit was that doing UrWasm is structured as several nested cores, with each core in this list being in the [subject](../../hoon/why-hoon.md#subject-oriented-programming) of the core below. ``` -/sur/wasm/wasm/hoon :: WASM types -/sur/wasm/engine/hoon :: WASM interpreter types +/sur/wasm/wasm/hoon :: Wasm types +/sur/wasm/engine/hoon :: Wasm interpreter types /sur/wasm/lia/hoon :: Lia types -/lib/wasm/parser/hoon :: WASM parser -/lib/wasm/validator/hoon :: WASM validator -/lib/wasm/runner/op-def/hoon :: WASM operator definitions -/lib/wasm/runner/engine/hoon :: WASM interpreter +/lib/wasm/parser/hoon :: Wasm parser +/lib/wasm/validator/hoon :: Wasm validator +/lib/wasm/runner/op-def/hoon :: Wasm operator definitions +/lib/wasm/runner/engine/hoon :: Wasm interpreter /lib/wasm/lia/hoon :: Lia interpreter ``` From e0c768c150509302bfa9cd8859665c1eb850964c Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Mon, 11 Aug 2025 15:32:51 +0100 Subject: [PATCH 13/27] Start Wasm data types --- .../wasm-walkthrough/reference/README.md | 17 +- .../wasm-walkthrough/reference/data-types.md | 1161 ++++++++++++++++- 2 files changed, 1159 insertions(+), 19 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/README.md b/content/build-on-urbit/wasm-walkthrough/reference/README.md index 8187c7d6..25da38d7 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/README.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/README.md @@ -1,9 +1,8 @@ # UrWasm Reference -foobar - -Urwasm is structured as a series of nested cores: +UrWasm is structured as a series of nested cores: +``` /sur/wasm/wasm/hoon :: Wasm types definition /sur/wasm/engine/hoon :: Wasm interpreter types /sur/wasm/lia/hoon :: Lia [Language for Invocation of (web)Assembly] types @@ -12,14 +11,6 @@ Urwasm is structured as a series of nested cores: /lib/wasm/runner/op-def/hoon :: Wasm operator definitions /lib/wasm/runner/engine/hoon :: Wasm interpreter /lib/wasm/lia/hoon :: Lia interpreter +``` -All cores except for the topmost, defined in /lib/wasm/lia/hoon are additionally wrapped in one-armed cores to manage the namespace: - -/sur/wasm/wasm/hoon -> wasm-sur -/sur/wasm/engine/hoon -> engine-sur -/sur/wasm/lia/hoon -> lia-sur -/lib/wasm/parser/hoon -> parser -/lib/wasm/validator/hoon -> validator -/lib/wasm/runner/op-def/hoon -> op-def -/lib/wasm/runner/engine/hoon -> engine - +This reference section documents the UrWasm project's data types and library functionality. diff --git a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md index 069eee74..df6cbb2a 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md @@ -1,18 +1,1167 @@ # UrWasm Data Types -nested core structure +UrWasm's data types are defined in three nested `/sur` files in `%base`; innermost to outermost: +``` /sur/wasm/wasm/hoon :: Wasm types definition /sur/wasm/engine/hoon :: Wasm interpreter types /sur/wasm/lia/hoon :: Lia [Language for Invocation of (web)Assembly] types +``` -foobar +## Wasm types -## /sur/wasm/wasm/hoon -Wasm types definition +UrWasm's inner core, `+wasm-sur`, contains the foundational Wasm types. + +The first part implements the Structure chapter of the [WebAssembly Core Specification](https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/syntax/index.html). The second part implements Wasm's binary-format opcodes. + +### `$octs` (pair @ud @) + +```hoon ++$ octs (pair @ud @) +``` + +Pair of byte-length and octet stream data. + +### `+wasm-sur` + +Wrapper arm around the Wasm types. This just makes the types addressable by limb resolution paths like `num-type:wasm-sur`. + +### `$num-type` + +```hoon ++$ num-type ?(%i32 %i64 %f32 %f64) +``` + +Type annotation for the four types of number Wasm calls can return: +- 32-bit integers (`@F`). +- 64-bit integers (`@G`). +- 32-bit floating point numbers (`@rs`). +- 64-bit floating point numbers (`@rd`). + +### `$vec-type` + +```hoon ++$ vec-type %v128 +``` + +Type annotation for a 128-bit vector (`@H`). + +### `$ref-type` + +```hoon ++$ ref-type ?(%extn %func) :: externref and funcref +``` + +Type annotation for ??? + +### `$valtype` + +```hoon ++$ valtype + $~ %i32 + $? num-type + vec-type + ref-type + == +``` + +Type annotation for ??? + +### `$coin-wasm` + +```hoon ++$ coin-wasm + $~ [%i32 *@F] + $% [%i32 @F] + [%i64 @G] + [%f32 @rs] + [%f64 @rd] + [vec-type @H] + $: %ref :: function reference, null or not + $% [%func (unit @)] :: local + $: %extn :: external + %- unit + $: [mod=cord name=cord] + type=func-type + == == == == + :: + == +``` + +Type-annotated Wasm value. + +### `$limits` + +```hoon ++$ limits + $% [%flor p=@] :: min only + [%ceil p=@ q=@] :: min and max + == +``` + +??? + +### `$memarg` + +```hoon ++$ memarg + $+ memarg + [align=@ offset=@] +``` + +??? + +### `$block-type` + +```hoon ++$ block-type $@(@ func-type) :: typeidx in type section or func-type +``` + +??? + +### `$func-type` + +```hoon ++$ func-type + $: params=(list valtype) + results=(list valtype) + == +``` + +??? + +### `$lane-type` + +```hoon ++$ lane-type ?(%i8 %i16 num-type) +``` + +??? + +### `$instruction` + +```hoon ++$ instruction + $%([%vec instr-vec] instr-short instr-num instr-dbug) +``` + +??? + +### `$instr-dbug` + +```hoon ++$ instr-dbug + $% + [%dbug %print-tee term] + == +``` + +??? + +### `$instr-num` + +```hoon ++$ instr-num ?(instr-num-zero instr-num-one instr-num-two) +``` + +??? + +### `$instr-num-zero` + +```hoon ++$ instr-num-zero + $% + [%const p=$<(?(%v128 %ref) coin-wasm)] + == +``` + +??? + +### `$instr-num-one` + +```hoon ++$ instr-num-one + $% + [%eqz type=?(%i32 %i64)] + [%clz type=?(%i32 %i64)] + [%ctz type=?(%i32 %i64)] + [%popcnt type=?(%i8 %i32 %i64)] + [%abs type=lane-type] + [%neg type=lane-type] + [%ceil type=?(%f32 %f64)] + [%floor type=?(%f32 %f64)] + :: + $: %trunc + type=num-type + source-type=(unit ?(%f32 %f64)) + mode=(unit ?(%s %u)) + sat=? + == + :: + [%nearest type=?(%f32 %f64)] + [%sqrt type=?(%f32 %f64)] + [%wrap ~] + :: + $: %extend + type=?(%i32 %i64) + source-type=?(%i32 %i64) + source-size=?(%8 %16 %32) + mode=?(%s %u) + == + :: + [%convert type=?(%f32 %f64) source-type=?(%i32 %i64) mode=?(%s %u)] + [%demote ~] + [%promote ~] + [%reinterpret type=num-type source-type=num-type] + == +``` + +??? + +### `$instr-num-two` + +```hoon ++$ instr-num-two + $% + [%eq type=lane-type] + [%ne type=lane-type] + [%lt type=lane-type mode=(unit ?(%s %u))] + [%gt type=lane-type mode=(unit ?(%s %u))] + [%le type=lane-type mode=(unit ?(%s %u))] + [%ge type=lane-type mode=(unit ?(%s %u))] + [%add type=lane-type] + [%sub type=lane-type] + [%mul type=lane-type] + [%div type=lane-type mode=(unit ?(%s %u))] + [%rem type=?(%i32 %i64) mode=?(%s %u)] + [%and type=?(%i32 %i64)] + [%or type=?(%i32 %i64)] + [%xor type=?(%i32 %i64)] + [%shl type=?(%i8 %i16 %i32 %i64)] + [%shr type=?(%i8 %i16 %i32 %i64) mode=?(%s %u)] + [%rotl type=?(%i32 %i64)] + [%rotr type=?(%i32 %i64)] + [%min type=?(%f32 %f64)] + [%max type=?(%f32 %f64)] + [%copysign type=?(%f32 %f64)] + == +``` + +??? + +### `$instr-short` + +```hoon ++$ instr-short + $% + :: Control instructions + :: + [%unreachable ~] + [%nop ~] + [%block type=block-type body=expression] + [%loop type=block-type body=expression] + $: %if + type=block-type + branch-true=expression + branch-false=expression + == + :: + [%br label=@] + [%br-if label=@] + [%br-table label-vec=(list @) label-default=@] + [%return ~] + [%call func-id=@] + [%call-indirect type-id=@ table-id=@] + :: Reference instructions + :: + [%ref-null t=ref-type] + [%ref-is-null ~] + [%ref-func func-id=@] + :: Parametric instructions + :: + [%drop ~] + [%select (unit (list valtype))] + :: Variable instructions + :: + [%local-get index=@] + [%local-set index=@] + [%local-tee index=@] + [%global-get index=@] + [%global-set index=@] + :: Table instructions + :: + [%table-get tab-id=@] + [%table-set tab-id=@] + [%table-init elem-id=@ tab-id=@] + [%elem-drop elem-id=@] + [%table-copy tab-id-x=@ tab-id-y=@] + [%table-grow tab-id=@] + [%table-size tab-id=@] + [%table-fill tab-id=@] + :: Memory instructions + :: + $: %load + type=num-type + m=memarg + n=(unit ?(%8 %16 %32)) + mode=(unit ?(%s %u)) + == + :: + $: %store + type=num-type + m=memarg + n=(unit ?(%8 %16 %32)) + == + :: + [%memory-size mem-id=%0] + [%memory-grow mem-id=%0] + [%memory-init x=@ mem-id=%0] + [%data-drop x=@] + [%memory-copy mem-1=%0 mem-2=%0] + [%memory-fill mem-id=%0] + == :: $instr-short +``` + +??? + +### `$instr-vec` + +```hoon ++$ instr-vec + $% + :: Load + :: + $: %load + m=memarg + $= kind %- unit + $: p=?(%8 %16 %32 %64) + q=?(%splat %zero [%extend ?(%s %u)]) + == == + :: + [%load-lane m=memarg p=?(%8 %16 %32 %64) l=@] + :: Store + :: + [%store m=memarg] + [%store-lane m=memarg p=?(%8 %16 %32 %64) l=@] + :: Misc + [%const p=$>(%v128 coin-wasm)] + [%shuffle lane-ids=(list @)] + [%extract p=lane-type l=@ mode=?(%s %u)] + [%replace p=lane-type l=@] + :: Plain + :: + [%swizzle ~] + [%splat p=lane-type] + [%eq p=lane-type] + [%ne p=lane-type] + [%lt p=lane-type mode=?(%u %s)] + [%gt p=lane-type mode=?(%u %s)] + [%le p=lane-type mode=?(%u %s)] + [%ge p=lane-type mode=?(%u %s)] + [%not ~] + [%and ~] + [%andnot ~] + [%or ~] + [%xor ~] + [%bitselect ~] + [%any-true ~] + [%abs p=lane-type] + [%neg p=lane-type] + [%popcnt ~] + [%all-true p=?(%i8 %i16 %i32 %i64)] + [%bitmask p=?(%i8 %i16 %i32 %i64)] + [%narrow p=?(%i8 %i16) mode=?(%u %s)] + [%shl p=?(%i8 %i16 %i32 %i64)] + [%shr p=?(%i8 %i16 %i32 %i64) mode=?(%u %s)] + [%add p=lane-type sat=(unit ?(%u %s))] + [%sub p=lane-type sat=(unit ?(%u %s))] + [%min p=lane-type mode=?(%u %s)] + [%max p=lane-type mode=?(%u %s)] + [%avgr p=?(%i8 %i16) mode=%u] + [%extadd p=?(%i16 %i32) mode=?(%u %s)] + [%q15mul-r-sat ~] + [%extend p=?(%i16 %i32 %i64) mode=?(%u %s) half=?(%high %low)] + [%mul p=lane-type] + [%extmul p=?(%i16 %i32 %i64) mode=?(%u %s) half=?(%high %low)] + [%dot ~] + [%ceil p=?(%f32 %f64)] + [%floor p=?(%f32 %f64)] + [%trunc p=?(%i32 %f32 %f64) from=?(%f32 %f64) mode=?(%u %s)] + [%nearest p=?(%f32 %f64)] + [%sqrt p=?(%f32 %f64)] + [%div p=?(%f32 %f64)] + [%pmin p=?(%f32 %f64)] + [%pmax p=?(%f32 %f64)] + [%convert p=?(%f32 %f64) mode=?(%u %s)] + [%demote ~] + [%promote ~] + == :: $instr-vec +``` + +??? + +### `$expression` + +```hoon ++$ expression (list instruction) +``` + +List of `$instruction`s. + +### `$const-instr` + +```hoon ++$ const-instr + $~ [%const %i32 `@`0] + $? [%vec $>(%const instr-vec)] + $>(?(%const %global-get %ref-null %ref-func) instruction) + == +``` + +??? + +### `$module` + +```hoon ++$ module + $: + =type-section + =import-section + =function-section + =table-section + =memory-section + =global-section + =export-section + =start-section + =elem-section + =datacnt-section + =code-section + =data-section + == +``` + +A Wasm module, represented in a format closer to its binary representation (i.e. separate code and function sections) to simplify parsing. + +### `$type-section` + +```hoon ++$ type-section + $+ type-section + (list func-type) +``` + +??? + +### `$import-section` + +```hoon ++$ import-section + $+ import-section + (list import) +``` + +??? + +### `$import` + +```hoon +``` + +??? + +### `$function-section` + +```hoon ++$ function-section + $+ function-section + (list type-id=@) +``` + +??? + +### `$table-section` + +```hoon ++$ table-section (list table) +``` + +??? + +### `$table` + +```hoon ++$ table (pair ref-type limits) +``` + +??? + +### `$memory-section` + +```hoon ++$ memory-section (list limits) +``` + +??? + +### `$global-section` + +```hoon ++$ global-section (list global) +``` + +??? + +### `$global` + +```hoon ++$ global + $: v=valtype + m=?(%con %var) + i=const-instr + == +``` + + :: valtype, mutability and init value. + :: We use a single constant instruction as opposed to a + :: (list instruction) since there is no global value type + :: that would take multiple constant values + +### `$export-section` + +```hoon ++$ export-section + $+ export-section + (list export) +``` + +??? + +### `$export` + +```hoon ++$ export [name=cord =export-desc] +``` + +??? + +### `$export-desc` + +```hoon ++$ export-desc + $% [%func i=@] + [%tabl i=@] + [%memo i=@] + [%glob i=@] + == +``` + +??? + +### `$start-section` + +```hoon ++$ start-section (unit @) +``` + +??? + +### `$elem-section` + +```hoon ++$ elem-section (list elem) +``` + +??? + +### `$elem` + +```hoon ++$ elem + $~ [*ref-type ~ %pass ~] + $: t=ref-type + i=(list $>(?(%ref-func %ref-null) instruction)) + $= m + $% [%pass ~] + [%decl ~] + [%acti tab=@ off=const-instr] + == == +``` + +??? + +### `$code-section` + +```hoon ++$ code-section + $+ code-section + (list code) +``` + +??? + +### `$code` + +```hoon ++$ code + $: locals=(list valtype) + =expression + == +``` + +??? + +### `$data-section` + +```hoon ++$ data-section (list data) +``` + +??? + +### `$data` + +```hoon ++$ data + $% + [%acti off=const-instr b=octs] + [%pass b=octs] + == +``` + +??? + +### `+datacnt-section` + +```hoon +++ datacnt-section (unit @) +``` + +??? + +### `$opcode` + +```hoon ++$ opcode $? bin-opcodes-zero-args + bin-opcodes-one-arg + bin-opcodes-two-args + bin-opcodes-blocks + pseudo-opcode + == +``` + +??? + +### `$bin-opcodes-zero-args` + +```hoon ++$ bin-opcodes-zero-args + $? +:: trap nop return drop select wrap demote promote + %0x0 %0x1 %0xf %0x1a %0x1b %0xa7 %0xb6 %0xbb +:: + eqz-opcodes eq-opcodes ne-opcodes lt-opcodes gt-opcodes le-opcodes + ge-opcodes clz-opcodes ctz-opcodes popcnt-opcodes add-opcodes + sub-opcodes mul-opcodes div-opcodes rem-opcodes and-opcodes or-opcodes + xor-opcodes shl-opcodes shr-opcodes rotl-opcodes rotr-opcodes + abs-opcodes neg-opcodes ceil-opcodes floor-opcodes trunc-opcodes + nearest-opcodes sqrt-opcodes min-opcodes max-opcodes copysign-opcodes + extend-opcodes convert-opcodes reinterpret-opcodes + == +``` + +WebAssembly opcodes. Most of these are defined in the types below, with some exceptions defined here: +- `%0x0`: ??? error? +- `%0x01`: `nop`, no-op, do nothing. +- `%0x0f`: `return` the result of a function, with two wrinkles: + - If there's nothing in the stack to return, this returns nothing. + - If there are more values on the stack than allowed by the function's return type, the first $$n$$ values are returned (where $$n$$ is the number of values allowed) and the rest are discarded. +- `%0x1a`: `drop` a value from the stack. +- `%0x1b`: Like a ternary operator, `select` one of the first two operands based on whether the third is `0` or not. +- `%0xa7`: Convert an `i64` to an `i32` if possible. (If not, the operation "`wrap`s" and returns a different number entirely.) +- `%0xb6`: Convert an `f64` to `f32`. +- `%0xbb`: Convert an `f32` to `f64`. + +### `$pseudo-opcode` + +```hoon ++$ pseudo-opcode ?(%0x5 %0xb) :: else, end +``` + +??? + +### `$bin-opcodes-one-arg` + +```hoon ++$ bin-opcodes-one-arg + $? +:: br br_if call local.get local.set local.tee global.get global.set + %0xc %0xd %0x10 %0x20 %0x21 %0x22 %0x23 %0x24 +:: + const-opcodes + %0x3f :: memory.size + %0x40 :: memory.grow + == +``` + +??? + +### `$bin-opcodes-two-args` + +```hoon ++$ bin-opcodes-two-args + $? + %0xe :: br_table + %0x11 :: call_indirect + load-opcodes + store-opcodes + == +``` + +??? + +### `$bin-opcodes-blocks` + +```hoon ++$ bin-opcodes-blocks + $? + %0x2 :: block + %0x3 :: loop + %0x4 :: if + == +``` + +??? + +### `$const-opcodes` + +```hoon ++$ const-opcodes + $? + %0x41 :: i32 + %0x42 :: i64 + %0x43 :: f32 + %0x44 :: f64 + == +``` + +??? + +### `$load-opcodes` + +```hoon ++$ load-opcodes + $? + %0x28 :: i32 + %0x29 :: i64 + %0x2a :: f32 + %0x2b :: f64 + %0x2c :: i32 8 s + %0x2d :: i32 8 u + %0x2e :: i32 16 s + %0x2f :: i32 16 u + %0x30 :: i64 8 s + %0x31 :: i64 8 u + %0x32 :: i64 16 s + %0x33 :: i64 16 u + %0x34 :: i64 32 s + %0x35 :: i64 32 u + == +``` + +??? + +### `$store-opcodes` + +```hoon ++$ store-opcodes + $? + %0x36 :: i32 + %0x37 :: i64 + %0x38 :: f32 + %0x39 :: f64 + %0x3a :: i32 8 + %0x3b :: i32 16 + %0x3c :: i64 8 + %0x3d :: i64 16 + %0x3e :: i64 32 + == +``` + +??? + +### `$eqz-opcodes` + +```hoon ++$ eqz-opcodes ?(%0x45 %0x50) :: i32, i64 +``` + +??? + +### `$eq-opcodes` + +```hoon ++$ eq-opcodes ?(%0x46 %0x51 %0x5b %0x61) :: i32, i64, f32, f64 +``` + +??? + +### `$ne-opcodes` + +```hoon ++$ ne-opcodes ?(%0x47 %0x52 %0x5c %0x62) :: i32, i64, f32, f64 +``` + +??? + +### `$lt-opcodes` + +```hoon ++$ lt-opcodes + $? + %0x48 :: i32 s + %0x49 :: i32 u + %0x53 :: i64 s + %0x54 :: i64 u + %0x5d :: f32 + %0x63 :: f64 + == +``` + +??? + +### `$gt-opcodes` + +```hoon ++$ gt-opcodes + $? + %0x4a :: i32 s + %0x4b :: i32 u + %0x55 :: i64 s + %0x56 :: i64 u + %0x5e :: f32 + %0x64 :: f64 + == +``` + +??? + +### `$le-opcodes` + +```hoon ++$ le-opcodes + $? + %0x4c :: i32 s + %0x4d :: i32 u + %0x57 :: i64 s + %0x58 :: i64 u + %0x5f :: f32 + %0x65 :: f64 + == +``` + +??? + +### `$ge-opcodes` + +```hoon ++$ ge-opcodes + $? + %0x4e :: i32 s + %0x4f :: i32 u + %0x59 :: i64 s + %0x5a :: i64 u + %0x60 :: f32 + %0x66 :: f64 + == +``` + +??? + +### `$clz-opcodes` + +```hoon ++$ clz-opcodes ?(%0x67 %0x79) :: i32, i64 +``` + +??? + +### `$ctz-opcodes` + +```hoon ++$ ctz-opcodes ?(%0x68 %0x7a) :: i32, i64 +``` + +??? + +### `$popcnt-opcodes` + +```hoon ++$ popcnt-opcodes ?(%0x69 %0x7b) :: i32, i64 +``` + +??? + +### `$add-opcodes` + +```hoon ++$ add-opcodes ?(%0x6a %0x7c %0x92 %0xa0) :: i32, i64, f32, f64 +``` + +??? + +### `$sub-opcodes` + +```hoon ++$ sub-opcodes ?(%0x6b %0x7d %0x93 %0xa1) :: i32, i64, f32, f64 +``` + +??? + +### `$mul-opcodes` + +```hoon ++$ mul-opcodes ?(%0x6c %0x7e %0x94 %0xa2) :: i32, i64, f32, f64 +``` + +??? + +### `$div-opcodes` + +```hoon ++$ div-opcodes + $? + %0x6d :: i32 s + %0x6e :: i32 u + %0x7f :: i64 s + %0x80 :: i64 u + %0x95 :: f32 + %0xa3 :: f64 + == +``` + +??? + +### `$rem-opcodes` + +```hoon ++$ rem-opcodes + $? + %0x6f :: i32 s + %0x70 :: i32 u + %0x81 :: i64 s + %0x82 :: i64 u + == +``` + +??? + +### `$and-opcodes` + +```hoon ++$ and-opcodes ?(%0x71 %0x83) :: i32, i64 +``` + +??? + +### `$or-opcodes` + +```hoon ++$ or-opcodes ?(%0x72 %0x84) :: i32, i64 +``` + +??? + +### `$xor-opcodes` + +```hoon ++$ xor-opcodes ?(%0x73 %0x85) :: i32, i64 +``` + +??? + +### `$shl-opcodes` + +```hoon ++$ shl-opcodes ?(%0x74 %0x86) :: i32, i64 +``` + +??? + +### `$shr-opcodes` + +```hoon ++$ shr-opcodes + $? + %0x75 :: i32 s + %0x76 :: i32 u + %0x87 :: i64 s + %0x88 :: i64 u + == +``` + +??? + +### `$rotl-opcodes` + +```hoon ++$ rotl-opcodes ?(%0x77 %0x89) :: i32, i64 +``` + +??? + +### `$rotr-opcodes` + +```hoon ++$ rotr-opcodes ?(%0x78 %0x8a) :: i32, i64 +``` + +??? + +### `$abs-opcodes` + +```hoon ++$ abs-opcodes ?(%0x8b %0x99) :: f32, f64 +``` + +??? + +### `$neg-opcodes` + +```hoon ++$ neg-opcodes ?(%0x8c %0x9a) :: f32, f64 +``` + +??? + +### `$ceil-opcodes` + +```hoon ++$ ceil-opcodes ?(%0x8d %0x9b) :: f32, f64 +``` + +??? + +### `$floor-opcodes` + +```hoon ++$ floor-opcodes ?(%0x8e %0x9c) :: f32, f64 +``` + +??? + +### `$trunc-opcodes` + +```hoon ++$ trunc-opcodes + $? + %0x8f :: f32 + %0x9d :: f64 + %0xa8 :: f32 -> i32 s + %0xa9 :: f32 -> i32 u + %0xaa :: f64 -> i32 s + %0xab :: f64 -> i32 u + %0xae :: f32 -> i64 s + %0xaf :: f32 -> i64 u + %0xb0 :: f64 -> i64 s + %0xb1 :: f64 -> i64 u + == +``` + +??? + +### `$nearest-opcodes` + +```hoon ++$ nearest-opcodes ?(%0x90 %0x9e) :: f32, f64 +``` + +??? + +### `$sqrt-opcodes` + +```hoon ++$ sqrt-opcodes ?(%0x91 %0x9f) :: f32, f64 +``` + +??? + +### `$min-opcodes` + +```hoon ++$ min-opcodes ?(%0x96 %0xa4) :: f32, f64 +``` + +??? + +### `$max-opcodes` + +```hoon ++$ max-opcodes ?(%0x97 %0xa5) :: f32, f64 +``` + +??? + +### `$copysign-opcodes` + +```hoon ++$ copysign-opcodes ?(%0x98 %0xa6) :: f32, f64 +``` + +??? + +### `$extend-opcodes` + +```hoon ++$ extend-opcodes + $? + %0xac :: i32 -> i64 s + %0xad :: i32 -> i64 u + %0xc0 :: i8 -> i32 s + %0xc1 :: i16 -> i32 s + %0xc2 :: i8 -> i64 s + %0xc3 :: i16 -> i64 s + %0xc4 :: i32 -> i64 s ?? same as 0xac??? (yes) + == +``` + +??? + +### `$convert-opcodes` + +```hoon ++$ convert-opcodes + $? + %0xb2 :: i32 s -> f32 + %0xb3 :: i32 u -> f32 + %0xb4 :: i64 s -> f32 + %0xb5 :: i64 u -> f32 + %0xb7 :: i32 s -> f64 + %0xb8 :: i32 u -> f64 + %0xb9 :: i64 s -> f64 + %0xba :: i64 u -> f64 + == +``` + +??? + +### `$reinterpret-opcodes` + +```hoon ++$ reinterpret-opcodes + $? + %0xbc :: f32 -> i32 + %0xbd :: f64 -> i64 + %0xbe :: i32 -> f32 + %0xbf :: i64 -> f64 + == +``` + +??? + +## Wasm interpreter types -## /sur/wasm/engine/hoon Wasm interpreter types -## /sur/wasm/lia/hoon +## Lia types Lia [Language for Invocation of (web)Assembly] types + From 607175aea7f81f153e861bd3e985719e2200c843 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Mon, 11 Aug 2025 15:34:38 +0100 Subject: [PATCH 14/27] Add atoms --- .../build-on-urbit/wasm-walkthrough/reference/data-types.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md index df6cbb2a..9617ccff 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/data-types.md @@ -677,9 +677,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc - If there are more values on the stack than allowed by the function's return type, the first $$n$$ values are returned (where $$n$$ is the number of values allowed) and the rest are discarded. - `%0x1a`: `drop` a value from the stack. - `%0x1b`: Like a ternary operator, `select` one of the first two operands based on whether the third is `0` or not. -- `%0xa7`: Convert an `i64` to an `i32` if possible. (If not, the operation "`wrap`s" and returns a different number entirely.) -- `%0xb6`: Convert an `f64` to `f32`. -- `%0xbb`: Convert an `f32` to `f64`. +- `%0xa7`: Convert an `i64` / `@G` to an `i32` / `@F` if possible. (If not, the operation "`wrap`s" and returns a different number entirely.) +- `%0xb6`: Convert an `f64` / `@rd` to `f32` / `@rs`. +- `%0xbb`: Convert an `f32` / `@rs` to `f64` / `@rd`. ### `$pseudo-opcode` From 9a6cd8c4bf13f9ed6ec1a76d6520541cee123212 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Mon, 11 Aug 2025 15:38:42 +0100 Subject: [PATCH 15/27] Break up Wasm reference section --- .../wasm-walkthrough/reference/README.md | 16 ++++++++++++++-- .../reference/lia-data-types.md | 1 + .../{data-types.md => wasm-data-types.md} | 18 +----------------- .../reference/wasm-interpreter-data-types.md | 1 + 4 files changed, 17 insertions(+), 19 deletions(-) create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md rename content/build-on-urbit/wasm-walkthrough/reference/{data-types.md => wasm-data-types.md} (97%) create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md diff --git a/content/build-on-urbit/wasm-walkthrough/reference/README.md b/content/build-on-urbit/wasm-walkthrough/reference/README.md index 25da38d7..c623181a 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/README.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/README.md @@ -1,6 +1,6 @@ # UrWasm Reference -UrWasm is structured as a series of nested cores: +The UrWasm project is structured as a series of nested cores, innermost to outermost: ``` /sur/wasm/wasm/hoon :: Wasm types definition @@ -13,4 +13,16 @@ UrWasm is structured as a series of nested cores: /lib/wasm/lia/hoon :: Lia interpreter ``` -This reference section documents the UrWasm project's data types and library functionality. +This reference section documents UrWasm's data types and library functionality. + +## Data types +- Wasm data types +- Wasm interpreter data types +- Lia data types + +## Libraries +- Wasm parser +- Wasm validator +- Wasm operator +- Wasm interpreter +- Lia interpreter diff --git a/content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md new file mode 100644 index 00000000..abb85df9 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md @@ -0,0 +1 @@ +# Lia Data Types diff --git a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md similarity index 97% rename from content/build-on-urbit/wasm-walkthrough/reference/data-types.md rename to content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index 9617ccff..64852671 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -1,14 +1,5 @@ -# UrWasm Data Types +# Wasm Data Types -UrWasm's data types are defined in three nested `/sur` files in `%base`; innermost to outermost: - -``` -/sur/wasm/wasm/hoon :: Wasm types definition -/sur/wasm/engine/hoon :: Wasm interpreter types -/sur/wasm/lia/hoon :: Lia [Language for Invocation of (web)Assembly] types -``` - -## Wasm types UrWasm's inner core, `+wasm-sur`, contains the foundational Wasm types. @@ -1158,10 +1149,3 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -## Wasm interpreter types - -Wasm interpreter types - -## Lia types -Lia [Language for Invocation of (web)Assembly] types - diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md new file mode 100644 index 00000000..7215f7f8 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md @@ -0,0 +1 @@ +# Wasm Interpeter Data Types From 470b27599da7bb7144695b3e786d2f6541cc3ec7 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Mon, 11 Aug 2025 15:39:53 +0100 Subject: [PATCH 16/27] Add /sur links to Wasm reference --- content/build-on-urbit/wasm-walkthrough/reference/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/README.md b/content/build-on-urbit/wasm-walkthrough/reference/README.md index c623181a..28ef154f 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/README.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/README.md @@ -16,9 +16,9 @@ The UrWasm project is structured as a series of nested cores, innermost to outer This reference section documents UrWasm's data types and library functionality. ## Data types -- Wasm data types -- Wasm interpreter data types -- Lia data types +- [Wasm data types](./wasm-data-types.md) +- [Wasm interpreter data types](./wasm-interpreter-data-types.md) +- [Lia data types](./lia-data-types.md) ## Libraries - Wasm parser From f05e2f502130fbe6d7c763e5adf9b835466ee0df Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Tue, 12 Aug 2025 10:44:12 +0100 Subject: [PATCH 17/27] Amend /sur/wasm --- .../wasm-walkthrough/reference/wasm-data-types.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index 64852671..6b2dd7b5 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -3,7 +3,9 @@ UrWasm's inner core, `+wasm-sur`, contains the foundational Wasm types. -The first part implements the Structure chapter of the [WebAssembly Core Specification](https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/syntax/index.html). The second part implements Wasm's binary-format opcodes. +The first part implements the [Structure chapter](https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/syntax/index.html) of the [WebAssembly Core Specification](https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/syntax/index.html). + +The second part implements Wasm's binary-format opcodes. ### `$octs` (pair @ud @) From ca2036b72f6f01f8ce7b3a02d78576b29216b9e0 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Tue, 12 Aug 2025 14:46:49 +0100 Subject: [PATCH 18/27] Moar draft Wasm data types --- .../reference/wasm-data-types.md | 269 ++++++++++-------- 1 file changed, 151 insertions(+), 118 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index 6b2dd7b5..f6d0fc46 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -15,11 +15,11 @@ The second part implements Wasm's binary-format opcodes. Pair of byte-length and octet stream data. -### `+wasm-sur` +### `+wasm-sur` {#wasm-sur} Wrapper arm around the Wasm types. This just makes the types addressable by limb resolution paths like `num-type:wasm-sur`. -### `$num-type` +### `$num-type` {#num-type} ```hoon +$ num-type ?(%i32 %i64 %f32 %f64) @@ -31,23 +31,23 @@ Type annotation for the four types of number Wasm calls can return: - 32-bit floating point numbers (`@rs`). - 64-bit floating point numbers (`@rd`). -### `$vec-type` +### `$vec-type` {#vec-type} ```hoon +$ vec-type %v128 ``` -Type annotation for a 128-bit vector (`@H`). +Type annotation for a 128-bit (`@H`) register. -### `$ref-type` +### `$ref-type` {#ref-type} ```hoon +$ ref-type ?(%extn %func) :: externref and funcref ``` -Type annotation for ??? +Type annotation for references in the Wasm state, be those functions or data. -### `$valtype` +### `$valtype` {#valtype} ```hoon +$ valtype @@ -58,9 +58,9 @@ Type annotation for ??? == ``` -Type annotation for ??? +Type annotation for all the types that Wasm can accept: numbers, vectors, and references. -### `$coin-wasm` +### `$coin-wasm` {#coin-wasm} ```hoon +$ coin-wasm @@ -81,9 +81,11 @@ Type annotation for ??? == ``` -Type-annotated Wasm value. +Type-annotated Wasm value. A `$coin-wasm` is UrWasm's version of Wasm's [result types](https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/syntax/types.html#result-types), which look something like Hoon's [`$coin`](https://docs.urbit.org/hoon/stdlib/3g#coin) nouns. -### `$limits` +These are the [`$valtype`](#valtype) type annotation terms with extra specification for atom size and object references. + +### `$limits` {#limits} ```hoon +$ limits @@ -92,9 +94,9 @@ Type-annotated Wasm value. == ``` -??? +Limits the range of available storage for [`$memarg`](#memarg)s and [`$table`](#table)s. -### `$memarg` +### `$memarg` {#memarg} ```hoon +$ memarg @@ -102,9 +104,9 @@ Type-annotated Wasm value. [align=@ offset=@] ``` -??? +Defines the minimum and maximum size of a memory instance. The `.align` and `.offset` values represent units of Wasm's page size, which is 128 bits (so, a `@H`). -### `$block-type` +### `$block-type` {#block-type} ```hoon +$ block-type $@(@ func-type) :: typeidx in type section or func-type @@ -112,7 +114,7 @@ Type-annotated Wasm value. ??? -### `$func-type` +### `$func-type` {#func-type} ```hoon +$ func-type @@ -121,17 +123,17 @@ Type-annotated Wasm value. == ``` -??? +Function signature. -### `$lane-type` +### `$lane-type` {#lane-type} ```hoon +$ lane-type ?(%i8 %i16 num-type) ``` -??? +Type annotation for lanes (memory elements) in a 128-bit (`@H`) register. Includes the usual [`$num-type`s](#num-type) and additional `%i8` and `%i16` types for smaller lanes. -### `$instruction` +### `$instruction` {#instruction} ```hoon +$ instruction @@ -140,7 +142,7 @@ Type-annotated Wasm value. ??? -### `$instr-dbug` +### `$instr-dbug` {#instr-dbug} ```hoon +$ instr-dbug @@ -151,7 +153,7 @@ Type-annotated Wasm value. ??? -### `$instr-num` +### `$instr-num` {#instr-num} ```hoon +$ instr-num ?(instr-num-zero instr-num-one instr-num-two) @@ -159,7 +161,7 @@ Type-annotated Wasm value. ??? -### `$instr-num-zero` +### `$instr-num-zero` {#instr-num-zero} ```hoon +$ instr-num-zero @@ -168,9 +170,9 @@ Type-annotated Wasm value. == ``` -??? +Any [`$coin-wasm`](#coin-wasm) that represents a constant value. -### `$instr-num-one` +### `$instr-num-one` {#instr-num-one} ```hoon +$ instr-num-one @@ -211,7 +213,7 @@ Type-annotated Wasm value. ??? -### `$instr-num-two` +### `$instr-num-two` {#instr-num-two} ```hoon +$ instr-num-two @@ -242,7 +244,7 @@ Type-annotated Wasm value. ??? -### `$instr-short` +### `$instr-short` {#instr-short} ```hoon +$ instr-short @@ -317,7 +319,7 @@ Type-annotated Wasm value. ??? -### `$instr-vec` +### `$instr-vec` {#instr-vec} ```hoon +$ instr-vec @@ -393,15 +395,15 @@ Type-annotated Wasm value. ??? -### `$expression` +### `$expression` {#expression} ```hoon +$ expression (list instruction) ``` -List of `$instruction`s. +An ordered sequence of [`$instruction`](#instruction)s. -### `$const-instr` +### `$const-instr` {#const-instr} ```hoon +$ const-instr @@ -411,9 +413,9 @@ List of `$instruction`s. == ``` -??? +Constant instruction. ??? -### `$module` +### `$module` {#module} ```hoon +$ module @@ -433,9 +435,9 @@ List of `$instruction`s. == ``` -A Wasm module, represented in a format closer to its binary representation (i.e. separate code and function sections) to simplify parsing. +A Wasm module, represented in a format closer to its binary representation to simplify parsing. -### `$type-section` +### `$type-section` {#type-section} ```hoon +$ type-section @@ -443,9 +445,9 @@ A Wasm module, represented in a format closer to its binary representation (i.e. (list func-type) ``` -??? +List of function signatures in the module. -### `$import-section` +### `$import-section` {#import-section} ```hoon +$ import-section @@ -453,16 +455,29 @@ A Wasm module, represented in a format closer to its binary representation (i.e. (list import) ``` -??? +List of [`$import`s](#import) this module requires from other modules. -### `$import` +### `$import` {#import} ```hoon ++$ import + $: mod=cord + name=cord + $= desc + $% + [%func type-id=@] + [%tabl t=table] + [%memo l=limits] + [%glob v=valtype m=?(%con %var)] :: constant or variable + == == ``` -??? +Import from another Wasm module, including: +- `.mod`: Module name. +- `.name`: Name for the entity in the module we'd like to import. +- `.desc`: Importable definitions within the module, including functions, tables, global variables, etc. -### `$function-section` +### `$function-section` {#function-section} ```hoon +$ function-section @@ -470,41 +485,41 @@ A Wasm module, represented in a format closer to its binary representation (i.e. (list type-id=@) ``` -??? +List of functions in this module, referenced by index. -### `$table-section` +### `$table-section` {#table-section} ```hoon +$ table-section (list table) ``` -??? +List of [`$table`s](#table) in the module. -### `$table` +### `$table` {#table} ```hoon +$ table (pair ref-type limits) ``` -??? +Wasm table, referenced by its [`$ref-type`](#ref-type) and describing the [`$limits`](#limits) of its size. -### `$memory-section` +### `$memory-section` {#memory-section} ```hoon +$ memory-section (list limits) ``` -??? +List of the module's memory arrays, defined by the [`$limits`](#limits) of their size. -### `$global-section` +### `$global-section` {#global-section} ```hoon +$ global-section (list global) ``` -??? +List of the module's [`$global`](#global) variables. -### `$global` +### `$global` {#global} ```hoon +$ global @@ -514,12 +529,12 @@ A Wasm module, represented in a format closer to its binary representation (i.e. == ``` - :: valtype, mutability and init value. - :: We use a single constant instruction as opposed to a - :: (list instruction) since there is no global value type - :: that would take multiple constant values +Global variable, including: +- `.val`: [`$valtype`](#valtype), type of the variable's value. +- `.m`: Constant or variable. +- `.i`: Initial value. (Note that this is a constant instruction and not a `(list instruction)` as Wasm has no global value type that would take multiple constant values.) -### `$export-section` +### `$export-section` {#export-section} ```hoon +$ export-section @@ -527,17 +542,19 @@ A Wasm module, represented in a format closer to its binary representation (i.e. (list export) ``` -??? +List of [`$export`s](#export) in the module. -### `$export` +### `$export` {#export} ```hoon +$ export [name=cord =export-desc] ``` -??? +Element to be exportable for use in other modules: +- `.name`: Name of the export. +- `.export-desk`: [`$export-desc`](#export-desc), type-annotated value of the export. -### `$export-desc` +### `$export-desc` {#export-desc} ```hoon +$ export-desc @@ -548,25 +565,31 @@ A Wasm module, represented in a format closer to its binary representation (i.e. == ``` -??? +Type-annotated value of an export addressed by its index: +- `%func`: Function. +- `%tabl`: Table. +- `%memo`: Memory. +- `%glob`: Global variable. + +In practice these indexes will always be 32-bit integers (`@F`s). -### `$start-section` +### `$start-section` {#start-section} ```hoon +$ start-section (unit @) ``` -??? +The initialization (or "start") function for the module, if one exists. -### `$elem-section` +### `$elem-section` {#elem-section} ```hoon +$ elem-section (list elem) ``` -??? +List of [`$elem`s](#elem). -### `$elem` +### `$elem` {#elem} ```hoon +$ elem @@ -580,9 +603,17 @@ A Wasm module, represented in a format closer to its binary representation (i.e. == == ``` -??? +Wasm element segment: +- `.t`: Reference type. (Currently Wasm only supports function references (`%func` [`$ref-type`s](#ref-type)).) +- `.i`: Sequence of [`$instruction`s](#instruction) to produce function references. +- `.m`: Element segment mode: + - `%pass`: Passive, elements copied manually via table initialization. + - `%decl`: Declarative, declares references which aren't copied to tables. + - `%acti`: Active, automatically copies element data to the table `.tab` at offset `.off` when the module is instantiated. -### `$code-section` +Element segments store static data with which to populate [`$table`s](#table) when the module is initialized. + +### `$code-section` {#code-section} ```hoon +$ code-section @@ -592,7 +623,7 @@ A Wasm module, represented in a format closer to its binary representation (i.e. ??? -### `$code` +### `$code` {#code} ```hoon +$ code @@ -603,15 +634,15 @@ A Wasm module, represented in a format closer to its binary representation (i.e. ??? -### `$data-section` +### `$data-section` {#data-section} ```hoon +$ data-section (list data) ``` -??? +List of the module's [`$data`](#data) segments. -### `$data` +### `$data` {#data} ```hoon +$ data @@ -621,9 +652,11 @@ A Wasm module, represented in a format closer to its binary representation (i.e. == ``` -??? +Data segment for initializing the module's state. +- `%acti`: Active segments automatically copy `$octs` `.b` to the module's memory at offset `.off` during instantiation. +- `%pass`: Passive segments are copied manually when instructed. -### `+datacnt-section` +### `+datacnt-section` {#datacnt-section} ```hoon ++ datacnt-section (unit @) @@ -631,7 +664,7 @@ A Wasm module, represented in a format closer to its binary representation (i.e. ??? -### `$opcode` +### `$opcode` {#opcode} ```hoon +$ opcode $? bin-opcodes-zero-args @@ -644,7 +677,7 @@ A Wasm module, represented in a format closer to its binary representation (i.e. ??? -### `$bin-opcodes-zero-args` +### `$bin-opcodes-zero-args` {#bin-opcodes-zero-args} ```hoon +$ bin-opcodes-zero-args @@ -674,7 +707,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc - `%0xb6`: Convert an `f64` / `@rd` to `f32` / `@rs`. - `%0xbb`: Convert an `f32` / `@rs` to `f64` / `@rd`. -### `$pseudo-opcode` +### `$pseudo-opcode` {#pseudo-opcode} ```hoon +$ pseudo-opcode ?(%0x5 %0xb) :: else, end @@ -682,7 +715,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$bin-opcodes-one-arg` +### `$bin-opcodes-one-arg` {#bin-opcodes-one-arg} ```hoon +$ bin-opcodes-one-arg @@ -698,7 +731,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$bin-opcodes-two-args` +### `$bin-opcodes-two-args` {#bin-opcodes-two-args} ```hoon +$ bin-opcodes-two-args @@ -712,7 +745,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$bin-opcodes-blocks` +### `$bin-opcodes-blocks` {#bin-opcodes-blocks} ```hoon +$ bin-opcodes-blocks @@ -725,7 +758,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$const-opcodes` +### `$const-opcodes` {#const-opcodes} ```hoon +$ const-opcodes @@ -739,7 +772,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$load-opcodes` +### `$load-opcodes` {#load-opcodes} ```hoon +$ load-opcodes @@ -763,7 +796,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$store-opcodes` +### `$store-opcodes` {#store-opcodes} ```hoon +$ store-opcodes @@ -782,7 +815,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$eqz-opcodes` +### `$eqz-opcodes` {#eqz-opcodes} ```hoon +$ eqz-opcodes ?(%0x45 %0x50) :: i32, i64 @@ -790,7 +823,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$eq-opcodes` +### `$eq-opcodes` {#eq-opcodes} ```hoon +$ eq-opcodes ?(%0x46 %0x51 %0x5b %0x61) :: i32, i64, f32, f64 @@ -798,7 +831,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$ne-opcodes` +### `$ne-opcodes` {#ne-opcodes} ```hoon +$ ne-opcodes ?(%0x47 %0x52 %0x5c %0x62) :: i32, i64, f32, f64 @@ -806,7 +839,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$lt-opcodes` +### `$lt-opcodes` {#lt-opcodes} ```hoon +$ lt-opcodes @@ -822,7 +855,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$gt-opcodes` +### `$gt-opcodes` {#gt-opcodes} ```hoon +$ gt-opcodes @@ -838,7 +871,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$le-opcodes` +### `$le-opcodes` {#le-opcodes} ```hoon +$ le-opcodes @@ -854,7 +887,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$ge-opcodes` +### `$ge-opcodes` {#ge-opcodes} ```hoon +$ ge-opcodes @@ -870,7 +903,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$clz-opcodes` +### `$clz-opcodes` {#clz-opcodes} ```hoon +$ clz-opcodes ?(%0x67 %0x79) :: i32, i64 @@ -878,7 +911,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$ctz-opcodes` +### `$ctz-opcodes` {#ctz-opcodes} ```hoon +$ ctz-opcodes ?(%0x68 %0x7a) :: i32, i64 @@ -886,7 +919,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$popcnt-opcodes` +### `$popcnt-opcodes` {#popcnt-opcodes} ```hoon +$ popcnt-opcodes ?(%0x69 %0x7b) :: i32, i64 @@ -894,7 +927,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$add-opcodes` +### `$add-opcodes` {#add-opcodes} ```hoon +$ add-opcodes ?(%0x6a %0x7c %0x92 %0xa0) :: i32, i64, f32, f64 @@ -902,7 +935,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$sub-opcodes` +### `$sub-opcodes` {#sub-opcodes} ```hoon +$ sub-opcodes ?(%0x6b %0x7d %0x93 %0xa1) :: i32, i64, f32, f64 @@ -910,7 +943,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$mul-opcodes` +### `$mul-opcodes` {#mul-opcodes} ```hoon +$ mul-opcodes ?(%0x6c %0x7e %0x94 %0xa2) :: i32, i64, f32, f64 @@ -918,7 +951,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$div-opcodes` +### `$div-opcodes` {#div-opcodes} ```hoon +$ div-opcodes @@ -934,7 +967,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$rem-opcodes` +### `$rem-opcodes` {#rem-opcodes} ```hoon +$ rem-opcodes @@ -948,7 +981,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$and-opcodes` +### `$and-opcodes` {#and-opcodes} ```hoon +$ and-opcodes ?(%0x71 %0x83) :: i32, i64 @@ -956,7 +989,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$or-opcodes` +### `$or-opcodes` {#or-opcodes} ```hoon +$ or-opcodes ?(%0x72 %0x84) :: i32, i64 @@ -964,7 +997,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$xor-opcodes` +### `$xor-opcodes` {#xor-opcodes} ```hoon +$ xor-opcodes ?(%0x73 %0x85) :: i32, i64 @@ -972,7 +1005,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$shl-opcodes` +### `$shl-opcodes` {#shl-opcodes} ```hoon +$ shl-opcodes ?(%0x74 %0x86) :: i32, i64 @@ -980,7 +1013,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$shr-opcodes` +### `$shr-opcodes` {#shr-opcodes} ```hoon +$ shr-opcodes @@ -994,7 +1027,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$rotl-opcodes` +### `$rotl-opcodes` {#rotl-opcodes} ```hoon +$ rotl-opcodes ?(%0x77 %0x89) :: i32, i64 @@ -1002,7 +1035,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$rotr-opcodes` +### `$rotr-opcodes` {#rotr-opcodes} ```hoon +$ rotr-opcodes ?(%0x78 %0x8a) :: i32, i64 @@ -1010,7 +1043,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$abs-opcodes` +### `$abs-opcodes` {#abs-opcodes} ```hoon +$ abs-opcodes ?(%0x8b %0x99) :: f32, f64 @@ -1018,7 +1051,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$neg-opcodes` +### `$neg-opcodes` {#neg-opcodes} ```hoon +$ neg-opcodes ?(%0x8c %0x9a) :: f32, f64 @@ -1026,7 +1059,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$ceil-opcodes` +### `$ceil-opcodes` {#ceil-opcodes} ```hoon +$ ceil-opcodes ?(%0x8d %0x9b) :: f32, f64 @@ -1034,7 +1067,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$floor-opcodes` +### `$floor-opcodes` {#floor-opcodes} ```hoon +$ floor-opcodes ?(%0x8e %0x9c) :: f32, f64 @@ -1042,7 +1075,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$trunc-opcodes` +### `$trunc-opcodes` {#trunc-opcodes} ```hoon +$ trunc-opcodes @@ -1062,7 +1095,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$nearest-opcodes` +### `$nearest-opcodes` {#nearest-opcodes} ```hoon +$ nearest-opcodes ?(%0x90 %0x9e) :: f32, f64 @@ -1070,7 +1103,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$sqrt-opcodes` +### `$sqrt-opcodes` {#sqrt-opcodes} ```hoon +$ sqrt-opcodes ?(%0x91 %0x9f) :: f32, f64 @@ -1078,7 +1111,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$min-opcodes` +### `$min-opcodes` {#min-opcodes} ```hoon +$ min-opcodes ?(%0x96 %0xa4) :: f32, f64 @@ -1086,7 +1119,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$max-opcodes` +### `$max-opcodes` {#max-opcodes} ```hoon +$ max-opcodes ?(%0x97 %0xa5) :: f32, f64 @@ -1094,7 +1127,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$copysign-opcodes` +### `$copysign-opcodes` {#copysign-opcodes} ```hoon +$ copysign-opcodes ?(%0x98 %0xa6) :: f32, f64 @@ -1102,7 +1135,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$extend-opcodes` +### `$extend-opcodes` {#extend-opcodes} ```hoon +$ extend-opcodes @@ -1119,7 +1152,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$convert-opcodes` +### `$convert-opcodes` {#convert-opcodes} ```hoon +$ convert-opcodes @@ -1137,7 +1170,7 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc ??? -### `$reinterpret-opcodes` +### `$reinterpret-opcodes` {#reinterpret-opcodes} ```hoon +$ reinterpret-opcodes From 5c87a41e11a0f5c6afda725e036b92db3df6a28f Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Tue, 12 Aug 2025 15:02:51 +0100 Subject: [PATCH 19/27] Code wasm docs --- .../wasm-walkthrough/reference/wasm-data-types.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index f6d0fc46..cead409a 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -621,7 +621,7 @@ Element segments store static data with which to populate [`$table`s](#table) wh (list code) ``` -??? +List of [`$code`](#code) entries. ### `$code` {#code} @@ -632,7 +632,9 @@ Element segments store static data with which to populate [`$table`s](#table) wh == ``` -??? +Function implementation stored in binary format: +- `.locals`: List of local variables in this function. +- `.expression`: The function body as a sequence of instructions. (See [`$expression`](#expression).) ### `$data-section` {#data-section} From 0bc20c7eb39ccf8a6ab154135f06988bcd807d94 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Tue, 12 Aug 2025 15:06:39 +0100 Subject: [PATCH 20/27] Note on separate sections --- .../wasm-walkthrough/reference/wasm-data-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index cead409a..404a6a89 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -435,7 +435,7 @@ Constant instruction. ??? == ``` -A Wasm module, represented in a format closer to its binary representation to simplify parsing. +A Wasm module. Note code and function sections have been separated here to simplify parsing. ### `$type-section` {#type-section} From b60ee4fa94cf8357ff4a85c3989bc9ad3542b443 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Tue, 12 Aug 2025 16:28:50 +0100 Subject: [PATCH 21/27] Draft instruction docs --- .../reference/wasm-data-types.md | 158 +++++++++++++++++- 1 file changed, 150 insertions(+), 8 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index 404a6a89..47a8585f 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -140,7 +140,13 @@ Type annotation for lanes (memory elements) in a 128-bit (`@H`) register. Includ $%([%vec instr-vec] instr-short instr-num instr-dbug) ``` -??? +Type union of all Wasm instructions. + +Instructions are categorized here by their operand patterns: +- `%vec`: Vector instructions. (See [`$instr-vec`]($instr-vec).) +- [`$instr-short`](#instr-short): ??? +- [`$instr-num`](#instr-num): Standard Wasm instructions categorized by arity. +- [`$instr-dbug`](#instr-dbug): Debugging. ### `$instr-dbug` {#instr-dbug} @@ -151,7 +157,7 @@ Type annotation for lanes (memory elements) in a 128-bit (`@H`) register. Includ == ``` -??? +Debugging instructions. The only one supported here is `%print-tee`, which prints a value {TODO ???} with the given `$term` as a label. ### `$instr-num` {#instr-num} @@ -159,7 +165,7 @@ Type annotation for lanes (memory elements) in a 128-bit (`@H`) register. Includ +$ instr-num ?(instr-num-zero instr-num-one instr-num-two) ``` -??? +Type union of all standard Wasm instructions, categorized here by arity. ### `$instr-num-zero` {#instr-num-zero} @@ -170,7 +176,15 @@ Type annotation for lanes (memory elements) in a 128-bit (`@H`) register. Includ == ``` -Any [`$coin-wasm`](#coin-wasm) that represents a constant value. +Wasm `const` instruction, whose value is any [`$coin-wasm`](#coin-wasm) that may represent a constant value. So... + +```hoon +$? [%i32 @F] + [%i64 @G] + [%f32 @rs] + [%f64 @rd] +== +``` ### `$instr-num-one` {#instr-num-one} @@ -211,7 +225,24 @@ Any [`$coin-wasm`](#coin-wasm) that represents a constant value. == ``` -??? +Standard Wasm instructions with one parameter each: +- `eqz`: Check if equals zero. +- `clz`: Count leading zeroes. +- `ctz`: Count trailing zeroes. +- `popcnt`: Population count (number of set bits). +- `abs`: Absolute value. +- `neg`: Negate. +- `ceil`: Round a float up to nearest integer. +- `floor`: Round a float down to nearest integer. +- `nearest`: Round a float to nearest integer. +- `sqrt`: Square root. +- `trunc`: Truncate float to integer (with optional saturation). +- `wrap`: Wrap larger integer to smaller type. +- `extend`: Extend smaller integer to larger type. +- `convert`: Convert between integer and float. +- `demote`: Convert `f64` (`@rd`) to `f32` `(@rs`). +- `promote`: Convert `f32` (`@rs`) to `f64` (`@rd`). +- `reinterpret`: Reinterpret bit pattern as different type. ### `$instr-num-two` {#instr-num-two} @@ -242,7 +273,28 @@ Any [`$coin-wasm`](#coin-wasm) that represents a constant value. == ``` -??? +Wasm's binary numeric instructions: +- `eq`: Test equality. +- `ne`: Test inequality. +- `lt`: Less than. +- `gt`: Greater than. +- `le`: Less than or equal. +- `ge`: Greater than or equal. +- `add`: Addition. +- `sub`: Subtraction. +- `mul`: Multiplication. +- `div`: Division. +- `rem`: Remainder. +- `and`: Bitwise AND. +- `or`: Bitwise OR. +- `xor`: Bitwise XOR. +- `shl`: Shift left. +- `shr`: Shift right (logical or arithmetic). +- `rotl`: Rotate left. +- `rotr`: Rotate right. +- `min`: Minimum value. +- `max`: Maximum value. +- `copysign`: Copy sign bit from second operand to first. ### `$instr-short` {#instr-short} @@ -317,7 +369,44 @@ Any [`$coin-wasm`](#coin-wasm) that represents a constant value. == :: $instr-short ``` -??? +Non-numeric Wasm instructions: +- `unreachable`: Trap execution unconditionally. +- `nop`: No operation. +- `block`: Start a block with optional result type. +- `loop`: Start a loop with optional result type. +- `if`: Conditional execution with true/false branches. +- `br`: Unconditional branch to label. +- `br-if`: Conditional branch to label. +- `br-table`: Multi-way branch (switch statement). +- `return`: Return from current function. +- `call`: Call function by index. +- `call-indirect`: Call function indirectly through table. +- `ref-null`: Create null reference. +- `ref-is-null`: Test if reference is null. +- `ref-func`: Get function reference. +- `drop`: Remove top stack value. +- `select`: Choose between two values based on condition. +- `local-get`: Get local variable value. +- `local-set`: Set local variable value. +- `local-tee`: Set local variable and return the value. +- `global-get`: Get global variable value. +- `global-set`: Set global variable value. +- `table-get`: Get element from table. +- `table-set`: Set element in table. +- `table-init`: Initialize table from element segment. +- `table-copy`: Copy elements between tables. +- `table-grow`: Grow table size. +- `table-size`: Get table size. +- `table-fill`: Fill table range with value. +- `elem-drop`: Drop element segment. +- `load`: Load value from memory. +- `store`: Store value to memory. +- `memory-size`: Get memory size in pages. +- `memory-grow`: Grow memory size. +- `memory-init`: Initialize memory from data segment. +- `data-drop`: Drop data segment. +- `memory-copy`: Copy memory regions. +- `memory-fill`: Fill memory range with byte value. ### `$instr-vec` {#instr-vec} @@ -393,7 +482,60 @@ Any [`$coin-wasm`](#coin-wasm) that represents a constant value. == :: $instr-vec ``` -??? +Wasm SIMD vector instructions for 128-bit vectors: +- `load`: Load vector from memory (with optional splat/zero-extend/sign-extend). +- `load-lane`: Load single value into specific lane. +- `store`: Store vector to memory. +- `store-lane`: Store single lane to memory. +- `const`: Vector constant. +- `shuffle`: Rearrange lanes by index list. +- `extract`: Get value from specific lane. +- `replace`: Set value in specific lane. +- `swizzle`: Rearrange lanes using second vector as indices. +- `splat`: Broadcast scalar to all lanes. +- `eq`: Lane-wise equality comparison. +- `ne`: Lane-wise inequality comparison. +- `lt`: Lane-wise less than comparison. +- `gt`: Lane-wise greater than comparison. +- `le`: Lane-wise less than or equal comparison. +- `ge`: Lane-wise greater than or equal comparison. +- `not`: Bitwise NOT on entire vector. +- `and`: Bitwise AND on entire vector. +- `andnot`: Bitwise AND-NOT on entire vector. +- `or`: Bitwise OR on entire vector. +- `xor`: Bitwise XOR on entire vector. +- `bitselect`: Select bits based on mask. +- `any-true`: Test if any lanes are true. +- `all-true`: Test if all lanes are true. +- `bitmask`: Extract high bit from each lane. +- `abs`: Lane-wise absolute value. +- `neg`: Lane-wise negation. +- `popcnt`: Population count on each lane. +- `narrow`: Pack two vectors into one with narrower lanes. +- `shl`: Lane-wise left bit shift. +- `shr`: Lane-wise right bit shift. +- `add`: Lane-wise addition (with optional saturation). +- `sub`: Lane-wise subtraction (with optional saturation). +- `min`: Lane-wise minimum. +- `max`: Lane-wise maximum. +- `avgr`: Averaging with rounding. +- `mul`: Lane-wise multiplication. +- `extend`: Extend lane width. +- `extmul`: Extended multiplication. +- `extadd`: Extended addition. +- `q15mul-r-sat`: Q15 fixed-point multiplication. +- `dot`: Dot product. +- `ceil`: Lane-wise ceiling (round up). +- `floor`: Lane-wise floor (round down). +- `nearest`: Lane-wise round to nearest. +- `sqrt`: Lane-wise square root. +- `div`: Lane-wise division. +- `trunc`: Lane-wise truncate to integer. +- `convert`: Lane-wise type conversion. +- `demote`: Lane-wise f64 to f32 conversion. +- `promote`: Lane-wise f32 to f64 conversion. +- `pmin`: Propagating minimum (NaN handling). +- `pmax`: Propagating maximum (NaN handling). ### `$expression` {#expression} From 15db8bdfbd6b010cac578a731bb3b63499c71d1f Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Wed, 13 Aug 2025 14:12:35 +0100 Subject: [PATCH 22/27] Draft binary opcodes docs --- .claude/settings.local.json | 11 + .../reference/wasm-data-types.md | 294 ++++++++++++++---- 2 files changed, 246 insertions(+), 59 deletions(-) create mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 00000000..009b64a9 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,11 @@ +{ + "permissions": { + "allow": [ + "WebSearch", + "WebFetch(domain:webassembly.github.io)", + "WebFetch(domain:pengowray.github.io)" + ], + "deny": [], + "ask": [] + } +} \ No newline at end of file diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index 47a8585f..982a67c6 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -112,7 +112,7 @@ Defines the minimum and maximum size of a memory instance. The `.align` and `.of +$ block-type $@(@ func-type) :: typeidx in type section or func-type ``` -??? +Block type for {structured control instructions ???}. Can be a type index in the [`$type-section`](#type-section) or a [`$func-type`](#func-type) function signature. ### `$func-type` {#func-type} @@ -369,7 +369,7 @@ Wasm's binary numeric instructions: == :: $instr-short ``` -Non-numeric Wasm instructions: +???: - `unreachable`: Trap execution unconditionally. - `nop`: No operation. - `block`: Start a block with optional result type. @@ -532,8 +532,8 @@ Wasm SIMD vector instructions for 128-bit vectors: - `div`: Lane-wise division. - `trunc`: Lane-wise truncate to integer. - `convert`: Lane-wise type conversion. -- `demote`: Lane-wise f64 to f32 conversion. -- `promote`: Lane-wise f32 to f64 conversion. +- `demote`: Lane-wise `f64` to `f32` conversion. +- `promote`: Lane-wise `f32` to `f64` conversion. - `pmin`: Propagating minimum (NaN handling). - `pmax`: Propagating maximum (NaN handling). @@ -555,7 +555,7 @@ An ordered sequence of [`$instruction`](#instruction)s. == ``` -Constant instruction. ??? +{??? - some kind of const but not sure how relates to `$instr-num-zero`} ### `$module` {#module} @@ -577,7 +577,7 @@ Constant instruction. ??? == ``` -A Wasm module. Note code and function sections have been separated here to simplify parsing. +A Wasm module. Note code and function sections are separated here to simplify parsing. ### `$type-section` {#type-section} @@ -806,7 +806,9 @@ Data segment for initializing the module's state. ++ datacnt-section (unit @) ``` -??? +{TODO check the below} + +Data count section of the Wasm module, which may optionally contain the number of data segments ([`$data`](#data)) in the module. This allows validators to check the index validity of the data section before trying to access it. ### `$opcode` {#opcode} @@ -819,7 +821,7 @@ Data segment for initializing the module's state. == ``` -??? +Type union of all Wasm's binary instruction opcodes. ### `$bin-opcodes-zero-args` {#bin-opcodes-zero-args} @@ -839,17 +841,19 @@ Data segment for initializing the module's state. == ``` -WebAssembly opcodes. Most of these are defined in the types below, with some exceptions defined here: -- `%0x0`: ??? error? -- `%0x01`: `nop`, no-op, do nothing. -- `%0x0f`: `return` the result of a function, with two wrinkles: +Wasm binary instruction opcodes that take no immediate arguments. + +A few simple opcodes are defined here: +- `%0x0`: `unreachable` - causes an unconditional trap when executed. +- `%0x1`: `nop` - no-op, do nothing. +- `%0xf`: `return` - return from current function with values from stack. - If there's nothing in the stack to return, this returns nothing. - If there are more values on the stack than allowed by the function's return type, the first $$n$$ values are returned (where $$n$$ is the number of values allowed) and the rest are discarded. -- `%0x1a`: `drop` a value from the stack. -- `%0x1b`: Like a ternary operator, `select` one of the first two operands based on whether the third is `0` or not. -- `%0xa7`: Convert an `i64` / `@G` to an `i32` / `@F` if possible. (If not, the operation "`wrap`s" and returns a different number entirely.) -- `%0xb6`: Convert an `f64` / `@rd` to `f32` / `@rs`. -- `%0xbb`: Convert an `f32` / `@rs` to `f64` / `@rd`. +- `%0x1a`: `drop` - remove top value from stack. +- `%0x1b`: `select` - choose between two values based on condition. +- `%0xa7`: `i64.wrap_i32` - convert `i64` to `i32` by wrapping (truncating high bits). +- `%0xb6`: `f32.demote_f64` - convert `f64` to `f32`. +- `%0xbb`: `f64.promote_f32` - convert `f32` to `f64`. ### `$pseudo-opcode` {#pseudo-opcode} @@ -857,7 +861,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ pseudo-opcode ?(%0x5 %0xb) :: else, end ``` -??? +Pseudo-opcodes for control flow constructs: +- `%0x5`: `else` - marks the else branch of an if block. +- `%0xb`: `end` - terminates blocks, loops, if-statements, and functions. ### `$bin-opcodes-one-arg` {#bin-opcodes-one-arg} @@ -873,7 +879,18 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Instructions taking one immediate argument: +- `%0xc`: `br` - unconditional branch to label. +- `%0xd`: `br_if` - conditional branch to label. +- `%0x10`: `call` - invoke function by index. +- `%0x20`: `local.get` - read local variable. +- `%0x21`: `local.set` - write local variable. +- `%0x22`: `local.tee` - write local variable and return value. +- `%0x23`: `global.get` - read global variable. +- `%0x24`: `global.set` - write global variable. +- `%0x3f`: `memory.size` - query memory size. +- `%0x40`: `memory.grow` - grow memory by given delta. +- [`$const-opcodes`](#const-opcodes): constants for `i32`, `i64`, `f32`, `f64`. ### `$bin-opcodes-two-args` {#bin-opcodes-two-args} @@ -887,7 +904,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Instructions taking two immediate arguments: +- `%0xe`: `br_table` - branch table for switch-like control flow. +- `%0x11`: `call_indirect` - invoke function indirectly through table. +- [`$load-opcodes`](#load-opcodes): memory load operations with alignment and offset. +- [`$store-opcodes`](#store-opcodes): memory store operations with alignment and offset. ### `$bin-opcodes-blocks` {#bin-opcodes-blocks} @@ -900,7 +921,10 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Structured control flow instructions that create blocks with labels: +- `%0x2`: `block` - creates a block construct that can be targeted by branch instructions. +- `%0x3`: `loop` - creates a loop construct where branches target the beginning of the block. +- `%0x4`: `if` - creates a conditional block that executes based on a condition value. ### `$const-opcodes` {#const-opcodes} @@ -914,7 +938,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Constant value instructions that push literal values onto the stack: +- `%0x41`: `i32.const` - push 32-bit integer constant. +- `%0x42`: `i64.const` - push 64-bit integer constant. +- `%0x43`: `f32.const` - push 32-bit float constant. +- `%0x44`: `f64.const` - push 64-bit float constant. ### `$load-opcodes` {#load-opcodes} @@ -938,7 +966,21 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Memory load instructions that read values from linear memory: +- `%0x28`: `i32.load` - load 32-bit integer. +- `%0x29`: `i64.load` - load 64-bit integer. +- `%0x2a`: `f32.load` - load 32-bit float. +- `%0x2b`: `f64.load` - load 64-bit float. +- `%0x2c`: `i32.load8_s` - load 8-bit signed, extend to `i32`. +- `%0x2d`: `i32.load8_u` - load 8-bit unsigned, extend to `i32`. +- `%0x2e`: `i32.load16_s` - load 16-bit signed, extend to `i32`. +- `%0x2f`: `i32.load16_u` - load 16-bit unsigned, extend to `i32`. +- `%0x30`: `i64.load8_s` - load 8-bit signed, extend to `i64`. +- `%0x31`: `i64.load8_u` - load 8-bit unsigned, extend to `i64`. +- `%0x32`: `i64.load16_s` - load 16-bit signed, extend to `i64`. +- `%0x33`: `i64.load16_u` - load 16-bit unsigned, extend to `i64`. +- `%0x34`: `i64.load32_s` - load 32-bit signed, extend to `i64`. +- `%0x35`: `i64.load32_u` - load 32-bit unsigned, extend to `i64`. ### `$store-opcodes` {#store-opcodes} @@ -957,7 +999,16 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Memory store instructions that write values to linear memory: +- `%0x36`: `i32.store` - store 32-bit integer. +- `%0x37`: `i64.store` - store 64-bit integer. +- `%0x38`: `f32.store` - store 32-bit float. +- `%0x39`: `f64.store` - store 64-bit float. +- `%0x3a`: `i32.store8` - store lower 8 bits of `i32`. +- `%0x3b`: `i32.store16` - store lower 16 bits of `i32`. +- `%0x3c`: `i64.store8` - store lower 8 bits of `i64`. +- `%0x3d`: `i64.store16` - store lower 16 bits of `i64`. +- `%0x3e`: `i64.store32` - store lower 32 bits of `i64`. ### `$eqz-opcodes` {#eqz-opcodes} @@ -965,7 +1016,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ eqz-opcodes ?(%0x45 %0x50) :: i32, i64 ``` -??? +Test if value equals zero: +- `%0x45`: `i32.eqz` - test if `i32` equals zero. +- `%0x50`: `i64.eqz` - test if `i64` equals zero. ### `$eq-opcodes` {#eq-opcodes} @@ -973,7 +1026,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ eq-opcodes ?(%0x46 %0x51 %0x5b %0x61) :: i32, i64, f32, f64 ``` -??? +Test if two values are equal: +- `%0x46`: `i32.eq` - `i32` equality comparison. +- `%0x51`: `i64.eq` - `i64` equality comparison. +- `%0x5b`: `f32.eq` - `f32` equality comparison. +- `%0x61`: `f64.eq` - `f64` equality comparison. ### `$ne-opcodes` {#ne-opcodes} @@ -981,7 +1038,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ ne-opcodes ?(%0x47 %0x52 %0x5c %0x62) :: i32, i64, f32, f64 ``` -??? +Test if two values are not equal: +- `%0x47`: `i32.ne` - `i32` inequality comparison. +- `%0x52`: `i64.ne` - `i64` inequality comparison. +- `%0x5c`: `f32.ne` - `f32` inequality comparison. +- `%0x62`: `f64.ne` - `f64` inequality comparison. ### `$lt-opcodes` {#lt-opcodes} @@ -997,7 +1058,13 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Test if first value is less than second: +- `%0x48`: `i32.lt_s` - `i32` signed less-than. +- `%0x49`: `i32.lt_u` - `i32` unsigned less-than. +- `%0x53`: `i64.lt_s` - `i64` signed less-than. +- `%0x54`: `i64.lt_u` - `i64` unsigned less-than. +- `%0x5d`: `f32.lt` - `f32` less-than. +- `%0x63`: `f64.lt` - `f64` less-than. ### `$gt-opcodes` {#gt-opcodes} @@ -1013,7 +1080,13 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Test if first value is greater than second: +- `%0x4a`: `i32.gt_s` - `i32` signed greater-than. +- `%0x4b`: `i32.gt_u` - `i32` unsigned greater-than. +- `%0x55`: `i64.gt_s` - `i64` signed greater-than. +- `%0x56`: `i64.gt_u` - `i64` unsigned greater-than. +- `%0x5e`: `f32.gt` - `f32` greater-than. +- `%0x64`: `f64.gt` - `f64` greater-than. ### `$le-opcodes` {#le-opcodes} @@ -1029,7 +1102,13 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Test if first value is less than or equal to second: +- `%0x4c`: `i32.le_s` - `i32` signed less-than-or-equal. +- `%0x4d`: `i32.le_u` - `i32` unsigned less-than-or-equal. +- `%0x57`: `i64.le_s` - `i64` signed less-than-or-equal. +- `%0x58`: `i64.le_u` - `i64` unsigned less-than-or-equal. +- `%0x5f`: `f32.le` - `f32` less-than-or-equal. +- `%0x65`: `f64.le` - `f64` less-than-or-equal. ### `$ge-opcodes` {#ge-opcodes} @@ -1045,7 +1124,13 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Test if first value is greater than or equal to second: +- `%0x4e`: `i32.ge_s` - `i32` signed greater-than-or-equal. +- `%0x4f`: `i32.ge_u` - `i32` unsigned greater-than-or-equal. +- `%0x59`: `i64.ge_s` - `i64` signed greater-than-or-equal. +- `%0x5a`: `i64.ge_u` - `i64` unsigned greater-than-or-equal. +- `%0x60`: `f32.ge` - `f32` greater-than-or-equal. +- `%0x66`: `f64.ge` - `f64` greater-than-or-equal. ### `$clz-opcodes` {#clz-opcodes} @@ -1053,7 +1138,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ clz-opcodes ?(%0x67 %0x79) :: i32, i64 ``` -??? +Count leading zeros: +- `%0x67`: `i32.clz` - count leading zeros in `i32`. +- `%0x79`: `i64.clz` - count leading zeros in `i64`. ### `$ctz-opcodes` {#ctz-opcodes} @@ -1061,7 +1148,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ ctz-opcodes ?(%0x68 %0x7a) :: i32, i64 ``` -??? +Count trailing zeros: +- `%0x68`: `i32.ctz` - count trailing zeros in `i32`. +- `%0x7a`: `i64.ctz` - count trailing zeros in `i64`. ### `$popcnt-opcodes` {#popcnt-opcodes} @@ -1069,7 +1158,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ popcnt-opcodes ?(%0x69 %0x7b) :: i32, i64 ``` -??? +Count number of set bits (population count): +- `%0x69`: `i32.popcnt` - count set bits in `i32`. +- `%0x7b`: `i64.popcnt` - count set bits in `i64`. ### `$add-opcodes` {#add-opcodes} @@ -1077,7 +1168,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ add-opcodes ?(%0x6a %0x7c %0x92 %0xa0) :: i32, i64, f32, f64 ``` -??? +Addition operations: +- `%0x6a`: `i32.add` - `i32` addition. +- `%0x7c`: `i64.add` - `i64` addition. +- `%0x92`: `f32.add` - `f32` addition. +- `%0xa0`: `f64.add` - `f64` addition. ### `$sub-opcodes` {#sub-opcodes} @@ -1085,7 +1180,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ sub-opcodes ?(%0x6b %0x7d %0x93 %0xa1) :: i32, i64, f32, f64 ``` -??? +Subtraction operations: +- `%0x6b`: `i32.sub` - `i32` subtraction. +- `%0x7d`: `i64.sub` - `i64` subtraction. +- `%0x93`: `f32.sub` - `f32` subtraction. +- `%0xa1`: `f64.sub` - `f64` subtraction. ### `$mul-opcodes` {#mul-opcodes} @@ -1093,7 +1192,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ mul-opcodes ?(%0x6c %0x7e %0x94 %0xa2) :: i32, i64, f32, f64 ``` -??? +Multiplication operations: +- `%0x6c`: `i32.mul` - `i32` multiplication. +- `%0x7e`: `i64.mul` - `i64` multiplication. +- `%0x94`: `f32.mul` - `f32` multiplication. +- `%0xa2`: `f64.mul` - `f64` multiplication. ### `$div-opcodes` {#div-opcodes} @@ -1109,7 +1212,13 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Division operations: +- `%0x6d`: `i32.div_s` - `i32` signed division. +- `%0x6e`: `i32.div_u` - `i32` unsigned division. +- `%0x7f`: `i64.div_s` - `i64` signed division. +- `%0x80`: `i64.div_u` - `i64` unsigned division. +- `%0x95`: `f32.div` - `f32` division. +- `%0xa3`: `f64.div` - `f64` division. ### `$rem-opcodes` {#rem-opcodes} @@ -1123,7 +1232,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Remainder operations: +- `%0x6f`: `i32.rem_s` - `i32` signed remainder. +- `%0x70`: `i32.rem_u` - `i32` unsigned remainder. +- `%0x81`: `i64.rem_s` - `i64` signed remainder. +- `%0x82`: `i64.rem_u` - `i64` unsigned remainder. ### `$and-opcodes` {#and-opcodes} @@ -1131,7 +1244,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ and-opcodes ?(%0x71 %0x83) :: i32, i64 ``` -??? +Bitwise AND operations: +- `%0x71`: `i32.and` - `i32` bitwise AND. +- `%0x83`: `i64.and` - `i64` bitwise AND. ### `$or-opcodes` {#or-opcodes} @@ -1139,7 +1254,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ or-opcodes ?(%0x72 %0x84) :: i32, i64 ``` -??? +Bitwise OR operations: +- `%0x72`: `i32.or` - `i32` bitwise OR. +- `%0x84`: `i64.or` - `i64` bitwise OR. ### `$xor-opcodes` {#xor-opcodes} @@ -1147,7 +1264,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ xor-opcodes ?(%0x73 %0x85) :: i32, i64 ``` -??? +Bitwise XOR operations: +- `%0x73`: `i32.xor` - `i32` bitwise exclusive OR. +- `%0x85`: `i64.xor` - `i64` bitwise exclusive OR. ### `$shl-opcodes` {#shl-opcodes} @@ -1155,7 +1274,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ shl-opcodes ?(%0x74 %0x86) :: i32, i64 ``` -??? +Bitwise left shift operations: +- `%0x74`: `i32.shl` - `i32` shift left. +- `%0x86`: `i64.shl` - `i64` shift left. ### `$shr-opcodes` {#shr-opcodes} @@ -1169,7 +1290,11 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Bitwise right shift operations: +- `%0x75`: `i32.shr_s` - `i32` arithmetic right shift (sign-extending). +- `%0x76`: `i32.shr_u` - `i32` logical right shift (zero-filling). +- `%0x87`: `i64.shr_s` - `i64` arithmetic right shift (sign-extending). +- `%0x88`: `i64.shr_u` - `i64` logical right shift (zero-filling). ### `$rotl-opcodes` {#rotl-opcodes} @@ -1177,7 +1302,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ rotl-opcodes ?(%0x77 %0x89) :: i32, i64 ``` -??? +Rotate left operations: +- `%0x77`: `i32.rotl` - `i32` rotate left. +- `%0x89`: `i64.rotl` - `i64` rotate left. ### `$rotr-opcodes` {#rotr-opcodes} @@ -1185,7 +1312,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ rotr-opcodes ?(%0x78 %0x8a) :: i32, i64 ``` -??? +Rotate right operations: +- `%0x78`: `i32.rotr` - `i32` rotate right. +- `%0x8a`: `i64.rotr` - `i64` rotate right. ### `$abs-opcodes` {#abs-opcodes} @@ -1193,7 +1322,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ abs-opcodes ?(%0x8b %0x99) :: f32, f64 ``` -??? +Floating-point absolute value operations: +- `%0x8b`: `f32.abs` - `f32` absolute value. +- `%0x99`: `f64.abs` - `f64` absolute value. ### `$neg-opcodes` {#neg-opcodes} @@ -1201,7 +1332,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ neg-opcodes ?(%0x8c %0x9a) :: f32, f64 ``` -??? +Floating-point negation operations: +- `%0x8c`: `f32.neg` - `f32` negation. +- `%0x9a`: `f64.neg` - `f64` negation. ### `$ceil-opcodes` {#ceil-opcodes} @@ -1209,7 +1342,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ ceil-opcodes ?(%0x8d %0x9b) :: f32, f64 ``` -??? +Floating-point ceiling operations (round up to nearest integer): +- `%0x8d`: `f32.ceil` - `f32` ceiling. +- `%0x9b`: `f64.ceil` - `f64` ceiling. ### `$floor-opcodes` {#floor-opcodes} @@ -1217,7 +1352,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ floor-opcodes ?(%0x8e %0x9c) :: f32, f64 ``` -??? +Floating-point floor operations (round down to nearest integer): +- `%0x8e`: `f32.floor` - `f32` floor. +- `%0x9c`: `f64.floor` - `f64` floor. ### `$trunc-opcodes` {#trunc-opcodes} @@ -1237,7 +1374,17 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Truncation operations (remove fractional part): +- `%0x8f`: `f32.trunc` - `f32` truncate toward zero. +- `%0x9d`: `f64.trunc` - `f64` truncate toward zero. +- `%0xa8`: `i32.trunc_f32_s` - convert `f32` to signed `i32` (truncate). +- `%0xa9`: `i32.trunc_f32_u` - convert `f32` to unsigned `i32` (truncate). +- `%0xaa`: `i32.trunc_f64_s` - convert `f64` to signed `i32` (truncate). +- `%0xab`: `i32.trunc_f64_u` - convert `f64` to unsigned `i32` (truncate). +- `%0xae`: `i64.trunc_f32_s` - convert `f32` to signed `i64` (truncate). +- `%0xaf`: `i64.trunc_f32_u` - convert `f32` to unsigned `i64` (truncate). +- `%0xb0`: `i64.trunc_f64_s` - convert `f64` to signed `i64` (truncate). +- `%0xb1`: `i64.trunc_f64_u` - convert `f64` to unsigned `i64` (truncate). ### `$nearest-opcodes` {#nearest-opcodes} @@ -1245,7 +1392,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ nearest-opcodes ?(%0x90 %0x9e) :: f32, f64 ``` -??? +Floating-point nearest integer operations (round to nearest, ties to even): +- `%0x90`: `f32.nearest` - `f32` round to nearest integer. +- `%0x9e`: `f64.nearest` - `f64` round to nearest integer. ### `$sqrt-opcodes` {#sqrt-opcodes} @@ -1253,7 +1402,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ sqrt-opcodes ?(%0x91 %0x9f) :: f32, f64 ``` -??? +Floating-point square root operations: +- `%0x91`: `f32.sqrt` - `f32` square root. +- `%0x9f`: `f64.sqrt` - `f64` square root. ### `$min-opcodes` {#min-opcodes} @@ -1261,7 +1412,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ min-opcodes ?(%0x96 %0xa4) :: f32, f64 ``` -??? +Floating-point minimum operations: +- `%0x96`: `f32.min` - `f32` minimum of two values. +- `%0xa4`: `f64.min` - `f64` minimum of two values. ### `$max-opcodes` {#max-opcodes} @@ -1269,7 +1422,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ max-opcodes ?(%0x97 %0xa5) :: f32, f64 ``` -??? +Floating-point maximum operations: +- `%0x97`: `f32.max` - `f32` maximum of two values. +- `%0xa5`: `f64.max` - `f64` maximum of two values. ### `$copysign-opcodes` {#copysign-opcodes} @@ -1277,7 +1432,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc +$ copysign-opcodes ?(%0x98 %0xa6) :: f32, f64 ``` -??? +Floating-point copy sign operations (combine magnitude of first value with sign of second): +- `%0x98`: `f32.copysign` - `f32` copy sign. +- `%0xa6`: `f64.copysign` - `f64` copy sign. ### `$extend-opcodes` {#extend-opcodes} @@ -1294,7 +1451,14 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Integer extension operations (widen integer types): +- `%0xac`: `i64.extend_i32_s` - extend signed `i32` to `i64`. +- `%0xad`: `i64.extend_i32_u` - extend unsigned `i32` to `i64`. +- `%0xc0`: `i32.extend8_s` - extend signed `i8` to `i32`. +- `%0xc1`: `i32.extend16_s` - extend signed `i16` to `i32`. +- `%0xc2`: `i64.extend8_s` - extend signed `i8` to `i64`. +- `%0xc3`: `i64.extend16_s` - extend signed `i16` to `i64`. +- `%0xc4`: `i64.extend32_s` - extend signed `i32` to `i64` (same as `%0xac`). ### `$convert-opcodes` {#convert-opcodes} @@ -1312,7 +1476,15 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Type conversion operations (integer to floating-point): +- `%0xb2`: `f32.convert_i32_s` - convert signed `i32` to `f32`. +- `%0xb3`: `f32.convert_i32_u` - convert unsigned `i32` to `f32`. +- `%0xb4`: `f32.convert_i64_s` - convert signed `i64` to `f32`. +- `%0xb5`: `f32.convert_i64_u` - convert unsigned `i64` to `f32`. +- `%0xb7`: `f64.convert_i32_s` - convert signed `i32` to `f64`. +- `%0xb8`: `f64.convert_i32_u` - convert unsigned `i32` to `f64`. +- `%0xb9`: `f64.convert_i64_s` - convert signed `i64` to `f64`. +- `%0xba`: `f64.convert_i64_u` - convert unsigned `i64` to `f64`. ### `$reinterpret-opcodes` {#reinterpret-opcodes} @@ -1326,5 +1498,9 @@ WebAssembly opcodes. Most of these are defined in the types below, with some exc == ``` -??? +Type reinterpretation operations (reinterpret bit pattern without conversion): +- `%0xbc`: `i32.reinterpret_f32` - reinterpret `f32` bits as `i32`. +- `%0xbd`: `i64.reinterpret_f64` - reinterpret `f64` bits as `i64`. +- `%0xbe`: `f32.reinterpret_i32` - reinterpret `i32` bits as `f32`. +- `%0xbf`: `f64.reinterpret_i64` - reinterpret `i64` bits as `f64`. From 3cdc641700795c63db085a6dc582816fd7ae6bff Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Wed, 13 Aug 2025 14:32:27 +0100 Subject: [PATCH 23/27] Finish draft wasm data types --- .../wasm-walkthrough/reference/wasm-data-types.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index 982a67c6..96cec64d 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -112,7 +112,7 @@ Defines the minimum and maximum size of a memory instance. The `.align` and `.of +$ block-type $@(@ func-type) :: typeidx in type section or func-type ``` -Block type for {structured control instructions ???}. Can be a type index in the [`$type-section`](#type-section) or a [`$func-type`](#func-type) function signature. +Function signature for control flow blocks (`if`, `loop`, etc.). This may be defined inline ([`$func-type`](#func-type)) or referred to by its index in the [`$type-section`](#type-section). ### `$func-type` {#func-type} @@ -144,7 +144,7 @@ Type union of all Wasm instructions. Instructions are categorized here by their operand patterns: - `%vec`: Vector instructions. (See [`$instr-vec`]($instr-vec).) -- [`$instr-short`](#instr-short): ??? +- [`$instr-short`](#instr-short): Non-numeric Wasm instructions. - [`$instr-num`](#instr-num): Standard Wasm instructions categorized by arity. - [`$instr-dbug`](#instr-dbug): Debugging. @@ -157,7 +157,7 @@ Instructions are categorized here by their operand patterns: == ``` -Debugging instructions. The only one supported here is `%print-tee`, which prints a value {TODO ???} with the given `$term` as a label. +Debugging instructions. The only one supported here is `%print-tee`, which prints a value to output with the given `$term` as a label. ### `$instr-num` {#instr-num} @@ -369,7 +369,7 @@ Wasm's binary numeric instructions: == :: $instr-short ``` -???: +Non-numeric WebAssembly instructions organized by category: - `unreachable`: Trap execution unconditionally. - `nop`: No operation. - `block`: Start a block with optional result type. @@ -555,7 +555,7 @@ An ordered sequence of [`$instruction`](#instruction)s. == ``` -{??? - some kind of const but not sure how relates to `$instr-num-zero`} +Instructions that produce constant values e.g. global variables. Unlike [`$instr-num-zero`](#instr-num-zero) which only handles scalar numeric constants, this includes vector constants, global variable reads, and reference constants. ### `$module` {#module} From e20fa17316d2335d3843043550b1a2f22fa09c5e Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Wed, 13 Aug 2025 15:14:08 +0100 Subject: [PATCH 24/27] Draft /sur/engine docs --- .../reference/wasm-interpreter-data-types.md | 267 +++++++++++++++++- 1 file changed, 266 insertions(+), 1 deletion(-) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md index 7215f7f8..8e1307e8 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md @@ -1 +1,266 @@ -# Wasm Interpeter Data Types +# Wasm Interpreter Data Types + +{??? not sure abt intro - not very deep / clear, LLM smell} + +UrWasm's engine layer, `+engine-sur`, contains the interpreter data types that represent Wasm modules in their executable form. + +While `+wasm-sur` implements the WebAssembly Core Specification, `+engine-sur` provides the runtime representation needed for execution, with optimized module structure and execution state management. + +### `+engine-sur` {#engine-sur} + +```hoon +++ engine-sur + =, wasm-sur + |% +``` + +Wrapper arm around the engine types, making them addressable by limb resolution paths like `module:engine-sur`. Also exposes the `+wasm-sur` namespace so it can refer to types like `$type-section` directly. + +### `$module` {#module} + +```hoon ++$ module + $: + =type-section + :: + =import-section :: Changed + =function-section :: Changed to include code + :: + =table-section + =memory-section + =global-section + =export-section + =start-section + =elem-section + :: =datacnt-section :: Removed + :: =code-section :: Code moved to function section + =data-section + == +``` + +Wasm [`$module`](./wasm-data-types.md#module) as seen by the engine. Some sections have been removed or modified for efficiency: +- [`$code-section](./wasm-data-types.md#code-section) is merged into the function section. +- [`$datacnt-section](./wasm-data-types.md#datacnt-section) is removed as it's not needed during execution. +- [`$import-section](./wasm-data-types.md#import-section) is restructured for runtime resolution. + +### `$function` {#function} + +```hoon ++$ function + $: type-id=@ + locals=(list valtype) + =expression + == +``` + +Unlike `+wasm-sur`'s [`$function`](./wasm-data-types.md#function), this includes both the function signature and its implementation merged together: +- `.type-id`: Index into the [`$type-section`](./wasm-data-types.md#type-section) for this function's signature. +- `.locals`: Local variables for this function. +- [`.expression`](./wasm-data-types.md#expression): The function body as a sequence of [`$instruction`s](./wasm-data-types.md#instruction). + +### `$function-section` {#function-section} + +```hoon ++$ function-section + (list function) +``` + +List of [`$function`s](#function) in the [`$module`](#module). + +### `$import-section` {#import-section} + +```hoon ++$ import-section + $: + funcs=(list [[mod=cord name=cord] type-id=@]) + tables=(list [[mod=cord name=cord] t=table]) + memos=(list [[mod=cord name=cord] l=limits]) + globs=(list [[mod=cord name=cord] v=valtype m=?(%con %var)]) + == +``` + +Restructured import section organized by import type for efficient runtime resolution: +- `.funcs`: Imported functions with module name, export name, and type signature by index. +- `.tables`: Imported [`$table`s](./wasm-data-types.md#table) with their specifications. +- `.memos`: Imported memories with size [`$limits`](./wasm-data-types.md#limits). +- `.globs`: Imported global variables with [value type](./wasm-data-types.md#valtype) and mutability. + +### `$store` {#store} + +```hoon ++$ store + $: =shop :: resolved imports + =module :: engine representation of module + mem=(unit [buffer=@ n-pages=@]) :: single membuffer + tables=(list (list $>(%ref coin-wasm))) :: tables + globals=(list coin-wasm) + == +``` + +Complete module store containing: +- `.shop`: Resolved import dependencies (see [`$shop`](#shop)). +- `.module`: The engine's [`$module`](#module). +- `.mem`: Optional memory buffer with page count. +- `.tables`: Table instances containing function references. +- `.globals`: Global variable values. + +### `$local-state` {#local-state} + +```hoon ++$ local-state [=stack locals=(list val) =store] +``` + +Execution state for a function call: +- `.stack`: Current execution stack (see [`$stack`](#stack)). +- `.locals`: Local variable values for current function. +- `.store`: Module store containing all persistent state. + +### `$stack` {#stack} + +```hoon ++$ stack [br=branch va=(pole val)] +``` + +Execution stack with: +- `.br`: Current branch state for control flow (see [`$branch`](#branch)). +- `.va`: Stack of values. + +### `$val` {#val} + +```hoon ++$ val + $~ `@`0 + $@ @ :: numerical value + $>(%ref coin-wasm) :: reference +``` + +Runtime value on the stack, which can be either: +- A raw atom. +- A typed reference. + +### `$branch` {#branch} + +```hoon ++$ branch + $~ ~ + $@ ~ + $% [%retr ~] :: return to the caller + [%targ i=@] :: targeted block + [%trap ~] :: deterministic crash + :: + $: %bloq :: blocked on import request + [[mod=cord name=cord] =request] + =module + mem=(unit [buffer=@ n-pages=@]) :: single membuffer + tables=(list (list $>(%ref coin-wasm))) :: tables + globals=(list coin-wasm) + == == +``` + +Branch state for control flow management: +- `~`: Normal execution (no branch pending). +- `%retr`: Return to caller function. +- `%targ`: Branch to specific block label `.i`. +- `%trap`: Execution trapped (deterministic crash). +- `%bloq`: Blocked waiting for import resolution, containing the [`$request`](#request) details and current execution state. + +### `$result` {#result} + +```hoon ++$ result + $% + [%0 out=(list coin-wasm) st=store] :: success + :: + $: %1 :: block + [[mod=cord name=cord] =request] :: /module/name, request + =module + mem=(unit [buffer=@ n-pages=@]) + tables=(list (list $>(%ref coin-wasm))) + globals=(list coin-wasm) + == + :: + [%2 st=store] :: trap, crash + == +``` + +Result of module instantiation or function invocation: +- `%0`: Successful execution with output values and updated [`$store`](#store). +- `%1`: Blocked on import [`$request`](#request), containing request details and current state for resumption. +- `%2`: Crashed with final `$store` state. + +### `$request` {#request} + +```hoon ++$ request + $% + [%func args=(list coin-wasm)] :: typed values for the call + :: + $: %tabl + args=(list coin-wasm) + $= instr + $~ [%table-size `@`0] + $> + $? %call-indirect %table-get + %table-set %table-init + %table-copy %table-grow + %table-size %table-fill + == + instr-short + == + :: + $: %memo + args=(list coin-wasm) + $= instr + $~ [%memory-size %0] + $? $> $? %load %store + %memory-size %memory-grow + %memory-init %memory-copy + %memory-fill + == + instr-short + :: + $: %vec + $> $? %load %load-lane + %store %store-lane + == + instr-vec + == == == + :: + $: %glob + args=(list coin-wasm) + $= instr + $~ [%global-get `@`0] + $>(?(%global-get %global-set) instr-short) + == + == +``` + +Import request types: +- `%func`: Function call with typed argument values. +- `%tabl`: Table operation with arguments and specific table instruction. +- `%memo`: Memory operation, including vector operations and standard memory instructions. +- `%glob`: Global variable. + +### `$shop` {#shop} + +```hoon ++$ shop (list item) +``` + +List of resolved import [`$item`s](#item) representing available external dependencies. + +### `$item` {#item} + +```hoon ++$ item + %+ pair (list coin-wasm) + $: =module + mem=(unit [buffer=@ n-pages=@]) :: single membuffer + tables=(list (list $>(%ref coin-wasm))) :: tables + globals=(list coin-wasm) + == +``` + +Resolved import item containing: +- A list of values to push onto the stack when this import is invoked. +- Complete module state including memory, tables, and globals that this import provides access to. From 15a35c1f0a89852492021114048d3b81f4a91496 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Thu, 14 Aug 2025 11:45:27 +0100 Subject: [PATCH 25/27] Draft /sur/lia.hoon docs --- .claude/settings.local.json | 5 +- .../reference/lia-data-types.md | 220 ++++++++++++++++++ .../reference/wasm-data-types.md | 2 +- .../reference/wasm-interpreter-data-types.md | 2 + 4 files changed, 227 insertions(+), 2 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 009b64a9..9e4de14b 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -3,7 +3,10 @@ "allow": [ "WebSearch", "WebFetch(domain:webassembly.github.io)", - "WebFetch(domain:pengowray.github.io)" + "WebFetch(domain:pengowray.github.io)", + "WebFetch(domain:gist.github.com)", + "WebFetch(domain:gist.github.com)", + "WebFetch(domain:gist.github.com)" ], "deny": [], "ask": [] diff --git a/content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md index abb85df9..71f21d25 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/lia-data-types.md @@ -1 +1,221 @@ # Lia Data Types + +The `+lia-sur` core builds on top of `+wasm-sur` and `+engine-sur` to define Lia's monadic, deterministic approach to making Wasm function calls and handling their results. + +### `+lia-sur` {#lia-sur} + +```hoon +++ lia-sur + =, wasm-sur + =, engine-sur + |% + :: ... +:: ... +``` + +Wrapper arm around the Lia core, making its arms and types addressable by limb resolution paths like `lia-value:lia-sur`. Also exposes the `+wasm-sur` and `+engine-sur` namespaces so this core can access the underlying Wasm types. + +### `+lia-value` {#lia-value} + +```hoon +++ lia-value + $~ [%i32 0] + $% [%octs octs] + $<(%ref coin-wasm) + == +``` + +Lia value type. Can be: +- 32-bit integer `0`. +- `%octs`: Byte data with length and content (see [`$octs`](./wasm-data-types.md#octs)). +- Any [`$coin-wasm`](./wasm-data-types.md#coin-wasm) except references. That leaves integers, floats, vectors, and binary data. + +### `+import` {#import} + +```hoon +++ import + |$ [acc] + %+ pair acc + %+ map (pair cord cord) + $- (list coin-wasm) + (script-raw-form (list coin-wasm) acc) +``` + +Wasm module import. + +Pair of the given `$acc` accumulator type with a map of imports to functions. Each `(pair cord cord)` key in the map is a cell of \[module-name export-name]. Each value in the map is a gate that takes a list of [`$coin-wasm`](./wasm-data-types.md#coin-wasm) arguments and returns the script. + +### `+lia-state` {#lia-state} + +```hoon +++ lia-state + |$ [acc] + (trel store (list (list lia-value)) (import acc)) +``` + +Execution state for a Lia script, returning a tuple of: +- [`$store`](./wasm-interpreter-data-types.md#store): Wasm module state. +- Stack of [`+lia-value`s](#lia-value) representing the current script state. +- [`+import`](#import): Available import functions and their implementations. + +### `+script-yield` {#script-yield} + +```hoon +++ script-yield + |$ [a] + $% [%0 p=a] + [%1 name=term args=(list lia-value)] + [%2 ~] + == +``` + +Result of executing a Lia script step: +- `%0`: Step completed with result of type `$a`. +- `%1`: Step blocked on external call to function `.name`, with the provided list of `.args` from the previous step. +- `%2`: Step crashed or errored. + +### `+script-result` {#script-result} + +```hoon +++ script-result + |$ [m-yil m-acc] + [(script-yield m-yil) (lia-state m-acc)] +``` + +Mold for the complete result of script execution including: +- [`$script-yield`](#script-yield) with the execution outcome. +- [`$lia-state`](#lia-state) with updated state. + +### `+script-raw-form` {#script-raw-form} + +```hoon +++ script-raw-form + |* [yil=mold acc=mold] + $-((lia-state acc) (script-result yil acc)) +``` + +Raw form of a Lia script: a gate that takes a [`$lia-state`](#lia-state) and produces a [`$script-result`](#script-result). This represents a stateful computation in the Lia monad. + +### `+script` {#script} + +```hoon +++ script + |* [m-yil=mold m-acc=mold] + |% + :: +output + :: +yield + :: +form + :: +m-sat + :: +return + :: +try + :: +catch + -- +``` + +Monadic interface for Lia scripts with yield mold `.m-yil` and accumulator mold `.m-acc`. + +#### `+output` {#output} + +```hoon +++ output (script-result m-yil m-acc) +``` + +Final `$script-result` of this script. + +#### `+yield` {#yield} + +```hoon +++ yield (script-yield m-yil) +``` + +Final `$script-yield` of this script. + +#### `+form` {#form} + +```hoon +++ form (script-raw-form m-yil m-acc) +``` + +Built script mold, analogous to `+form:m` from thread [strands](../../../urbit-os/base/threads/basics/fundamentals.md#strands). + +#### `+m-sat` {#m-sat} + +```hoon +++ m-sat (lia-state m-acc) +``` + +Execution state for this script with the provided `.m-acc`. + +#### `+return` {#return} + +```hoon +++ return :: pure + |= arg=m-yil + ^- form + |= s=m-sat + [0+arg s] +``` + +Monadic (pure) return: lifts a value into the Lia monad without changing script state. + +#### `+try` {#try} + +```hoon +++ try :: monadic bind + |* m-mond=mold + |= [mond=(script-raw-form m-mond m-acc) cont=$-(m-mond form)] + ^- form + |= s=m-sat + =^ mond-yil=(script-yield m-mond) s (mond s) + ^- output + ?. ?=(%0 -.mond-yil) [mond-yil s] + ((cont p.mond-yil) s) +``` + +Monadic bind: sequences two computations, passing the result of the first to the second if successful (`%0`). Handles early termination for blocked (`%1`) or crashed (`%2`) states. + +#### `+catch` {#catch} + +```hoon +++ catch :: bind either + |* m-mond=mold + |= $: $: try=(script-raw-form m-mond m-acc) + err=(script-raw-form m-mond m-acc) + == + cont=$-(m-mond form) + == + ^- form + |= s=m-sat + =^ try-yil=(script-yield m-mond) s (try s) + ^- output + ?: ?=(%0 -.try-yil) + ((cont p.try-yil) s) + ?: ?=(%1 -.try-yil) + [try-yil s] + =^ err-yil s (err s) + ?. ?=(%0 -.err-yil) [err-yil s] + ((cont p.err-yil) s) +``` + +Error handling combinator: attempts the first computation, and if it crashes (`%2`), tries the error handler. Blocked states (`%1`) are propagated immediately. + +### `$seed` {#seed} + +```hoon ++$ seed + $: + module=octs + past=(script-raw-form (list lia-value) *) + shop=(list (list lia-value)) + import=(import *) + == +``` + +Complete Lia interpreter state containing all necessary components for module execution: +- `.module`: Wasm module binary data. +- `.past`: Previously executed script that established the current state. +- `.shop`: External results accumulator - lists of values from resolved import function calls. +- `.import`: Map of available import functions that the module can call. + +This represents the "formal state" of the Lia interpreter, suitable for caching and resuming if necessary. + diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md index 96cec64d..01e8ed75 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-data-types.md @@ -7,7 +7,7 @@ The first part implements the [Structure chapter](https://www.w3.org/TR/2022/WD- The second part implements Wasm's binary-format opcodes. -### `$octs` (pair @ud @) +### `$octs` {#octs} ```hoon +$ octs (pair @ud @) diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md index 8e1307e8..72b2dbe2 100644 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md +++ b/content/build-on-urbit/wasm-walkthrough/reference/wasm-interpreter-data-types.md @@ -12,6 +12,8 @@ While `+wasm-sur` implements the WebAssembly Core Specification, `+engine-sur` p ++ engine-sur =, wasm-sur |% + :: ... +:: ... ``` Wrapper arm around the engine types, making them addressable by limb resolution paths like `module:engine-sur`. Also exposes the `+wasm-sur` namespace so it can refer to types like `$type-section` directly. From e7589e5070ce032d5b403f8682c4d71d82f25a56 Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Thu, 14 Aug 2025 11:48:48 +0100 Subject: [PATCH 26/27] Add /lib/wasm skeleton --- .../reference/lib-wasm-lia.md | 31 ++ .../reference/lib-wasm-parser.md | 157 +++++++ .../reference/lib-wasm-runner-engine.md | 26 ++ .../reference/lib-wasm-runner-op-def.md | 126 ++++++ .../reference/lib-wasm-validator.md | 31 ++ .../wasm-walkthrough/reference/wasm-libs.md | 389 ------------------ 6 files changed, 371 insertions(+), 389 deletions(-) create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-lia.md create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-parser.md create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-engine.md create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-op-def.md create mode 100644 content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-validator.md delete mode 100644 content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md diff --git a/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-lia.md b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-lia.md new file mode 100644 index 00000000..92344e2b --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-lia.md @@ -0,0 +1,31 @@ + +## /lib/wasm/lia + +++ run-once + ++ init +++ run + ++ init + +++ arrows +* [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) + ++ m-sat (lia-state m-acc) + ++ call + ++ call-1 + ++ memread + ++ memwrite + ++ call-ext + ++ global-set + ++ global-get + ++ memory-size + ++ memory-grow :: returns old size in pages + ++ get-acc + ++ set-acc + ++ get-all-local-globals + ++ set-all-local-globals + +++ runnable (script (list lia-value) *) +++ cw-to-atom +++ types-atoms-to-coins +++ valtype-from-coin +++ page-size ^\~((bex 16)) +++ yield-need diff --git a/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-parser.md b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-parser.md new file mode 100644 index 00000000..50b42cf6 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-parser.md @@ -0,0 +1,157 @@ + +## /lib/wasm/parser + +++ parser + ++ main + ++ r + ++ womp + ++ bild + ++ bonk + ++ feel + ++ u-n + ++ s-n + ++ u32 (u-n 32) + ++ u64 (u-n 64) + ++ f32 + ++ f64 + ++ vec + ++ name (cook crip (vec next)) + ++ vec-u32 (vec u32) + ++ num-type + ++ vec-type (cold %v128 (just '\7b')) + ++ ref-type + ++ valtype + ++ func-type + ++ limits + ++ expr + ++ expr-pair + ++ end (just '\0b') + ++ else (just '\05') + ++ const-i32 (just '\41') + ++ const-i64 (just '\42') + ++ const-f32 (just '\43') + ++ const-f64 (just '\44') + ++ block-op (just '\02') + ++ loop-op (just '\03') + ++ if-op (just '\04') + ++ form-ranges + ++ instr + ++ select-vec + ++ br-table + ++ instr-zero (sear op-map next) + ++ block + ++ loop + ++ if + ++ block-type + ++ handle-one-arg-i32 + ++ handle-two-args-i32 + ++ handle-br-table + ++ handle-block + ++ get-valtype + ++ handle-loop + ++ handle-if + ++ handle-const-f64 + ++ handle-const-f32 + ++ handle-const-i32 + ++ handle-const-i64 + ++ fc + ++ zero-args (sear handle-zero u32) + ++ one-arg (sear handle-one ;\~(plug u32 u32)) + ++ two-args (sear handle-two ;\~(plug u32 u32 u32)) + ++ handle-zero + ++ handle-one + ++ handle-two + ++ fd + ++ memarg + ++ mem-lane + ++ const + ++ shuffle + ++ lane + ++ type-section + ++ import-section + ++ import + ++ import-desc + ++ import-func ;\~(plug (cold %func (just '\00')) u32) + ++ import-tabl ;\~(plug (cold %tabl (just '\01')) ref-type limits) + ++ import-memo ;\~(plug (cold %memo (just '\02')) limits) + ++ import-glob + ++ con-var + ++ function-section + ++ table-section + ++ table ;\~(plug ref-type limits) + ++ memory-section + ++ global-section + ++ global + ++ const-expr ;\~(sfix const-instr end) :: single instruction + ++ const-instr + ++ export-section + ++ export + ++ start-section + ++ elem-section + ++ elem + ++ elem-kind (just '\00') + ++ elem-0 + ++ elem-1 + ++ elem-2 + ++ elem-3 + ++ elem-4 + ++ elem-5 + ++ elem-6 + ++ elem-7 + ++ handle-elem-0 + ++ handle-elem-1 + ++ handle-elem-2 + ++ handle-elem-3 + ++ handle-elem-4 + ++ handle-elem-5 + ++ handle-elem-6 + ++ handle-elem-7 + ++ code-section + ++ code (bonk (vec next) ;\~(pfix u32 func)) + ++ func + ++ locals ;\~(plug u32 valtype) + ++ handle-locals + ++ data-section + ++ data + ++ to-octs + ++ datacnt-section + ++ module + ++ module-contents + ++ check + ++ customs + ++ magic (jest '\00asm') + ++ version + ++ op-map + ++ simd-map + ++ nearest + ++ sqrt + ++ div + ++ pmin + ++ pmax + ++ avgr + ++ ceil + ++ floor + ++ all-true + ++ bitmask + ++ narrow + ++ shl + ++ extadd + ++ convert + ++ mul + ++ splat + ++ eq + ++ ne + ++ abs + ++ neg + ++ trunc + ++ lt + ++ gt + ++ le + ++ ge + ++ shr + ++ min + ++ max + ++ add + ++ sub + ++ extend + ++ extmul diff --git a/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-engine.md b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-engine.md new file mode 100644 index 00000000..b3c4391e --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-engine.md @@ -0,0 +1,26 @@ + +## /lib/wasm/runner/engine + +++ engine + ++ get-types + ++ mint + ++ make-export-map + ++ find-func-id + ++ conv + ++ import-upd + ++ prep + ++ instantiate + ++ init-globals + ++ init-table + ++ init-elems + ++ init-mem + ++ init-data + ++ start + ++ wasm-need + ++ wasm-bind + ++ invoke + ++ invoke-id + ++ call + ++ eval + ++ dec-br + ++ apply diff --git a/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-op-def.md b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-op-def.md new file mode 100644 index 00000000..2687c631 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-runner-op-def.md @@ -0,0 +1,126 @@ + +## /lib/wasm/runner/op-def + +++ op-def + ++ mayb + ++ sure + ++ torn + ++ lane-size + ++ fuse :: from \~paldev + ++ chap + ++ page-size ^\~((bex 16)) + ++ place + ++ lim-min + ++ lim-max + ++ lte-lim + ++ change + ++ to-si + ++ en-si + ++ sat + ++ coin-to-val + ++ val-to-coin + ++ snug + ++ shot + ++ buy + ++ grab + ++ func + ++ table + ++ memo + ++ glob + ++ mem-store + ++ mem-load + ++ kind + ++ fetch-gate + ++ fetch + ++ dbug + ++ print-tee + ++ select + ++ null + ++ unreachable + ++ nop |=(local-state +<) + ++ return + ++ drop + ++ ref + ++ ref-null + ++ ref-is-null + ++ ref-func + ++ load + ++ store + ++ const + ++ get + ++ set + ++ branch + ++ table + ++ table-get + ++ table-set + ++ table-init + ++ elem-drop + ++ table-copy + ++ table-grow + ++ table-size + ++ table-fill + ++ memo + ++ memory-size + ++ memory-grow + ++ memory-init + ++ data-drop + ++ memory-copy + ++ memory-fill + ++ unar + ++ clz + ++ ctz + ++ popcnt + ++ abs + ++ neg + ++ sqrt + ++ ceil + ++ floor + ++ trunc + ++ nearest + ++ eqz + ++ wrap + ++ extend + ++ convert + ++ demote + ++ promote + ++ reinterpret + ++ bina + ++ add + ++ sub + ++ mul + ++ div + ++ rem + ++ and + ++ or + ++ xor + ++ shl + ++ shr + ++ rotl + ++ rotr + ++ min + ++ max + ++ copysign + ++ eq + ++ ne + ++ lt + ++ gt + ++ le + ++ ge + ++ simd + ++ rope + ++ fetch-vec + ++ load + ++ load-lane + ++ store + ++ store-lane + ++ const + ++ shuffle + ++ extract + ++ replace + ++ plain + ++ kind + ++ vec-unar + ++ vec-bina + ++ get-op-unar + ++ get-op-bina + ++ get-size diff --git a/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-validator.md b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-validator.md new file mode 100644 index 00000000..6d939a59 --- /dev/null +++ b/content/build-on-urbit/wasm-walkthrough/reference/lib-wasm-validator.md @@ -0,0 +1,31 @@ + +## /lib/wasm/validator + +++ validator + ++ output + ++ result-form + ++ result + ++ bind + ++ snug + ++ validate-module + ++ v-import-section + ++ validate-limits + ++ v-function-section + ++ v-table-section + ++ v-memory-section + ++ v-global-section + ++ v-export-section + ++ v-start-section + ++ v-elem-section + ++ v-datacnt-section + ++ v-code-section + ++ v-data-section + ++ validate-code + ++ validate-expr + ++ validate-instr + ++ get-type + ++ get-type-vec + ++ from-coin + ++ byte-width + ++ dim-lane + ++ unpack diff --git a/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md b/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md deleted file mode 100644 index 2c63980e..00000000 --- a/content/build-on-urbit/wasm-walkthrough/reference/wasm-libs.md +++ /dev/null @@ -1,389 +0,0 @@ -# UrWasm Library Reference - -nested core structure - -/lib/wasm/parser/hoon :: Wasm parser -/lib/wasm/validator/hoon :: Wasm validator -/lib/wasm/runner/op-def/hoon :: Wasm operator definitions -/lib/wasm/runner/engine/hoon :: Wasm interpreter -/lib/wasm/lia/hoon :: Lia interpreter - -foobar - - * Stateless UrWasm: `+run-once` - * Stateful UrWasm: `+run` - -*** - -## /lib/wasm/runner/engine - -++ engine - ++ get-types - ++ mint - ++ make-export-map - ++ find-func-id - ++ conv - ++ import-upd - ++ prep - ++ instantiate - ++ init-globals - ++ init-table - ++ init-elems - ++ init-mem - ++ init-data - ++ start - ++ wasm-need - ++ wasm-bind - ++ invoke - ++ invoke-id - ++ call - ++ eval - ++ dec-br - ++ apply - - -## /lib/wasm/runner/op-def - -++ op-def - ++ mayb - ++ sure - ++ torn - ++ lane-size - ++ fuse :: from \~paldev - ++ chap - ++ page-size ^\~((bex 16)) - ++ place - ++ lim-min - ++ lim-max - ++ lte-lim - ++ change - ++ to-si - ++ en-si - ++ sat - ++ coin-to-val - ++ val-to-coin - ++ snug - ++ shot - ++ buy - ++ grab - ++ func - ++ table - ++ memo - ++ glob - ++ mem-store - ++ mem-load - ++ kind - ++ fetch-gate - ++ fetch - ++ dbug - ++ print-tee - ++ select - ++ null - ++ unreachable - ++ nop |=(local-state +<) - ++ return - ++ drop - ++ ref - ++ ref-null - ++ ref-is-null - ++ ref-func - ++ load - ++ store - ++ const - ++ get - ++ set - ++ branch - ++ table - ++ table-get - ++ table-set - ++ table-init - ++ elem-drop - ++ table-copy - ++ table-grow - ++ table-size - ++ table-fill - ++ memo - ++ memory-size - ++ memory-grow - ++ memory-init - ++ data-drop - ++ memory-copy - ++ memory-fill - ++ unar - ++ clz - ++ ctz - ++ popcnt - ++ abs - ++ neg - ++ sqrt - ++ ceil - ++ floor - ++ trunc - ++ nearest - ++ eqz - ++ wrap - ++ extend - ++ convert - ++ demote - ++ promote - ++ reinterpret - ++ bina - ++ add - ++ sub - ++ mul - ++ div - ++ rem - ++ and - ++ or - ++ xor - ++ shl - ++ shr - ++ rotl - ++ rotr - ++ min - ++ max - ++ copysign - ++ eq - ++ ne - ++ lt - ++ gt - ++ le - ++ ge - ++ simd - ++ rope - ++ fetch-vec - ++ load - ++ load-lane - ++ store - ++ store-lane - ++ const - ++ shuffle - ++ extract - ++ replace - ++ plain - ++ kind - ++ vec-unar - ++ vec-bina - ++ get-op-unar - ++ get-op-bina - ++ get-size - -## /lib/wasm/lia - -++ run-once - ++ init -++ run - ++ init - -++ arrows -* [cookbook.md](https://gist.github.com/Quodss/a7dca761f6bcd887241bdc04db2c026a) - ++ m-sat (lia-state m-acc) - ++ call - ++ call-1 - ++ memread - ++ memwrite - ++ call-ext - ++ global-set - ++ global-get - ++ memory-size - ++ memory-grow :: returns old size in pages - ++ get-acc - ++ set-acc - ++ get-all-local-globals - ++ set-all-local-globals - -++ runnable (script (list lia-value) *) -++ cw-to-atom -++ types-atoms-to-coins -++ valtype-from-coin -++ page-size ^\~((bex 16)) -++ yield-need - -## /lib/wasm/parser - -++ parser - ++ main - ++ r - ++ womp - ++ bild - ++ bonk - ++ feel - ++ u-n - ++ s-n - ++ u32 (u-n 32) - ++ u64 (u-n 64) - ++ f32 - ++ f64 - ++ vec - ++ name (cook crip (vec next)) - ++ vec-u32 (vec u32) - ++ num-type - ++ vec-type (cold %v128 (just '\7b')) - ++ ref-type - ++ valtype - ++ func-type - ++ limits - ++ expr - ++ expr-pair - ++ end (just '\0b') - ++ else (just '\05') - ++ const-i32 (just '\41') - ++ const-i64 (just '\42') - ++ const-f32 (just '\43') - ++ const-f64 (just '\44') - ++ block-op (just '\02') - ++ loop-op (just '\03') - ++ if-op (just '\04') - ++ form-ranges - ++ instr - ++ select-vec - ++ br-table - ++ instr-zero (sear op-map next) - ++ block - ++ loop - ++ if - ++ block-type - ++ handle-one-arg-i32 - ++ handle-two-args-i32 - ++ handle-br-table - ++ handle-block - ++ get-valtype - ++ handle-loop - ++ handle-if - ++ handle-const-f64 - ++ handle-const-f32 - ++ handle-const-i32 - ++ handle-const-i64 - ++ fc - ++ zero-args (sear handle-zero u32) - ++ one-arg (sear handle-one ;\~(plug u32 u32)) - ++ two-args (sear handle-two ;\~(plug u32 u32 u32)) - ++ handle-zero - ++ handle-one - ++ handle-two - ++ fd - ++ memarg - ++ mem-lane - ++ const - ++ shuffle - ++ lane - ++ type-section - ++ import-section - ++ import - ++ import-desc - ++ import-func ;\~(plug (cold %func (just '\00')) u32) - ++ import-tabl ;\~(plug (cold %tabl (just '\01')) ref-type limits) - ++ import-memo ;\~(plug (cold %memo (just '\02')) limits) - ++ import-glob - ++ con-var - ++ function-section - ++ table-section - ++ table ;\~(plug ref-type limits) - ++ memory-section - ++ global-section - ++ global - ++ const-expr ;\~(sfix const-instr end) :: single instruction - ++ const-instr - ++ export-section - ++ export - ++ start-section - ++ elem-section - ++ elem - ++ elem-kind (just '\00') - ++ elem-0 - ++ elem-1 - ++ elem-2 - ++ elem-3 - ++ elem-4 - ++ elem-5 - ++ elem-6 - ++ elem-7 - ++ handle-elem-0 - ++ handle-elem-1 - ++ handle-elem-2 - ++ handle-elem-3 - ++ handle-elem-4 - ++ handle-elem-5 - ++ handle-elem-6 - ++ handle-elem-7 - ++ code-section - ++ code (bonk (vec next) ;\~(pfix u32 func)) - ++ func - ++ locals ;\~(plug u32 valtype) - ++ handle-locals - ++ data-section - ++ data - ++ to-octs - ++ datacnt-section - ++ module - ++ module-contents - ++ check - ++ customs - ++ magic (jest '\00asm') - ++ version - ++ op-map - ++ simd-map - ++ nearest - ++ sqrt - ++ div - ++ pmin - ++ pmax - ++ avgr - ++ ceil - ++ floor - ++ all-true - ++ bitmask - ++ narrow - ++ shl - ++ extadd - ++ convert - ++ mul - ++ splat - ++ eq - ++ ne - ++ abs - ++ neg - ++ trunc - ++ lt - ++ gt - ++ le - ++ ge - ++ shr - ++ min - ++ max - ++ add - ++ sub - ++ extend - ++ extmul - - -## /lib/wasm/validator - -++ validator - ++ output - ++ result-form - ++ result - ++ bind - ++ snug - ++ validate-module - ++ v-import-section - ++ validate-limits - ++ v-function-section - ++ v-table-section - ++ v-memory-section - ++ v-global-section - ++ v-export-section - ++ v-start-section - ++ v-elem-section - ++ v-datacnt-section - ++ v-code-section - ++ v-data-section - ++ validate-code - ++ validate-expr - ++ validate-instr - ++ get-type - ++ get-type-vec - ++ from-coin - ++ byte-width - ++ dim-lane - ++ unpack From 4d3f142a60d0974c0036a0244c5d22720b556aea Mon Sep 17 00:00:00 2001 From: bonbud-macryg Date: Thu, 14 Aug 2025 13:20:17 +0100 Subject: [PATCH 27/27] Ignore .claude --- .claude/settings.local.json | 14 -------------- .gitignore | 3 +++ 2 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 9e4de14b..00000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "permissions": { - "allow": [ - "WebSearch", - "WebFetch(domain:webassembly.github.io)", - "WebFetch(domain:pengowray.github.io)", - "WebFetch(domain:gist.github.com)", - "WebFetch(domain:gist.github.com)", - "WebFetch(domain:gist.github.com)" - ], - "deny": [], - "ask": [] - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4fa15125..dec0a36f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +#claude +.claude + # vim .tags