Improve error handling and misc cleanups.
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(new_without_default, new_without_default_derive)
|
allow(clippy::new_without_default, clippy::new_without_default_derive)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(new_without_default, new_without_default_derive)
|
allow(clippy::new_without_default, clippy::new_without_default_derive)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
|
|||||||
@@ -174,32 +174,32 @@ mod test_vmglobal_definition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VMGlobalDefinition {
|
impl VMGlobalDefinition {
|
||||||
#[allow(cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn as_i32(&mut self) -> &mut i32 {
|
pub unsafe fn as_i32(&mut self) -> &mut i32 {
|
||||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut i32)
|
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn as_i64(&mut self) -> &mut i64 {
|
pub unsafe fn as_i64(&mut self) -> &mut i64 {
|
||||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut i64)
|
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn as_f32(&mut self) -> &mut f32 {
|
pub unsafe fn as_f32(&mut self) -> &mut f32 {
|
||||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut f32)
|
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn as_f32_bits(&mut self) -> &mut u32 {
|
pub unsafe fn as_f32_bits(&mut self) -> &mut u32 {
|
||||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut u32)
|
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn as_f64(&mut self) -> &mut f64 {
|
pub unsafe fn as_f64(&mut self) -> &mut f64 {
|
||||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut f64)
|
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn as_f64_bits(&mut self) -> &mut u64 {
|
pub unsafe fn as_f64_bits(&mut self) -> &mut u64 {
|
||||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut u64)
|
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u8 as *mut u64)
|
||||||
}
|
}
|
||||||
@@ -578,7 +578,7 @@ impl VMContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return a mutable reference to the associated `Instance`.
|
/// Return a mutable reference to the associated `Instance`.
|
||||||
#[allow(cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn instance(&mut self) -> &mut Instance {
|
pub unsafe fn instance(&mut self) -> &mut Instance {
|
||||||
&mut *((self as *mut Self as *mut u8).offset(-Instance::vmctx_offset()) as *mut Instance)
|
&mut *((self as *mut Self as *mut u8).offset(-Instance::vmctx_offset()) as *mut Instance)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(new_without_default, new_without_default_derive)
|
allow(clippy::new_without_default, clippy::new_without_default_derive)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(new_without_default, new_without_default_derive)
|
allow(clippy::new_without_default, clippy::new_without_default_derive)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
|
|||||||
@@ -6,29 +6,36 @@ use target_lexicon::HOST;
|
|||||||
use wasmtime_environ::{translate_signature, MemoryPlan, MemoryStyle, TablePlan, TableStyle};
|
use wasmtime_environ::{translate_signature, MemoryPlan, MemoryStyle, TablePlan, TableStyle};
|
||||||
use wasmtime_execute::{ExportValue, Resolver, VMGlobal, VMMemory, VMTable};
|
use wasmtime_execute::{ExportValue, Resolver, VMGlobal, VMMemory, VMTable};
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
extern "C" fn spectest_print() {}
|
extern "C" fn spectest_print() {}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
extern "C" fn spectest_print_i32(x: i32) {
|
extern "C" fn spectest_print_i32(x: i32) {
|
||||||
println!("{}: i32", x);
|
println!("{}: i32", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
extern "C" fn spectest_print_i64(x: i64) {
|
extern "C" fn spectest_print_i64(x: i64) {
|
||||||
println!("{}: i64", x);
|
println!("{}: i64", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
extern "C" fn spectest_print_f32(x: f32) {
|
extern "C" fn spectest_print_f32(x: f32) {
|
||||||
println!("{}: f32", x);
|
println!("{}: f32", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
extern "C" fn spectest_print_f64(x: f64) {
|
extern "C" fn spectest_print_f64(x: f64) {
|
||||||
println!("{}: f64", x);
|
println!("{}: f64", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
extern "C" fn spectest_print_i32_f32(x: i32, y: f32) {
|
extern "C" fn spectest_print_i32_f32(x: i32, y: f32) {
|
||||||
println!("{}: i32", x);
|
println!("{}: i32", x);
|
||||||
println!("{}: f32", y);
|
println!("{}: f32", y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
extern "C" fn spectest_print_f64_f64(x: f64, y: f64) {
|
extern "C" fn spectest_print_f64_f64(x: f64, y: f64) {
|
||||||
println!("{}: f64", x);
|
println!("{}: f64", x);
|
||||||
println!("{}: f64", y);
|
println!("{}: f64", y);
|
||||||
|
|||||||
@@ -44,7 +44,11 @@ impl Instances {
|
|||||||
self.namespace.insert(name, world);
|
self.namespace.insert(name, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_action(&mut self, isa: &isa::TargetIsa, action: Action) -> ActionOutcome {
|
pub fn perform_action(
|
||||||
|
&mut self,
|
||||||
|
isa: &isa::TargetIsa,
|
||||||
|
action: Action,
|
||||||
|
) -> Result<ActionOutcome, String> {
|
||||||
match action {
|
match action {
|
||||||
Action::Invoke {
|
Action::Invoke {
|
||||||
module,
|
module,
|
||||||
@@ -62,44 +66,50 @@ impl Instances {
|
|||||||
}
|
}
|
||||||
match module {
|
match module {
|
||||||
None => match self.current {
|
None => match self.current {
|
||||||
None => panic!("invoke performed with no module present"),
|
None => Err("invoke performed with no module present".to_string()),
|
||||||
Some(ref mut instance_world) => instance_world
|
Some(ref mut instance_world) => instance_world
|
||||||
.invoke(&mut self.code, isa, &field, &value_args)
|
.invoke(&mut self.code, isa, &field, &value_args)
|
||||||
.expect(&format!("error invoking {} in current module", field)),
|
.map_err(|e| {
|
||||||
|
format!("error invoking {} in current module: {}", field, e)
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
Some(name) => self
|
Some(name) => self
|
||||||
.namespace
|
.namespace
|
||||||
.get_mut(&name)
|
.get_mut(&name)
|
||||||
.expect(&format!("module {} not declared", name))
|
.ok_or_else(|| format!("module {} not declared", name))?
|
||||||
.invoke(&mut self.code, isa, &field, &value_args)
|
.invoke(&mut self.code, isa, &field, &value_args)
|
||||||
.expect(&format!("error invoking {} in module {}", field, name)),
|
.map_err(|e| format!("error invoking {} in module {}: {}", field, name, e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::Get { module, field } => {
|
Action::Get { module, field } => {
|
||||||
let value = match module {
|
let value = match module {
|
||||||
None => match self.current {
|
None => match self.current {
|
||||||
None => panic!("get performed with no module present"),
|
None => return Err("get performed with no module present".to_string()),
|
||||||
Some(ref mut instance_world) => instance_world
|
Some(ref mut instance_world) => {
|
||||||
.get(&field)
|
instance_world.get(&field).map_err(|e| {
|
||||||
.expect(&format!("error getting {} in current module", field)),
|
format!("error getting {} in current module: {}", field, e)
|
||||||
|
})?
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Some(name) => self
|
Some(name) => self
|
||||||
.namespace
|
.namespace
|
||||||
.get_mut(&name)
|
.get_mut(&name)
|
||||||
.expect(&format!("module {} not declared", name))
|
.ok_or_else(|| format!("module {} not declared", name))?
|
||||||
.get(&field)
|
.get(&field)
|
||||||
.expect(&format!("error getting {} in module {}", field, name)),
|
.map_err(|e| {
|
||||||
|
format!("error getting {} in module {}: {}", field, name, e)
|
||||||
|
})?,
|
||||||
};
|
};
|
||||||
ActionOutcome::Returned {
|
Ok(ActionOutcome::Returned {
|
||||||
values: vec![value],
|
values: vec![value],
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a wast script from a byte buffer.
|
/// Run a wast script from a byte buffer.
|
||||||
pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
|
pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) -> Result<(), String> {
|
||||||
let mut parser = ScriptParser::from_str(str::from_utf8(wast).unwrap()).unwrap();
|
let mut parser = ScriptParser::from_str(str::from_utf8(wast).unwrap()).unwrap();
|
||||||
let mut instances = Instances::new();
|
let mut instances = Instances::new();
|
||||||
|
|
||||||
@@ -107,19 +117,19 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
|
|||||||
match kind {
|
match kind {
|
||||||
CommandKind::Module { module, name } => {
|
CommandKind::Module { module, name } => {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
instances.define_named_module(&*isa, name, module.clone());
|
instances.define_named_module(isa, name, module.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
instances.define_unnamed_module(&*isa, module)
|
instances.define_unnamed_module(isa, module)
|
||||||
}
|
}
|
||||||
CommandKind::PerformAction(action) => match instances.perform_action(&*isa, action) {
|
CommandKind::PerformAction(action) => match instances.perform_action(isa, action)? {
|
||||||
ActionOutcome::Returned { .. } => {}
|
ActionOutcome::Returned { .. } => {}
|
||||||
ActionOutcome::Trapped { message } => {
|
ActionOutcome::Trapped { message } => {
|
||||||
panic!("{}:{}: a trap occurred: {}", name, line, message);
|
panic!("{}:{}: a trap occurred: {}", name, line, message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CommandKind::AssertReturn { action, expected } => {
|
CommandKind::AssertReturn { action, expected } => {
|
||||||
match instances.perform_action(&*isa, action) {
|
match instances.perform_action(isa, action)? {
|
||||||
ActionOutcome::Returned { values } => {
|
ActionOutcome::Returned { values } => {
|
||||||
for (v, e) in values.iter().zip(expected.iter()) {
|
for (v, e) in values.iter().zip(expected.iter()) {
|
||||||
match *e {
|
match *e {
|
||||||
@@ -147,7 +157,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandKind::AssertTrap { action, message } => {
|
CommandKind::AssertTrap { action, message } => {
|
||||||
match instances.perform_action(&*isa, action) {
|
match instances.perform_action(isa, action)? {
|
||||||
ActionOutcome::Returned { values } => panic!(
|
ActionOutcome::Returned { values } => panic!(
|
||||||
"{}:{}: expected trap, but invoke returned with {:?}",
|
"{}:{}: expected trap, but invoke returned with {:?}",
|
||||||
name, line, values
|
name, line, values
|
||||||
@@ -163,7 +173,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandKind::AssertExhaustion { action } => {
|
CommandKind::AssertExhaustion { action } => {
|
||||||
match instances.perform_action(&*isa, action) {
|
match instances.perform_action(isa, action)? {
|
||||||
ActionOutcome::Returned { values } => panic!(
|
ActionOutcome::Returned { values } => panic!(
|
||||||
"{}:{}: expected exhaustion, but invoke returned with {:?}",
|
"{}:{}: expected exhaustion, but invoke returned with {:?}",
|
||||||
name, line, values
|
name, line, values
|
||||||
@@ -177,7 +187,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandKind::AssertReturnCanonicalNan { action } => {
|
CommandKind::AssertReturnCanonicalNan { action } => {
|
||||||
match instances.perform_action(&*isa, action) {
|
match instances.perform_action(isa, action)? {
|
||||||
ActionOutcome::Returned { values } => {
|
ActionOutcome::Returned { values } => {
|
||||||
for v in values.iter() {
|
for v in values.iter() {
|
||||||
match v {
|
match v {
|
||||||
@@ -210,7 +220,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandKind::AssertReturnArithmeticNan { action } => {
|
CommandKind::AssertReturnArithmeticNan { action } => {
|
||||||
match instances.perform_action(&*isa, action) {
|
match instances.perform_action(isa, action)? {
|
||||||
ActionOutcome::Returned { values } => {
|
ActionOutcome::Returned { values } => {
|
||||||
for v in values.iter() {
|
for v in values.iter() {
|
||||||
match v {
|
match v {
|
||||||
@@ -247,13 +257,14 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a wast script from a file.
|
/// Run a wast script from a file.
|
||||||
pub fn wast_file(path: &Path, isa: &isa::TargetIsa) -> Result<(), String> {
|
pub fn wast_file(path: &Path, isa: &isa::TargetIsa) -> Result<(), String> {
|
||||||
let wast = read_to_end(path).map_err(|e| e.to_string())?;
|
let wast = read_to_end(path).map_err(|e| e.to_string())?;
|
||||||
wast_buffer(&path.display().to_string(), isa, &wast);
|
wast_buffer(&path.display().to_string(), isa, &wast)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_to_end(path: &Path) -> Result<Vec<u8>, io::Error> {
|
fn read_to_end(path: &Path) -> Result<Vec<u8>, io::Error> {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(new_without_default, new_without_default_derive)
|
allow(clippy::new_without_default, clippy::new_without_default_derive)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
@@ -96,6 +96,7 @@ fn main() {
|
|||||||
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
||||||
for filename in &args.arg_file {
|
for filename in &args.arg_file {
|
||||||
let path = Path::new(&filename);
|
let path = Path::new(&filename);
|
||||||
wast_file(path, &*isa).expect(&format!("error reading file {}", path.display()));
|
wast_file(path, &*isa)
|
||||||
|
.unwrap_or_else(|e| panic!("error reading file {}: {}", path.display(), e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(new_without_default, new_without_default_derive)
|
allow(clippy::new_without_default, clippy::new_without_default_derive)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(new_without_default, new_without_default_derive)
|
allow(clippy::new_without_default, clippy::new_without_default_derive)
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
@@ -128,7 +128,7 @@ fn main() {
|
|||||||
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
||||||
for filename in &args.arg_file {
|
for filename in &args.arg_file {
|
||||||
let path = Path::new(&filename);
|
let path = Path::new(&filename);
|
||||||
match handle_module(&args, path.to_path_buf(), &*isa) {
|
match handle_module(&args, path, &*isa) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(message) => {
|
Err(message) => {
|
||||||
let name = path.as_os_str().to_string_lossy();
|
let name = path.as_os_str().to_string_lossy();
|
||||||
@@ -139,8 +139,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_module(args: &Args, path: PathBuf, isa: &TargetIsa) -> Result<(), String> {
|
fn handle_module(args: &Args, path: &Path, isa: &TargetIsa) -> Result<(), String> {
|
||||||
let mut data = read_to_end(path.clone()).map_err(|err| String::from(err.description()))?;
|
let mut data =
|
||||||
|
read_to_end(path.to_path_buf()).map_err(|err| String::from(err.description()))?;
|
||||||
// if data is using wat-format, first convert data to wasm
|
// if data is using wat-format, first convert data to wasm
|
||||||
if !data.starts_with(&[b'\0', b'a', b's', b'm']) {
|
if !data.starts_with(&[b'\0', b'a', b's', b'm']) {
|
||||||
data = wabt::wat2wasm(data).map_err(|err| String::from(err.description()))?;
|
data = wabt::wat2wasm(data).map_err(|err| String::from(err.description()))?;
|
||||||
|
|||||||
Reference in New Issue
Block a user