Skip to content

Commit df5ef6c

Browse files
authored
WASM ABI: implement console ABIs (#1664)
1 parent da71d0f commit df5ef6c

File tree

9 files changed

+191
-150
lines changed

9 files changed

+191
-150
lines changed

crates/bindings-csharp/Runtime/bindings.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ OPAQUE_TYPEDEF(RowIter, uint32_t);
3636
#endif
3737

3838
IMPORT(void, _console_log,
39-
(LogLevel level, const uint8_t* target, uint32_t target_len,
40-
const uint8_t* filename, uint32_t filename_len, uint32_t line_number,
41-
const uint8_t* message, uint32_t message_len),
42-
(level, target, target_len, filename, filename_len, line_number, message,
43-
message_len));
39+
(LogLevel level, const uint8_t* target_ptr, uint32_t target_len,
40+
const uint8_t* filename_ptr, uint32_t filename_len, uint32_t line_number,
41+
const uint8_t* message_ptr, uint32_t message_len),
42+
(level, target_ptr, target_len, filename_ptr, filename_len, line_number,
43+
message_ptr, message_len));
4444

4545
IMPORT(Status, _table_id_from_name,
4646
(const uint8_t* name, uint32_t name_len, TableId* id),

crates/bindings-csharp/Runtime/build/SpacetimeDB.Runtime.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<ItemGroup Condition="'$(EXPERIMENTAL_WASM_AOT)' == '1'">
44
<NativeLibrary Include="$(MSBuildThisFileDirectory)..\bindings.c" />
55
<UnmanagedEntryPointsAssembly Include="SpacetimeDB.Runtime" />
6-
<WasmImport Include="$(SpacetimeNamespace)!_console_log" />
76
<WasmImport Include="$(SpacetimeNamespace)!_iter_by_col_eq" />
87
<WasmImport Include="$(SpacetimeNamespace)!_delete_by_col_eq" />
98
<WasmImport Include="$(SpacetimeNamespace)!_iter_start_filtered" />
@@ -16,6 +15,7 @@
1615
<WasmImport Include="$(SpacetimeNamespace)!_datastore_delete_all_by_eq_bsatn" />
1716
<WasmImport Include="$(SpacetimeNamespace)!_bytes_source_read" />
1817
<WasmImport Include="$(SpacetimeNamespace)!_bytes_sink_write" />
18+
<WasmImport Include="$(SpacetimeNamespace)!_console_log" />
1919

2020
<PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM" Version="8.0.0-*" />
2121
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="8.0.0-*" />

crates/bindings-sys/src/lib.rs

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -247,31 +247,6 @@ pub mod raw {
247247
/// - `SCHEDULE_AT_DELAY_TOO_LONG`, when the delay specified in the row was too long.
248248
pub fn _datastore_insert_bsatn(table_id: TableId, row_ptr: *mut u8, row_len_ptr: *mut usize) -> u16;
249249

250-
/// Log at `level` a `message` message occuring in `filename:line_number`
251-
/// with [`target`] being the module path at the `log!` invocation site.
252-
///
253-
/// These various pointers are interpreted lossily as UTF-8 strings with a corresponding `_len`.
254-
///
255-
/// The `target` and `filename` pointers are ignored by passing `NULL`.
256-
/// The line number is ignored if `line_number == u32::MAX`.
257-
///
258-
/// No message is logged if
259-
/// - `target != NULL && target + target_len > u64::MAX`
260-
/// - `filename != NULL && filename + filename_len > u64::MAX`
261-
/// - `message + message_len > u64::MAX`
262-
///
263-
/// [`target`]: https://docs.rs/log/latest/log/struct.Record.html#method.target
264-
pub fn _console_log(
265-
level: u8,
266-
target: *const u8,
267-
target_len: usize,
268-
filename: *const u8,
269-
filename_len: usize,
270-
line_number: u32,
271-
message: *const u8,
272-
message_len: usize,
273-
);
274-
275250
/// Schedules a reducer to be called asynchronously, nonatomically,
276251
/// and immediately on a best effort basis.
277252
///
@@ -374,23 +349,66 @@ pub mod raw {
374349
/// ```
375350
pub fn _bytes_source_read(source: BytesSource, buffer_ptr: *mut u8, buffer_len_ptr: *mut usize) -> i16;
376351

377-
/// Begin a timing span.
352+
/// Logs at `level` a `message` message occuring in `filename:line_number`
353+
/// with [`target`](target) being the module path at the `log!` invocation site.
354+
///
355+
/// These various pointers are interpreted lossily as UTF-8 strings with a corresponding `_len`.
378356
///
379-
/// When the returned `u32` span ID is passed to [`_span_end`],
357+
/// The `target` and `filename` pointers are ignored by passing `NULL`.
358+
/// The line number is ignored if `line_number == u32::MAX`.
359+
///
360+
/// No message is logged if
361+
/// - `target != NULL && target + target_len > u64::MAX`
362+
/// - `filename != NULL && filename + filename_len > u64::MAX`
363+
/// - `message + message_len > u64::MAX`
364+
///
365+
/// # Traps
366+
///
367+
/// Traps if:
368+
/// - `target` is not NULL and `target_ptr[..target_len]` is not in bounds of WASM memory.
369+
/// - `filename` is not NULL and `filename_ptr[..filename_len]` is not in bounds of WASM memory.
370+
/// - `message` is not NULL and `message_ptr[..message_len]` is not in bounds of WASM memory.
371+
///
372+
/// [target]: https://docs.rs/log/latest/log/struct.Record.html#method.target
373+
pub fn _console_log(
374+
level: u8,
375+
target_ptr: *const u8,
376+
target_len: usize,
377+
filename_ptr: *const u8,
378+
filename_len: usize,
379+
line_number: u32,
380+
message_ptr: *const u8,
381+
message_len: usize,
382+
);
383+
384+
/// Begins a timing span with `name = name_ptr[..name_len]`.
385+
///
386+
/// When the returned `ConsoleTimerId` is passed to [`console_timer_end`],
380387
/// the duration between the calls will be printed to the module's logs.
381388
///
382-
/// The slice (`name`, `name_len`) must be valid UTF-8 bytes.
383-
pub fn _span_start(name: *const u8, name_len: usize) -> u32;
389+
/// The `name` is interpreted lossily as UTF-8.
390+
///
391+
/// # Traps
392+
///
393+
/// Traps if:
394+
/// - `name_ptr` is NULL or `name` is not in bounds of WASM memory.
395+
pub fn _console_timer_start(name_ptr: *const u8, name_len: usize) -> u32;
384396

385397
/// End a timing span.
386398
///
387-
/// The `span_id` must be the result of a call to `_span_start`.
399+
/// The `timer_id` must be the result of a call to `console_timer_start`.
388400
/// The duration between the two calls will be computed and printed to the module's logs.
401+
/// Once `console_timer_end` is called on `id: ConsoleTimerId`, the `id` is invalid.
402+
/// That is, `console_timer_end(id)` the second time will yield `NO_SUCH_CONSOLE_TIMER`.
389403
///
390-
/// Behavior is unspecified
391-
/// if `_span_end` is called on a `span_id` which is not the result of a call to `_span_start`,
392-
/// or if `_span_end` is called multiple times with the same `span_id`.
393-
pub fn _span_end(span_id: u32);
404+
/// Note that the host is free to reuse allocations in a pool,
405+
/// destroying the handle logically does not entail that memory is necessarily reclaimed.
406+
///
407+
/// # Errors
408+
///
409+
/// Returns an error:
410+
/// - `NO_SUCH_CONSOLE_TIMER`, when `timer_id` does not exist.
411+
pub fn _console_timer_end(timer_id: u32) -> u16;
394412
}
395413

396414
/// What strategy does the database index use?

crates/bindings/src/time_span.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub struct Span {
55
impl Span {
66
pub fn start(name: &str) -> Self {
77
let name = name.as_bytes();
8-
let id = unsafe { spacetimedb_bindings_sys::raw::_span_start(name.as_ptr(), name.len()) };
8+
let id = unsafe { spacetimedb_bindings_sys::raw::_console_timer_start(name.as_ptr(), name.len()) };
99
Self { span_id: id }
1010
}
1111

@@ -17,7 +17,7 @@ impl Span {
1717
impl std::ops::Drop for Span {
1818
fn drop(&mut self) {
1919
unsafe {
20-
spacetimedb_bindings_sys::raw::_span_end(self.span_id);
20+
spacetimedb_bindings_sys::raw::_console_timer_end(self.span_id);
2121
}
2222
}
2323
}

crates/cli/src/subcommands/generate/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,15 +415,15 @@ pub fn extract_descriptions(wasm_file: &Path) -> anyhow::Result<RawModuleDefV8>
415415
"_console_log",
416416
|mut caller: Caller<'_, WasmCtx>,
417417
_level: u32,
418-
_target: u32,
418+
_target_ptr: u32,
419419
_target_len: u32,
420-
_filename: u32,
420+
_filename_ptr: u32,
421421
_filename_len: u32,
422422
_line_number: u32,
423-
message: u32,
423+
message_ptr: u32,
424424
message_len: u32| {
425425
let (mem, _) = WasmCtx::mem_env(&mut caller);
426-
let slice = mem.deref_slice(message, message_len).unwrap();
426+
let slice = mem.deref_slice(message_ptr, message_len).unwrap();
427427
println!("from wasm: {}", String::from_utf8_lossy(slice));
428428
},
429429
)?;

crates/core/src/host/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,20 @@ fn from_json_seed<'de, T: serde::de::DeserializeSeed<'de>>(s: &'de str, seed: T)
143143
pub enum AbiCall {
144144
TableIdFromName,
145145
DatastoreTableRowCount,
146+
DatastoreTableScanBsatn,
146147
RowIterBsatnAdvance,
147148
RowIterBsatnClose,
149+
DatastoreInsertBsatn,
150+
DatastoreDeleteAllByEqBsatn,
148151
BytesSourceRead,
149152
BytesSinkWrite,
150-
151-
CancelReducer,
152153
ConsoleLog,
154+
ConsoleTimerStart,
155+
ConsoleTimerEnd,
156+
153157
DeleteByColEq,
154-
DeleteByRel,
155-
DatastoreInsertBsatn,
156158
IterByColEq,
157-
IterStart,
158159
IterStartFiltered,
159-
ScheduleReducer,
160+
161+
VolatileNonatomicScheduleImmediate,
160162
}

crates/core/src/host/wasm_common.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,11 @@ pub(super) type RowIters = ResourceSlab<RowIterIdx>;
302302

303303
pub(super) struct TimingSpan {
304304
pub start: Instant,
305-
pub name: Vec<u8>,
305+
pub name: String,
306306
}
307307

308308
impl TimingSpan {
309-
pub fn new(name: Vec<u8>) -> Self {
309+
pub fn new(name: String) -> Self {
310310
Self {
311311
start: Instant::now(),
312312
name,
@@ -357,10 +357,9 @@ macro_rules! abi_funcs {
357357
"spacetime_10.0"::datastore_delete_all_by_eq_bsatn,
358358
"spacetime_10.0"::bytes_source_read,
359359
"spacetime_10.0"::bytes_sink_write,
360-
361360
"spacetime_10.0"::console_log,
362-
"spacetime_10.0"::span_end,
363-
"spacetime_10.0"::span_start,
361+
"spacetime_10.0"::console_timer_start,
362+
"spacetime_10.0"::console_timer_end,
364363

365364
"spacetime_10.0"::delete_by_col_eq,
366365
"spacetime_10.0"::iter_by_col_eq,

0 commit comments

Comments
 (0)