Skip to content

Commit eb8d73f

Browse files
authored
Add extended-const Wasm proposal support (#707)
* add extended-const Wasm proposal to config * add Wasm spec tests for extended-const * enable extended-const for tests * apply rustfmt * add ConstExpr to support extended const * fix no_std build * rename func_ref * add module docs
1 parent 6dbbada commit eb8d73f

File tree

13 files changed

+416
-227
lines changed

13 files changed

+416
-227
lines changed

crates/wasmi/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ spin = { version = "0.9", default-features = false, features = [
2121
"spin_mutex",
2222
"rwlock",
2323
] }
24+
smallvec = { version = "1.10.0", features = ["union"] }
2425

2526
[dev-dependencies]
2627
wat = "1"

crates/wasmi/src/engine/config.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub struct Config {
2929
reference_types: bool,
3030
/// Is `true` if the [`tail-call`] Wasm proposal is enabled.
3131
tail_call: bool,
32+
/// Is `true` if the [`extended-const`] Wasm proposal is enabled.
33+
extended_const: bool,
3234
/// Is `true` if Wasm instructions on `f32` and `f64` types are allowed.
3335
floats: bool,
3436
/// Is `true` if `wasmi` executions shall consume fuel.
@@ -201,6 +203,7 @@ impl Default for Config {
201203
bulk_memory: true,
202204
reference_types: true,
203205
tail_call: false,
206+
extended_const: false,
204207
floats: true,
205208
consume_fuel: false,
206209
fuel_costs: FuelCosts::default(),
@@ -321,6 +324,18 @@ impl Config {
321324
self
322325
}
323326

327+
/// Enable or disable the [`extended-const`] Wasm proposal for the [`Config`].
328+
///
329+
/// # Note
330+
///
331+
/// Disabled by default.
332+
///
333+
/// [`tail-call`]: https://github.com/WebAssembly/extended-const
334+
pub fn wasm_extended_const(&mut self, enable: bool) -> &mut Self {
335+
self.extended_const = enable;
336+
self
337+
}
338+
324339
/// Enable or disable Wasm floating point (`f32` and `f64`) instructions and types.
325340
///
326341
/// Enabled by default.
@@ -395,6 +410,7 @@ impl Config {
395410
bulk_memory: self.bulk_memory,
396411
reference_types: self.reference_types,
397412
tail_call: self.tail_call,
413+
extended_const: self.extended_const,
398414
floats: self.floats,
399415
component_model: false,
400416
simd: false,
@@ -403,7 +419,6 @@ impl Config {
403419
multi_memory: false,
404420
exceptions: false,
405421
memory64: false,
406-
extended_const: false,
407422
memory_control: false,
408423
}
409424
}

crates/wasmi/src/engine/func_builder/translator.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ use crate::{
3434
},
3535
module::{
3636
BlockType,
37+
ConstExpr,
3738
FuncIdx,
3839
FuncTypeIdx,
3940
GlobalIdx,
40-
InitExpr,
4141
MemoryIdx,
4242
ModuleResources,
4343
DEFAULT_MEMORY_INDEX,
@@ -416,14 +416,14 @@ impl<'parser> FuncTranslator<'parser> {
416416
/// have a chance to be optimized to more efficient instructions.
417417
fn optimize_global_get(
418418
global_type: &GlobalType,
419-
init_value: Option<&InitExpr>,
419+
init_value: Option<&ConstExpr>,
420420
) -> Option<Instruction> {
421421
if let (Mutability::Const, Some(init_expr)) = (global_type.mutability(), init_value) {
422-
if let Some(value) = init_expr.to_const() {
422+
if let Some(value) = init_expr.eval_const() {
423423
// We can optimize `global.get` to the constant value.
424424
return Some(Instruction::constant(value));
425425
}
426-
if let Some(func_index) = init_expr.func_ref() {
426+
if let Some(func_index) = init_expr.funcref() {
427427
// We can optimize `global.get` to the equivalent `ref.func x` instruction.
428428
let func_index = bytecode::FuncIdx::from(func_index.into_u32());
429429
return Some(Instruction::RefFunc { func_index });

crates/wasmi/src/module/builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{
22
export::ExternIdx,
33
import::FuncTypeIdx,
4+
ConstExpr,
45
DataSegment,
56
ElementSegment,
67
ExternTypeIdx,
@@ -9,7 +10,6 @@ use super::{
910
GlobalIdx,
1011
Import,
1112
ImportName,
12-
InitExpr,
1313
Module,
1414
};
1515
use crate::{
@@ -33,7 +33,7 @@ pub struct ModuleBuilder<'engine> {
3333
pub tables: Vec<TableType>,
3434
pub memories: Vec<MemoryType>,
3535
pub globals: Vec<GlobalType>,
36-
pub globals_init: Vec<InitExpr>,
36+
pub globals_init: Vec<ConstExpr>,
3737
pub exports: BTreeMap<Box<str>, ExternIdx>,
3838
pub start: Option<FuncIdx>,
3939
pub func_bodies: Vec<FuncBody>,
@@ -90,7 +90,7 @@ impl<'a> ModuleResources<'a> {
9090
}
9191

9292
/// Returns the global variable type and optional initial value.
93-
pub fn get_global(&self, global_idx: GlobalIdx) -> (GlobalType, Option<&InitExpr>) {
93+
pub fn get_global(&self, global_idx: GlobalIdx) -> (GlobalType, Option<&ConstExpr>) {
9494
let index = global_idx.into_u32() as usize;
9595
let len_imports = self.res.imports.len_globals();
9696
let global_type = self.get_type_of_global(global_idx);

crates/wasmi/src/module/data.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InitExpr, MemoryIdx};
1+
use super::{ConstExpr, MemoryIdx};
22
use alloc::sync::Arc;
33

44
/// A Wasm [`Module`] data segment.
@@ -27,7 +27,7 @@ pub struct ActiveDataSegment {
2727
/// The linear memory that is to be initialized with this active segment.
2828
memory_index: MemoryIdx,
2929
/// The offset at which the data segment is initialized.
30-
offset: InitExpr,
30+
offset: ConstExpr,
3131
}
3232

3333
impl ActiveDataSegment {
@@ -37,7 +37,7 @@ impl ActiveDataSegment {
3737
}
3838

3939
/// Returns the offset expression of the [`ActiveDataSegment`].
40-
pub fn offset(&self) -> &InitExpr {
40+
pub fn offset(&self) -> &ConstExpr {
4141
&self.offset
4242
}
4343
}
@@ -50,7 +50,7 @@ impl From<wasmparser::DataKind<'_>> for DataSegmentKind {
5050
offset_expr,
5151
} => {
5252
let memory_index = MemoryIdx::from(memory_index);
53-
let offset = InitExpr::new(offset_expr);
53+
let offset = ConstExpr::new(offset_expr);
5454
Self::Active(ActiveDataSegment {
5555
memory_index,
5656
offset,

crates/wasmi/src/module/element.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InitExpr, TableIdx};
1+
use super::{ConstExpr, TableIdx};
22
use crate::module::utils::WasmiValueType;
33
use alloc::sync::Arc;
44
use wasmi_core::ValueType;
@@ -19,7 +19,7 @@ pub struct ElementSegment {
1919
/// The items of an [`ElementSegment`].
2020
#[derive(Debug, Clone)]
2121
pub struct ElementSegmentItems {
22-
exprs: Arc<[InitExpr]>,
22+
exprs: Arc<[ConstExpr]>,
2323
}
2424

2525
impl ElementSegmentItems {
@@ -36,22 +36,22 @@ impl ElementSegmentItems {
3636
.map(|item| {
3737
item.unwrap_or_else(|error| panic!("failed to parse element item: {error}"))
3838
})
39-
.map(InitExpr::new_funcref)
39+
.map(ConstExpr::new_funcref)
4040
.collect::<Arc<[_]>>(),
4141
wasmparser::ElementItems::Expressions(items) => items
4242
.clone()
4343
.into_iter()
4444
.map(|item| {
4545
item.unwrap_or_else(|error| panic!("failed to parse element item: {error}"))
4646
})
47-
.map(InitExpr::new)
47+
.map(ConstExpr::new)
4848
.collect::<Arc<[_]>>(),
4949
};
5050
Self { exprs }
5151
}
5252

5353
/// Returns a shared reference to the items of the [`ElementSegmentItems`].
54-
pub fn items(&self) -> &[InitExpr] {
54+
pub fn items(&self) -> &[ConstExpr] {
5555
&self.exprs
5656
}
5757
}
@@ -73,7 +73,7 @@ pub struct ActiveElementSegment {
7373
/// The index of the Wasm table that is to be initialized.
7474
table_index: TableIdx,
7575
/// The offset where the Wasm table is to be initialized.
76-
offset: InitExpr,
76+
offset: ConstExpr,
7777
}
7878

7979
impl ActiveElementSegment {
@@ -83,7 +83,7 @@ impl ActiveElementSegment {
8383
}
8484

8585
/// Returns the offset expression of the [`ActiveElementSegment`].
86-
pub fn offset(&self) -> &InitExpr {
86+
pub fn offset(&self) -> &ConstExpr {
8787
&self.offset
8888
}
8989
}
@@ -96,7 +96,7 @@ impl From<wasmparser::ElementKind<'_>> for ElementSegmentKind {
9696
offset_expr,
9797
} => {
9898
let table_index = TableIdx::from(table_index);
99-
let offset = InitExpr::new(offset_expr);
99+
let offset = ConstExpr::new(offset_expr);
100100
Self::Active(ActiveElementSegment {
101101
table_index,
102102
offset,

crates/wasmi/src/module/global.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::InitExpr;
1+
use super::ConstExpr;
22
use crate::GlobalType;
33

44
/// The index of a global variable within a [`Module`].
@@ -33,13 +33,13 @@ pub struct Global {
3333
///
3434
/// This is represented by a so called initializer expression
3535
/// that is run at module instantiation time.
36-
init_expr: InitExpr,
36+
init_expr: ConstExpr,
3737
}
3838

3939
impl From<wasmparser::Global<'_>> for Global {
4040
fn from(global: wasmparser::Global<'_>) -> Self {
4141
let global_type = GlobalType::from_wasmparser(global.ty);
42-
let init_expr = InitExpr::new(global.init_expr);
42+
let init_expr = ConstExpr::new(global.init_expr);
4343
Self {
4444
global_type,
4545
init_expr,
@@ -49,7 +49,7 @@ impl From<wasmparser::Global<'_>> for Global {
4949

5050
impl Global {
5151
/// Splits the [`Global`] into its global type and its global initializer.
52-
pub fn into_type_and_init(self) -> (GlobalType, InitExpr) {
52+
pub fn into_type_and_init(self) -> (GlobalType, ConstExpr) {
5353
(self.global_type, self.init_expr)
5454
}
5555
}

0 commit comments

Comments
 (0)