1use crate::value::*;
6#[cfg(feature = "serde_borsh")]
7use borsh::{maybestd::io::Result, maybestd::io::Write, BorshDeserialize, BorshSerialize};
8#[cfg(feature = "serde_borsh")]
9use go_parser::PiggyVecKey;
10use go_parser::{piggy_key_type, PiggyVec};
11
12#[cfg(feature = "serde_borsh")]
13macro_rules! impl_borsh_for_key {
14 ($key:ident) => {
15 impl BorshSerialize for $key {
16 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
17 self.as_usize().serialize(writer)
18 }
19 }
20
21 impl BorshDeserialize for $key {
22 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self> {
23 let i: usize = usize::deserialize_reader(reader)?;
24 Ok(i.into())
25 }
26 }
27 };
28}
29
30piggy_key_type! {
31 pub struct MetadataKey;
32 pub struct FunctionKey;
33 pub struct PackageKey;
34}
35
36#[cfg(feature = "serde_borsh")]
37impl_borsh_for_key!(MetadataKey);
38#[cfg(feature = "serde_borsh")]
39impl_borsh_for_key!(FunctionKey);
40#[cfg(feature = "serde_borsh")]
41impl_borsh_for_key!(PackageKey);
42
43pub type MetadataObjs = PiggyVec<MetadataKey, MetadataType>;
44pub type FunctionObjs = PiggyVec<FunctionKey, FunctionObj>;
45pub type PackageObjs = PiggyVec<PackageKey, PackageObj>;
46
47pub struct VMObjects {
48 pub metas: MetadataObjs,
49 pub functions: FunctionObjs,
50 pub packages: PackageObjs,
51 pub prim_meta: PrimitiveMeta,
52 pub(crate) arr_slice_caller: Box<ArrCaller>,
53}
54
55impl VMObjects {
56 pub fn new() -> VMObjects {
57 const CAP: usize = 16;
58 let mut metas = PiggyVec::with_capacity(CAP);
59 let prim_meta = PrimitiveMeta::new(&mut metas);
60 VMObjects {
61 metas,
62 functions: PiggyVec::with_capacity(CAP),
63 packages: PiggyVec::with_capacity(CAP),
64 prim_meta,
65 arr_slice_caller: Box::new(ArrCaller::new()),
66 }
67 }
68
69 pub fn with_components(
70 mut metas: MetadataObjs,
71 functions: FunctionObjs,
72 packages: PackageObjs,
73 ) -> VMObjects {
74 let prim_meta = PrimitiveMeta::new(&mut metas);
75 VMObjects {
76 metas,
77 functions,
78 packages,
79 prim_meta,
80 arr_slice_caller: Box::new(ArrCaller::new()),
81 }
82 }
83}
84
85#[cfg(feature = "serde_borsh")]
86impl BorshSerialize for VMObjects {
87 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
88 self.metas.serialize(writer)?;
89 self.functions.serialize(writer)?;
90 self.packages.serialize(writer)
91 }
92}
93
94#[cfg(feature = "serde_borsh")]
95impl BorshDeserialize for VMObjects {
96 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self> {
97 let metas = MetadataObjs::deserialize_reader(reader)?.into();
98 let functions = FunctionObjs::deserialize_reader(reader)?.into();
99 let packages = PackageObjs::deserialize_reader(reader)?.into();
100 Ok(Self::with_components(metas, functions, packages))
101 }
102}
103
104#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
105pub struct Bytecode {
106 pub objects: VMObjects,
107 pub consts: Vec<GosValue>,
108 pub ifaces: Vec<(Meta, Vec<Binding4Runtime>)>,
110 pub indices: Vec<Vec<OpIndex>>,
112 pub entry: FunctionKey,
113 pub main_pkg: PackageKey,
114 pub file_set: Option<go_parser::FileSet>,
116}
117
118impl Bytecode {
119 pub fn new(
120 objects: VMObjects,
121 consts: Vec<GosValue>,
122 ifaces: Vec<(Meta, Vec<IfaceBinding>)>,
123 indices: Vec<Vec<OpIndex>>,
124 entry: FunctionKey,
125 main_pkg: PackageKey,
126 file_set: Option<go_parser::FileSet>,
127 ) -> Bytecode {
128 let ifaces = ifaces
129 .into_iter()
130 .map(|(ms, binding)| {
131 let binding = binding.into_iter().map(|x| x.into()).collect();
132 (ms, binding)
133 })
134 .collect();
135 Bytecode {
136 objects,
137 consts,
138 ifaces,
139 indices,
140 entry,
141 main_pkg,
142 file_set,
143 }
144 }
145
146 pub fn with_components(
147 metas: MetadataObjs,
148 functions: FunctionObjs,
149 packages: PackageObjs,
150 consts: Vec<GosValue>,
151 ifaces: Vec<(Meta, Vec<Binding4Runtime>)>,
152 indices: Vec<Vec<OpIndex>>,
153 entry: FunctionKey,
154 main_pkg: PackageKey,
155 file_set: Option<go_parser::FileSet>,
156 ) -> Bytecode {
157 let objects = VMObjects::with_components(metas, functions, packages);
158 Bytecode {
159 objects,
160 consts,
161 ifaces,
162 indices,
163 entry,
164 main_pkg,
165 file_set,
166 }
167 }
168}