summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-01-27 15:27:47 +0100
committerHenry Gressmann <mail@henrygressmann.de>2024-01-27 15:27:47 +0100
commit4f405d192503d0b22f2da59cfac64f4b4e3aebe6 (patch)
treeaa533e31d5db3f68b385de1fb0a5d9bc631d50d8 /crates
parent9d30a1b0d93b45c05f86e61df77359303aab449d (diff)
pref: more callstack/callframe improvements
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates')
-rw-r--r--crates/tinywasm/src/func.rs4
-rw-r--r--crates/tinywasm/src/imports.rs4
-rw-r--r--crates/tinywasm/src/reference.rs2
-rw-r--r--crates/tinywasm/src/runtime/interpreter/mod.rs79
-rw-r--r--crates/tinywasm/src/runtime/stack.rs2
-rw-r--r--crates/tinywasm/src/runtime/stack/blocks.rs60
-rw-r--r--crates/tinywasm/src/runtime/stack/call_stack.rs63
-rw-r--r--crates/tinywasm/src/runtime/stack/value_stack.rs8
-rw-r--r--crates/tinywasm/src/runtime/value.rs1
-rw-r--r--crates/tinywasm/src/store.rs20
-rw-r--r--crates/types/src/lib.rs9
11 files changed, 128 insertions, 124 deletions
diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs
index 9c9938b..1c5129b 100644
--- a/crates/tinywasm/src/func.rs
+++ b/crates/tinywasm/src/func.rs
@@ -1,4 +1,4 @@
-use crate::log;
+use crate::{log, runtime::RawWasmValue};
use alloc::{boxed::Box, format, string::String, string::ToString, vec, vec::Vec};
use tinywasm_types::{FuncAddr, FuncType, ValType, WasmValue};
@@ -63,7 +63,7 @@ impl FuncHandle {
// 6. Let f be the dummy frame
log::debug!("locals: {:?}", locals);
- let call_frame = CallFrame::new(func_inst, params, locals);
+ let call_frame = CallFrame::new(func_inst, params.iter().map(|v| RawWasmValue::from(*v)), locals);
// 7. Push the frame f to the call stack
// & 8. Push the values to the stack (Not needed since the call frame owns the values)
diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs
index 28ea0ec..32140a7 100644
--- a/crates/tinywasm/src/imports.rs
+++ b/crates/tinywasm/src/imports.rs
@@ -154,7 +154,7 @@ impl Extern {
let inner_func = move |ctx: FuncContext<'_>, args: &[WasmValue]| -> Result<Vec<WasmValue>> {
let args = P::from_wasm_value_tuple(args)?;
let result = func(ctx, args)?;
- Ok(result.into_wasm_value_tuple())
+ Ok(result.into_wasm_value_tuple().to_vec())
};
let ty = tinywasm_types::FuncType { params: P::val_types(), results: R::val_types() };
@@ -383,7 +383,7 @@ impl Imports {
.ok_or_else(|| LinkingError::incompatible_import_type(import))?;
Self::compare_types(import, extern_func.ty(), import_func_type)?;
- imports.funcs.push(store.add_func(extern_func, *ty, idx)?);
+ imports.funcs.push(store.add_func(extern_func, idx)?);
}
_ => return Err(LinkingError::incompatible_import_type(import).into()),
},
diff --git a/crates/tinywasm/src/reference.rs b/crates/tinywasm/src/reference.rs
index fdaae18..ed09530 100644
--- a/crates/tinywasm/src/reference.rs
+++ b/crates/tinywasm/src/reference.rs
@@ -83,7 +83,7 @@ impl MemoryRef {
/// Load a UTF-8 string from memory
pub fn load_string(&self, offset: usize, len: usize) -> Result<String> {
let bytes = self.load_vec(offset, len)?;
- Ok(String::from_utf8(bytes).map_err(|_| crate::Error::Other("Invalid UTF-8 string".to_string()))?)
+ String::from_utf8(bytes).map_err(|_| crate::Error::Other("Invalid UTF-8 string".to_string()))
}
/// Load a C-style string from memory
diff --git a/crates/tinywasm/src/runtime/interpreter/mod.rs b/crates/tinywasm/src/runtime/interpreter/mod.rs
index 285ba8d..a59b544 100644
--- a/crates/tinywasm/src/runtime/interpreter/mod.rs
+++ b/crates/tinywasm/src/runtime/interpreter/mod.rs
@@ -1,7 +1,7 @@
use super::{InterpreterRuntime, Stack};
use crate::{cold, log, unlikely};
use crate::{
- runtime::{BlockType, CallFrame, LabelArgs, LabelFrame},
+ runtime::{BlockType, CallFrame, LabelFrame},
Error, FuncContext, ModuleInstance, Result, Store, Trap,
};
use alloc::format;
@@ -29,13 +29,12 @@ impl InterpreterRuntime {
let mut cf = stack.call_stack.pop()?;
let mut func_inst = cf.func_instance.clone();
- let mut wasm_func = func_inst.assert_wasm().expect("exec expected wasm function");
+ let mut wasm_func = func_inst.assert_wasm()?;
// The function to execute, gets updated from ExecResult::Call
let mut instrs = &wasm_func.instructions;
let mut instr_count = instrs.len();
-
- let mut current_module = store.get_module_instance(func_inst.owner).unwrap().clone();
+ let mut current_module = store.get_module_instance_raw(func_inst.owner);
loop {
if unlikely(cf.instr_ptr >= instr_count) {
@@ -164,8 +163,8 @@ fn exec_one(
}
};
- let params = stack.values.pop_n_rev(ty.params.len())?.collect::<Vec<_>>();
- let call_frame = CallFrame::new_raw(func_inst, &params, locals);
+ let params = stack.values.pop_n_rev(ty.params.len())?;
+ let call_frame = CallFrame::new(func_inst, params, locals);
// push the call frame
cf.instr_ptr += 1; // skip the call instruction
@@ -213,8 +212,8 @@ fn exec_one(
}
};
- let params = stack.values.pop_n_rev(func_ty.params.len())?.collect::<Vec<_>>();
- let call_frame = CallFrame::new_raw(func_inst, &params, locals);
+ let params = stack.values.pop_n_rev(func_ty.params.len())?;
+ let call_frame = CallFrame::new(func_inst, params, locals);
// push the call frame
cf.instr_ptr += 1; // skip the call instruction
@@ -229,13 +228,14 @@ fn exec_one(
// truthy value is on the top of the stack, so enter the then block
if stack.values.pop_t::<i32>()? != 0 {
cf.enter_label(
- LabelFrame {
- instr_ptr: cf.instr_ptr,
- end_instr_ptr: cf.instr_ptr + *end_offset,
- stack_ptr: stack.values.len(), // - params,
- args: LabelArgs::new(*args, module)?,
- ty: BlockType::If,
- },
+ LabelFrame::new(
+ cf.instr_ptr,
+ cf.instr_ptr + *end_offset,
+ stack.values.len(), // - params,
+ BlockType::If,
+ args,
+ module,
+ ),
&mut stack.values,
);
return Ok(ExecResult::Ok);
@@ -244,13 +244,14 @@ fn exec_one(
// falsy value is on the top of the stack
if let Some(else_offset) = else_offset {
cf.enter_label(
- LabelFrame {
- instr_ptr: cf.instr_ptr + *else_offset,
- end_instr_ptr: cf.instr_ptr + *end_offset,
- stack_ptr: stack.values.len(), // - params,
- args: LabelArgs::new(*args, module)?,
- ty: BlockType::Else,
- },
+ LabelFrame::new(
+ cf.instr_ptr + *else_offset,
+ cf.instr_ptr + *end_offset,
+ stack.values.len(), // - params,
+ BlockType::Else,
+ args,
+ module,
+ ),
&mut stack.values,
);
cf.instr_ptr += *else_offset;
@@ -261,26 +262,28 @@ fn exec_one(
Loop(args, end_offset) => {
cf.enter_label(
- LabelFrame {
- instr_ptr: cf.instr_ptr,
- end_instr_ptr: cf.instr_ptr + *end_offset,
- stack_ptr: stack.values.len(), // - params,
- args: LabelArgs::new(*args, module)?,
- ty: BlockType::Loop,
- },
+ LabelFrame::new(
+ cf.instr_ptr,
+ cf.instr_ptr + *end_offset,
+ stack.values.len(), // - params,
+ BlockType::Loop,
+ args,
+ module,
+ ),
&mut stack.values,
);
}
Block(args, end_offset) => {
cf.enter_label(
- LabelFrame {
- instr_ptr: cf.instr_ptr,
- end_instr_ptr: cf.instr_ptr + *end_offset,
- stack_ptr: stack.values.len(), //- params,
- args: LabelArgs::new(*args, module)?,
- ty: BlockType::Block,
- },
+ LabelFrame::new(
+ cf.instr_ptr,
+ cf.instr_ptr + *end_offset,
+ stack.values.len(), // - params,
+ BlockType::Block,
+ args,
+ module,
+ ),
&mut stack.values,
);
}
@@ -341,7 +344,7 @@ fn exec_one(
panic!("else: no label to end, this should have been validated by the parser");
};
- let res_count = block.args.results;
+ let res_count = block.results;
stack.values.truncate_keep(block.stack_ptr, res_count);
cf.instr_ptr += *end_offset;
}
@@ -352,7 +355,7 @@ fn exec_one(
cold();
panic!("end: no label to end, this should have been validated by the parser");
};
- stack.values.truncate_keep(block.stack_ptr, block.args.results)
+ stack.values.truncate_keep(block.stack_ptr, block.results)
}
LocalGet(local_index) => stack.values.push(cf.get_local(*local_index as usize)),
diff --git a/crates/tinywasm/src/runtime/stack.rs b/crates/tinywasm/src/runtime/stack.rs
index 07d9316..285d967 100644
--- a/crates/tinywasm/src/runtime/stack.rs
+++ b/crates/tinywasm/src/runtime/stack.rs
@@ -3,7 +3,7 @@ mod call_stack;
mod value_stack;
use self::{call_stack::CallStack, value_stack::ValueStack};
-pub(crate) use blocks::{BlockType, LabelArgs, LabelFrame};
+pub(crate) use blocks::{BlockType, LabelFrame};
pub(crate) use call_stack::CallFrame;
/// A WebAssembly Stack
diff --git a/crates/tinywasm/src/runtime/stack/blocks.rs b/crates/tinywasm/src/runtime/stack/blocks.rs
index ab2d28c..ff77cf8 100644
--- a/crates/tinywasm/src/runtime/stack/blocks.rs
+++ b/crates/tinywasm/src/runtime/stack/blocks.rs
@@ -1,12 +1,17 @@
use alloc::vec::Vec;
use tinywasm_types::BlockArgs;
-use crate::{ModuleInstance, Result};
+use crate::{unlikely, ModuleInstance};
-#[derive(Debug, Clone, Default)]
+#[derive(Debug, Clone)]
pub(crate) struct Labels(Vec<LabelFrame>);
impl Labels {
+ pub(crate) fn new() -> Self {
+ // this is somehow a lot faster than Vec::with_capacity(128) or even using Default::default() in the benchmarks
+ Self(Vec::new())
+ }
+
pub(crate) fn len(&self) -> usize {
self.0.len()
}
@@ -19,7 +24,12 @@ impl Labels {
#[inline]
/// get the label at the given index, where 0 is the top of the stack
pub(crate) fn get_relative_to_top(&self, index: usize) -> Option<&LabelFrame> {
- self.0.get(self.0.len() - index - 1)
+ // the vast majority of wasm functions don't use break to return
+ if unlikely(index >= self.0.len()) {
+ return None;
+ }
+
+ Some(&self.0[self.0.len() - index - 1])
}
#[inline]
@@ -43,10 +53,34 @@ pub(crate) struct LabelFrame {
// position of the stack pointer when the block was entered
pub(crate) stack_ptr: usize,
- pub(crate) args: LabelArgs,
+ pub(crate) results: usize,
+ pub(crate) params: usize,
pub(crate) ty: BlockType,
}
+impl LabelFrame {
+ #[inline]
+ pub(crate) fn new(
+ instr_ptr: usize,
+ end_instr_ptr: usize,
+ stack_ptr: usize,
+ ty: BlockType,
+ args: &BlockArgs,
+ module: &ModuleInstance,
+ ) -> Self {
+ let (params, results) = match args {
+ BlockArgs::Empty => (0, 0),
+ BlockArgs::Type(_) => (0, 1),
+ BlockArgs::FuncType(t) => {
+ let ty = module.func_ty(*t);
+ (ty.params.len(), ty.results.len())
+ }
+ };
+
+ Self { instr_ptr, end_instr_ptr, stack_ptr, results, params, ty }
+ }
+}
+
#[derive(Debug, Copy, Clone)]
#[allow(dead_code)]
pub(crate) enum BlockType {
@@ -55,21 +89,3 @@ pub(crate) enum BlockType {
Else,
Block,
}
-
-#[derive(Debug, Clone, Default)]
-pub(crate) struct LabelArgs {
- pub(crate) params: usize,
- pub(crate) results: usize,
-}
-
-impl LabelArgs {
- pub(crate) fn new(args: BlockArgs, module: &ModuleInstance) -> Result<Self> {
- Ok(match args {
- BlockArgs::Empty => LabelArgs { params: 0, results: 0 },
- BlockArgs::Type(_) => LabelArgs { params: 0, results: 1 },
- BlockArgs::FuncType(t) => {
- LabelArgs { params: module.func_ty(t).params.len(), results: module.func_ty(t).results.len() }
- }
- })
- }
-}
diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs
index 46c745a..ebec142 100644
--- a/crates/tinywasm/src/runtime/stack/call_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/call_stack.rs
@@ -1,16 +1,15 @@
-use crate::log;
+use crate::unlikely;
use crate::{
runtime::{BlockType, RawWasmValue},
Error, FunctionInstance, Result, Trap,
};
-use alloc::vec;
use alloc::{boxed::Box, rc::Rc, vec::Vec};
-use tinywasm_types::{ValType, WasmValue};
+use tinywasm_types::ValType;
use super::{blocks::Labels, LabelFrame};
// minimum call stack size
-const CALL_STACK_SIZE: usize = 256;
+const CALL_STACK_SIZE: usize = 128;
const CALL_STACK_MAX_SIZE: usize = 1024;
#[derive(Debug)]
@@ -32,16 +31,17 @@ impl CallStack {
#[inline]
pub(crate) fn pop(&mut self) -> Result<CallFrame> {
- self.stack.pop().ok_or_else(|| Error::CallStackEmpty)
+ match self.stack.pop() {
+ Some(frame) => Ok(frame),
+ None => Err(Error::CallStackEmpty),
+ }
}
#[inline]
pub(crate) fn push(&mut self, call_frame: CallFrame) -> Result<()> {
- log::debug!("stack size: {}", self.stack.len());
- if self.stack.len() >= CALL_STACK_MAX_SIZE {
+ if unlikely(self.stack.len() >= CALL_STACK_MAX_SIZE) {
return Err(Trap::CallStackOverflow.into());
}
-
self.stack.push(call_frame);
Ok(())
}
@@ -55,15 +55,14 @@ pub(crate) struct CallFrame {
pub(crate) labels: Labels,
pub(crate) locals: Box<[RawWasmValue]>,
- pub(crate) local_count: usize,
}
impl CallFrame {
#[inline]
/// Push a new label to the label stack and ensure the stack has the correct values
pub(crate) fn enter_label(&mut self, label_frame: LabelFrame, stack: &mut super::ValueStack) {
- if label_frame.args.params > 0 {
- stack.extend_from_within((label_frame.stack_ptr - label_frame.args.params)..label_frame.stack_ptr);
+ if label_frame.params > 0 {
+ stack.extend_from_within((label_frame.stack_ptr - label_frame.params)..label_frame.stack_ptr);
}
self.labels.push(label_frame);
@@ -80,7 +79,7 @@ impl CallFrame {
BlockType::Loop => {
// this is a loop, so we want to jump back to the start of the loop
// We also want to push the params to the stack
- value_stack.break_to(break_to.stack_ptr, break_to.args.params);
+ value_stack.break_to(break_to.stack_ptr, break_to.params);
self.instr_ptr = break_to.instr_ptr;
@@ -90,7 +89,7 @@ impl CallFrame {
BlockType::Block | BlockType::If | BlockType::Else => {
// this is a block, so we want to jump to the next instruction after the block ends
// We also want to push the block's results to the stack
- value_stack.break_to(break_to.stack_ptr, break_to.args.results);
+ value_stack.break_to(break_to.stack_ptr, break_to.results);
// (the inst_ptr will be incremented by 1 before the next instruction is executed)
self.instr_ptr = break_to.end_instr_ptr;
@@ -103,46 +102,30 @@ impl CallFrame {
Some(())
}
- // TOOD: perf: this function is pretty hot
- // Especially the two `extend` calls
- pub(crate) fn new_raw(
- func_instance_ptr: Rc<FunctionInstance>,
- params: &[RawWasmValue],
- local_types: Vec<ValType>,
- ) -> Self {
- let mut locals = vec![RawWasmValue::default(); local_types.len() + params.len()];
- locals[..params.len()].copy_from_slice(params);
-
- Self {
- instr_ptr: 0,
- func_instance: func_instance_ptr,
- local_count: locals.len(),
- locals: locals.into_boxed_slice(),
- labels: Labels::default(),
- }
- }
-
+ #[inline]
pub(crate) fn new(
func_instance_ptr: Rc<FunctionInstance>,
- params: &[WasmValue],
+ params: impl Iterator<Item = RawWasmValue> + ExactSizeIterator,
local_types: Vec<ValType>,
) -> Self {
- CallFrame::new_raw(
- func_instance_ptr,
- &params.iter().map(|v| RawWasmValue::from(*v)).collect::<Vec<_>>(),
- local_types,
- )
+ let locals = {
+ let total_size = local_types.len() + params.len();
+ let mut locals = Vec::with_capacity(total_size);
+ locals.extend(params);
+ locals.resize_with(total_size, RawWasmValue::default);
+ locals.into_boxed_slice()
+ };
+
+ Self { instr_ptr: 0, func_instance: func_instance_ptr, locals, labels: Labels::new() }
}
#[inline]
pub(crate) fn set_local(&mut self, local_index: usize, value: RawWasmValue) {
- assert!(local_index < self.local_count, "Invalid local index");
self.locals[local_index] = value;
}
#[inline]
pub(crate) fn get_local(&self, local_index: usize) -> RawWasmValue {
- assert!(local_index < self.local_count, "Invalid local index");
self.locals[local_index]
}
}
diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs
index e1c3107..3c5f48b 100644
--- a/crates/tinywasm/src/runtime/stack/value_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/value_stack.rs
@@ -1,11 +1,12 @@
use core::ops::Range;
use crate::{cold, runtime::RawWasmValue, unlikely, Error, Result};
+use alloc::vec;
use alloc::vec::Vec;
use tinywasm_types::{ValType, WasmValue};
-// minimum stack size
-pub(crate) const STACK_SIZE: usize = 1024;
+pub(crate) const MIN_VALUE_STACK_SIZE: usize = 1024;
+// pub(crate) const MAX_VALUE_STACK_SIZE: usize = 1024 * 1024;
#[derive(Debug)]
pub(crate) struct ValueStack {
@@ -14,7 +15,7 @@ pub(crate) struct ValueStack {
impl Default for ValueStack {
fn default() -> Self {
- Self { stack: Vec::with_capacity(STACK_SIZE) }
+ Self { stack: vec![RawWasmValue::default(); MIN_VALUE_STACK_SIZE] }
}
}
@@ -97,6 +98,7 @@ impl ValueStack {
Ok(res)
}
+ #[inline]
pub(crate) fn break_to(&mut self, new_stack_size: usize, result_count: usize) {
self.stack.drain(new_stack_size..(self.stack.len() - result_count));
}
diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs
index 7230830..329a60b 100644
--- a/crates/tinywasm/src/runtime/value.rs
+++ b/crates/tinywasm/src/runtime/value.rs
@@ -8,6 +8,7 @@ use tinywasm_types::{ValType, WasmValue};
///
/// See [`WasmValue`] for the public representation.
#[derive(Clone, Copy, Default, PartialEq, Eq)]
+#[repr(transparent)]
pub struct RawWasmValue(u64);
impl Debug for RawWasmValue {
diff --git a/crates/tinywasm/src/store.rs b/crates/tinywasm/src/store.rs
index ff40b33..dd8112d 100644
--- a/crates/tinywasm/src/store.rs
+++ b/crates/tinywasm/src/store.rs
@@ -46,10 +46,13 @@ impl Store {
/// Get a module instance by the internal id
pub fn get_module_instance(&self, addr: ModuleInstanceAddr) -> Option<&ModuleInstance> {
- log::debug!("existing module instances: {:?}", self.module_instances.len());
self.module_instances.get(addr as usize)
}
+ pub(crate) fn get_module_instance_raw(&self, addr: ModuleInstanceAddr) -> ModuleInstance {
+ self.module_instances[addr as usize].clone()
+ }
+
/// Create a new store with the given runtime
pub(crate) fn runtime(&self) -> runtime::InterpreterRuntime {
match self.runtime {
@@ -118,12 +121,8 @@ impl Store {
let func_count = self.data.funcs.len();
let mut func_addrs = Vec::with_capacity(func_count);
- for (i, (type_idx, func)) in funcs.into_iter().enumerate() {
- self.data.funcs.push(Rc::new(FunctionInstance {
- func: Function::Wasm(func),
- _type_idx: type_idx,
- owner: idx,
- }));
+ for (i, (_, func)) in funcs.into_iter().enumerate() {
+ self.data.funcs.push(Rc::new(FunctionInstance { func: Function::Wasm(func), owner: idx }));
func_addrs.push((i + func_count) as FuncAddr);
}
@@ -222,7 +221,7 @@ impl Store {
) -> Result<(Box<[Addr]>, Option<Trap>)> {
let elem_count = self.data.elements.len();
let mut elem_addrs = Vec::with_capacity(elem_count);
- for (i, element) in elements.into_iter().enumerate() {
+ for (i, element) in elements.iter().enumerate() {
let init = element
.items
.iter()
@@ -344,8 +343,8 @@ impl Store {
Ok(self.data.memories.len() as MemAddr - 1)
}
- pub(crate) fn add_func(&mut self, func: Function, type_idx: TypeAddr, idx: ModuleInstanceAddr) -> Result<FuncAddr> {
- self.data.funcs.push(Rc::new(FunctionInstance { func, _type_idx: type_idx, owner: idx }));
+ pub(crate) fn add_func(&mut self, func: Function, idx: ModuleInstanceAddr) -> Result<FuncAddr> {
+ self.data.funcs.push(Rc::new(FunctionInstance { func, owner: idx }));
Ok(self.data.funcs.len() as FuncAddr - 1)
}
@@ -445,7 +444,6 @@ impl Store {
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
pub(crate) struct FunctionInstance {
pub(crate) func: Function,
- pub(crate) _type_idx: TypeAddr,
pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances, none for host functions
}
diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs
index 9af8e11..2ccf869 100644
--- a/crates/types/src/lib.rs
+++ b/crates/types/src/lib.rs
@@ -12,6 +12,7 @@ extern crate alloc;
// log for logging (optional).
#[cfg(feature = "logging")]
+#[allow(clippy::single_component_path_imports)]
use log;
#[cfg(not(feature = "logging"))]
@@ -173,7 +174,7 @@ impl TryFrom<WasmValue> for i32 {
match value {
WasmValue::I32(i) => Ok(i),
_ => {
- log::error!("i32: try_from failed: {:?}", value);
+ crate::log::error!("i32: try_from failed: {:?}", value);
Err(())
}
}
@@ -187,7 +188,7 @@ impl TryFrom<WasmValue> for i64 {
match value {
WasmValue::I64(i) => Ok(i),
_ => {
- log::error!("i64: try_from failed: {:?}", value);
+ crate::log::error!("i64: try_from failed: {:?}", value);
Err(())
}
}
@@ -201,7 +202,7 @@ impl TryFrom<WasmValue> for f32 {
match value {
WasmValue::F32(i) => Ok(i),
_ => {
- log::error!("f32: try_from failed: {:?}", value);
+ crate::log::error!("f32: try_from failed: {:?}", value);
Err(())
}
}
@@ -215,7 +216,7 @@ impl TryFrom<WasmValue> for f64 {
match value {
WasmValue::F64(i) => Ok(i),
_ => {
- log::error!("f64: try_from failed: {:?}", value);
+ crate::log::error!("f64: try_from failed: {:?}", value);
Err(())
}
}