mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
update types
This commit is contained in:
parent
8a18ba607f
commit
e28914ae01
@ -285,29 +285,28 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
||||
0x38 => (input, Instruction::ByteArrayLowerMemory),
|
||||
0x39 => (input, Instruction::ByteArraySize),
|
||||
|
||||
/*
|
||||
0x25 => {
|
||||
consume!((input, argument_0) = uleb(input)?);
|
||||
/*
|
||||
0x25 => {
|
||||
consume!((input, argument_0) = uleb(input)?);
|
||||
|
||||
(
|
||||
input,
|
||||
Instruction::RecordLift {
|
||||
type_index: argument_0 as u32,
|
||||
},
|
||||
)
|
||||
}
|
||||
0x26 => {
|
||||
consume!((input, argument_0) = uleb(input)?);
|
||||
|
||||
(
|
||||
input,
|
||||
Instruction::RecordLower {
|
||||
type_index: argument_0 as u32,
|
||||
},
|
||||
)
|
||||
}
|
||||
*/
|
||||
(
|
||||
input,
|
||||
Instruction::RecordLift {
|
||||
type_index: argument_0 as u32,
|
||||
},
|
||||
)
|
||||
}
|
||||
0x26 => {
|
||||
consume!((input, argument_0) = uleb(input)?);
|
||||
|
||||
(
|
||||
input,
|
||||
Instruction::RecordLower {
|
||||
type_index: argument_0 as u32,
|
||||
},
|
||||
)
|
||||
}
|
||||
*/
|
||||
0x3A => {
|
||||
consume!((input, argument_0) = uleb(input)?);
|
||||
|
||||
|
@ -178,6 +178,7 @@ impl Parse<'_> for RecordType {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::suspicious_else_formatting)]
|
||||
impl<'a> Parse<'a> for Instruction {
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
@ -348,7 +349,7 @@ impl<'a> Parse<'a> for Instruction {
|
||||
|
||||
Ok(Instruction::ByteArraySize)
|
||||
}
|
||||
/*
|
||||
/*
|
||||
else if lookahead.peek::<keyword::record_lift>() {
|
||||
parser.parse::<keyword::record_lift>()?;
|
||||
|
||||
@ -363,7 +364,7 @@ impl<'a> Parse<'a> for Instruction {
|
||||
})
|
||||
}
|
||||
*/
|
||||
else if lookahead.peek::<keyword::record_lift_memory>() {
|
||||
else if lookahead.peek::<keyword::record_lift_memory>() {
|
||||
parser.parse::<keyword::record_lift_memory>()?;
|
||||
|
||||
Ok(Instruction::RecordLiftMemory {
|
||||
|
@ -170,6 +170,9 @@ pub enum InstructionErrorKind {
|
||||
type_name: String,
|
||||
},
|
||||
|
||||
/// Corrupted record's been popped from the stack.
|
||||
CorruptedRecord(String),
|
||||
|
||||
/// Read a type that has an unexpected type.
|
||||
InvalidTypeKind {
|
||||
/// The expected kind.
|
||||
@ -274,6 +277,13 @@ impl Display for InstructionErrorKind {
|
||||
"type with `{}` is missing in a Wasm binary",
|
||||
type_name
|
||||
),
|
||||
|
||||
Self::CorruptedRecord(err) => write!(
|
||||
formatter,
|
||||
"{}",
|
||||
err
|
||||
),
|
||||
|
||||
Self::SerdeError(err) => write!(
|
||||
formatter,
|
||||
"serde error: {}", err,
|
||||
|
@ -8,7 +8,8 @@ mod strings;
|
||||
mod swap2;
|
||||
|
||||
use crate::interpreter::wasm;
|
||||
use crate::types::InterfaceType;
|
||||
use crate::types::{InterfaceType, RecordType};
|
||||
use crate::vec1::Vec1;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind, InstructionResult, WasmValueNativeCastError},
|
||||
values::{InterfaceValue, NativeType},
|
||||
@ -169,7 +170,6 @@ pub enum Instruction {
|
||||
},
|
||||
|
||||
*/
|
||||
|
||||
/// The `record.lift_memory` instruction.
|
||||
RecordLiftMemory {
|
||||
/// The type index of the record.
|
||||
@ -277,26 +277,7 @@ where
|
||||
)
|
||||
})?;
|
||||
|
||||
if record_fields.len() != record_type.fields.len() {
|
||||
return Err(InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: interface_type.clone(),
|
||||
received_value: interface_value.clone(),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
for (record_type_field, record_value_field) in
|
||||
record_type.fields.iter().zip(record_fields.iter())
|
||||
{
|
||||
is_value_compatible_to_type(
|
||||
instance,
|
||||
&record_type_field.ty,
|
||||
record_value_field,
|
||||
instruction,
|
||||
)?;
|
||||
}
|
||||
is_record_fields_compatible_to_type(instance, record_type, record_fields, instruction)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -310,6 +291,58 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_record_fields_compatible_to_type<
|
||||
'instance,
|
||||
Instance,
|
||||
Export,
|
||||
LocalImport,
|
||||
Memory,
|
||||
MemoryView,
|
||||
>(
|
||||
instance: &'instance Instance,
|
||||
record_type: &RecordType,
|
||||
record_fields: &[InterfaceValue],
|
||||
instruction: Instruction,
|
||||
) -> Result<(), InstructionError>
|
||||
where
|
||||
Export: wasm::structures::Export + 'instance,
|
||||
LocalImport: wasm::structures::LocalImport + 'instance,
|
||||
Memory: wasm::structures::Memory<MemoryView> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
{
|
||||
if record_fields.is_empty() {
|
||||
return Err(InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::CorruptedRecord(String::from("record contains no fields")),
|
||||
));
|
||||
}
|
||||
|
||||
if record_fields.len() != record_type.fields.len() {
|
||||
return Err(InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: InterfaceType::Record(record_type.name.clone()),
|
||||
// unwrap is safe here - len's been already checked
|
||||
received_value: InterfaceValue::Record(Vec1::new(record_fields.to_vec()).unwrap()),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
for (record_type_field, record_value_field) in
|
||||
record_type.fields.iter().zip(record_fields.iter())
|
||||
{
|
||||
is_value_compatible_to_type(
|
||||
instance,
|
||||
&record_type_field.ty,
|
||||
record_value_field,
|
||||
instruction,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use crate::{ast::*, interpreter::wasm, types::*, values::*};
|
||||
|
@ -3,11 +3,8 @@ mod utils;
|
||||
use utils::read_from_instance_mem;
|
||||
use utils::write_to_instance_mem;
|
||||
|
||||
// use crate::interpreter::wasm;
|
||||
|
||||
use crate::interpreter::instructions::to_native;
|
||||
use crate::interpreter::instructions::{is_record_fields_compatible_to_type, to_native};
|
||||
use crate::{
|
||||
ast::{Type, TypeKind},
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
types::{InterfaceType, RecordType},
|
||||
@ -287,25 +284,14 @@ where
|
||||
|
||||
// TODO: size = 0
|
||||
let instance = &runtime.wasm_instance;
|
||||
let record_type = match instance.wit_type_by_id(type_index).ok_or_else(|| {
|
||||
let record_type = instance.wit_record_by_id(type_index).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::TypeIsMissing { type_index },
|
||||
)
|
||||
})? {
|
||||
Type::Record(record_type) => record_type.clone(),
|
||||
Type::Function { .. } => {
|
||||
return Err(InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::InvalidTypeKind {
|
||||
expected_kind: TypeKind::Record,
|
||||
received_kind: TypeKind::Function,
|
||||
},
|
||||
))
|
||||
}
|
||||
};
|
||||
})?;
|
||||
|
||||
let record = record_lift_memory_(&**instance, &record_type, offset, instruction)?;
|
||||
let record = record_lift_memory_(&**instance, record_type, offset, instruction)?;
|
||||
runtime.stack.push(record);
|
||||
|
||||
Ok(())
|
||||
@ -395,40 +381,22 @@ where
|
||||
Box::new({
|
||||
move |runtime| -> _ {
|
||||
let instance = &mut runtime.wasm_instance;
|
||||
let record_type = match instance.wit_type_by_id(type_index).ok_or_else(|| {
|
||||
let record_type = instance.wit_record_by_id(type_index).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::TypeIsMissing { type_index },
|
||||
)
|
||||
})? {
|
||||
Type::Record(record_type) => record_type,
|
||||
Type::Function { .. } => {
|
||||
return Err(InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::InvalidTypeKind {
|
||||
expected_kind: TypeKind::Record,
|
||||
received_kind: TypeKind::Function,
|
||||
},
|
||||
))
|
||||
}
|
||||
};
|
||||
})?;
|
||||
|
||||
match runtime.stack.pop1() {
|
||||
Some(InterfaceValue::Record(record_values)) => {
|
||||
/*
|
||||
let value: Vec<u8> = crate::serde::de::from_interface_values(&record_values)
|
||||
.map_err(|e| {
|
||||
InstructionError::new(
|
||||
instruction,
|
||||
InstructionErrorKind::SerdeError(e.to_string()),
|
||||
)
|
||||
})?;
|
||||
|
||||
let value_pointer = write_to_instance_mem(*instance, instruction, &value)?;
|
||||
runtime.stack.push(InterfaceValue::I32(value_pointer));
|
||||
runtime.stack.push(InterfaceValue::I32(value.len() as _));
|
||||
*/
|
||||
let offset = record_lower_memory_(*instance, instruction, record_values)?;
|
||||
Some(InterfaceValue::Record(record_fields)) => {
|
||||
is_record_fields_compatible_to_type(
|
||||
&**instance,
|
||||
record_type,
|
||||
&record_fields,
|
||||
instruction,
|
||||
)?;
|
||||
let offset = record_lower_memory_(*instance, instruction, record_fields)?;
|
||||
runtime.stack.push(InterfaceValue::I32(offset));
|
||||
|
||||
Ok(())
|
||||
|
@ -148,7 +148,12 @@ where
|
||||
)
|
||||
})?;
|
||||
|
||||
crate::interpreter::instructions::check_function_signature(instance, local_or_import, &inputs, instruction)?;
|
||||
crate::interpreter::instructions::check_function_signature(
|
||||
instance,
|
||||
local_or_import,
|
||||
&inputs,
|
||||
instruction,
|
||||
)?;
|
||||
|
||||
let outputs = local_or_import.call(&inputs).map_err(|_| {
|
||||
InstructionError::new(
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::types::RecordType;
|
||||
use crate::{ast, types::InterfaceType, values::InterfaceValue};
|
||||
use crate::{types::InterfaceType, values::InterfaceValue};
|
||||
use std::{cell::Cell, ops::Deref};
|
||||
|
||||
pub trait TypedIndex: Copy + Clone {
|
||||
@ -75,7 +75,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_type_by_id(&self, index: u32) -> Option<&ast::Type>;
|
||||
fn wit_record_by_id(&self, index: u32) -> Option<&RecordType>;
|
||||
fn wit_record_by_name(&self, name: &str) -> Option<&RecordType>;
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ where
|
||||
None
|
||||
}
|
||||
|
||||
fn wit_type_by_id(&self, _index: u32) -> Option<&ast::Type> {
|
||||
fn wit_record_by_id(&self, _index: u32) -> Option<&RecordType> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -56,48 +56,12 @@ pub enum InterfaceValue {
|
||||
Record(Vec1<InterfaceValue>),
|
||||
}
|
||||
|
||||
/*
|
||||
impl From<&InterfaceValue> for InterfaceType {
|
||||
fn from(value: &InterfaceValue) -> Self {
|
||||
match value {
|
||||
InterfaceValue::S8(_) => Self::S8,
|
||||
InterfaceValue::S16(_) => Self::S16,
|
||||
InterfaceValue::S32(_) => Self::S32,
|
||||
InterfaceValue::S64(_) => Self::S64,
|
||||
InterfaceValue::U8(_) => Self::U8,
|
||||
InterfaceValue::U16(_) => Self::U16,
|
||||
InterfaceValue::U32(_) => Self::U32,
|
||||
InterfaceValue::U64(_) => Self::U64,
|
||||
InterfaceValue::F32(_) => Self::F32,
|
||||
InterfaceValue::F64(_) => Self::F64,
|
||||
InterfaceValue::String(_) => Self::String,
|
||||
InterfaceValue::ByteArray(_) => Self::ByteArray,
|
||||
//InterfaceValue::Anyref(_) => Self::Anyref,
|
||||
InterfaceValue::I32(_) => Self::I32,
|
||||
InterfaceValue::I64(_) => Self::I64,
|
||||
InterfaceValue::Record(name) => Self::Record(name.to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl Default for InterfaceValue {
|
||||
fn default() -> Self {
|
||||
Self::I32(0)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl From<&Vec<InterfaceValue>> for RecordType {
|
||||
fn from(values: &Vec<InterfaceValue>) -> Self {
|
||||
RecordType {
|
||||
fields: Vec1::new(values.iter().map(Into::into).collect())
|
||||
.expect("Record must have at least one field, zero given."),
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// Represents a native type supported by WIT.
|
||||
pub trait NativeType {
|
||||
/// The associated interface type that maps to the native type.
|
||||
|
Loading…
Reference in New Issue
Block a user