Skip to content

Commit 8483472

Browse files
authored
Use a new StubInstance to avoid requiring the "test" feature (#2509)
* Move `wit_generation` module into a sub-directory Prepare to add a new sub-module with a `StubInstance`, so that there's no need to use the `MockInstance`. * Create a new `StubInstance` type A replacement for the `MockInstance` type to use when generating WIT files. This allows generating the files without having to activate the "test" feature. * Use the `StubInstance` in the `wit_generator` Replace usages of the `MockInstance` type and don't enable `linera-witty`'s "test" feature.
1 parent 1bdec44 commit 8483472

File tree

4 files changed

+130
-16
lines changed

4 files changed

+130
-16
lines changed

linera-sdk/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ linera-chain = { workspace = true, features = ["metrics"] }
6666
linera-core = { workspace = true, features = ["metrics", "wasmer"] }
6767
linera-execution = { workspace = true, features = ["fs", "metrics", "wasmer"] }
6868
linera-storage = { workspace = true, features = ["metrics", "wasmer"] }
69-
linera-witty = { workspace = true, features = ["test"] }
69+
linera-witty.workspace = true
7070
serde_json.workspace = true
7171
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
7272
wasmtime.workspace = true

linera-sdk/src/bin/wit_generator.rs

+12-15
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ use linera_execution::{
1818
ContractEntrypoints, ContractSyncRuntimeHandle, ContractSystemApi, ServiceEntrypoints,
1919
ServiceSyncRuntimeHandle, ServiceSystemApi, SystemApiData, ViewSystemApi,
2020
};
21-
use linera_witty::{
22-
wit_generation::{WitInterfaceWriter, WitWorldWriter},
23-
MockInstance,
24-
};
21+
use linera_witty::wit_generation::{StubInstance, WitInterfaceWriter, WitWorldWriter};
2522

2623
/// Command line parameters for the WIT generator.
2724
#[derive(Debug, clap::Parser)]
@@ -50,27 +47,27 @@ fn main() -> Result<()> {
5047

5148
/// Runs the main `operation` on all the WIT files.
5249
fn run_operation(options: WitGeneratorOptions, mut operation: impl Operation) -> Result<()> {
53-
let contract_entrypoints = WitInterfaceWriter::new::<ContractEntrypoints<MockInstance<()>>>();
54-
let service_entrypoints = WitInterfaceWriter::new::<ServiceEntrypoints<MockInstance<()>>>();
50+
let contract_entrypoints = WitInterfaceWriter::new::<ContractEntrypoints<StubInstance>>();
51+
let service_entrypoints = WitInterfaceWriter::new::<ServiceEntrypoints<StubInstance>>();
5552

5653
let contract_system_api = WitInterfaceWriter::new::<
57-
ContractSystemApi<MockInstance<SystemApiData<ContractSyncRuntimeHandle>>>,
54+
ContractSystemApi<StubInstance<SystemApiData<ContractSyncRuntimeHandle>>>,
5855
>();
5956
let service_system_api = WitInterfaceWriter::new::<
60-
ServiceSystemApi<MockInstance<SystemApiData<ServiceSyncRuntimeHandle>>>,
57+
ServiceSystemApi<StubInstance<SystemApiData<ServiceSyncRuntimeHandle>>>,
6158
>();
6259
let view_system_api = WitInterfaceWriter::new::<
63-
ViewSystemApi<MockInstance<SystemApiData<ContractSyncRuntimeHandle>>>,
60+
ViewSystemApi<StubInstance<SystemApiData<ContractSyncRuntimeHandle>>>,
6461
>();
6562

6663
let contract_world = WitWorldWriter::new("linera:app", "contract")
67-
.export::<ContractEntrypoints<MockInstance<()>>>()
68-
.import::<ContractSystemApi<MockInstance<SystemApiData<ContractSyncRuntimeHandle>>>>()
69-
.import::<ViewSystemApi<MockInstance<SystemApiData<ContractSyncRuntimeHandle>>>>();
64+
.export::<ContractEntrypoints<StubInstance>>()
65+
.import::<ContractSystemApi<StubInstance<SystemApiData<ContractSyncRuntimeHandle>>>>()
66+
.import::<ViewSystemApi<StubInstance<SystemApiData<ContractSyncRuntimeHandle>>>>();
7067
let service_world = WitWorldWriter::new("linera:app", "service")
71-
.export::<ServiceEntrypoints<MockInstance<()>>>()
72-
.import::<ServiceSystemApi<MockInstance<SystemApiData<ServiceSyncRuntimeHandle>>>>()
73-
.import::<ViewSystemApi<MockInstance<SystemApiData<ContractSyncRuntimeHandle>>>>();
68+
.export::<ServiceEntrypoints<StubInstance>>()
69+
.import::<ServiceSystemApi<StubInstance<SystemApiData<ServiceSyncRuntimeHandle>>>>()
70+
.import::<ViewSystemApi<StubInstance<SystemApiData<ContractSyncRuntimeHandle>>>>();
7471

7572
operation.run_for_file(
7673
&options.base_directory.join("contract-entrypoints.wit"),

linera-witty/src/wit_generation.rs renamed to linera-witty/src/wit_generation/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33

44
//! Generation of WIT files.
55
6+
mod stub_instance;
7+
68
use std::collections::BTreeMap;
79

810
use genawaiter::{rc::gen, yield_};
911

12+
pub use self::stub_instance::StubInstance;
1013
pub use crate::type_traits::RegisterWitTypes;
1114

1215
/// Generates WIT snippets for an interface.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright (c) Zefchain Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Contains a [`StubInstance`] type and the code it requires to implement the necessary
5+
//! trait to be used as a Wasm instance type during compile time.
6+
7+
use std::{borrow::Cow, marker::PhantomData};
8+
9+
use crate::{
10+
memory_layout::FlatLayout, GuestPointer, Instance, InstanceWithFunction, InstanceWithMemory,
11+
Runtime, RuntimeError, RuntimeMemory,
12+
};
13+
14+
/// A stub Wasm instance.
15+
///
16+
/// This is when a Wasm instance type is needed for type-checking but is not needed during
17+
/// runtime.
18+
pub struct StubInstance<UserData = ()> {
19+
_user_data: PhantomData<UserData>,
20+
}
21+
22+
impl<UserData> Default for StubInstance<UserData> {
23+
fn default() -> Self {
24+
StubInstance {
25+
_user_data: PhantomData,
26+
}
27+
}
28+
}
29+
30+
impl<UserData> Instance for StubInstance<UserData> {
31+
type Runtime = StubRuntime;
32+
type UserData = UserData;
33+
type UserDataReference<'a> = &'a UserData
34+
where
35+
Self::UserData: 'a,
36+
Self: 'a;
37+
type UserDataMutReference<'a> = &'a mut UserData
38+
where
39+
Self::UserData: 'a,
40+
Self: 'a;
41+
42+
fn load_export(&mut self, _name: &str) -> Option<()> {
43+
unimplemented!("`StubInstance` can not be used as a real `Instance`");
44+
}
45+
46+
fn user_data(&self) -> Self::UserDataReference<'_> {
47+
unimplemented!("`StubInstance` can not be used as a real `Instance`");
48+
}
49+
50+
fn user_data_mut(&mut self) -> Self::UserDataMutReference<'_> {
51+
unimplemented!("`StubInstance` can not be used as a real `Instance`");
52+
}
53+
}
54+
55+
impl<Parameters, Results, UserData> InstanceWithFunction<Parameters, Results>
56+
for StubInstance<UserData>
57+
where
58+
Parameters: FlatLayout + 'static,
59+
Results: FlatLayout + 'static,
60+
{
61+
type Function = ();
62+
63+
fn function_from_export(
64+
&mut self,
65+
_name: <Self::Runtime as Runtime>::Export,
66+
) -> Result<Option<Self::Function>, RuntimeError> {
67+
unimplemented!("`StubInstance` can not be used as a real `InstanceWithFunction`");
68+
}
69+
70+
fn call(
71+
&mut self,
72+
_function: &Self::Function,
73+
_parameters: Parameters,
74+
) -> Result<Results, RuntimeError> {
75+
unimplemented!("`StubInstance` can not be used as a real `InstanceWithFunction`");
76+
}
77+
}
78+
79+
impl<UserData> InstanceWithMemory for StubInstance<UserData> {
80+
fn memory_from_export(&self, _export: ()) -> Result<Option<StubMemory>, RuntimeError> {
81+
unimplemented!("`StubInstance` can not be used as a real `InstanceWithMemory`");
82+
}
83+
}
84+
85+
/// A stub Wasm runtime.
86+
pub struct StubRuntime;
87+
88+
impl Runtime for StubRuntime {
89+
type Export = ();
90+
type Memory = StubMemory;
91+
}
92+
93+
/// A stub Wasm runtime memory.
94+
pub struct StubMemory;
95+
96+
impl<UserData> RuntimeMemory<StubInstance<UserData>> for StubMemory {
97+
fn read<'instance>(
98+
&self,
99+
_instance: &'instance StubInstance<UserData>,
100+
_location: GuestPointer,
101+
_length: u32,
102+
) -> Result<Cow<'instance, [u8]>, RuntimeError> {
103+
unimplemented!("`StubMemory` can not be used as a real `RuntimeMemory`");
104+
}
105+
106+
fn write(
107+
&mut self,
108+
_instance: &mut StubInstance<UserData>,
109+
_location: GuestPointer,
110+
_bytes: &[u8],
111+
) -> Result<(), RuntimeError> {
112+
unimplemented!("`StubMemory` can not be used as a real `RuntimeMemory`");
113+
}
114+
}

0 commit comments

Comments
 (0)