QuickBEAM.VM (QuickBEAM v0.11.0)

View Source

Compiles and executes verified QuickJS bytecode with an isolated BEAM interpreter.

Programs are immutable and version-locked. Each evaluation owns its frames, heap, Promise state, host operations, and resource limits. The optional BEAM compiler is an internal, release-quarantined subsystem and is not selected through this public facade.

Execution model and limitations

eval/2 and call/4 create fresh mutable JavaScript state for every request. call/4 runs program initialization and then invokes its named global in that same fresh state; unlike QuickBEAM.call/4, mutations do not persist across calls. Programs and bytecode are locked to the exact vendored QuickJS ABI and must be recompiled after an incompatible upgrade.

The interpreter implements bounded, explicitly tested bytecode and builtin profiles rather than every native QuickJS, browser, Node.js, DOM, WASM, or addon feature. Unsupported behavior fails without native fallback. :memory_limit governs deterministic logical VM allocation, while endpoint BEAM process memory is reported separately by measurement APIs. An evaluation may have at most 64 asynchronous BEAM handler operations outstanding at once. Pinned storage is fixed-capacity, explicitly retired, and never implicitly evicted.

Summary

Functions

Returns the vendored QuickJS bytecode version.

Initializes a fresh isolated heap and calls a named global JavaScript function.

Compiles JavaScript with the vendored QuickJS compiler and returns a verified immutable program.

Decodes and verifies bytecode from this exact QuickJS build.

Evaluates a verified program with the isolated BEAM interpreter.

Returns the exact vendored QuickJS bytecode ABI fingerprint.

Evaluates with the same isolation and limits as eval/2 and returns resource observations in a QuickBEAM.VM.Measurement.

Calls a named global with the same fresh initialization and limits as call/4 and returns resource observations in a QuickBEAM.VM.Measurement.

Pins a verified program in bounded immutable storage.

Unpins a handle after its current evaluations finish.

Types

compile_option()

@type compile_option() ::
  {:filename, String.t()}
  | {:max_bytecode_bytes, pos_integer()}
  | verifier_option()

decode_option()

@type decode_option() :: {:max_bytecode_bytes, pos_integer()} | verifier_option()

error_reason()

@type error_reason() ::
  :invalid_program
  | :invalid_source
  | :invalid_bytecode
  | :invalid_function_name
  | :invalid_arguments
  | :invalid_pinned_program
  | :pinned_program_capacity
  | :pinned_program_unavailable
  | :program_too_large
  | :residency_budget
  | {:invalid_options, term()}
  | {:unknown_option, atom()}
  | {:invalid_option, atom(), term()}
  | {:limit_exceeded, atom(), term()}
  | {:unsupported, term()}
  | {:evaluation_process_exit, term()}
  | tuple()
  | atom()

evaluation_option()

@type evaluation_option() ::
  {:vars, map()}
  | {:handlers, %{optional(String.t()) => ([term()] -> term())}}
  | {:profile, :core | :ssr}
  | {:timeout, pos_integer() | :infinity}
  | {:max_steps, pos_integer()}
  | {:max_stack_depth, pos_integer()}
  | {:memory_limit, pos_integer() | :infinity}
  | {:isolation, :process | :caller}

pinned_program()

@type pinned_program() :: QuickBEAM.VM.Program.Pinned.t()

program()

@type program() :: QuickBEAM.VM.Program.t()

result(value)

@type result(value) :: {:ok, value} | {:error, QuickBEAM.JSError.t() | error_reason()}

verifier_option()

@type verifier_option() ::
  {:max_atoms, pos_integer()}
  | {:max_constants_per_function, pos_integer()}
  | {:max_function_depth, pos_integer()}
  | {:max_functions, pos_integer()}
  | {:max_instructions, pos_integer()}
  | {:max_stack_size, pos_integer()}

Functions

bytecode_version()

@spec bytecode_version() :: non_neg_integer()

Returns the vendored QuickJS bytecode version.

call(program, name, arguments \\ [], opts \\ [])

Initializes a fresh isolated heap and calls a named global JavaScript function.

Program initialization runs before every call, so globals mutated by one call are not visible to the next. Arguments and Promise results use the same value conversion, asynchronous handlers, isolation, and resource limits as eval/2. Missing globals produce ReferenceError; non-callable globals produce TypeError.

compile(source, opts \\ [])

@spec compile(String.t(), [compile_option()]) :: result(program())

Compiles JavaScript with the vendored QuickJS compiler and returns a verified immutable program.

Compilation uses a short-lived bare native runtime. Supported options are :filename, :max_bytecode_bytes, and the bounded verifier limit options. Use decode/2 when bytecode has already been compiled by this exact QuickJS build.

decode(bytecode, opts \\ [])

@spec decode(binary(), [decode_option()]) :: result(program())

Decodes and verifies bytecode from this exact QuickJS build.

The :max_bytecode_bytes option and bounded verifier limits can only reduce the built-in maximums; unknown options fail explicitly.

eval(program, opts \\ [])

Evaluates a verified program with the isolated BEAM interpreter.

Supported options are :vars, asynchronous :handlers, builtin :profile, :timeout, :max_steps, :max_stack_depth, :memory_limit, and :isolation. The default isolation: :process provides timeout, process-heap, and failure containment. isolation: :caller is only for trusted diagnostics.

fingerprint()

@spec fingerprint() :: String.t()

Returns the exact vendored QuickJS bytecode ABI fingerprint.

measure(program, opts \\ [])

Evaluates with the same isolation and limits as eval/2 and returns resource observations in a QuickBEAM.VM.Measurement.

Evaluation failures are stored in measurement.result. Invalid programs or options return directly as {:error, reason} because no evaluation started.

measure_call(program, name, arguments \\ [], opts \\ [])

Calls a named global with the same fresh initialization and limits as call/4 and returns resource observations in a QuickBEAM.VM.Measurement.

Call failures are stored in measurement.result. Invalid names, arguments, programs, or options return directly because no evaluation started.

pin(program)

Pins a verified program in bounded immutable storage.

The default store has eight fixed slots. Serialized bytecode is limited to 2 MiB, decoded external-term residency to 32 MiB per program, and total residency to 128 MiB. Concurrent pins of the same program identity are idempotent and return the same lightweight handle. The application-supervised store restores valid slots after its own restart; call unpin/1 explicitly when the lifecycle owner no longer needs the program.

unpin(pinned)

@spec unpin(QuickBEAM.VM.Program.Pinned.t()) ::
  :ok | {:error, :pinned_program_unavailable | :invalid_pinned_program}

Unpins a handle after its current evaluations finish.

Returns {:error, :pinned_program_unavailable} when the handle is stale. Because pins are idempotent by program identity rather than ownership-counted, one lifecycle owner should coordinate pinning and unpinning.