1 // Copyright © 2024 Igalia S.L.
2 // SPDX-License-Identifier: MIT
3
4 use crate::parser::*;
5 use crate::util::EtnaAsmResultExt;
6
7 use isa_bindings::*;
8 use std::ffi::CStr;
9 use std::os::raw::c_char;
10
11 /// Shared implementation to interact with the asm parser
12 ///
13 /// # Safety
14 ///
15 /// `c_str` must point to a valid nul-termintated string not longer than `isize::MAX` bytes.
16 /// See https://doc.rust-lang.org/std/ffi/struct.CStr.html#safety for further details.
isa_parse( c_str: *const c_char, dual_16_mode: bool, func: impl FnOnce(&str, bool, &mut etna_asm_result), ) -> *mut etna_asm_result17 unsafe fn isa_parse(
18 c_str: *const c_char,
19 dual_16_mode: bool,
20 func: impl FnOnce(&str, bool, &mut etna_asm_result),
21 ) -> *mut etna_asm_result {
22 let mut result = Box::new(etna_asm_result::default());
23
24 if c_str.is_null() {
25 result.set_error("str pointer is NULL");
26 return Box::into_raw(result);
27 }
28
29 // SAFETY: As per the safety section, the caller has to uphold these requirements
30 let c_str_safe = unsafe { CStr::from_ptr(c_str) };
31
32 if let Ok(str) = c_str_safe.to_str() {
33 func(str, dual_16_mode, &mut result);
34 } else {
35 result.set_error("Failed to convert CStr to &str");
36 result.success = false;
37 }
38
39 Box::into_raw(result)
40 }
41
42 /// # Safety
43 ///
44 /// `c_str` must point to a valid nul-termintated string not longer than `isize::MAX` bytes.
45 /// See https://doc.rust-lang.org/std/ffi/struct.CStr.html#safety for further details.
46 #[no_mangle]
isa_parse_str( c_str: *const c_char, dual_16_mode: bool, ) -> *mut etna_asm_result47 pub unsafe extern "C" fn isa_parse_str(
48 c_str: *const c_char,
49 dual_16_mode: bool,
50 ) -> *mut etna_asm_result {
51 // SAFETY: As per the safety section, the caller has to uphold these requirements
52 unsafe { isa_parse(c_str, dual_16_mode, asm_process_str) }
53 }
54
55 /// # Safety
56 ///
57 /// `c_filepath` must point to a valid nul-termintated string not longer than `isize::MAX` bytes.
58 /// See https://doc.rust-lang.org/std/ffi/struct.CStr.html#safety for further details.
59 #[no_mangle]
isa_parse_file( c_filepath: *const c_char, dual_16_mode: bool, ) -> *mut etna_asm_result60 pub unsafe extern "C" fn isa_parse_file(
61 c_filepath: *const c_char,
62 dual_16_mode: bool,
63 ) -> *mut etna_asm_result {
64 // SAFETY: As per the safety section, the caller has to uphold these requirements
65 unsafe { isa_parse(c_filepath, dual_16_mode, asm_process_file) }
66 }
67
68 /// # Safety
69 ///
70 /// `result` must have previously been obtained from `isa_parse_str` or `isa_parse_file`.
71 #[no_mangle]
isa_asm_result_destroy(result: *mut etna_asm_result)72 pub unsafe extern "C" fn isa_asm_result_destroy(result: *mut etna_asm_result) {
73 // SAFETY: As per the safety section, the caller has to uphold these requirements
74 let mut r = unsafe { Box::from_raw(result) };
75 r.dealloc_instructions();
76 r.dealloc_error();
77 }
78