mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
update
This commit is contained in:
parent
2a756bd485
commit
f2f0792820
@ -123,9 +123,9 @@ fn ty<'input, E: ParseError<&'input [u8]>>(
|
||||
0x0c => InterfaceType::I32,
|
||||
0x0d => InterfaceType::I64,
|
||||
0x0e => {
|
||||
consume!((input, record_name) = owned_string(input)?);
|
||||
consume!((input, record_id) = uleb(input)?);
|
||||
|
||||
InterfaceType::Record(record_name)
|
||||
InterfaceType::Record(record_id)
|
||||
}
|
||||
_ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
|
||||
};
|
||||
@ -320,7 +320,7 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
||||
(
|
||||
input,
|
||||
Instruction::RecordLiftMemory {
|
||||
type_index: argument_0 as u32,
|
||||
record_type_id: argument_0 as u32,
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -330,7 +330,7 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
||||
(
|
||||
input,
|
||||
Instruction::RecordLowerMemory {
|
||||
type_index: argument_0 as u32,
|
||||
record_type_id: argument_0 as u32,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -368,13 +368,13 @@ impl<'a> Parse<'a> for Instruction {
|
||||
parser.parse::<keyword::record_lift_memory>()?;
|
||||
|
||||
Ok(Instruction::RecordLiftMemory {
|
||||
type_index: parser.parse()?,
|
||||
record_type_id: parser.parse()?,
|
||||
})
|
||||
} else if lookahead.peek::<keyword::record_lower_memory>() {
|
||||
parser.parse::<keyword::record_lower_memory>()?;
|
||||
|
||||
Ok(Instruction::RecordLowerMemory {
|
||||
type_index: parser.parse()?,
|
||||
record_type_id: parser.parse()?,
|
||||
})
|
||||
} else if lookahead.peek::<keyword::dup>() {
|
||||
parser.parse::<keyword::dup>()?;
|
||||
|
@ -127,9 +127,9 @@ where
|
||||
InterfaceType::Anyref => 0x0b_u8.to_bytes(writer),
|
||||
InterfaceType::I32 => 0x0c_u8.to_bytes(writer),
|
||||
InterfaceType::I64 => 0x0d_u8.to_bytes(writer),
|
||||
InterfaceType::Record(record_type) => {
|
||||
InterfaceType::Record(record_id) => {
|
||||
0x0e_u8.to_bytes(writer)?;
|
||||
record_type.as_str().to_bytes(writer)
|
||||
record_id.to_bytes(writer)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -391,11 +391,15 @@ where
|
||||
(*type_index as u64).to_bytes(writer)?
|
||||
}
|
||||
*/
|
||||
Instruction::RecordLiftMemory { type_index } => {
|
||||
Instruction::RecordLiftMemory {
|
||||
record_type_id: type_index,
|
||||
} => {
|
||||
0x3A_u8.to_bytes(writer)?;
|
||||
(*type_index as u64).to_bytes(writer)?
|
||||
}
|
||||
Instruction::RecordLowerMemory { type_index } => {
|
||||
Instruction::RecordLowerMemory {
|
||||
record_type_id: type_index,
|
||||
} => {
|
||||
0x3B_u8.to_bytes(writer)?;
|
||||
(*type_index as u64).to_bytes(writer)?
|
||||
}
|
||||
|
@ -151,12 +151,12 @@ impl ToString for &Instruction {
|
||||
Instruction::RecordLift { type_index } => format!("record.lift {}", type_index),
|
||||
Instruction::RecordLower { type_index } => format!("record.lower {}", type_index),
|
||||
*/
|
||||
Instruction::RecordLiftMemory { type_index } => {
|
||||
format!("record.lift_memory {}", type_index)
|
||||
}
|
||||
Instruction::RecordLowerMemory { type_index } => {
|
||||
format!("record.lower_memory {}", type_index)
|
||||
}
|
||||
Instruction::RecordLiftMemory {
|
||||
record_type_id: type_index,
|
||||
} => format!("record.lift_memory {}", type_index),
|
||||
Instruction::RecordLowerMemory {
|
||||
record_type_id: type_index,
|
||||
} => format!("record.lower_memory {}", type_index),
|
||||
Instruction::Dup => "dup".into(),
|
||||
Instruction::Swap2 => "swap2".into(),
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ pub enum InstructionErrorKind {
|
||||
/// The searched by name type doesn't exist.
|
||||
RecordTypeByNameIsMissing {
|
||||
/// The record type name.
|
||||
type_name: String,
|
||||
record_type_id: u64,
|
||||
},
|
||||
|
||||
/// Corrupted record's been popped from the stack.
|
||||
@ -272,7 +272,7 @@ impl Display for InstructionErrorKind {
|
||||
received_kind, expected_kind
|
||||
),
|
||||
|
||||
Self::RecordTypeByNameIsMissing { type_name } => write!(
|
||||
Self::RecordTypeByNameIsMissing { record_type_id: type_name } => write!(
|
||||
formatter,
|
||||
"type with `{}` is missing in a Wasm binary",
|
||||
type_name
|
||||
|
@ -8,7 +8,7 @@ mod strings;
|
||||
mod swap2;
|
||||
|
||||
use crate::interpreter::wasm;
|
||||
use crate::types::{InterfaceType, RecordType};
|
||||
use crate::types::InterfaceType;
|
||||
use crate::vec1::Vec1;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind, InstructionResult, WasmValueNativeCastError},
|
||||
@ -173,13 +173,13 @@ pub enum Instruction {
|
||||
/// The `record.lift_memory` instruction.
|
||||
RecordLiftMemory {
|
||||
/// The type index of the record.
|
||||
type_index: u32,
|
||||
record_type_id: u32,
|
||||
},
|
||||
|
||||
/// The `record.lower_memory` instruction.
|
||||
RecordLowerMemory {
|
||||
/// The type index of the record.
|
||||
type_index: u32,
|
||||
record_type_id: u32,
|
||||
},
|
||||
|
||||
/// The `dup` instructions.
|
||||
@ -267,17 +267,13 @@ where
|
||||
(InterfaceType::F64, InterfaceValue::F64(_)) => Ok(()),
|
||||
(InterfaceType::String, InterfaceValue::String(_)) => Ok(()),
|
||||
(InterfaceType::ByteArray, InterfaceValue::ByteArray(_)) => Ok(()),
|
||||
(InterfaceType::Record(ref record_name), InterfaceValue::Record(record_fields)) => {
|
||||
let record_type = instance.wit_record_by_name(record_name).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing {
|
||||
type_name: record_name.to_owned(),
|
||||
},
|
||||
)
|
||||
})?;
|
||||
|
||||
is_record_fields_compatible_to_type(instance, record_type, record_fields, instruction)?;
|
||||
(InterfaceType::Record(ref record_type_id), InterfaceValue::Record(record_fields)) => {
|
||||
is_record_fields_compatible_to_type(
|
||||
instance,
|
||||
*record_type_id,
|
||||
record_fields,
|
||||
instruction,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -300,7 +296,7 @@ pub(crate) fn is_record_fields_compatible_to_type<
|
||||
MemoryView,
|
||||
>(
|
||||
instance: &'instance Instance,
|
||||
record_type: &RecordType,
|
||||
record_type_id: u64,
|
||||
record_fields: &[InterfaceValue],
|
||||
instruction: Instruction,
|
||||
) -> Result<(), InstructionError>
|
||||
@ -311,18 +307,18 @@ where
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
{
|
||||
if record_fields.is_empty() {
|
||||
return Err(InstructionError::new(
|
||||
let record_type = instance.wit_record_by_id(record_type_id).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::CorruptedRecord(String::from("record contains no fields")),
|
||||
));
|
||||
}
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing { record_type_id },
|
||||
)
|
||||
})?;
|
||||
|
||||
if record_fields.len() != record_type.fields.len() {
|
||||
return Err(InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: InterfaceType::Record(record_type.name.clone()),
|
||||
expected_type: InterfaceType::Record(record_type_id),
|
||||
// unwrap is safe here - len's been already checked
|
||||
received_value: InterfaceValue::Record(Vec1::new(record_fields.to_vec()).unwrap()),
|
||||
},
|
||||
|
@ -216,20 +216,17 @@ where
|
||||
values.push_back(InterfaceValue::ByteArray(vec![]));
|
||||
}
|
||||
}
|
||||
InterfaceType::Record(record_type_name) => {
|
||||
InterfaceType::Record(record_type_id) => {
|
||||
let offset = value;
|
||||
|
||||
let record_type =
|
||||
instance
|
||||
.wit_record_by_name(&record_type_name)
|
||||
.ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing {
|
||||
type_name: record_type_name.to_owned(),
|
||||
},
|
||||
)
|
||||
})?;
|
||||
let record_type = instance.wit_record_by_id(*record_type_id).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing {
|
||||
record_type_id: *record_type_id,
|
||||
},
|
||||
)
|
||||
})?;
|
||||
|
||||
values.push_back(record_lift_memory_(
|
||||
instance,
|
||||
@ -251,7 +248,7 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn record_lift_memory<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
type_index: u32,
|
||||
record_type_id: u64,
|
||||
instruction: Instruction,
|
||||
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
where
|
||||
@ -280,10 +277,10 @@ where
|
||||
|
||||
// TODO: size = 0
|
||||
let instance = &runtime.wasm_instance;
|
||||
let record_type = instance.wit_record_by_id(type_index).ok_or_else(|| {
|
||||
let record_type = instance.wit_record_by_id(record_type_id).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::TypeIsMissing { type_index },
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing { record_type_id },
|
||||
)
|
||||
})?;
|
||||
|
||||
@ -364,7 +361,7 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn record_lower_memory<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
type_index: u32,
|
||||
record_type_id: u64,
|
||||
instruction: Instruction,
|
||||
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
where
|
||||
@ -380,18 +377,12 @@ where
|
||||
Box::new({
|
||||
move |runtime| -> _ {
|
||||
let instance = &mut runtime.wasm_instance;
|
||||
let record_type = instance.wit_record_by_id(type_index).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::TypeIsMissing { type_index },
|
||||
)
|
||||
})?;
|
||||
|
||||
match runtime.stack.pop1() {
|
||||
Some(InterfaceValue::Record(record_fields)) => {
|
||||
is_record_fields_compatible_to_type(
|
||||
&**instance,
|
||||
record_type,
|
||||
record_type_id,
|
||||
&record_fields,
|
||||
instruction,
|
||||
)?;
|
||||
@ -403,7 +394,7 @@ where
|
||||
Some(value) => Err(InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: InterfaceType::Record(record_type.name.clone()),
|
||||
expected_type: InterfaceType::Record(record_type_id),
|
||||
received_value: value,
|
||||
},
|
||||
)),
|
||||
|
@ -253,11 +253,11 @@ where
|
||||
instructions::record_lower(*type_index, *instruction)
|
||||
}
|
||||
*/
|
||||
Instruction::RecordLiftMemory { type_index } => {
|
||||
instructions::record_lift_memory(*type_index, *instruction)
|
||||
Instruction::RecordLiftMemory { record_type_id } => {
|
||||
instructions::record_lift_memory(*record_type_id as _, *instruction)
|
||||
}
|
||||
Instruction::RecordLowerMemory { type_index } => {
|
||||
instructions::record_lower_memory(*type_index, *instruction)
|
||||
Instruction::RecordLowerMemory { record_type_id } => {
|
||||
instructions::record_lower_memory(*record_type_id as _, *instruction)
|
||||
}
|
||||
Instruction::Dup => instructions::dup(*instruction),
|
||||
Instruction::Swap2 => instructions::swap2(*instruction),
|
||||
|
@ -76,8 +76,7 @@ where
|
||||
fn export(&self, export_name: &str) -> Option<&E>;
|
||||
fn local_or_import<I: TypedIndex + LocalImportIndex>(&self, index: I) -> Option<&LI>;
|
||||
fn memory(&self, index: usize) -> Option<&M>;
|
||||
fn wit_record_by_id(&self, index: u32) -> Option<&RecordType>;
|
||||
fn wit_record_by_name(&self, name: &str) -> Option<&RecordType>;
|
||||
fn wit_record_by_id(&self, index: u64) -> Option<&RecordType>;
|
||||
}
|
||||
|
||||
impl Export for () {
|
||||
@ -161,11 +160,7 @@ where
|
||||
None
|
||||
}
|
||||
|
||||
fn wit_record_by_id(&self, _index: u32) -> Option<&RecordType> {
|
||||
None
|
||||
}
|
||||
|
||||
fn wit_record_by_name(&self, _name: &str) -> Option<&RecordType> {
|
||||
fn wit_record_by_id(&self, _index: u64) -> Option<&RecordType> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
18
src/types.rs
18
src/types.rs
@ -51,9 +51,8 @@ pub enum InterfaceType {
|
||||
/// A 64-bits integer (as defiend in WebAssembly core).
|
||||
I64,
|
||||
|
||||
/// A record contains type name.
|
||||
// TODO: consider making it &str
|
||||
Record(String),
|
||||
/// A record contains record index from interfaces AST.
|
||||
Record(u64),
|
||||
}
|
||||
|
||||
/// Represents a record field type.
|
||||
@ -78,3 +77,16 @@ pub struct RecordType {
|
||||
/// [`Vec1`][crate::vec1::Vec1].
|
||||
pub fields: Vec1<RecordFieldType>,
|
||||
}
|
||||
|
||||
impl Default for RecordType {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: String::new(),
|
||||
fields: Vec1::new(vec![RecordFieldType {
|
||||
name: String::new(),
|
||||
ty: InterfaceType::S8,
|
||||
}])
|
||||
.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user