mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
feat(interface-types) Rename write-utf8
to string-to-memory
.
This commit is contained in:
parent
2d6b987791
commit
a93421f6c2
@ -187,11 +187,11 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
||||
0x03 => (input, Instruction::MemoryToString),
|
||||
|
||||
0x04 => {
|
||||
consume!((input, argument_0) = string(input)?);
|
||||
consume!((input, argument_0) = uleb(input)?);
|
||||
(
|
||||
input,
|
||||
Instruction::WriteUtf8 {
|
||||
allocator_name: argument_0,
|
||||
Instruction::StringToMemory {
|
||||
allocator_index: argument_0 as u32,
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -642,7 +642,7 @@ mod tests {
|
||||
0x01, 0x01, // Call { function_index: 1 }
|
||||
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
|
||||
0x03, // MemoryToString
|
||||
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
|
||||
0x04, 0x01, // StringToMemory { allocator_index: 1 }
|
||||
0x07, // I32ToS8
|
||||
0x08, // I32ToS8X
|
||||
0x09, // I32ToU8
|
||||
@ -691,9 +691,7 @@ mod tests {
|
||||
Instruction::Call { function_index: 1 },
|
||||
Instruction::CallExport { export_name: "abc" },
|
||||
Instruction::MemoryToString,
|
||||
Instruction::WriteUtf8 {
|
||||
allocator_name: "abc",
|
||||
},
|
||||
Instruction::StringToMemory { allocator_index: 1 },
|
||||
Instruction::I32ToS8,
|
||||
Instruction::I32ToS8X,
|
||||
Instruction::I32ToU8,
|
||||
|
@ -30,7 +30,7 @@ mod keyword {
|
||||
custom_keyword!(call);
|
||||
custom_keyword!(call_export = "call-export");
|
||||
custom_keyword!(memory_to_string = "memory-to-string");
|
||||
custom_keyword!(write_utf8 = "write-utf8");
|
||||
custom_keyword!(string_to_memory = "string-to-memory");
|
||||
custom_keyword!(i32_to_s8 = "i32-to-s8");
|
||||
custom_keyword!(i32_to_s8x = "i32-to-s8x");
|
||||
custom_keyword!(i32_to_u8 = "i32-to-u8");
|
||||
@ -165,11 +165,11 @@ impl<'a> Parse<'a> for Instruction<'a> {
|
||||
parser.parse::<keyword::memory_to_string>()?;
|
||||
|
||||
Ok(Instruction::MemoryToString)
|
||||
} else if lookahead.peek::<keyword::write_utf8>() {
|
||||
parser.parse::<keyword::write_utf8>()?;
|
||||
} else if lookahead.peek::<keyword::string_to_memory>() {
|
||||
parser.parse::<keyword::string_to_memory>()?;
|
||||
|
||||
Ok(Instruction::WriteUtf8 {
|
||||
allocator_name: parser.parse()?,
|
||||
Ok(Instruction::StringToMemory {
|
||||
allocator_index: parser.parse()?,
|
||||
})
|
||||
} else if lookahead.peek::<keyword::i32_to_s8>() {
|
||||
parser.parse::<keyword::i32_to_s8>()?;
|
||||
@ -676,7 +676,7 @@ mod tests {
|
||||
"call 7",
|
||||
r#"call-export "foo""#,
|
||||
"memory-to-string",
|
||||
r#"write-utf8 "foo""#,
|
||||
"string-to-memory 42",
|
||||
"i32-to-s8",
|
||||
"i32-to-s8x",
|
||||
"i32-to-u8",
|
||||
@ -722,8 +722,8 @@ mod tests {
|
||||
Instruction::Call { function_index: 7 },
|
||||
Instruction::CallExport { export_name: "foo" },
|
||||
Instruction::MemoryToString,
|
||||
Instruction::WriteUtf8 {
|
||||
allocator_name: "foo",
|
||||
Instruction::StringToMemory {
|
||||
allocator_index: 42,
|
||||
},
|
||||
Instruction::I32ToS8,
|
||||
Instruction::I32ToS8X,
|
||||
|
@ -267,9 +267,9 @@ where
|
||||
|
||||
Instruction::MemoryToString => 0x03_u8.to_bytes(writer)?,
|
||||
|
||||
Instruction::WriteUtf8 { allocator_name } => {
|
||||
Instruction::StringToMemory { allocator_index } => {
|
||||
0x04_u8.to_bytes(writer)?;
|
||||
allocator_name.to_bytes(writer)?;
|
||||
(*allocator_index as u64).to_bytes(writer)?;
|
||||
}
|
||||
|
||||
Instruction::I32ToS8 => 0x07_u8.to_bytes(writer)?,
|
||||
@ -557,9 +557,7 @@ mod tests {
|
||||
Instruction::Call { function_index: 1 },
|
||||
Instruction::CallExport { export_name: "abc" },
|
||||
Instruction::MemoryToString,
|
||||
Instruction::WriteUtf8 {
|
||||
allocator_name: "abc",
|
||||
},
|
||||
Instruction::StringToMemory { allocator_index: 1 },
|
||||
Instruction::I32ToS8,
|
||||
Instruction::I32ToS8X,
|
||||
Instruction::I32ToU8,
|
||||
@ -606,7 +604,7 @@ mod tests {
|
||||
0x01, 0x01, // Call { function_index: 1 }
|
||||
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
|
||||
0x03, // MemoryToString
|
||||
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
|
||||
0x04, 0x01, // StringToMemory { allocator_index: 1 }
|
||||
0x07, // I32ToS8
|
||||
0x08, // I32ToS8X
|
||||
0x09, // I32ToU8
|
||||
|
@ -87,8 +87,8 @@ impl<'input> ToString for &Instruction<'input> {
|
||||
Instruction::Call { function_index } => format!("call {}", function_index),
|
||||
Instruction::CallExport { export_name } => format!(r#"call-export "{}""#, export_name),
|
||||
Instruction::MemoryToString => "memory-to-string".into(),
|
||||
Instruction::WriteUtf8 { allocator_name } => {
|
||||
format!(r#"write-utf8 "{}""#, allocator_name)
|
||||
Instruction::StringToMemory { allocator_index } => {
|
||||
format!(r#"string-to-memory {}"#, allocator_index)
|
||||
}
|
||||
Instruction::I32ToS8 => "i32-to-s8".into(),
|
||||
Instruction::I32ToS8X => "i32-to-s8x".into(),
|
||||
@ -364,8 +364,8 @@ mod tests {
|
||||
(&Instruction::Call { function_index: 7 }).to_string(),
|
||||
(&Instruction::CallExport { export_name: "foo" }).to_string(),
|
||||
(&Instruction::MemoryToString).to_string(),
|
||||
(&Instruction::WriteUtf8 {
|
||||
allocator_name: "foo",
|
||||
(&Instruction::StringToMemory {
|
||||
allocator_index: 42,
|
||||
})
|
||||
.to_string(),
|
||||
(&Instruction::I32ToS8).to_string(),
|
||||
@ -413,7 +413,7 @@ mod tests {
|
||||
"call 7",
|
||||
r#"call-export "foo""#,
|
||||
"memory-to-string",
|
||||
r#"write-utf8 "foo""#,
|
||||
"string-to-memory 42",
|
||||
"i32-to-s8",
|
||||
"i32-to-s8x",
|
||||
"i32-to-u8",
|
||||
|
@ -24,10 +24,10 @@ pub enum Instruction<'input> {
|
||||
/// The `memory-to-string` instruction.
|
||||
MemoryToString,
|
||||
|
||||
/// The `write-utf8` instruction.
|
||||
WriteUtf8 {
|
||||
/// The allocator function name.
|
||||
allocator_name: &'input str,
|
||||
/// The `string-to-memory` instruction.
|
||||
StringToMemory {
|
||||
/// The allocator function index.
|
||||
allocator_index: u32,
|
||||
},
|
||||
|
||||
/// The `i32-to-s8,` instruction.
|
||||
|
@ -3,14 +3,14 @@ mod call;
|
||||
mod call_export;
|
||||
mod lowering_lifting;
|
||||
mod memory_to_string;
|
||||
mod write_utf8;
|
||||
mod string_to_memory;
|
||||
|
||||
pub(crate) use argument_get::argument_get;
|
||||
pub(crate) use call::call;
|
||||
pub(crate) use call_export::call_export;
|
||||
pub(crate) use lowering_lifting::*;
|
||||
pub(crate) use memory_to_string::memory_to_string;
|
||||
pub(crate) use write_utf8::write_utf8;
|
||||
pub(crate) use string_to_memory::string_to_memory;
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
@ -133,23 +133,12 @@ pub(crate) mod tests {
|
||||
},
|
||||
},
|
||||
);
|
||||
hashmap.insert(
|
||||
"alloc".into(),
|
||||
Export {
|
||||
inputs: vec![InterfaceType::I32],
|
||||
outputs: vec![InterfaceType::I32],
|
||||
function: |arguments: &[InterfaceValue]| {
|
||||
let _size: i32 = (&arguments[0]).try_into().unwrap();
|
||||
|
||||
Ok(vec![InterfaceValue::I32(0)])
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
hashmap
|
||||
},
|
||||
locals_or_imports: {
|
||||
let mut hashmap = HashMap::new();
|
||||
// sum
|
||||
hashmap.insert(
|
||||
42,
|
||||
LocalImport {
|
||||
@ -163,6 +152,19 @@ pub(crate) mod tests {
|
||||
},
|
||||
},
|
||||
);
|
||||
// string allocator
|
||||
hashmap.insert(
|
||||
43,
|
||||
LocalImport {
|
||||
inputs: vec![InterfaceType::I32],
|
||||
outputs: vec![InterfaceType::I32],
|
||||
function: |arguments: &[InterfaceValue]| {
|
||||
let _size: i32 = (&arguments[0]).try_into().unwrap();
|
||||
|
||||
Ok(vec![InterfaceValue::I32(0)])
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
hashmap
|
||||
},
|
||||
|
169
src/interpreter/instructions/string_to_memory.rs
Normal file
169
src/interpreter/instructions/string_to_memory.rs
Normal file
@ -0,0 +1,169 @@
|
||||
use crate::interpreter::wasm::{
|
||||
structures::{FunctionIndex, TypedIndex},
|
||||
values::{InterfaceType, InterfaceValue},
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
|
||||
executable_instruction!(
|
||||
string_to_memory(allocator_index: u32, instruction_name: String) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let instance = &mut runtime.wasm_instance;
|
||||
let index = FunctionIndex::new(allocator_index as usize);
|
||||
|
||||
let allocator = instance.local_or_import(index).ok_or_else(|| {
|
||||
format!(
|
||||
"`{}` failed because the function `{}` (the allocator) doesn't exist.",
|
||||
instruction_name,
|
||||
allocator_index
|
||||
)
|
||||
})?;
|
||||
|
||||
if allocator.inputs() != [InterfaceType::I32] || allocator.outputs() != [InterfaceType::I32] {
|
||||
return Err(format!(
|
||||
"`{}` failed because the allocator `{}` has an invalid signature (expects [I32] -> [I32]).",
|
||||
instruction_name,
|
||||
allocator_index,
|
||||
));
|
||||
}
|
||||
|
||||
let string = runtime.stack.pop1().ok_or_else(|| {
|
||||
format!(
|
||||
"`{}` cannot call the allocator `{}` because there is not enough data on the stack for the arguments (needs {}).",
|
||||
instruction_name,
|
||||
allocator_index,
|
||||
1
|
||||
)
|
||||
})?;
|
||||
|
||||
let string: String = (&string).try_into()?;
|
||||
let string_bytes = string.as_bytes();
|
||||
let string_length = (string_bytes.len() as i32)
|
||||
.try_into()
|
||||
.map_err(|error| format!("{}", error))?;
|
||||
|
||||
let outputs = allocator.call(&[InterfaceValue::I32(string_length)]).map_err(|_| format!(
|
||||
"`{}` failed when calling the allocator `{}`.",
|
||||
instruction_name,
|
||||
allocator_index,
|
||||
))?;
|
||||
|
||||
let string_pointer: i32 = (&outputs[0]).try_into()?;
|
||||
|
||||
let memory_view = instance
|
||||
.memory(0)
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"`{}` failed because there is no memory to write into.",
|
||||
instruction_name
|
||||
)
|
||||
})?
|
||||
.view();
|
||||
|
||||
for (nth, byte) in string_bytes.iter().enumerate() {
|
||||
memory_view[string_pointer as usize + nth].set(*byte);
|
||||
}
|
||||
|
||||
runtime.stack.push(InterfaceValue::I32(string_pointer));
|
||||
runtime.stack.push(InterfaceValue::I32(string_length));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
test_executable_instruction!(
|
||||
test_string_to_memory =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::StringToMemory { allocator_index: 43 },
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: Instance::new(),
|
||||
stack: [
|
||||
InterfaceValue::I32(0),
|
||||
// ^^^^^^ pointer
|
||||
InterfaceValue::I32(13),
|
||||
// ^^^^^^^ length
|
||||
]
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_string_to_memory__roundtrip_with_memory_to_string =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::StringToMemory { allocator_index: 43 },
|
||||
Instruction::MemoryToString,
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: Instance::new(),
|
||||
stack: [InterfaceValue::String("Hello, World!".into())],
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_string_to_memory__allocator_does_not_exist =
|
||||
instructions: [Instruction::StringToMemory { allocator_index: 43 }],
|
||||
invocation_inputs: [],
|
||||
instance: Instance { ..Default::default() },
|
||||
error: r#"`string-to-memory 43` failed because the function `43` (the allocator) doesn't exist."#,
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_string_to_memory__stack_is_too_small =
|
||||
instructions: [
|
||||
Instruction::StringToMemory { allocator_index: 43 }
|
||||
// ^^ `43` expects 1 value on the stack, none is present
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: Instance::new(),
|
||||
error: r#"`string-to-memory 43` cannot call the allocator `43` because there is not enough data on the stack for the arguments (needs 1)."#,
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_string_to_memory__failure_when_calling_the_allocator =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::StringToMemory { allocator_index: 153 }
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: {
|
||||
let mut instance = Instance::new();
|
||||
instance.locals_or_imports.insert(
|
||||
153,
|
||||
LocalImport {
|
||||
inputs: vec![InterfaceType::I32],
|
||||
outputs: vec![InterfaceType::I32],
|
||||
function: |_| Err(()),
|
||||
// ^^^^^^^ function fails
|
||||
},
|
||||
);
|
||||
|
||||
instance
|
||||
},
|
||||
error: r#"`string-to-memory 153` failed when calling the allocator `153`."#,
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_string_to_memory__invalid_allocator_signature =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::StringToMemory { allocator_index: 153 }
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: {
|
||||
let mut instance = Instance::new();
|
||||
instance.locals_or_imports.insert(
|
||||
153,
|
||||
LocalImport {
|
||||
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
||||
outputs: vec![],
|
||||
function: |_| Err(()),
|
||||
},
|
||||
);
|
||||
|
||||
instance
|
||||
},
|
||||
error: r#"`string-to-memory 153` failed because the allocator `153` has an invalid signature (expects [I32] -> [I32])."#,
|
||||
);
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
use crate::interpreter::wasm::values::{InterfaceType, InterfaceValue};
|
||||
use std::convert::TryInto;
|
||||
|
||||
executable_instruction!(
|
||||
write_utf8(allocator_name: String, instruction_name: String) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let instance = &mut runtime.wasm_instance;
|
||||
|
||||
match instance.export(&allocator_name) {
|
||||
Some(allocator) => {
|
||||
if allocator.inputs() != [InterfaceType::I32] ||
|
||||
allocator.outputs() != [InterfaceType::I32] {
|
||||
return Err(format!(
|
||||
"`{}` failed because the allocator `{}` has an invalid signature (expects [I32] -> [I32]).",
|
||||
instruction_name,
|
||||
allocator_name,
|
||||
))
|
||||
}
|
||||
|
||||
match instance.memory(0) {
|
||||
Some(memory) => match runtime.stack.pop1() {
|
||||
Some(string) => {
|
||||
let memory_view = memory.view();
|
||||
|
||||
let string: String = (&string).try_into()?;
|
||||
let string_bytes = string.as_bytes();
|
||||
let string_length = (string_bytes.len() as i32)
|
||||
.try_into()
|
||||
.map_err(|error| format!("{}", error))?;
|
||||
|
||||
match allocator.call(&[InterfaceValue::I32(string_length)]) {
|
||||
Ok(outputs) => {
|
||||
let string_pointer: i32 = (&outputs[0]).try_into()?;
|
||||
|
||||
for (nth, byte) in string_bytes.iter().enumerate() {
|
||||
memory_view[string_pointer as usize + nth].set(*byte);
|
||||
}
|
||||
|
||||
runtime.stack.push(InterfaceValue::I32(string_pointer));
|
||||
runtime.stack.push(InterfaceValue::I32(string_length));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err(format!(
|
||||
"`{}` failed when calling the allocator `{}`.",
|
||||
instruction_name,
|
||||
allocator_name,
|
||||
))
|
||||
}
|
||||
}
|
||||
None => Err(format!(
|
||||
"`{}` cannot call the allocator `{}` because there is not enough data on the stack for the arguments (needs {}).",
|
||||
instruction_name,
|
||||
allocator_name,
|
||||
1
|
||||
))
|
||||
}
|
||||
None => Err(format!(
|
||||
"`{}` failed because there is no memory to write into.",
|
||||
instruction_name
|
||||
))
|
||||
}
|
||||
}
|
||||
None => Err(format!(
|
||||
"`{}` failed because the exported function `{}` (the allocator) doesn't exist.",
|
||||
instruction_name,
|
||||
allocator_name
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
test_executable_instruction!(
|
||||
test_write_utf8 =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::WriteUtf8 { allocator_name: "alloc" },
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: Instance::new(),
|
||||
stack: [
|
||||
InterfaceValue::I32(0),
|
||||
// ^^^^^^ pointer
|
||||
InterfaceValue::I32(13),
|
||||
// ^^^^^^^ length
|
||||
]
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_write_utf8__roundtrip_with_memory_to_string =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::WriteUtf8 { allocator_name: "alloc" },
|
||||
Instruction::MemoryToString,
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: Instance::new(),
|
||||
stack: [InterfaceValue::String("Hello, World!".into())],
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_write_utf8__allocator_does_not_exist =
|
||||
instructions: [Instruction::WriteUtf8 { allocator_name: "alloc" }],
|
||||
invocation_inputs: [],
|
||||
instance: Instance { ..Default::default() },
|
||||
error: r#"`write-utf8 "alloc"` failed because the exported function `alloc` (the allocator) doesn't exist."#,
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_write_utf8__stack_is_too_small =
|
||||
instructions: [
|
||||
Instruction::WriteUtf8 { allocator_name: "alloc" }
|
||||
// ^^^^^ `alloc` expects 1 value on the stack, none is present
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: Instance::new(),
|
||||
error: r#"`write-utf8 "alloc"` cannot call the allocator `alloc` because there is not enough data on the stack for the arguments (needs 1)."#,
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_write_utf8__failure_when_calling_the_allocator =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::WriteUtf8 { allocator_name: "alloc-fail" }
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: {
|
||||
let mut instance = Instance::new();
|
||||
instance.exports.insert(
|
||||
"alloc-fail".into(),
|
||||
Export {
|
||||
inputs: vec![InterfaceType::I32],
|
||||
outputs: vec![InterfaceType::I32],
|
||||
function: |_| Err(()),
|
||||
// ^^^^^^^ function fails
|
||||
},
|
||||
);
|
||||
|
||||
instance
|
||||
},
|
||||
error: r#"`write-utf8 "alloc-fail"` failed when calling the allocator `alloc-fail`."#,
|
||||
);
|
||||
|
||||
test_executable_instruction!(
|
||||
test_write_utf8__invalid_allocator_signature =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::WriteUtf8 { allocator_name: "alloc-fail" }
|
||||
],
|
||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||
instance: {
|
||||
let mut instance = Instance::new();
|
||||
instance.exports.insert(
|
||||
"alloc-fail".into(),
|
||||
Export {
|
||||
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
||||
outputs: vec![],
|
||||
function: |_| Err(()),
|
||||
},
|
||||
);
|
||||
|
||||
instance
|
||||
},
|
||||
error: r#"`write-utf8 "alloc-fail"` failed because the allocator `alloc-fail` has an invalid signature (expects [I32] -> [I32])."#,
|
||||
);
|
||||
}
|
@ -203,8 +203,8 @@ where
|
||||
instructions::call_export((*export_name).to_owned(), instruction_name)
|
||||
}
|
||||
Instruction::MemoryToString => instructions::memory_to_string(instruction_name),
|
||||
Instruction::WriteUtf8 { allocator_name } => {
|
||||
instructions::write_utf8((*allocator_name).to_owned(), instruction_name)
|
||||
Instruction::StringToMemory { allocator_index } => {
|
||||
instructions::string_to_memory(*allocator_index, instruction_name)
|
||||
}
|
||||
|
||||
Instruction::I32ToS8 => instructions::i32_to_s8(),
|
||||
|
Loading…
Reference in New Issue
Block a user