1use crate::compiler::CompileOutput;
9use crate::compiler::compile;
10use candela_vm::artifact::DynLibFnImage;
11use candela_vm::artifact::EnumImage;
12use candela_vm::artifact::EnumVariantImage;
13use candela_vm::artifact::HostFnImage;
14use candela_vm::artifact::InstrSrcImage;
15use candela_vm::artifact::ProgramImage;
16use candela_vm::artifact::SourceImage;
17use candela_vm::artifact::StructImage;
18use candela_vm::artifact::serialize_image;
19
20pub fn build_bytecode(source: String, filename: &str) -> Result<Vec<u8>, String> {
33 let out = compile(source, filename, false);
34 let image = image_from_output(out);
35 serialize_image(&image)
36}
37
38fn image_from_output(out: CompileOutput) -> ProgramImage {
39 let dyn_lib_fns = out
44 .dyn_lib_fns
45 .iter()
46 .map(|d| DynLibFnImage {
47 library: d.library.to_string(),
48 symbol: d.symbol.to_string(),
49 types: d.types.to_vec(),
50 })
51 .collect();
52 let host_fns = out
56 .host_fns
57 .iter()
58 .map(|h| HostFnImage {
59 namespace: h.namespace.to_string(),
60 name: h.name.to_string(),
61 types: h.types.to_vec(),
62 variadic: h.variadic,
63 })
64 .collect();
65
66 ProgramImage {
67 instructions: out.instructions,
68 registers: out.registers.iter().map(|d| d.0).collect(),
69 objs: out
70 .pools
71 .objs
72 .0
73 .iter()
74 .map(|v| v.iter().map(|d| d.0).collect())
75 .collect(),
76 maps: out
77 .pools
78 .maps
79 .0
80 .iter()
81 .map(|m| m.iter().map(|(k, v)| (k.0, v.0)).collect())
82 .collect(),
83 strings: out.pools.strings.0.clone(),
84 instr_src: out
85 .instr_src
86 .iter()
87 .map(|s| InstrSrcImage {
88 instr: s.instr,
89 span: s.span,
90 file_id: s.file_id,
91 })
92 .collect(),
93 fn_registers: out.fn_registers,
94 structs: out
95 .structs
96 .iter()
97 .map(|s| StructImage {
98 name: s.name.to_string(),
99 fields: s
100 .fields
101 .iter()
102 .map(|(n, t, sp)| (n.to_string(), t.clone(), *sp))
103 .collect(),
104 id: s.id,
105 name_span: s.name_span,
106 })
107 .collect(),
108 enums: out
109 .enums
110 .iter()
111 .map(|e| EnumImage {
112 name: e.name.to_string(),
113 variants: e
114 .variants
115 .iter()
116 .map(|vt| EnumVariantImage {
117 name: vt.name.to_string(),
118 payload: vt.payload.to_vec(),
119 name_span: vt.name_span,
120 })
121 .collect(),
122 id: e.id,
123 name_span: e.name_span,
124 })
125 .collect(),
126 sources: out
127 .sources
128 .iter()
129 .map(|s| SourceImage {
130 filename: s.filename.to_string(),
131 contents: s.contents.clone(),
132 })
133 .collect(),
134 allocated_arg_count: out.allocated_arg_count as u64,
135 allocated_call_depth: out.allocated_call_depth as u64,
136 dyn_lib_fns,
137 host_fns,
138 }
139}