Files
rose-ash/hosts/ocaml/lib/extensions

SX VM extensions

Each *.ml file here is a VM extension — a first-class OCaml module that registers specialized bytecode opcodes with Sx_vm_extensions. See plans/sx-vm-opcode-extension.md for the design.

Pattern

(* lib/extensions/myport.ml *)
open Sx_types

type Sx_vm_extension.extension_state += MyportState of { ... }

module M : Sx_vm_extension.EXTENSION = struct
  let name = "myport"
  let init () = MyportState { ... }
  let opcodes _st = [
    (id, "myport.OP_NAME", handler);
    ...
  ]
end

let register () = Sx_vm_extensions.register (module M)

Then call Myport.register () once at startup from any binary that should have the extension loaded.

Opcode-ID allocation

Range 200-247 (per Sx_vm_extensions.extension_min / extension_max). Conventions:

Range Use
200-209 reserved for lib/guest/vm/ shared opcodes (chiselled out on 2nd use)
210-219 inline test extensions defined in bin/run_tests.ml
220-229 this directory's test_ext (the canonical template)
230-247 first-come-first-served by language ports (Erlang first)

When a port claims a contiguous block, document it in the table above. The registry rejects collisions at startup with a loud error — there is no silent shadowing.

Naming

Always prefix opcode names with the extension name plus a dot: myport.OP_<NAME>. The prefix is a hard convention so that multiple extensions can share the global opcode-name namespace cleanly.

State

extension_state is an extensible variant. Add your case (e.g. MyportState of { ... }) at the top of your file, return it from init, and pattern-match it inside your handlers. Other extensions cannot see your state — the variant case is private to your module.

Testing

test_ext.ml is the canonical worked example. bin/run_tests.ml calls Test_ext.register (), then drives bytecode that exercises the opcodes end-to-end (push, double, dispatch, disassemble, invocation counter). Mirror this shape when adding a real port's extension.

Build wiring

lib/dune has (include_subdirs unqualified), so any .ml you drop in here is automatically part of the sx library. Module name follows the filename verbatim (test_ext.mlTest_ext).