Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions crates/core/src/host/module_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@

use crate::{
energy::EnergyMonitor,
host::{
module_host::ModuleInfo,
wasm_common::{module_host_actor::DescribeError, DESCRIBE_MODULE_DUNDER},
Scheduler,
},
host::{module_host::ModuleInfo, wasm_common::module_host_actor::DescribeError, Scheduler},
module_host_context::ModuleCreationContextLimited,
replica_context::ReplicaContext,
};
Expand Down Expand Up @@ -90,11 +86,10 @@ impl ModuleCommon {

/// Runs the describer of modules in `run` and does some logging around it.
pub(crate) fn run_describer<T>(
describer_func_name: &str,
log_traceback: impl Copy + FnOnce(&str, &str, &anyhow::Error),
run: impl FnOnce() -> anyhow::Result<T>,
) -> Result<T, DescribeError> {
let describer_func_name = DESCRIBE_MODULE_DUNDER;

let start = std::time::Instant::now();
log::trace!("Start describer \"{describer_func_name}\"...");

Expand Down
4 changes: 3 additions & 1 deletion crates/core/src/host/v8/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::host::wasm_common::module_host_actor::{
InstanceOp, ProcedureExecuteResult, ProcedureOp, ReducerExecuteResult, ReducerOp, ViewExecuteResult, ViewOp,
WasmInstance,
};
use crate::host::wasm_common::{RowIters, TimingSpanSet};
use crate::host::wasm_common::{RowIters, TimingSpanSet, DESCRIBE_MODULE_DUNDER};
use crate::host::{ModuleHost, ReducerCallError, ReducerCallResult, Scheduler};
use crate::module_host_context::{ModuleCreationContext, ModuleCreationContextLimited};
use crate::replica_context::ReplicaContext;
Expand Down Expand Up @@ -862,6 +862,8 @@ fn extract_description<'scope>(
replica_ctx: &ReplicaContext,
) -> Result<RawModuleDef, DescribeError> {
run_describer(
//TODO(shub): make it work with `DESCRIBE_MODULE_DUNDER_V10`
DESCRIBE_MODULE_DUNDER,
|a, b, c| log_traceback(replica_ctx, a, b, c),
|| {
catch_exception(scope, |scope| {
Expand Down
47 changes: 44 additions & 3 deletions crates/core/src/host/wasm_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use super::{scheduler::ScheduleError, AbiCall};
use crate::error::{DBError, DatastoreError, IndexError, NodesError};
use spacetimedb_primitives::errno;
use spacetimedb_sats::typespace::TypeRefError;
use spacetimedb_schema::def::RawModuleDefVersion;
use spacetimedb_table::table::UniqueConstraintViolation;

pub const CALL_REDUCER_DUNDER: &str = "__call_reducer__";
Expand All @@ -20,13 +21,52 @@ pub const CALL_VIEW_DUNDER: &str = "__call_view__";

pub const CALL_VIEW_ANON_DUNDER: &str = "__call_view_anon__";

/// Name of the function that modules export to the host to describe themselves.
///
/// Used by module definitions with versions up to
/// [`RawModuleDefVersion::V9OrEarlier`].
pub const DESCRIBE_MODULE_DUNDER: &str = "__describe_module__";

/// Versioned variant of [`DESCRIBE_MODULE_DUNDER`] for
/// [`RawModuleDefVersion::V10`].
pub const DESCRIBE_MODULE_DUNDER_V10: &str = "__describe_module_v10__";

/// functions with this prefix run prior to __setup__, initializing global variables and the like
pub const PREINIT_DUNDER: &str = "__preinit__";
/// initializes the user code in the module. fallible
pub const SETUP_DUNDER: &str = "__setup__";

/// Detects the [`RawModuleDefVersion`] of a module by checking for the presence
/// of a known describe function export.
pub fn detect_raw_def_version<M>(module: &M) -> Result<RawModuleDefVersion, module_host_actor::DescribeError>
where
M: module_host_actor::WasmModule,
{
if module.get_export(DESCRIBE_MODULE_DUNDER).is_some() {
Ok(RawModuleDefVersion::V9OrEarlier)
} else if module.get_export(DESCRIBE_MODULE_DUNDER_V10).is_some() {
Ok(RawModuleDefVersion::V10)
} else {
Err(module_host_actor::DescribeError::Signature(anyhow::anyhow!(
"module does not export a {} or {} function",
DESCRIBE_MODULE_DUNDER,
DESCRIBE_MODULE_DUNDER_V10
)))
}
}
/// Returns the describe dunder symbol for a given module version.
pub const fn describe_dunder(version: RawModuleDefVersion) -> &'static str {
match version {
RawModuleDefVersion::V9OrEarlier => DESCRIBE_MODULE_DUNDER,
RawModuleDefVersion::V10 => DESCRIBE_MODULE_DUNDER_V10,
}
}

/// Returns all known describe dunder symbols.
pub const fn describe_dunders() -> &'static [&'static str] {
&[DESCRIBE_MODULE_DUNDER, DESCRIBE_MODULE_DUNDER_V10]
}

#[derive(Debug, Clone)]
#[allow(unused)]
pub enum WasmType {
Expand Down Expand Up @@ -229,7 +269,7 @@ impl FuncNames {
}
Ok(())
}
pub fn check_required<F, T>(get_export: F) -> Result<(), ValidationError>
pub fn check_required<F, T>(raw_def_ver: RawModuleDefVersion, get_export: F) -> Result<(), ValidationError>
where
F: Fn(&str) -> Option<T>,
T: FuncSigLike,
Expand All @@ -243,8 +283,9 @@ impl FuncNames {
let sig = get_func(CALL_REDUCER_DUNDER)?;
Self::validate_signature("call_reducer", &sig, CALL_REDUCER_DUNDER, CALL_REDUCER_SIG)?;

let sig = get_func(DESCRIBE_MODULE_DUNDER)?;
Self::validate_signature("describe_module", &sig, DESCRIBE_MODULE_DUNDER, DESCRIBE_MODULE_SIG)?;
let describe_dunder = describe_dunder(raw_def_ver);
let sig = get_func(describe_dunder)?;
Self::validate_signature("describe_module", &sig, describe_dunder, DESCRIBE_MODULE_SIG)?;

Ok(())
}
Expand Down
5 changes: 3 additions & 2 deletions crates/core/src/host/wasm_common/module_host_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ impl From<TypeRefError> for InitializationError {

#[derive(thiserror::Error, Debug)]
pub enum DescribeError {
#[error("bad signature for descriptor function: {0}")]
#[error("failed to call descriptor function: invalid signature or function does not exist: {0}")]
Signature(anyhow::Error),
#[error("error when preparing descriptor function: {0}")]
Setup(anyhow::Error),
Expand All @@ -301,8 +301,9 @@ impl<T: WasmModule> WasmModuleHostActor<T> {
mcc.program_hash,
);

let raw_def_version = detect_raw_def_version(&module)?;
let func_names = {
FuncNames::check_required(|name| module.get_export(name))?;
FuncNames::check_required(raw_def_version, |name| module.get_export(name))?;
let mut func_names = FuncNames::default();
module.for_each_export(|sym, ty| func_names.update_from_general(sym, ty))?;
func_names.preinits.sort_unstable();
Expand Down
23 changes: 17 additions & 6 deletions crates/core/src/host/wasmtime/wasmtime_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,16 +352,27 @@ pub struct WasmtimeInstance {

impl module_host_actor::WasmInstance for WasmtimeInstance {
fn extract_descriptions(&mut self) -> Result<RawModuleDef, DescribeError> {
let describer_func_name = DESCRIBE_MODULE_DUNDER;
let mut describer_res = None;
for &describe_func_name in describe_dunders() {
match self
.instance
.get_typed_func::<u32, ()>(&mut self.store, describe_func_name)
{
Ok(describer) => {
describer_res = Some(Ok((describe_func_name, describer)));
break;
}
Err(e) => describer_res = Some(Err(DescribeError::Signature(e))),
}
}

let describer = self
.instance
.get_typed_func::<u32, ()>(&mut self.store, describer_func_name)
.map_err(DescribeError::Signature)?;
let (describer_func_name, describer) = describer_res
.transpose()?
.ok_or_else(|| DescribeError::Signature(anyhow::anyhow!("no describer function found")))?;

let sink = self.store.data_mut().setup_standard_bytes_sink();

run_describer(log_traceback, || {
run_describer(describer_func_name, log_traceback, || {
call_sync_typed_func(&describer, &mut self.store, sink)
})?;

Expand Down
2 changes: 1 addition & 1 deletion crates/schema/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ pub struct ModuleDef {
raw_module_def_version: RawModuleDefVersion,
}

#[derive(Debug, Clone)]
#[derive(Debug, Copy, Clone)]
pub enum RawModuleDefVersion {
/// Represents [`RawModuleDefV9`] and earlier.
V9OrEarlier,
Expand Down
Loading