Rev. 1.2
October 1997
Each call frame on the stack starts with a return-address pointer, CP, followed by local variables which are accessed by integer offset from a pointer to the top of the stack. Frames are allocated only after a clause guard is evaluated and if the clause body contains local variables and function calls. Frames are allocated and discarded by the A_op and D_op instructions with explicitly given frame size N. For garbage collection purposes the stack structure can be obtained by looking for stored return addresses. A call frame can contain as well catch resumption addresses (see the Catch instruction) and next-instruction pointers (see the C instruction).
The Erlang BEAM system allows mixing threaded code emulation with compiling into C. When an Erlang function compiled to C is called, the next instruction pointer, I, is stored in the current local frame and the CP pointer is set to the emulator code which would restore the I pointer upon return from the called function.
The value part of an atom is an index into a global atom table where the atom is represented. The value part of a small integer is the integer itself. The value part of a big number integer is a pointer to a heap object containing the integer sign and number of words building the integer value. The value part of a list is a pointer to two consecutive heap locations with two tagged objects (the head and tail of the list). The value part of a tuple is a pointer to a heap object containing tuple size followed by the tuple elements. The value part of a float is a pointer to a heap object containing a two-word float value. The value part of a process identifier is the process identifier itself.
The current BEAM implementation uses the following tags:
#define SMALL 15 /* small integer */ #define BIG 11 /* big integer pointer */ #define FLOAT 9 /* float pointer */ #define ATOM 7 /* atom */ #define REFER 6 /* reference */ #define PORT 5 /* port */ #define PID 3 /* process identifier */ #define TUPLE 2 /* tuple pointer */ #define NIL (BIG + 16) /* empty list */ #define LIST 1 /* list pointer */ #define ARITYVAL 10 /* tuple arity */ #define MOVED 12 /* moved heap pointer */ #define CATCH THING /* resumption address */ #define THING 13 /* float value */ #define BINARY 14 /* binary pointer */ #define BLANK ARITYVAL /* blank local var */ #define IC SMALL /* next instr. pointer */ #define CP0 0 /* CP pointer */ #define CP4 4 /* CP pointer */ #define CP8 8 /* CP pointer */ #define CP12 12 /* CP pointer */Since some data objects can reside only on heap or stack the same tag can be used for two different objects (CATCH and THING, BLANK and ARITYVAL). There are some other cases when the same tag can be reused. Since objects representing the big-number integers are tagged heap pointers, the BIG flag can be used as well to represent an empty list, NIL (since the NIL value part becomes a non valid heap pointer).
The CP tags are reserved for the return-address pointer, CP. The pointer does not have to be tagged if on the current platform the pointer has always the two last bits set to 0.
To receive messages each process has its own local message queue. Sending a message results in copying the message into the receiver heap and storing the message reference in the receiver message queue. While waiting for messages to be received a process is swapped out, and is added to the scheduler queue only when a new message is received (i.e. the addition is done by a process sending the message), or a time-out occurs.
|
|
|
|
Opcode values less than 255 are coded as one byte, opcode values larger than 255 are coded as two bytes (255 and the rest). Module, function, atom names and floating point numbers are coded as a list of ASCII values preceded by the length of the list.
It means that operands in the byte-code syntax diagram can have different size due to their type:
Threaded-code Syntax (produced by the BEAM loader while loading the
compiled byte code):
|
|
|
|
The label address (four bytes) is an address of the corresponding emulator code. After loading, atoms and small integers are ready created (index in atom table + TAG, integer value + TAG). After loading all operands are four-bytes long (one 32-bit word). When an operand is NIL or a temporal variable x(0), only one word is used. When an operand is a temporal variable x(N) or a local variable y(N) the first word indicates type of the variable (X_arg or Y_arg) and the second its index N. For efficiency purposes in many instructions types of operands are implicitly coded as the instructions opcodes. Each line in the threaded-code syntax diagram represents a 32-bit word.
When a threaded-code syntax corresponds to a byte-code syntax (only instruction opcode is changed to a label address and operands are build, &FuncBegin is added, or instruction offset is changed to instruction address for branch purposes), only the threaded-code syntax is given.
Byte-code Syntax:
|
|
|
|
Threaded-code Syntax: none (the instruction is removed by loader)
code size is a total size (in 32-bit words)of the compiled module code after loading
module name is an atom name corresponding to the name of the module
magic number is used to prevent loading of old format code (is checked against the loader magic number while loading)
Byte-code Syntax:
|
|
|
Threaded-code Syntax:
|
|
|
|
module_name, function_name are ready created atoms.
Generate the current context information (the current module, function and arity), set the BADMATCH error, branch to error handling procedure.
The FuncBegin instruction starts each compiled Erlang function. To save space the context information provided is reused by other instructions. When an Erlang function is called the first instruction after FuncBegin is executed.
CO: Call a local Erlang function. The continuation program pointer (CP register) is already set.
ResC: Call a resident Erlang function. A resident Erlang function is a local function which cannot be called from and return to other modules. The instruction is used to optimize control handling when a threaded-code Erlang function cannot be mixed with other Erlang functions compiled into C code.
Byte-code Syntax:
|
|
|
Threaded-code Syntax:
|
|
|
|
&function is an address of the first instruction corresponding to the called function (more precisely the first instruction after corresponding FuncBegin).
function_arity is a number of function arguments.
&FuncBegin is an address of the current function FuncBegin instruction.
C: Store pointer to the next instruction in the current stack frame. Set the continuation program pointer at the emulator code restoring the next instruction pointer, increment number of reductions and check for suspension (if suspending, generate the current module, function and arity information using &FuncBegin), branch to called function.
CO: As above but the continuation program pointer is already set in the CP register (the instruction is used when the last function in the body is called and there is no stack frame to be discarded).
ResC: Set the continuation program pointer at the next instruction, increment number of reductions and check for suspension (if suspending, generate the current module, function and arity information using &FuncBegin), branch to called function.
Byte-code Syntax:
|
|
|
|
Threaded-code Syntax:
|
|
|
|
|
frame_size is a size of the current stack frame to be discarded.
For info on other operands see C/CO.
Copy the continuation program pointer from the current stack frame into CP, discard the frame, increment number of reductions and check for suspension, branch to called function.
TrCO: A traced version of the CO instruction.
Byte-code Syntax:
|
|
|
Threaded-code Syntax:
|
|
|
|
|
function_name is an atom corresponding to the called function name; used to generate some information for tracing purposes.
For info on other operands see C/CO.
The same semantics as C/CO but some trace information (the called function module, name, arity) is sent to a tracing Erlang process.
Byte-code Syntax:
|
|
|
|
Threaded-code Syntax:
|
|
|
|
|
|
function_name is an atom corresponding to the called function name; used to generate some information for tracing purposes.
For info on other operands see TrCL.
The same semantics as CL but some trace information (the called function module, name, arity) is sent to a tracing Erlang process.
Byte-code Syntax:
|
|
|
|
Threaded-code Syntax:
|
|
|
|
|
module_name, function_name, function_arity define the external function to be called.
&FuncBegin is an address of the current function FuncBegin instruction.
CEx: Set the continuation program pointer at the next instruction, increment number of reductions and check for suspension (if suspending, generate the current module, function and arity information using &FuncBegin), check if the called function is loaded, if yes branch to the called function (the address is taken from the export-function table), if not call an error handler.
TrCEx: The same semantics as CEx but some trace information (the called function: module, name, arity) is sent to a tracing Erlang process.
Byte-code Syntax:
|
|
|
|
|
Threaded-code Syntax:
|
|
|
|
|
|
frame_size is a size of the current stack frame to be discarded.
For info on other operands see CEx/TrCEx.
CExL: Copy the continuation program pointer from the current stack frame into CP, discard the frame, increment number of reductions and check for suspension, check if the called external function is loaded, branch to the function.
TrCExL: The same semantics as CExL but some trace information (the called function: module, name, arity) is sent to a tracing Erlang process.
ResR: Return from a resident Erlang function call.
Threaded-code Syntax:
|
R: Restore the next instruction pointer from the current stack frame. Return control to the function caller.
ResR: Go to instruction which address is stored in the CP register.
Threaded-code Syntax:
|
|
The same semantics as R but some trace information (the function we return to: module, name, arity) is sent to a tracing Erlang process.
Threaded-code Syntax:
|
|
Generate the current context information using the &FuncBegin pointer, set the FUNCTION_CLAUSE error, branch to error handling procedure.
Threaded-code Syntax:
|
|
|
n is a number of live temporal variables x(0), ..., x(n-1) (for garbage collection purposes).
Check for required stack space, call garbage collection if necessary. Allocate a new stack frame (of frame_size). Update the stack-top pointer E. Copy the continuation program pointer CP into the new frame.
Threaded-code Syntax:
|
|
n is an index of a local variable y(n) which must be explicitly initialized.
Initialize a local variable y(n).
Threaded-code Syntax:
|
|
Copy the continuation program pointer from the current stack frame into CP, discard the frame. Update the stack-top pointer E.
Threaded-code Syntax:
|
|
|
m is a size of required heap space (in words).
n is a number of live temporal variables x(0), ..., x(n-1) (for garbage collection purposes).
Check for required heap space, call garbage collection if necessary.
Threaded-code Syntax:
|
|
|
|
|
|
|
type indicates sort of the following operand: X_arg - a temporal variable, Y_arg - a local variable, C_arg - a constant (atom, NIL, or a small integer). Depending on its type, an operand can be an index (for X_arg and Y_arg) or ready created Erlang data object (for C_arg).
Having head and tail build a new list. Set list to the new created data object. Update the heap-top pointer, HTOP.
Threaded-code Syntax:
|
|
|
|
PL_<type> has the same semantics as the PL instruction. The only difference is that types of all operands are coded implicitly as instruction opcode. For example PL_xyx means that the first and the third operands are temporal variables while the second operand is a local variable. The decision which types are coded as specialized instructions has been based on their frequency in existing large industrial applications.
Threaded-code Syntax:
|
|
|
|
|
|
|
string_length is the length of the included string (number of string elements).
string_elements<i> is a 32-bit word consisting of four string elements (each 8-bit long). Depending on string_length the last string_elements<i> can be shorter.
type indicates sort of the following operand.
Having a string of a given length, build a new list consisting of the string elements. Set list to the new created data object. Update the heap-top pointer, HTOP.
Threaded-code Syntax:
|
|
|
|
pointer is a pointer to the being created big number integer.
arity gives a number of following words with the big number value.
sign is the big number sign.
Create an initial l structure for a big number integer. The instruction is followed by an arity number of PIntVal instructions. Set pointer to the new created data object. Update the heap-top pointer. The type of pointer is implicitly coded as instruction opcode.
Threaded-code Syntax:
|
|
value is a word being part of a big number integer value.
Put a value word on a process heap. The instruction must be preceded by the PInt_<type> instruction or other PIntVal instructions. Update the heap-top pointer.
Threaded-code Syntax:
|
|
|
|
value0 and value1 build the double float value.
Put value0 and value1 on a process heap. Set pointer to the new created data object. Update the heap-top pointer. The type of pointer is implicitly coded as instruction opcode.
Threaded-code Syntax:
|
|
|
tuple is a pointer to the being created tuple data object.
arity gives a number of following tuple elements.
Create an initial structure for a tuple data object. The instruction is followed by an arity number of PTEl_<type> instructions. Set the tuple pointer to the new created object. Update the heap-top pointer. The type of tuple is implicitly coded as instruction opcode.
Threaded-code Syntax:
|
|
element is a tuple element to be put on heap.
Put a tuple element on a process heap. The instruction must be preceded by the PT0_<type> instruction or other PTEl_<type> instructions. Update the heap-top pointer. The type of element is implicitly coded as instruction opcode.
Threaded-code Syntax:
|
|
|
|
list is a pointer to existing list.
head and tail are pointers to respectively head and tail.
Having a given list set the head pointer to its head and tail to its tail. Types of all operands are coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
tuple is a pointer to existing tuple.
arity is the required arity.
The instruction occurs only in a clause/case/if/receive body. Having a given tuple check its arity. If not equal the required one (arity), generate the current context information (using &FuncBegin), set the BADMATCH error, and branch to error handling procedure. Type of tuple is coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
address is a branch address in a case of failure.
tuple is a pointer to existing tuple.
arity is the required arity.
The instruction occurs only in a clause/case/if/receive head. Having a given tuple check its arity. If not equal the required one, branch to the next clause/option using address. Type of tuple is coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
tuple is a pointer to existing tuple.
element is a tuple element with required index.
Get a tuple element with required index. The instruction must be preceded by the GTp_<type> or GTp_head_<type> instruction. Types of tuple and element are coded implicitly as instruction opcode.
<Test0> succeeds if a data object is:
Threaded-code Syntax:
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
object is an existing Erlang data object.
The instruction occurs only in a clause/case/if/receive body. Having a given data object check its type. In a case of failure, generate the current context information (using &FuncBegin), set the BADMATCH error, and branch to error handling procedure. Type of object (X_arg, Y_arg, C_arg) is coded implicitly as instruction opcode.
<Test1> succeeds if a data object is:
Threaded-code Syntax:
|
|
|
address is a branch address in a case of failure.
object is an existing Erlang data object.
The instruction occurs only in a clause/case/if/receive head. Having a given data object check its type. In a case of failure, branch to next clause/option using address. Type of object (X_arg, Y_arg, C_arg) is coded implicitly as instruction opcode.
<Test2> succeeds if a data object is:
Threaded-code Syntax:
|
|
|
address is a branch address in a case of failure.
object is an existing Erlang data object.
The instruction occurs only in a clause/case/if/receive guard. Having a given data object check its type. In a case of failure, branch to next clause/option using address. Type of object (X_arg, Y_arg, C_arg) is coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
object is an internal data object.
register is a temporal or local variable.
Move an internal data object (can be of type X_arg, Y_arg, C_arg) to a temporal or local variable (X_arg or Y_arg). Types of operands are coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
object is an internal data object.
Throw an internal data object (can be of type X_arg, Y_arg, C_arg). When a Throw is executed the stack is searched for a saved resumption address (set by Catch), the top-of-stack pointer is reset to point at the found call frame and the execution continues there. If there is no resumption address on the stack (a process catch counter is zero), the current context information is generated (using the &FuncBegin pointer), the THROWN error is set, and the control is transfered to error handling procedure.
Threaded-code Syntax:
|
|
|
index is a place in the local frame when a resumption address &CatchEnd is saved.
&CatchEnd is a catch resumption address.
Save a resumption address &CatchEnd in the local frame at position with index offset. Increment a process catch counter. The instruction is followed by a CatchEnd instruction. By followed we mean that the CatchEnd instruction is put after corresponding Erlang Expression the catch protects from errors.
Threaded-code Syntax:
|
|
index is a place in the local frame when a resumption address &CatchEnd was saved.
Clear a resumption address stored in the local frame at position with index offset. Decrement a process catch counter. The instruction is preceded by a matching Catch instruction (see Catch for further details).
Threaded-code Syntax:
|
|
|
|
|
|
type indicates sort of the following operand (X_arg, Y_arg, C_arg).
address is the address of the message being sent (can be an Erlang process or port).
message is an internal data object containing the message.
Having a given message send it to a given address. If the address is not valid, call an Erlang error handler. If while sending to a remote node the corresponding communication channel is busy, suspend for a certain period of time and try later. When suspending, generate the current context information using &FuncBegin.
rec: Rec (set a message pointer) loop: loopRec (fetch the message) pattern: match the message against required pattern if matched then RmMsg (remove the message from the mailbox, mark all other messages as untried, if the timeout has been set then clear the timeout) evaluate given action TPattEnd (goto next instruction after receive) else if there are more patterns to be matched then goto pattern (try the next pattern) else loopRecEnd (mark the current message as tried, if there are more messages then update message pointer, goto loop (try the next message)) WaitTOut (if there is given timeout and the timeout is not set set the required timeout and suspend) Wait (suspend)If there are no matching messages the process suspends until a new message is received or a timeout occurs, then the process is rescheduled for execution.
if a new message is received then goto rec (set a message pointer) else if a timeout occurs then goto timeout (evaluate given timeout action) else remain suspended
timeout: TimeOut (mark all messages as untried) evaluate given timeout action TPattEnd (goto next instruction after receive)Depending on the context set a message pointer can mean set the pointer to the first message in the mailbox (when the receive primitive is entered for the first time), or set the pointer to the first new received, untried, message (when a new message is received and the suspended process is rescheduled for execution).
Threaded-code Syntax:
|
The Rec instruction is executed when an Erlang process enters the receive primitive for the first time (the message pointer is set to the first message in the mailbox) or the suspended process is rescheduled for execution (the pointer is set to the first new received, untried, message).
Threaded-code Syntax:
|
|
|
&wait is a branch address in a case of no more messages to be matched.
index is a place in the local frame where a being matched message is saved.
Check the message pointer, if NIL (no more messages) branch to the Wait or WaitTOut instruction for suspension. Otherwise save the message in the local variable, y(index), before matching. The instruction is followed by other instructions for the required matching, and a loopRecEnd instruction. The loopRecEnd instruction is put after all instructions doing the required pattern matching.
Threaded-code Syntax:
|
|
&loopRec is an address of the corresponding loopRec instruction.
Update the message pointer, branch to the corresponding loopRec instruction (try the next message). The instruction is preceded by a matching loopRec instruction (see loopRec for further details).
Threaded-code Syntax:
|
|
|
&rec is an address of the corresponding Rec instruction.
There are no matching messages in the mailbox and the current Erlang process is suspended. When the process is rescheduled later for execution the next-instruction pointer is set to the &rec address. When suspending, generate the current context information using &FuncBegin.
Threaded-code Syntax:
|
|
|
|
|
&rec is an address of the corresponding Rec instruction.
type indicates sort of the following operand (X_arg, Y_arg, C_arg).
time contains the required timeout value.
The same semantics as Wait with the difference that the required timeout is set first. The timeout is set only once when the receive primitive is entered for the first time. The instruction is part of receive augmented with a timeout.
Threaded-code Syntax:
|
Remove a matched message from a process mailbox. The RmMsg instruction is executed when a fetched message is successfully matched and a corresponding action is going to be evaluated. All other messages are marked as untried. The instruction clears the previously set timeout (if any).
Threaded-code Syntax:
|
Mark all messages in the current mailbox as untried. The TimeOut instruction is executed when a timeout occurs and the messages must be marked as untried for future receives.
Threaded-code Syntax:
|
|
&instruction is an instruction address.
Set the next-instruction pointer to &instruction and branch to it. The TPattEnd instruction is used to transfer control when one of the alternatives in receive/case/if primitive is ready evaluated. &instruction points to the first instruction after the primitive.
Threaded-code Syntax:
|
|
|
|
type indicates sort of the following operand (X_arg, Y_arg, C_arg).
object is an internal data object being matched.
The instruction is executed when there are no matching case patterns. Generate the current context information using &FuncBegin, set the CASE_CLAUSE error, generate information about the object being matched, branch to error handling procedure.
Threaded-code Syntax:
|
|
The instruction is executed when there are no succeeding if guards. Generate the current context information using &FuncBegin, set the IF_CLAUSE error, branch to error handling procedure.
Threaded-code Syntax:
|
|
|
bif is a bif-table index.
ret is an internal data object.
Given a bif-table index, bif, execute a corresponding build-in function. Put the result in the ret object. Type of the object (X_arg or Y_arg) is coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
|
bif is a bif-table index.
address is a branch address in a case of failure.
arg and ret are internal data objects.
Given a bif-table index, bif, and argument, arg, execute a corresponding build-in function. Put the result in the ret object. In a case of failure, if the built-in function occurs in a guard, branch to the next clause/option using address. If the function occurs in a body (address points to the corresponding FuncBegin), the current context information is generated and the error handling procedure is called. The error information is set by the failing build-in function. Types of arg and ret are coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
|
|
|
|
|
bif is a bif-table index.
address is a branch address in a case of failure.
type indicates sort of the following operand.
arg0, arg1, and ret are internal data objects.
The same semantics as Bif_1_<type> with the difference that the built-in function is called with two arguments and types of all operands are explicitly given.
Threaded-code Syntax:
|
|
|
|
|
|
|
|
|
|
|
bif is a bif-table index.
address is a branch address in a case of failure.
type indicates sort of the following operand.
arg0, arg1, arg2 and ret are internal data objects.
Given a bif-table index, bif, and arguments: arg0, arg1, and arg2 execute a corresponding build-in function. Put the result in the ret object. In a case of failure, if the built-in function occurs in a guard, branch to the next clause/option using address. If the function occurs in a body (address points to the corresponding FuncBegin), the current context information is generated and the error handling procedure is called. The error information is set by the failing build-in function.
Threaded-code Syntax:
|
|
|
|
|
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
type indicates sort of the following operand.
module, func, and arg_list are internal data objects.
Call apply(module,func,arg_list). Put the result in x(0). In a case of failure, generate the current context information and branch to error handling procedure. The error information is set by the failing build-in function.
Threaded-code Syntax:
|
|
|
|
|
|
address is a branch address in a case of failure.
type indicates sort of the following operand.
list and hd/tl are internal data objects.
Given a list, list, extract its head/tail. Put the result in the hd/tl object. In a case of failure, if the built-in function occurs in a guard, branch to the next clause/option using address. If the function occurs in a body (address points to the corresponding FuncBegin), the current context information is generated and the error handling procedure is called. The error information is set by the failing build-in function.
<Bif0> can be the following:
Threaded-code Syntax:
|
|
|
type indicates sort of the following operand.
ret is an internal data object.
Call a given built-in function. Put the result in the ret object.
Threaded-code Syntax:
|
|
|
|
|
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
type indicates sort of the following operand.
arg0, arg1, and ret are internal data objects.
Call check_process_code(arg0,arg1) or exit(arg0,arg1). Put the result in ret. In a case of failure, generate the current context information and branch to error handling procedure. The error information is set by the failing build-in function.
Threaded-code Syntax:
|
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
type indicates sort of the following operand.
arg0 is an internal data object.
Call exit(arg0). &FuncBegin is used to generate required context information.
Threaded-code Syntax:
|
|
|
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
type indicates sort of the following operand.
arg0 and ret are internal data objects.
Call garbage_collect(arg0). Put the result in ret. In a case of failure, generate the current context information and branch to error handling procedure. The error information is set by the failing build-in function.
Threaded-code Syntax:
|
Call halt().
Threaded-code Syntax:
|
|
|
|
|
|
|
|
|
address is a branch address in a case of failure.
op is a given operator (+, -, *).
type indicates sort of the following operand.
arg0, arg1, and ret are internal data objects.
Having an operator, op, and its arguments arg0 and arg1 evaluate the required floating point arithmetic. Put the result in ret. In a case of failure, if the arithmetic expression occurs in a guard, branch to the next clause/option using address. If the expression occurs in a body (address points to the corresponding FuncBegin), the current context information is generated, the BADARITH error is set and the error handling procedure is called.
Threaded-code Syntax:
|
|
|
|
|
|
|
|
address is a branch address in a case of failure.
type indicates sort of the following operand.
arg0, arg1, and ret are internal data objects.
Having two floating point arguments, arg0 and arg1, evaluate a floating point division. Put the result in ret. In a case of failure, if the arithmetic expression occurs in a guard, branch to the next clause/option using address. If the expression occurs in a body (address points to the corresponding FuncBegin), the current context information is generated, the BADARITH error is set and the error handling procedure is called.
Threaded-code Syntax:
|
|
|
|
|
|
|
|
op is a given operator (+, -, *).
type indicates sort of the following operand.
arg0, arg1, and ret are internal data objects.
Having an operator, op, and its integer arguments arg0 and arg1 evaluate the required arithmetic. Put the result in ret.
Threaded-code Syntax:
|
|
|
|
arg0, arg1, and ret are internal data objects.
Having an operator and its integer arguments arg0 and arg1 evaluate the required arithmetic. Put the result in ret. The operator and types of operands are coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
|
address is a branch address in a case of failure.
arg1 is a small integer.
arg0, and ret are internal data objects.
Having an operator and its arguments (the second argument is a small integer) check if the result is a small integer (by checking the first argument). If not, call a general purpose C-function doing the arithmetic. If yes, evaluate the arithmetic expression directly in the emulator. Put the result in ret. In a case of failure, if the arithmetic expression occurs in a guard, branch to the next clause/option using address. If the expression occurs in a body (address points to the corresponding FuncBegin), the current context information is generated, the BADARITH error is set and the error handling procedure is called. Types of arg0 and ret are coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
|
|
address is a branch address in a case of failure.
type indicates sort of the following operand.
arg0 and ret are internal data objects.
Having an arguments, arg0, evaluate a bitwise not arithmetic. Put the result in ret. In a case of failure, if the arithmetic expression occurs in a guard, branch to the next clause/option using address. If the expression occurs in a body (address points to the corresponding FuncBegin), the current context information is generated, the BADARITH error is set and the error handling procedure is called.
Threaded-code Syntax:
|
|
|
|
|
|
|
address is a branch address in a case of failure.
type indicates sort of the following operand.
arg0 and arg1 are internal data objects.
Having a comparison operator, cmp, and its arguments, arg0 and arg1, perform the required term comparison. In a case of failure, branch to the next clause/option using address.
Threaded-code Syntax:
|
|
|
|
|
|
address is a branch address in a case of failure.
type indicates sort of the following operand.
arg0 and arg1 are internal data objects.
Having two arguments, arg0 and arg1, perform the required term comparison (ExEqEq_head: =:=; ExNEq: =/=). When arguments are small integers or atoms the exact not equal comparison, NEql, and the exact equal comparison, Eql, are done directly in the emulator. In a case of failure, branch to the next clause/option using address.
Threaded-code Syntax:
|
|
|
|
address is a branch address in a case of failure.
arg0 and arg1 are internal data objects.
Eql_head_<type> has the same semantics as the Eql_head instruction. The only difference is that types of all operands are coded implicitly as instruction opcode. Which types are coded as specialized instructions has been based on their frequency in existing large industrial applications.
Threaded-code Syntax:
|
|
|
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
type indicates sort of the following operand.
arg0 and arg1 are internal data objects.
Having two arguments, arg0 and arg1, perform the exact equal, =:=, term comparison. When arguments are small integers or atoms the comparison is done directly in the emulator (Eql). In a case of failure, generate the current context information using &FuncBegin, set the BADMATCH error, generate information about the object being matched, and branch to error handling procedure.
Threaded-code Syntax:
|
|
|
|
|
|
|
|
|
type indicates sort of the following operand.
arg0 is an internal data object.
size is a size of the included jump table (N+1).
value<i> is an integer value.
address<i> is a branch address in a case of value match.
Having arg0 check its value against values in a given jump table, in a case of match branch to the corresponding instruction (using address<i>). To enable a binary search the values are sorted when the instruction is generated. If there are no matches found, the next instruction is picked.
Threaded-code Syntax:
|
|
|
|
|
|
|
type indicates sort of the following operand.
arg0 is an internal data object.
size is a size of the included jump table (N+1).
address<i> is a branch address in a case of value match.
Having arg0 check its value against size of a given jump table. If the value is less or equal the given size, the corresponding branch address is used. If not, the next instruction is picked.
Byte-code Syntax:
|
|
|
|
|
|
|
|
|
Threaded-code Syntax:
|
|
|
|
|
|
|
|
|
type indicates sort of the following operand.
arg0 is an internal data object.
size is a size of the included jump table (N+1).
atom<i> is a ready created atom.
address<i> is a branch address in a case of value match.
Having arg0 check it against atoms in a given jump table, in a case of match branch to the corresponding instruction (using address<i>). To enable a binary search the atoms are sorted when the instruction is loaded and the atoms are built. If there are no matches found, the next instruction is picked.
Threaded-code Syntax:
|
|
|
|
m is a size of required heap space (in words).
n is a number of live temporal variables x(0), ..., x(n-1) (for garbage collection purposes).
Check for required stack and heap space, call garbage collection if necessary. Allocate a new stack frame. Update the stack-top pointer E. Copy the continuation program pointer CP into the new frame.
Threaded-code Syntax:
|
|
|
|
tuple is a pointer to the being created tuple data object.
arity gives a number of following tuple elements.
element is the tuple first element.
Create an initial structure for a tuple data object. Build the first tuple element. Set the tuple pointer to the new created object. Update the heap-top pointer. The type of tuple is implicitly coded as instruction opcode.
Threaded-code Syntax:
|
|
object is an internal data object.
Move an internal data object, object (can be of type X_arg, Y_arg, C_arg) to x(0) and return control to the function caller.
Threaded-code Syntax:
|
|
|
object is an internal data object.
frame_size is a size of the current stack frame to be discarded.
Move an internal data object, object, to x(0). Copy the continuation program pointer from the current stack frame into CP and discard the frame. Update the stack-top pointer E. Return control to the function caller.
Threaded-code Syntax:
|
|
frame_size is a size of the current stack frame to be discarded.
Copy the continuation program pointer from the current stack frame into CP and discard the frame. Update the stack-top pointer E. Return control to the function caller.
Threaded-code Syntax:
|
|
|
|
&FuncBegin is an address of the current function FuncBegin instruction.
object is an existing Erlang data object.
arity is the required arity.
The instruction occurs only in a clause/case/if/receive body. Having a given data object check if it is a tuple of arity arity. In a case of failure, generate the current context information, set the BADMATCH error, and branch to error handling procedure. Type of object is coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
address is a branch address in a case of failure.
object is an existing Erlang data object.
arity is the required arity.
The instruction occurs only in a clause/case/if/receive head. Having a given data object check if it is a tuple of arity arity. In a case of failure branch to the next clause/option using address. Type of object is coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
|
address is a branch address in a case of failure.
object is an existing Erlang data object.
frame_size is the required frame size.
n is a number of live temporal variables x(0), ..., x(n-1) (for garbage collection purposes).
The instruction occurs only in a clause/case/if/receive head. Having a given data object check if it is a non-empty list/an integer. If yes, allocate a new stack frame (of frame_size). If not, branch to the next clause/option using address. Type of object is coded implicitly as instruction opcode.
Threaded-code Syntax:
|
|
|
|
index<i> is an index of a local variable y(index<i>) which must be explicitly initialized.
Initialize a number of local variables y(index<i>). Due to some compiler optimizations the indexes are not necessarily a sequence of numbers.
Threaded-code Syntax:
|
|
|
|
|
|
frame_size is the required frame size.
n is a number of live temporal variables x(0), ..., x(n-1) (for garbage collection purposes).
index<i> is an index of a local variable y(index<i>) which must be explicitly initialized.
Allocate a new stack frame (of frame_size). Initialize a number of local variables y(index<i>). Due to some compiler optimizations the indexes are not necessarily a sequence of numbers.
Byte-code Syntax:
|
|
|
|
Threaded-code Syntax:
|
|
|
|
|
object is an internal data object.
&function is an address of the first instruction corresponding to the called function.
function_arity is a number of function arguments.
&FuncBegin is an address of the current function FuncBegin instruction.
Move an internal data object, object, to x(0). Set the continuation program pointer at the next instruction, increment number of reductions and check for suspension (if suspending, generate the current context information), branch to called function. Type of object is coded implicitly as instruction opcode.
Byte-code Syntax:
|
|
|
|
|
Threaded-code Syntax:
|
|
|
|
|
|
object is an internal data object.
frame_size is a size of the current stack frame to be discarded.
For info on other operands see C/CO.
Move an internal data object, object, to x(0). Copy the continuation program pointer from the current stack frame into CP, discard the frame, increment number of reductions and check for suspension, branch to called function. Type of object is coded implicitly as instruction opcode.