marine_it_generator/instructions_generator/
utils.rs

1/*
2 * Copyright 2020 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use super::IType;
18use crate::instructions_generator::ITResolver;
19use crate::Result;
20
21use marine_macro_impl::FnSignature;
22use marine_macro_impl::ParsedType;
23use marine_macro_impl::RustType;
24use wasmer_it::ast::FunctionArg as IFunctionArg;
25
26use std::sync::Arc;
27
28// return error if there is no record with such name
29pub(crate) fn ptype_to_itype_checked(
30    pty: &ParsedType,
31    it_resolver: &mut ITResolver<'_>,
32) -> Result<IType> {
33    match pty {
34        ParsedType::I8(_) => Ok(IType::S8),
35        ParsedType::I16(_) => Ok(IType::S16),
36        ParsedType::I32(_) => Ok(IType::S32),
37        ParsedType::I64(_) => Ok(IType::S64),
38        ParsedType::U8(_) => Ok(IType::U8),
39        ParsedType::U16(_) => Ok(IType::U16),
40        ParsedType::U32(_) => Ok(IType::U32),
41        ParsedType::U64(_) => Ok(IType::U64),
42        ParsedType::F32(_) => Ok(IType::F32),
43        ParsedType::F64(_) => Ok(IType::F64),
44        ParsedType::Boolean(_) => Ok(IType::Boolean),
45        ParsedType::Utf8Str(_) => Ok(IType::String),
46        ParsedType::Utf8String(_) => Ok(IType::String),
47        ParsedType::Vector(ty, _) => {
48            let array_itype = ptype_to_itype_checked(ty, it_resolver)?;
49            if let IType::U8 = array_itype {
50                Ok(IType::ByteArray)
51            } else {
52                Ok(IType::Array(Box::new(array_itype)))
53            }
54        }
55        ParsedType::Record(record_name, _) => {
56            let record_type_id = it_resolver.get_record_type_id(record_name)?;
57            Ok(IType::Record(record_type_id as _))
58        }
59    }
60}
61
62pub(crate) fn ptype_to_itype_unchecked(
63    pty: &ParsedType,
64    it_resolver: &mut ITResolver<'_>,
65) -> IType {
66    match pty {
67        ParsedType::I8(_) => IType::S8,
68        ParsedType::I16(_) => IType::S16,
69        ParsedType::I32(_) => IType::S32,
70        ParsedType::I64(_) => IType::S64,
71        ParsedType::U8(_) => IType::U8,
72        ParsedType::U16(_) => IType::U16,
73        ParsedType::U32(_) => IType::U32,
74        ParsedType::U64(_) => IType::U64,
75        ParsedType::F32(_) => IType::F32,
76        ParsedType::F64(_) => IType::F64,
77        ParsedType::Boolean(_) => IType::Boolean,
78        ParsedType::Utf8Str(_) => IType::String,
79        ParsedType::Utf8String(_) => IType::String,
80        ParsedType::Vector(ty, _) => {
81            let array_itype = ptype_to_itype_unchecked(ty, it_resolver);
82            if let IType::U8 = array_itype {
83                IType::ByteArray
84            } else {
85                IType::Array(Box::new(array_itype))
86            }
87        }
88        ParsedType::Record(record_name, _) => {
89            let record_type_id = it_resolver.get_record_type_id_unchecked(record_name);
90            IType::Record(record_type_id as _)
91        }
92    }
93}
94
95pub(crate) fn wtype_to_itype(pty: &RustType) -> IType {
96    match pty {
97        RustType::I8 => IType::S8,
98        RustType::I16 => IType::S16,
99        RustType::I32 => IType::S32,
100        RustType::I64 => IType::S64,
101        RustType::U8 => IType::U8,
102        RustType::U16 => IType::U16,
103        RustType::U32 => IType::U32,
104        RustType::U64 => IType::U64,
105        RustType::F32 => IType::F32,
106        RustType::F64 => IType::F64,
107    }
108}
109
110pub(crate) fn generate_it_args(
111    signature: &FnSignature,
112    it_resolver: &mut ITResolver<'_>,
113) -> Result<Arc<Vec<IFunctionArg>>> {
114    let arguments = signature
115        .arguments
116        .iter()
117        .map(|arg| -> Result<IFunctionArg> {
118            Ok(IFunctionArg {
119                name: arg.name.clone(),
120                ty: ptype_to_itype_checked(&arg.ty, it_resolver)?,
121            })
122        })
123        .collect::<Result<Vec<_>>>()?;
124
125    let arguments = Arc::new(arguments);
126    Ok(arguments)
127}
128
129pub(crate) fn generate_it_output_type(
130    signature: &FnSignature,
131    it_resolver: &mut ITResolver<'_>,
132) -> Result<Arc<Vec<IType>>> {
133    let output_types = signature
134        .output_types
135        .iter()
136        .map(|ty| ptype_to_itype_checked(ty, it_resolver))
137        .collect::<Result<Vec<_>>>()?;
138
139    let output_types = Arc::new(output_types);
140
141    Ok(output_types)
142}