pub struct EvmCompiler<B: Backend> {
name: Option<String>,
backend: B,
out_dir: Option<PathBuf>,
config: FcxConfig,
builtins: Builtins<B>,
dump_assembly: bool,
dump_unopt_assembly: bool,
finalized: bool,
}
Expand description
EVM bytecode compiler.
This currently represents one single-threaded IR context and module, which can be used to compile multiple functions as JIT or AOT.
Functions can be incrementally added with translate
, and then either written to an object
file with write_object
when in AOT mode, or JIT-compiled with jit_function
.
Performing either of these operations finalizes the module, and no more functions can be added
afterwards until clear
is called, which will reset the module to its initial state.
Fields§
§name: Option<String>
§backend: B
§out_dir: Option<PathBuf>
§config: FcxConfig
§builtins: Builtins<B>
§dump_assembly: bool
§dump_unopt_assembly: bool
§finalized: bool
Implementations§
Source§impl<B: Backend> EvmCompiler<B>
impl<B: Backend> EvmCompiler<B>
Sourcepub fn set_module_name(&mut self, name: impl Into<String>)
pub fn set_module_name(&mut self, name: impl Into<String>)
Sets the name of the module.
fn is_aot(&self) -> bool
fn is_jit(&self) -> bool
Sourcepub fn set_dump_to(&mut self, output_dir: Option<PathBuf>)
pub fn set_dump_to(&mut self, output_dir: Option<PathBuf>)
Dumps intermediate outputs and other debug info to the given directory after compilation.
Disables dumping if output_dir
is None
.
Sourcepub fn dump_assembly(&mut self, yes: bool)
pub fn dump_assembly(&mut self, yes: bool)
Dumps assembly to the output directory.
This can be quite slow.
Defaults to true
.
Sourcepub fn dump_unopt_assembly(&mut self, yes: bool)
pub fn dump_unopt_assembly(&mut self, yes: bool)
Dumps the unoptimized assembly to the output directory.
This can be quite slow.
Defaults to false
.
Sourcepub fn opt_level(&self) -> OptimizationLevel
pub fn opt_level(&self) -> OptimizationLevel
Returns the optimization level.
Sourcepub fn set_opt_level(&mut self, level: OptimizationLevel)
pub fn set_opt_level(&mut self, level: OptimizationLevel)
Sets the optimization level.
Note that some backends may not support setting the optimization level after initialization.
Defaults to the backend’s initial optimization level.
Sourcepub fn debug_assertions(&mut self, yes: bool)
pub fn debug_assertions(&mut self, yes: bool)
Sets whether to enable debug assertions.
These are useful for debugging, but they do a moderate performance penalty due to the insertion of extra checks and removal of certain assumptions.
Defaults to cfg!(debug_assertions)
.
Sourcepub fn frame_pointers(&mut self, yes: bool)
pub fn frame_pointers(&mut self, yes: bool)
Sets whether to enable frame pointers.
This is useful for profiling and debugging, but it incurs a very slight performance penalty.
Defaults to cfg!(debug_assertions)
.
Sourcepub fn validate_eof(&mut self, yes: bool)
pub fn validate_eof(&mut self, yes: bool)
Sets whether to validate input EOF containers.
An invalid EOF container will likely results in a panic.
Defaults to true
.
Sourcepub fn local_stack(&mut self, yes: bool)
pub fn local_stack(&mut self, yes: bool)
Sets whether to allocate the stack locally.
If this is set to true
, the stack pointer argument will be ignored and the stack will be
allocated in the function.
This setting will fail at runtime if the bytecode suspends execution, as it cannot be restored afterwards.
Defaults to false
.
Sourcepub fn inspect_stack_length(&mut self, yes: bool)
pub fn inspect_stack_length(&mut self, yes: bool)
Sets whether to treat the stack length as observable outside the function.
This also implies that the length is loaded in the beginning of the function, meaning that a function can be executed with an initial stack.
If this is set to true
, the stack length must be passed in the arguments.
This is useful to inspect the stack length after the function has been executed, but it does incur a performance penalty as the length will be stored at all return sites.
Defaults to false
.
Sourcepub unsafe fn stack_bound_checks(&mut self, yes: bool)
pub unsafe fn stack_bound_checks(&mut self, yes: bool)
Sets whether to enable stack bound checks.
Ignored for EOF bytecodes, as they are assumed to be correct.
Defaults to true
.
§Safety
Removing stack length checks may improve compilation speed and performance, but will result
in undefined behavior if the stack length overflows at runtime, rather than a
StackUnderflow
/StackOverflow
result.
Sourcepub fn gas_metering(&mut self, yes: bool)
pub fn gas_metering(&mut self, yes: bool)
Sets whether to track gas costs.
Disabling this will greatly improves compilation speed and performance, at the cost of not being able to check for gas exhaustion.
Note that this does not disable gas usage in certain instructions, mainly the ones that are implemented as builtins.
Use with care, as executing a function with gas disabled may result in an infinite loop.
Defaults to true
.
Sourcepub fn translate<'a>(
&mut self,
name: &str,
input: impl Into<EvmCompilerInput<'a>>,
spec_id: SpecId,
) -> Result<B::FuncId>
pub fn translate<'a>( &mut self, name: &str, input: impl Into<EvmCompilerInput<'a>>, spec_id: SpecId, ) -> Result<B::FuncId>
Translates the given EVM bytecode into an internal function.
NOTE: name
must be unique for each function, as it is used as the name of the final
symbol.
Sourcepub unsafe fn jit<'a>(
&mut self,
name: &str,
bytecode: impl Into<EvmCompilerInput<'a>>,
spec_id: SpecId,
) -> Result<EvmCompilerFn>
pub unsafe fn jit<'a>( &mut self, name: &str, bytecode: impl Into<EvmCompilerInput<'a>>, spec_id: SpecId, ) -> Result<EvmCompilerFn>
Sourcepub unsafe fn jit_function(&mut self, id: B::FuncId) -> Result<EvmCompilerFn>
pub unsafe fn jit_function(&mut self, id: B::FuncId) -> Result<EvmCompilerFn>
(JIT) Finalizes the module and JITs the given function.
§Safety
The returned function pointer is owned by the module, and must not be called after the module is cleared or the function is freed.
Sourcepub fn write_object_to_file(&mut self, path: &Path) -> Result<()>
pub fn write_object_to_file(&mut self, path: &Path) -> Result<()>
(AOT) Writes the compiled object to the given file.
Sourcepub fn write_object<W: Write>(&mut self, w: W) -> Result<()>
pub fn write_object<W: Write>(&mut self, w: W) -> Result<()>
(AOT) Finalizes the module and writes the compiled object to the given writer.
Sourcepub unsafe fn free_function(&mut self, id: B::FuncId) -> Result<()>
pub unsafe fn free_function(&mut self, id: B::FuncId) -> Result<()>
(JIT) Frees the memory associated with a single function.
Note that this will not reset the state of the internal module even if all functions are
freed with this function. Use clear
to reset the module.
§Safety
Because this function invalidates any pointers retrieved from the corresponding module, it
should only be used when none of the functions from that module are currently executing and
none of the fn
pointers are called afterwards.
Sourcepub unsafe fn clear(&mut self) -> Result<()>
pub unsafe fn clear(&mut self) -> Result<()>
Frees all functions and resets the state of the internal module, allowing for new functions to be compiled.
§Safety
Because this function invalidates any pointers retrieved from the corresponding module, it
should only be used when none of the functions from that module are currently executing and
none of the fn
pointers are called afterwards.
fn do_validate_eof(&self, eof: &Eof) -> Result<()>
fn translate_inner( &mut self, name: &str, bytecode: &Bytecode<'_>, ) -> Result<B::FuncId>
fn finalize(&mut self) -> Result<()>
fn make_builder<'a>( backend: &'a mut B, config: &FcxConfig, name: &str, linkage: Linkage, ) -> Result<(B::Builder<'a>, B::FuncId)>
fn dump_ir(&mut self, path: &Path) -> Result<()>
fn dump_disasm(&mut self, path: &Path) -> Result<()>
fn verify_module(&mut self) -> Result<()>
fn optimize_module(&mut self) -> Result<()>
fn dump_bytecode(dump_dir: &Path, bytecode: &Bytecode<'_>) -> Result<()>
fn dump_dir(&self) -> Option<PathBuf>
Auto Trait Implementations§
impl<B> Freeze for EvmCompiler<B>
impl<B> RefUnwindSafe for EvmCompiler<B>
impl<B> Send for EvmCompiler<B>
impl<B> Sync for EvmCompiler<B>
impl<B> Unpin for EvmCompiler<B>
impl<B> UnwindSafe for EvmCompiler<B>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.§impl<T> TryConv for T
impl<T> TryConv for T
§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘwhere
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘwhere
S: Into<Dispatch>,
§fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Layout§
Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.