Instruction Reference

This page documents every instruction in the BearVM IR. Syntax shown here reflects what the interpreter actually accepts, as demonstrated by working sample programs.

Control Flow

jmp <label>

Unconditional jump to the named label:

jmp loop_cond
br_if <cond> <true_label> <false_label>

Conditional branch. Jumps to true_label if cond is non-zero or true, otherwise jumps to false_label:

%cond = lt %i, %n
br_if %cond, loop_body, loop_end
ret <expr>

Returns a value from the current function:

ret %result
ret 0
call <func_name>(<args>)

Calls a user-defined or builtin function:

%result = call fib(%n)
call puts("hello")

Assignment

%reg = <expr>

Assigns the result of an expression to a register:

%x = const 10
%y = add %x, 1
set %reg.<field> = <expr>

Sets a field on a struct value held in a register:

set %p.age = add %p.age, 1
%reg = phi [<label>: %reg, ...]

Selects a value based on the predecessor block. Used at control flow merge points in explicit SSA form:

%a = phi [entry: %a0, loop_body: %a_next]

Arithmetic

Arithmetic instructions operate on int, float, and double values.

add <a>, <b>

Returns a + b:

%res = add %a, %b
%sum = add %f1, %f2
sub <a>, <b>

Returns a - b:

%n1 = sub %n, 1
mul <a>, <b>

Returns a * b.

div <a>, <b>

Returns a / b, truncated toward zero for int. Raises DivisionByZero if b is zero.

Type Casts

cast <type> <reg>

Converts a value to the specified type. Supported types are int, float, and double:

%dbl            = cast double %sum
%back_to_float  = cast float %dbl
%int_from_float = cast int %f_result

Any numeric type can be cast to any other numeric type.

Comparison

Comparison instructions return a boolean result that can be used with br_if or while.

lt <a>, <b>

True if a < b:

%cond = lt %i, %n
gt <a>, <b>

True if a > b.

le <a>, <b>

True if a <= b:

%cond0 = le %n, 1
ge <a>, <b>

True if a >= b.

eq <a>, <b>

True if a == b. Supports both int and string.

Memory

See Memory Model for a conceptual overview of BearVM’s memory model.

alloc <size_or_type>

Allocates memory on the heap. The argument may be a byte size or a struct type name:

%buf = alloc 16
%p   = alloc Person

Returns a pointer or reference to the allocated memory. Memory is zero-initialised.

free <reg>

Frees a heap-allocated pointer or array reference:

free %buf
free %p
alloc_array <type> <count>

Allocates an array of count elements of the given type. Supported element types are int, bool, and string:

%arr = alloc_array int, 5
store <ref>, <expr>

Stores a value into a reference:

store %age_ref, 42
store %p_ptr, { name: "Alice", age: 25 }
load <ref>

Loads the value from a reference:

%age_val = load %age_ref
get_field_ref <ptr>, <field>

Returns a reference to a named field of a heap-allocated struct:

%age_ref = get_field_ref %p, age
get_index_ref <arr>, <idx>

Returns a reference to an element of an array. Raises IndexOutOfBounds if the index is out of range:

%elem_ptr = get_index_ref %arr, %i

Arena Allocation

See Memory Model for arena usage patterns.

arena_create

Creates a new arena and returns an arena ID:

%arena = arena_create
arena_alloc <arena> <size>

Allocates size bytes from the given arena:

%a = arena_alloc %arena, 64
arena_destroy <arena>

Destroys the arena and frees all memory allocated within it:

arena_destroy %arena

Concurrency

See Concurrency for a full description of the task model.

spawn call <func>(<args>)

Spawns a new thread running the given function. Returns a task handle:

%task1 = spawn call fib(%n1)
sync <task>

Blocks until the task completes and returns its result:

%r1 = sync %task1

Loop Sugar

while (<cond>) { <body> }

Executes body repeatedly while cond is truthy. Lowers to explicit basic blocks and branches internally:

while (lt %i, %n) {
    %i = add %i, 1
}

Error Conditions

The following runtime errors can be raised by instructions:

  • DivisionByZerodiv with a zero divisor.

  • NoSuchField — field access on a struct that does not have that field.

  • NotAStruct — field access on a non-struct value.

  • NotAPointerload or store on a non-pointer value.

  • InvalidFreefree on an invalid pointer.

  • InvalidArenaarena_alloc or arena_destroy with an invalid arena ID.

  • IndexOutOfBoundsget_index_ref with an out-of-range index.

  • InvalidArrayPointerget_index_ref on a non-array value.

  • UnknownTypealloc with an undefined type name.

  • UndefinedFunction — call to a function that does not exist.

  • UndefinedLabel — jump to a label that does not exist.

  • PhiWithNoPredecessorphi evaluated without predecessor context.

  • PhiNoMatchingArmphi with no arm matching the predecessor label.

  • TypeMismatch — type error in an operation.

  • TooManyArguments — more than 32 arguments passed to a function.

  • NoMainFunction — program does not define a @main function.