Struct jit::UncompiledFunction
[−]
[src]
pub struct UncompiledFunction<'a> { // some fields omitted }
A function which has not been compiled yet, so it can have instructions added to it.
A function persists for the lifetime of its containing context. This represents
the function in the "building" state, where the user constructs instructions
that represents the function body. Once the build process is complete, the
user calls function.compile()
to convert it into its executable form.
Methods
impl<'a> UncompiledFunction<'a>
fn new<T>(context: &'a mut Context<T>, signature: &Ty) -> UncompiledFunction<'a>
Create a new function block and associate it with a JIT context.
It is recommended that you call Function::new
and function.compile()
in the closure you give to context.build(...)
.
This will protect the JIT's internal data structures within a multi-threaded environment.
use jit::*; let mut ctx = Context::<()>::new(); let func = UncompiledFunction::new(&mut ctx, &get::<fn(f64) -> f64>());
fn new_nested<T>(context: &'a mut Context<T>, signature: &Ty, parent: &'a UncompiledFunction<'a>) -> UncompiledFunction<'a>
Create a new function block and associate it with a JIT context. In addition, this function is nested inside the specified parent function and is able to access its parent's (and grandparent's) local variables.
The front end is responsible for ensuring that the nested function can never be called by anyone except its parent and sibling functions. The front end is also responsible for ensuring that the nested function is compiled before its parent.
fn insn_convert(&self, v: &'a Val, t: &Ty, overflow_check: bool) -> &'a Val
Make an instruction that converts the value to the type given
fn insn_of<T>(&self, val: T) -> &'a Val where T: Compile<'a>
Make an instructional representation of a Rust value
rust use jit::*; let mut ctx = Context::<()>::new(); let func = UncompiledFunction::new(&mut ctx, &get::<fn() -> i32>()); func.insn_return(func.insn_of(42i32));
fn insn_uses_catcher(&self)
Notify the function building process that this function has a catch block in it. This must be called before any code that is part of a try block
fn insn_throw(&self, retval: &'a Val)
Make an instruction to throw an exception from the function with the value given
fn insn_return(&self, retval: &'a Val)
Make an instruction that will return from the function with the value given
fn insn_default_return(&self)
Return from the function
fn insn_mul(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that multiplies the values
fn insn_mul_ovf(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that multiplies the values and throws upon overflow
fn insn_add(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that adds the values
You can also just use v1 + v2
in your code instead of running this method,
&Val
has the Add
trait implemented so it can be added with normal operators.
fn insn_add_ovf(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that adds the values and throws upon overflow
fn insn_sub(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that subtracts the second value from the first
You can also just use v1 - v2
in your code instead of running this method,
&Val
has the Sub
trait implemented so it can be subtracted with normal operators.
fn insn_sub_ovf(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that subtracts the second value from the first and throws upon overflow
fn insn_div(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that divides the first number by the second
You can also just use v1 / v2
in your code instead of running this method,
&Val
has the Div
trait implemented so it can be divided with normal operators.
fn insn_rem(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that finds the remainder when the first number is divided by the second
You can also just use v1 % v2
in your code instead of running this method,
&Val
has the Rem
trait implemented so it can be done with normal operators.
fn insn_leq(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that checks if the first value is lower than or equal to the second
fn insn_geq(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that checks if the first value is greater than or equal to the second
fn insn_lt(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that checks if the first value is lower than the second
fn insn_gt(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that checks if the first value is greater than the second
fn insn_eq(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that checks if the values are equal
fn insn_neq(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that checks if the values are not equal
fn insn_and(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that performs a bitwise and on the two values
You can also just use v1 & v2
in your code instead of running this method,
&Val
has the BitAnd
trait implemented so it can be done with normal operators.
fn insn_or(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that performs a bitwise or on the two values
You can also just use v1 | v2
in your code instead of running this method,
&Val
has the BitOr
trait implemented so it can be done with normal operators.
fn insn_xor(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that performs a bitwise xor on the two values
You can also just use v1 ^ v2
in your code instead of running this method,
&Val
has the BitXor
trait implemented so it can be done with normal operators.
fn insn_not(&self, value: &'a Val) -> &'a Val
Make an instruction that performs a bitwise not on the two values
You can also just use !value
in your code instead of running this method.
&Val
has the Not
trait implemented so it can be inversed with normal operators.
fn insn_shl(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that performs a left bitwise shift on the first value by the second value
You can also just use v1 << v2
in your code instead of running this method,
&Val
has the Shl
trait implemented so it can be shifted with normal operators.
fn insn_shr(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that performs a right bitwise shift on the first value by the second value
You can also just use v1 >> v2
in your code instead of running this method,
&Val
has the Shr
trait implemented so it can be shifted with normal operators.
fn insn_ushr(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that performs a right bitwise shift on the first value by the second value
fn insn_neg(&self, value: &'a Val) -> &'a Val
Make an instruction that performs a negation on the value
You can also just use -value
in your code instead of running this method.
&Val
has the Neg
trait implemented so it can be negatedd with normal operators.
fn insn_dup(&self, value: &'a Val) -> &'a Val
Make an instruction that duplicates the value given
This is the same as load
fn insn_load(&self, src: &'a Val) -> &'a Val
Make an instruction that loads the contents of src
into a temporary
fn insn_load_relative(&self, value: &'a Val, offset: usize, ty: &Ty) -> &'a Val
Make an instruction that loads a value of the given type from value + offset
, where
value
must be a pointer
fn insn_store(&self, dest: &'a Val, val: &'a Val)
Make an instruction that stores the contents of val
into dest
, where dest
is a
temporary value or local value
fn insn_store_relative(&self, dest: &'a Val, offset: usize, value: &'a Val)
Make an instruction that stores the value
at the address dest + offset
, where dest
must be a pointer
fn insn_label(&self, label: &mut Label<'a>)
Make an instruction that sets a label
fn insn_branch(&self, label: &mut Label<'a>)
Make an instruction that branches to a certain label
fn insn_branch_if(&self, value: &'a Val, label: &mut Label<'a>)
Make an instruction that branches to a certain label if the value is true
fn insn_branch_if_not(&self, value: &'a Val, label: &mut Label<'a>)
Make an instruction that branches to a certain label if the value is false
fn insn_jump_table(&self, value: &'a Val, labels: &mut [Label<'a>])
Make an instruction that branches to a label in the table
fn insn_acos(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the inverse cosine of the number given
fn insn_asin(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the inverse sine of the number given
fn insn_atan(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the inverse tangent of the number given
fn insn_atan2(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that gets the inverse tangent of the numbers given
fn insn_ceil(&self, v: &'a Val) -> &'a Val
Make an instruction that finds the nearest integer above a number
fn insn_cos(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the consine of the number given
fn insn_cosh(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the hyperbolic consine of the number given
fn insn_exp(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the natural logarithm rased to the power of the number
fn insn_floor(&self, v: &'a Val) -> &'a Val
Make an instruction that finds the nearest integer below a number
fn insn_log(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the natural logarithm of the number
fn insn_log10(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the base 10 logarithm of the number
fn insn_pow(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction the gets the result of raising the first value to the power of the second value
fn insn_rint(&self, v: &'a Val) -> &'a Val
Make an instruction the gets the result of rounding the value to the nearest integer
fn insn_round(&self, v: &'a Val) -> &'a Val
Make an instruction the gets the result of rounding the value to the nearest integer
fn insn_sin(&self, v: &'a Val) -> &'a Val
Make an instruction the gets the sine of the number
fn insn_sinh(&self, v: &'a Val) -> &'a Val
Make an instruction the gets the hyperbolic sine of the number
fn insn_sqrt(&self, value: &'a Val) -> &'a Val
Make an instruction the gets the square root of a number
fn insn_tan(&self, v: &'a Val) -> &'a Val
Make an instruction the gets the tangent of a number
fn insn_tanh(&self, v: &'a Val) -> &'a Val
Make an instruction the gets the hyperbolic tangent of a number
fn insn_trunc(&self, v: &'a Val) -> &'a Val
Make an instruction that truncates the value
fn insn_is_nan(&self, v: &'a Val) -> &'a Val
Make an instruction that checks if the number is NaN
fn insn_is_finite(&self, v: &'a Val) -> &'a Val
Make an instruction that checks if the number is finite
fn insn_is_inf(&self, v: &'a Val) -> &'a Val
Make an instruction that checks if the number is infinite
fn insn_abs(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the absolute value of a number
fn insn_min(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that gets the smallest of two numbers
fn insn_max(&self, v1: &'a Val, v2: &'a Val) -> &'a Val
Make an instruction that gets the biggest of two numbers
fn insn_sign(&self, v: &'a Val) -> &'a Val
Make an instruction that gets the sign of a number
fn insn_call(&self, name: Option<&str>, func: &Func, sig: Option<&Ty>, args: &mut [&'a Val], flags: CallFlags) -> &'a Val
Call the function, which may or may not be translated yet
fn insn_call_indirect(&self, func: &'a Val, signature: &Ty, args: &mut [&'a Val], flags: CallFlags) -> &'a Val
Make an instruction that calls a function that has the signature given with some arguments through a pointer to the fucntion
fn insn_call_native0<R>(&self, name: Option<&str>, native_func: extern "C" fn() -> R, signature: &Ty, flags: CallFlags) -> &'a Val
Make an instruction that calls a Rust function that has the signature given with no arguments and expects a return value
fn insn_call_native1<A, R>(&self, name: Option<&str>, native_func: extern "C" fn(A) -> R, signature: &Ty, args: [&'a Val; 1], flags: CallFlags) -> &'a Val
Make an instruction that calls a Rust function that has the signature given with a single argument and expects a return value
fn insn_call_native2<A, B, R>(&self, name: Option<&str>, native_func: extern "C" fn(A, B) -> R, signature: &Ty, args: [&'a Val; 2], flags: CallFlags) -> &'a Val
Make an instruction that calls a Rust function that has the signature given with two arguments and expects a return value
fn insn_call_native3<A, B, C, R>(&self, name: Option<&str>, native_func: extern "C" fn(A, B, C) -> R, signature: &Ty, args: [&'a Val; 3], flags: CallFlags) -> &'a Val
Make an instruction that calls a Rust function that has the signature given with three arguments and expects a return value
fn insn_call_native4<A, B, C, D, R>(&self, name: Option<&str>, native_func: extern "C" fn(A, B, C, D) -> R, signature: &Ty, args: [&'a Val; 4], flags: CallFlags) -> &'a Val
Make an instruction that calls a Rust function that has the signature given with four arguments and expects a return value
fn insn_memcpy(&self, dest: &'a Val, source: &'a Val, size: &'a Val) -> bool
Make an instruction that copies size
bytes from the source
address to the dest
address
fn insn_memmove(&self, dest: &'a Val, source: &'a Val, size: &'a Val) -> bool
Make an instruction that moves memory from a source address to a destination address
fn insn_memset(&self, dest: &'a Val, source: &'a Val, size: &'a Val) -> bool
Make an instruction that sets memory at the destination address
fn insn_alloca(&self, size: &'a Val) -> &'a Val
Make an instruction that allocates size
bytes of memory from the stack
fn insn_address_of(&self, value: &'a Val) -> &'a Val
Make an instruction that gets the address of a value
fn insn_if<B>(&self, cond: &'a Val, block: B) where B: FnOnce()
Make instructions to run the block if the condition is met
fn insn_if_not<B>(&self, cond: &'a Val, block: B) where B: FnOnce()
Make instructions to run the block if the condition is not met
fn insn_if_else<A, B>(&self, cond: &'a Val, if_block: A, else_block: B) where A: FnOnce(), B: FnOnce()
Make instructions to run the block if the condition is met
fn insn_loop<B>(&self, block: B) where B: FnOnce()
Make instructions to run the block forever
fn insn_while<C, B>(&self, cond: C, block: B) where C: FnOnce() -> &'a Val, B: FnOnce()
Make instructions to run the block and continue running it so long as the condition is met
fn set_optimization_level(&self, level: c_uint)
Set the optimization level of the function, where the bigger the level, the more effort should be spent optimising
fn get_max_optimization_level() -> c_uint
Get the max optimization level
fn set_recompilable(&self)
Make this function a candidate for recompilation
fn get_entry(&self) -> Option<Block<'a>>
Get the entry block of this function
fn get_current(&self) -> Option<Block<'a>>
Get the current block of this function
fn compile(self) -> CompiledFunction<'a>
Compile the function
fn compile_with<A, R, F>(self, cb: F) -> CompiledFunction<'a> where F: FnOnce( extern "C" fn(A) -> R)
Compile the function and call a closure with it directly
Methods from Deref<Target=Func>
fn is_compiled(&self) -> bool
Check if the given function has been compiled
fn get_signature(&self) -> &Ty
Get the signature of the given function