* tests: cover the wasm opcode emitters and section encoders at the byte level `vlib/wasm` has a `tests/` directory, so the module was not untested: those files compile a module and assert on the result. What none of them do is assert the bytes the emitters write, which is the actual contract. `b_and`, `clz`, `unreachable`, `result_type` and `push_f32` had no coverage at all, and neither did the section/length-patching machinery. So this asserts opcode numbers from the spec rather than from the implementation: - the arithmetic, bitwise, unary-count, comparison and float-unary families, where the opcode depends on the `NumType`/`RefType` argument, so all four types must land in different opcode blocks - the signed/unsigned split in `b_shr`, `lt`, `gt`, `le` and `ge`, which is exactly the kind of distinction that regresses silently - the section and name encoders, and the insert-rather-than-overwrite behaviour of `patch_len`/`patch_u32`, which is what makes `compile` able to write a length before it knows it - `compile`'s eight magic bytes Tests that overlap `tests/` are kept deliberately: `test_const_instructions _emit_opcode_then_operand` and `test_local_instructions_emit_opcode_then_index` assert exact bytes where the existing tests assert behaviour, so the two test different properties rather than testing the same one twice. Two branches are not tested, and the reason is recorded in the file rather than left implicit: `get_local_func_idx` and `get_function_idx` panic on an unknown name, and V has no assert_panics to catch it. `v test vlib/wasm/` is green: 9 passed, 1 of which is new to this commit. * os: cover the short_path guards on Windows `short_path` had no test. It is pure enough to test: the empty-string guard and the forward/backslash normalisation are both reachable without a real 8.3 path existing, and they are the two branches a caller actually depends on. `test_short_path_empty_string_is_empty` pins the documented empty input. `test_short_path_accepts_forward_slashes` checks that a path written with backslashes survives `GetShortPathNameW` unchanged, so the separator style of the answer does not depend on the separator style of the input. The recursive fallback deeper in the function needs a genuinely long path to reach, and the directory has to exist on disk, so it is left out rather than tested with a fixture that would not exercise it. `vlib/os/` is 45 passed, 1 skipped, 4 failed. Those four (`process_test`, `process_literal_args_test`, `process_exit_code_windows_test`, `walk_dir_test`) fail on process spawning on this host and are unchanged by this commit, which only adds tests. Added to the existing `os_stat_windows_test.v` rather than a new file: the file already carried the Windows stat tests, and a second file covering the same module surface would split it for no gain. * tests: isolate Windows short-path fixture and exercise slash inputs --------- Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
Description
The wasm module is a pure V implementation of the WebAssembly bytecode module format,
available in the form of a builder.
It allows users to generate WebAssembly modules in memory.
With the V wasm module, users can create functions, opcodes, and utilize the entire wasm specification without the need for a large dependency like binaryen. All of this functionality is available within V itself, making the module a valuable resource for V developers seeking to build high-performance web applications.
The module is designed to generate a []u8, which can be written to a .wasm file
or executed in memory.
Examples are present in examples/wasm_codegen.
import wasm
import os
fn main() {
mut m := wasm.Module{}
mut func := m.new_function('add', [.i32_t, .i32_t], [.i32_t])
{
func.local_get(0) // | local.get 0
func.local_get(1) // | local.get 1
func.add(.i32_t) // | i32.add
}
m.commit(func, true) // `export: true`
mod := m.compile() // []u8
os.write_file_array('add.wasm', mod)!
}
This module does not perform verification of the WebAssembly output.
Use a tool like wasm-validate to validate, and wasm-dis to show a decompiled form.