spirv_tools/assembler/
compiled.rs1use spirv_tools_sys::{assembler, shared};
2
3pub struct CompiledAssembler {
4 inner: *mut shared::ToolContext,
5}
6
7use super::Assembler;
8
9impl Assembler for CompiledAssembler {
10 fn with_env(target_env: crate::TargetEnv) -> Self {
11 Self {
12 inner: unsafe { shared::context_create(target_env) },
13 }
14 }
15
16 fn assemble(
17 &self,
18 text: &str,
19 options: super::AssemblerOptions,
20 ) -> Result<crate::binary::Binary, crate::error::Error> {
21 unsafe {
22 let mut binary = std::ptr::null_mut();
23 let mut diagnostic = std::ptr::null_mut();
24
25 let res = assembler::assemble(
26 self.inner,
27 text.as_ptr().cast(),
28 text.len(),
29 options.into(),
30 &mut binary,
31 &mut diagnostic,
32 );
33
34 let diagnostic = crate::error::Diagnostic::from_diag(diagnostic).ok();
36
37 match res {
38 shared::SpirvResult::Success => {
39 if binary.is_null() {
40 return Err(crate::error::Error {
41 inner: shared::SpirvResult::InternalError,
42 diagnostic: Some("spirv assemble indicated success but did not return a valid binary".to_owned().into()),
43 });
44 }
45
46 let bin = crate::binary::external::ExternalBinary::new(binary);
47 Ok(crate::binary::Binary::External(bin))
48 }
49 other => Err(crate::error::Error {
50 inner: other,
51 diagnostic,
52 }),
53 }
54 }
55 }
56
57 fn disassemble(
58 &self,
59 binary: impl AsRef<[u32]>,
60 options: super::DisassembleOptions,
61 ) -> Result<Option<String>, crate::error::Error> {
62 unsafe {
63 let mut text = std::ptr::null_mut();
64 let mut diagnostic = std::ptr::null_mut();
65
66 let binary = binary.as_ref();
67
68 let res = assembler::disassemble(
69 self.inner,
70 binary.as_ptr().cast(),
71 binary.len(),
72 options.into(),
73 &mut text,
74 &mut diagnostic,
75 );
76
77 let diagnostic = crate::error::Diagnostic::from_diag(diagnostic).ok();
79
80 match res {
81 shared::SpirvResult::Success => {
82 if text.is_null() {
83 return Ok(None);
84 }
85
86 let disassemble_res = std::str::from_utf8(std::slice::from_raw_parts(
88 (*text).data.cast::<u8>(),
89 (*text).length,
90 ))
91 .map(|disasm| Some(disasm.to_owned()))
92 .map_err(|e| crate::error::Error {
93 inner: shared::SpirvResult::InvalidText,
94 diagnostic: Some(
95 format!("spirv disassemble returned non-utf8 text: {}", e).into(),
96 ),
97 });
98
99 assembler::text_destroy(text);
100
101 disassemble_res
102 }
103 other => Err(crate::error::Error {
104 inner: other,
105 diagnostic,
106 }),
107 }
108 }
109 }
110}
111
112impl Default for CompiledAssembler {
113 fn default() -> Self {
114 Self::with_env(crate::TargetEnv::default())
115 }
116}
117
118impl Drop for CompiledAssembler {
119 fn drop(&mut self) {
120 unsafe {
121 shared::context_destroy(self.inner);
122 }
123 }
124}