1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
use crate::{ImportLinker, Opcode, N_DEFAULT_MAX_MEMORY_PAGES};
use alloc::{boxed::Box, sync::Arc};
use wasmparser::WasmFeatures;
#[derive(Debug, Clone)]
/// Configuration for dispatching to different entry functions based on a runtime state value.
/// The router maps state tags to function indices and optionally provides an opcode to compute the tag.
pub struct StateRouterConfig {
/// List of states to be router based on the state.
pub states: Box<[(Box<str>, u32)]>,
/// Instruction that describes how we determine an input state.
/// Keep it None only if you already have a state element on the stack, because after execution
/// it's being dropped.
pub opcode: Option<Opcode>,
}
#[derive(Clone, Debug)]
/// Controls how a Wasm module is lowered into rwasm bytecode.
/// Options affect entry routing, import linking, fuel metering, and validation relaxations for tests.
pub struct CompilationConfig {
/// State router is used to choose one of the function based on the index provided.
/// P.S: this flag doesn't work if you have WASM's start entry point.
pub state_router: Option<StateRouterConfig>,
/// Entrypoint that stores bytecode for module init.
/// P.S: this flag doesn't work if you have WASM's start entry point.
pub entrypoint_name: Option<Box<str>>,
/// Import linker that stores mapping from function to special identifiers that is used
/// to remember unique external calls ids. We need this to simplify a proving process to
/// forward external calls to corresponding circuits.
pub import_linker: Option<Arc<ImportLinker>>,
/// An option to disable malformed entrypoint func type check. We need this check for e2e tests
/// where we manage stack manually.
///
/// WARNING: only for trusted environment, can cause stack overflow/underflow
pub allow_malformed_entrypoint_func_type: bool,
/// Should fuel-charging instructions be injected before each builtin call.
pub builtins_consume_fuel: bool,
/// We don't support imported global, but you can set a default value for these values instead.
/// Thus is required by testing suite.
pub default_imported_global_value: Option<i64>,
/// Enable fuel metering (always eager mode)
pub consume_fuel: bool,
/// Enable replacement with optimized code snippets
pub code_snippets: bool,
/// Enable fuel metering for params and locals
pub consume_fuel_for_params_and_locals: bool,
/// Allow function types with funcref and externref (needed only for e2e testing suite, but
/// practically inside a blockchain environment it's not possible)
///
/// WARNING: the flag can be removed one funcref/externref type mapping is
/// implemented for wasmtime
pub allow_func_ref_function_types: bool,
/// Allow a start section inside rWasm module. Be aware that a start section is called during resource
/// init for rWasm VM.
pub allow_start_section: bool,
/// The maximum number of memory pages that can be allocated by the module.
pub max_allowed_memory_pages: u32,
}
impl Default for CompilationConfig {
fn default() -> Self {
Self {
state_router: None,
entrypoint_name: None,
import_linker: None,
allow_malformed_entrypoint_func_type: false,
builtins_consume_fuel: false,
default_imported_global_value: None,
consume_fuel: true,
consume_fuel_for_params_and_locals: true,
code_snippets: true,
allow_func_ref_function_types: false,
allow_start_section: false,
max_allowed_memory_pages: N_DEFAULT_MAX_MEMORY_PAGES,
}
}
}
impl CompilationConfig {
/// Returns the WebAssembly features configuration for the current instance.
pub fn wasm_features(&self) -> WasmFeatures {
WasmFeatures {
mutable_global: true,
saturating_float_to_int: true,
sign_extension: true,
multi_value: true,
bulk_memory: true,
reference_types: true,
tail_call: true,
extended_const: true,
..Default::default()
}
}
pub fn with_state_router(mut self, state_router: StateRouterConfig) -> Self {
self.state_router = Some(state_router);
self
}
pub fn with_entrypoint_name(mut self, name: Box<str>) -> Self {
self.entrypoint_name = Some(name);
self
}
pub fn with_import_linker(mut self, import_linker: Arc<ImportLinker>) -> Self {
self.import_linker = Some(import_linker);
self
}
pub fn with_allow_malformed_entrypoint_func_type(
mut self,
allow_malformed_entrypoint_func_type: bool,
) -> Self {
self.allow_malformed_entrypoint_func_type = allow_malformed_entrypoint_func_type;
self
}
pub fn with_builtins_consume_fuel(mut self, builtins_consume_fuel: bool) -> Self {
self.builtins_consume_fuel = builtins_consume_fuel;
self
}
pub fn with_default_imported_global_value(
mut self,
default_imported_global_value: i64,
) -> Self {
self.default_imported_global_value = Some(default_imported_global_value);
self
}
pub fn with_consume_fuel(mut self, consume_fuel: bool) -> Self {
self.consume_fuel = consume_fuel;
if !consume_fuel {
self.consume_fuel_for_params_and_locals = false;
self.builtins_consume_fuel = false;
}
self
}
pub fn with_consume_fuel_for_params_and_locals(mut self, v: bool) -> Self {
self.consume_fuel_for_params_and_locals = v;
self
}
pub fn with_code_snippets(mut self, v: bool) -> Self {
self.code_snippets = v;
self
}
pub fn with_allow_func_ref_function_types(
mut self,
allow_func_ref_function_types: bool,
) -> Self {
self.allow_func_ref_function_types = allow_func_ref_function_types;
self
}
pub fn with_allow_start_section(mut self, allow_start_section: bool) -> Self {
self.allow_start_section = allow_start_section;
self
}
pub fn with_max_allowed_memory_pages(mut self, max_allowed_memory_pages: u32) -> Self {
self.max_allowed_memory_pages = max_allowed_memory_pages;
self
}
}