Files
Mahdi ramezaan zaadeandAlexander Medvednikov d00689b322 tests: cover the vlib/wasm opcode emitters and section encoders (#30299)
* 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>
2026-10-14 14:07:33 +03:00
..
2026-09-17 10:47:56 +03:00

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.