feat(interface-types) Reformat the instructions.

This commit is contained in:
Ivan Enderlin
2020-03-10 15:53:46 +01:00
parent f0c97a1b81
commit 7d6bc577b7
3 changed files with 100 additions and 121 deletions

View File

@ -13,62 +13,55 @@ executable_instruction!(
let instance = &mut runtime.wasm_instance; let instance = &mut runtime.wasm_instance;
let index = FunctionIndex::new(function_index); let index = FunctionIndex::new(function_index);
match instance.local_or_import(index) { let local_or_import = instance.local_or_import(index).ok_or_else(|| {
Some(local_or_import) => { InstructionError::new(
instruction,
InstructionErrorKind::LocalOrImportIsMissing {
function_index: function_index as u32,
},
)
})?;
let inputs_cardinality = local_or_import.inputs_cardinality(); let inputs_cardinality = local_or_import.inputs_cardinality();
match runtime.stack.pop(inputs_cardinality) { let inputs = runtime.stack.pop(inputs_cardinality).ok_or_else(|| {
Some(inputs) => { InstructionError::new(
instruction,
InstructionErrorKind::StackIsTooSmall {
needed: inputs_cardinality,
},
)
})?;
let input_types = inputs let input_types = inputs
.iter() .iter()
.map(Into::into) .map(Into::into)
.collect::<Vec<InterfaceType>>(); .collect::<Vec<InterfaceType>>();
if input_types != local_or_import.inputs() { if input_types != local_or_import.inputs() {
return Err( return Err(InstructionError::new(
InstructionError::new(
instruction, instruction,
InstructionErrorKind::LocalOrImportSignatureMismatch { InstructionErrorKind::LocalOrImportSignatureMismatch {
function_index: function_index as u32, function_index: function_index as u32,
expected: (local_or_import.inputs().to_vec(), vec![]), expected: (local_or_import.inputs().to_vec(), vec![]),
received: (input_types, vec![]), received: (input_types, vec![]),
} },
) ));
)
} }
match local_or_import.call(&inputs) { let outputs = local_or_import.call(&inputs).map_err(|_| {
Ok(outputs) => { InstructionError::new(
instruction,
InstructionErrorKind::LocalOrImportCall {
function_index: function_index as u32,
},
)
})?;
for output in outputs.iter() { for output in outputs.iter() {
runtime.stack.push(output.clone()); runtime.stack.push(output.clone());
} }
Ok(()) Ok(())
} }
Err(_) => Err(
InstructionError::new(
instruction,
InstructionErrorKind::LocalOrImportCall { function_index: function_index as u32, },
)
)
}
}
None => Err(
InstructionError::new(
instruction,
InstructionErrorKind::StackIsTooSmall { needed: inputs_cardinality },
)
)
}
}
None => Err(
InstructionError::new(
instruction,
InstructionErrorKind::LocalOrImportIsMissing { function_index: function_index as u32, },
)
)
}
}
} }
); );

View File

@ -18,31 +18,30 @@ macro_rules! lowering_lifting {
|_| { |_| {
InstructionError::new( InstructionError::new(
instruction, instruction,
InstructionErrorKind::LoweringLifting { from: InterfaceType::$from_variant, to: InterfaceType::$to_variant }, InstructionErrorKind::LoweringLifting {
from: InterfaceType::$from_variant,
to: InterfaceType::$to_variant
},
) )
}, },
)?)) )?))
} }
Some(wrong_value) => { Some(wrong_value) => {
return Err( return Err(InstructionError::new(
InstructionError::new(
instruction, instruction,
InstructionErrorKind::InvalidValueOnTheStack { InstructionErrorKind::InvalidValueOnTheStack {
expected_type: InterfaceType::$from_variant, expected_type: InterfaceType::$from_variant,
received_type: (&wrong_value).into(), received_type: (&wrong_value).into(),
} }
) ))
)
}, },
None => { None => {
return Err( return Err(InstructionError::new(
InstructionError::new(
instruction, instruction,
InstructionErrorKind::StackIsTooSmall { needed: 1 }, InstructionErrorKind::StackIsTooSmall { needed: 1 },
) ))
)
} }
} }

View File

@ -8,26 +8,37 @@ use std::cell::Cell;
executable_instruction!( executable_instruction!(
memory_to_string(instruction: Instruction) -> _ { memory_to_string(instruction: Instruction) -> _ {
move |runtime| -> _ { move |runtime| -> _ {
match runtime.stack.pop(2) { let inputs = runtime.stack.pop(2).ok_or_else(|| {
Some(inputs) => { InstructionError::new(
instruction,
InstructionErrorKind::StackIsTooSmall { needed: 2 },
)
})?;
let memory_index: u32 = 0; let memory_index: u32 = 0;
match runtime.wasm_instance.memory(memory_index as usize) { let memory = runtime
Some(memory) => { .wasm_instance
.memory(memory_index as usize)
.ok_or_else(|| {
InstructionError::new(
instruction,
InstructionErrorKind::MemoryIsMissing { memory_index },
)
})?;
let length = to_native::<i32>(&inputs[0], instruction)? as usize; let length = to_native::<i32>(&inputs[0], instruction)? as usize;
let pointer = to_native::<i32>(&inputs[1], instruction)? as usize; let pointer = to_native::<i32>(&inputs[1], instruction)? as usize;
let memory_view = memory.view(); let memory_view = memory.view();
if memory_view.len() < pointer + length { if memory_view.len() < pointer + length {
return Err( return Err(InstructionError::new(
InstructionError::new(
instruction, instruction,
InstructionErrorKind::MemoryOutOfBoundsAccess { InstructionErrorKind::MemoryOutOfBoundsAccess {
index: pointer + length, index: pointer + length,
length: memory_view.len(), length: memory_view.len(),
} },
), ));
)
} }
let data: Vec<u8> = (&memory_view[pointer..pointer + length]) let data: Vec<u8> = (&memory_view[pointer..pointer + length])
@ -35,37 +46,13 @@ executable_instruction!(
.map(Cell::get) .map(Cell::get)
.collect(); .collect();
match String::from_utf8(data) { let string = String::from_utf8(data)
Ok(string) => { .map_err(|error| InstructionError::new(instruction, InstructionErrorKind::String(error)))?;
runtime.stack.push(InterfaceValue::String(string)); runtime.stack.push(InterfaceValue::String(string));
Ok(()) Ok(())
} }
Err(utf8_error) => Err(
InstructionError::new(
instruction,
InstructionErrorKind::String(utf8_error)
),
)
}
}
None => Err(
InstructionError::new(
instruction,
InstructionErrorKind::MemoryIsMissing { memory_index }
),
)
}
}
None => Err(
InstructionError::new(
instruction,
InstructionErrorKind::StackIsTooSmall { needed: 2 }
),
)
}
}
} }
); );