The runtime system contains 140 subroutines, each of which is briefly
described in the following table. The arguments and return values are
“typed” by the registers in which they are passed. Many arithmetic
subroutines act on the accumulators ac0
and ac1
, each of
which can be unboxed, i.e. contain a raw integer, or
boxed, i.e. contain a tagged pointer to a big integer or float,
either on the global stack or on a scratchpad area. If both
accumulators are live, then either both are boxed or both are unboxed.
The type cc
denotes a return value passed as a condition code,
with the following conventions:
o
Signals an arithmetic overflow or other error. Other condition codes are undefined.
e
vs. ne
Continue in write mode vs. read mode. Other condition codes are undefined.
e
vs. ne
Continue with unboxed accumulators vs. boxed accumulators. Other condition codes are undefined.
e
vs. ne
Reflects the outcome of native_test_numbers()
; see below. Other condition codes are undefined.
e
vs. ne
Failure vs. success of a type test. Other condition codes are undefined.
e
, ne
, l
, le
, g
, ge
Reflects the outcome of a comparison. Other condition codes are undefined.
Following are the subroutines:
void native_nonjit()
Handle general events as well as calls to non-jitex predicates.
void native_restore_link()
Patch the caller, which corresponds to an IR instructions of the form
call(native_entry(M:F/A))
, to call the lead-in sequence, and
remake the call. For x86/x86_64, this affects a call
machine
instruction, in the main body or in a trampoline. For PPC64, this never
affects any machine instructions. Only TOC slots are affected.
void native_shunt_link()
Patch the caller, which corresponds to an IR instructions of the form
call(native_entry(M:F/A))
, to call the prefix sequence, and
jump there. For x86/x86_64, this affects a call
machine
instruction, in the main body or in a trampoline. For PPC64, this never
affects any machine instructions. Only TOC slots are affected.
void native_get_constant(val Xj, arg1 C)
Unify Xj
with the constant C
.
cc native_get_list(val Xj)
Unify Xj
with a list, setting s
if read mode. Condition
void native_get_nil(val Xj)
Unify Xj
with the constant []
.
cc native_get_structure(val Xj, arg1 F)
Unify Xj
with a structure with principal functor F
, setting s
if read mode.
void native_get_subconstant(val Xj, arg1 C)
Unify Xj
with the constant C
, where Xj occurs in compound term.
cc native_get_sublist(val Xj)
Unify Xj
with a list, setting s
if read mode, where Xj occurs in compound term.
void native_get_subnil(val Xj)
Unify Xj
with the constant []
, where Xj occurs in compound term.
cc native_get_substructure(val Xj, arg1 F)
Unify Xj
with a structure with principal functor F
,
setting s
if read mode, where Xj occurs in compound term.
void native_get_value(val X, arg1 Y)
Unify X
and Y
.
void native_bind(val X)
Trail the binding of X that just took place if necessary.
void native_trail_unsafe(val X)
Trail local variable X
if needed, in the context of *_unsafe_variable
.
void native_make_global(val X)
Globalize variable X if needed.
cc native_compareop(arg0 X, arg1 Y)
Term compare X
and Y
with the condition code
reflecting the output.
void native_cut(val B)
Execute a cut (!) back to the choicepoint B
.
void native_fail()
Backtrack.
void native_if()
Support for ANOP_IF
.
void native_metacall(val Callee)
Support for a metacall to Callee
.
void native_proceed()
Handle PROCEED
, continuing into native code for NATIVE_OP
continuations.
void native_progress()
A general event has occurred; fall back on the WAM emulator to handle it
and to proceed with a PROGRESS
operation.
void native_subproceed()
Tell the WAM emulator to proceed at address w->insn
.
void native_switch()
Dispatch on the principal functor of x(0)
. The return address
points at possible padding followed by an aligned switch_on_key
struct.
void native_try(val Label)
Push a choicepoint with a chain of alternatives at Label
,
and branch to the first alternative.
void native_spill(val V, arg1 Xi)
Support SPILL
.
val native_unspill(val V)
Support UNSPILL
.
void native_first_float()
Support for converting unboxed ac0
to a boxed float, allocated on the numstack.
void native_first_long()
Support for boxing unboxed ac0
.
cc native_first_value(val X)
Load ac0
with the value of X
.
cc
reflects read/write mode.
void native_fli_close()
Close the foreign call: restore C and SP_term_ref stacks, reset FLI
exception flag, free any mems for +codes
arguments, and proceed
.
val native_fli_get_atom(val X)
Check a +atom
foreign argument. Escape to the emulator in case
of error.
void native_fli_get_codes(val X, val arg1)
Check a +codes
foreign argument. Escape to the emulator in case
of error. Otherwise, convert it to a string, allocate a mem, and add it
to the mem ring in arg1
. Returns the augmented mem ring.
fpr(8) native_fli_get_float(val X)
Check a +float
foreign argument. Escape to the emulator in case
of error. Otherwise, convert it and return as a float.
val native_fli_get_integer(val X)
Check a +integer
foreign argument. Escape to the emulator in case
of error. Otherwise, convert it and return as an integer.
val native_fli_get_string(val X)
Check a +string
foreign argument. Escape to the emulator in case
of error. Otherwise, convert it and return as a string.
void native_fli_open(inline Pred, inline Size, inline Arity)
Open a foreign call, with w_insn
pointing to the corresponding
WAM instruction. Push a C stack frame of size Size
. Save
SP_term_ref stack index and FLI exception flag. Push a WAM stack frame
with the dereferenced argument registers of size Arity
. Point
cp
to an inline KONTINUE
instruction just after
Arity
.
val native_fli_refresh(val X)
Check FLI exception flag, and if set, close the foreign call and fail.
call heap_overflow()
if necessary. Must preserve val
and
fpr(0)
.
void native_fli_unify_atom(val X, arg1 Y)
Unify a foreign -atom
or [-atom]
argument with X
.
void native_fli_unify_codes(val X, arg1 Y)
Unify a foreign -codes
or [-codes]
argument with
X
. If the received value is misencoded, close the call and raise an error.
void native_fli_unify_float(val X, arg1 Y)
Unify a foreign -float
or [-float]
argument with X
.
If the received value is not a proper float, close the call and raise an
error.
void native_fli_unify_integer(val X, arg1 Y)
Unify a foreign -integer
or [-integer]
argument with X
.
void native_fli_unify_string(val X, arg1 Y)
Unify a foreign -string
or [-string]
argument with
X
. If the received value is misencoded, close the call and raise an error.
void native_fli_unify_term(val X, arg1 Y)
Unify a foreign -term
or [-term]
argument with X
.
void native_later_float()
Convert unboxed ac1
to a boxed float, allocated on the numstack.
void native_later_long()
Box unboxed ac1
.
void native_later_value_boxed(val X)
Load ac1
with the value of X
where ac0
is boxed.
cc native_later_value_unboxed(val X)
Load ac1
with the value of X
where ac0
is
unboxed.
cc
reflects read/write mode.
void native_store_value_boxed(val X)
Support for unifying boxed ac0
with the value of X
.
void native_store_value_unboxed(val X)
Support for unifying unboxed ac0
with the value of X
.
val native_store_variable_boxed()
Support for storing the value of boxed ac0
in val
.
val native_store_variable_unboxed()
Support for storing the value of unboxed ac0
in val
.
cc native_compare_numbers()
Compare the numbers in the accumulators with the condition code
reflecting the output. Overflow reflects an error.
[PERM: Who clears Overflow on non-error? Not native_compare_numbers()
, it seems.]
void native_test_numbers()
Perform a logical and of the boxed accumulators. The condition code reflects whether the result is zero.
cc native_fdivide_unboxed()
cc native_gcd_unboxed()
cc native_idivide_unboxed()
cc native_ipower2_unboxed()
cc native_lsh_unboxed()
cc native_modulus_unboxed()
cc native_msb_unboxed()
cc native_remainder_unboxed()
cc native_rsh_unboxed()
Support for binary operations on unboxed accumulators.
void native_float1()
cc native_integer1()
cc native_left_shift()
cc native_minus()
cc native_right_shift()
cc native_sign()
Support for unary and binary operations on boxed accumulators.
cc native_atom(val X)
cc native_atomic(val X)
cc native_float(val X)
cc native_integer(val X)
cc native_number(val X)
cc native_nonvar(val X)
cc native_var(val X)
cc native_simple(val X)
cc native_compound(val X)
cc native_callable(val X)
cc native_ground(val X)
cc native_mutable(val X)
cc native_db_reference(val X)
Support for type-test instructions. Condition code e
signals failure.
void native_append(arg0 X, arg1 Y, arg2 Z)
void native_arg(arg0 X, arg1 Y, arg2 Z)
void native_compare(arg0 X, arg1 Y, arg2 Z)
void native_create_mutable(arg0 X, arg1 Y)
void native_get_mutable(arg0 X, arg1 Y)
void native_update_mutable(arg0 X, arg1 Y)
void native_functor(arg0 X, arg1 Y, arg2 Z)
void native_length(arg0 X, arg1 Y)
void native_univ(arg0 X, arg1 Y)
Support for the corresponding built-in predicates, which all compile inline.
cc native_abs()
cc native_acos()
cc native_acosh()
cc native_acot()
cc native_acot2()
cc native_acoth()
cc native_add()
cc native_and()
cc native_asin()
cc native_asinh()
cc native_atan()
cc native_atan2()
cc native_atanh()
cc native_ceiling()
cc native_complement()
cc native_cos()
cc native_cosh()
cc native_cot()
cc native_coth()
cc native_divide()
cc native_exp()
cc native_exp2()
cc native_fdivide()
cc native_float_fractional_part()
cc native_float_integer_part()
cc native_floor()
cc native_gcd()
cc native_idivide()
cc native_ipower2()
cc native_log()
cc native_log2()
cc native_maximum()
cc native_minimum()
cc native_modulus()
cc native_msb()
cc native_multiply()
cc native_or()
cc native_power2()
cc native_remainder()
cc native_round()
cc native_sin()
cc native_sinh()
cc native_sqrt()
cc native_subtract()
cc native_tan()
cc native_tanh()
cc native_truncate()
cc native_xor()
Arithmetic support acting on boxed accumulators.