Skip to content

Commit 70d0429

Browse files
rbranemesare
authored andcommitted
separate User and System implementations of TypeParserResult
1 parent e3919ef commit 70d0429

File tree

1 file changed

+87
-58
lines changed

1 file changed

+87
-58
lines changed

rust/src/typeparser.rs

Lines changed: 87 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use binaryninjacore_sys::*;
55
use crate::binaryview::BinaryView;
66
use crate::disassembly::InstructionTextToken;
77
use crate::platform::Platform;
8-
use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref};
8+
use crate::rc::{Array, ArrayGuard, CoreArrayProvider, CoreArrayProviderInner, Ref};
99
use crate::string::{BnStrCompatible, BnString};
1010
use crate::types::{NamedTypeReference, QualifiedName, QualifiedNameAndType, Type};
1111

@@ -222,7 +222,7 @@ pub trait TypeParser {
222222
options: &[BnString],
223223
include_dirs: &[BnString],
224224
auto_type_source: &str,
225-
) -> Result<TypeParserResult, Vec<TypeParserError>>;
225+
) -> Result<TypeParserResultUser, Vec<TypeParserError>>;
226226

227227
/// Parse a single type and name from a string containing their definition.
228228
///
@@ -874,82 +874,87 @@ unsafe impl CoreArrayProviderInner for TypeParserError {
874874
}
875875
}
876876

877+
/// The user created version of TypeParserResult
877878
#[derive(Debug, Clone, Default)]
878-
pub struct TypeParserResult {
879+
pub struct TypeParserResultUser {
879880
pub types: Vec<ParsedType>,
880881
pub variables: Vec<ParsedType>,
881882
pub functions: Vec<ParsedType>,
882883
}
883884

884-
impl TypeParserResult {
885-
pub(crate) unsafe fn from_raw(mut value: BNTypeParserResult) -> Self {
886-
fn from_types(values: *mut BNParsedType, value_len: usize) -> Vec<ParsedType> {
887-
unsafe { core::slice::from_raw_parts(values, value_len) }
888-
.iter()
889-
.map(|t| unsafe { ParsedType::clone_from_raw(t) })
890-
.collect()
891-
}
892-
let output = Self {
893-
types: from_types(value.types, value.typeCount),
894-
variables: from_types(value.variables, value.variableCount),
895-
functions: from_types(value.functions, value.functionCount),
896-
};
897-
BNFreeTypeParserResult(&mut value);
898-
output
899-
}
900-
901-
unsafe fn into_raw(self) -> TypeParserResultRaw {
885+
impl TypeParserResultUser {
886+
fn into_user_raw(self) -> BNTypeParserResult {
902887
let Self {
903888
types,
904889
variables,
905890
functions,
906891
} = self;
907-
let types: &mut [BNParsedType] =
908-
Box::leak(types.into_iter().map(|x| x.into_raw()).collect());
909-
let variables: &mut [BNParsedType] =
910-
Box::leak(variables.into_iter().map(|x| x.into_raw()).collect());
911-
let functions: &mut [BNParsedType] =
912-
Box::leak(functions.into_iter().map(|x| x.into_raw()).collect());
913-
TypeParserResultRaw(BNTypeParserResult {
892+
let types = Box::leak(types.into_iter().map(|t| unsafe { t.into_raw() }).collect());
893+
let variables = Box::leak(
894+
variables
895+
.into_iter()
896+
.map(|t| unsafe { t.into_raw() })
897+
.collect(),
898+
);
899+
let functions = Box::leak(
900+
functions
901+
.into_iter()
902+
.map(|t| unsafe { t.into_raw() })
903+
.collect(),
904+
);
905+
BNTypeParserResult {
914906
types: types.as_mut_ptr(),
915-
variables: variables.as_mut_ptr(),
916-
functions: functions.as_mut_ptr(),
917907
typeCount: types.len(),
908+
variables: variables.as_mut_ptr(),
918909
variableCount: variables.len(),
910+
functions: functions.as_mut_ptr(),
919911
functionCount: functions.len(),
920-
})
912+
}
913+
}
914+
915+
/// SAFETY only can be used with products from [TypeParserResultUser::into_user_raw]
916+
unsafe fn from_user_raw(value: BNTypeParserResult) -> Self {
917+
let from_raw = |raw, count| {
918+
Box::from_raw(ptr::slice_from_raw_parts_mut(raw, count))
919+
.into_iter()
920+
.map(|t| ParsedType::from_raw(t))
921+
.collect()
922+
};
923+
Self {
924+
types: from_raw(value.types, value.typeCount),
925+
variables: from_raw(value.variables, value.variableCount),
926+
functions: from_raw(value.functions, value.functionCount),
927+
}
921928
}
922929
}
923930

924-
#[repr(transparent)]
925-
struct TypeParserResultRaw(BNTypeParserResult);
931+
pub struct TypeParserResult(BNTypeParserResult);
932+
933+
impl TypeParserResult {
934+
pub(crate) unsafe fn from_raw(value: BNTypeParserResult) -> Self {
935+
Self(value)
936+
}
937+
938+
fn as_raw(&mut self) -> &mut BNTypeParserResult {
939+
&mut self.0
940+
}
926941

927-
impl TypeParserResultRaw {
928-
pub(crate) unsafe fn into_raw(self) -> BNTypeParserResult {
929-
mem::ManuallyDrop::new(self).0
942+
pub fn types(&self) -> ArrayGuard<&ParsedType> {
943+
unsafe { ArrayGuard::new(self.0.types, self.0.typeCount, &()) }
944+
}
945+
946+
pub fn variables(&self) -> ArrayGuard<&ParsedType> {
947+
unsafe { ArrayGuard::new(self.0.variables, self.0.variableCount, &()) }
948+
}
949+
950+
pub fn functions(&self) -> ArrayGuard<&ParsedType> {
951+
unsafe { ArrayGuard::new(self.0.functions, self.0.functionCount, &()) }
930952
}
931953
}
932954

933-
impl Drop for TypeParserResultRaw {
955+
impl Drop for TypeParserResult {
934956
fn drop(&mut self) {
935-
drop(unsafe {
936-
Box::from_raw(ptr::slice_from_raw_parts_mut(
937-
self.0.types,
938-
self.0.typeCount,
939-
))
940-
});
941-
drop(unsafe {
942-
Box::from_raw(ptr::slice_from_raw_parts_mut(
943-
self.0.variables,
944-
self.0.variableCount,
945-
))
946-
});
947-
drop(unsafe {
948-
Box::from_raw(ptr::slice_from_raw_parts_mut(
949-
self.0.functions,
950-
self.0.functionCount,
951-
))
952-
});
957+
unsafe { BNFreeTypeParserResult(self.as_raw()) }
953958
}
954959
}
955960

@@ -969,6 +974,14 @@ impl ParsedType {
969974
}
970975
}
971976

977+
pub(crate) unsafe fn from_raw(parsed: &BNParsedType) -> Self {
978+
Self {
979+
name: QualifiedName(parsed.name),
980+
type_: Type::ref_from_raw(parsed.type_),
981+
is_user: parsed.isUser,
982+
}
983+
}
984+
972985
pub(crate) unsafe fn clone_from_raw(parsed: &BNParsedType) -> Self {
973986
let name = mem::ManuallyDrop::new(QualifiedName(parsed.name));
974987
let type_ = Type {
@@ -1005,6 +1018,23 @@ impl ParsedType {
10051018
}
10061019
}
10071020

1021+
impl<'a> CoreArrayProvider for &'a ParsedType {
1022+
type Raw = BNParsedType;
1023+
type Context = &'a ();
1024+
type Wrapped<'b> = ParsedType where 'a: 'b;
1025+
}
1026+
1027+
unsafe impl<'a> CoreArrayProviderInner for &'a ParsedType {
1028+
// ParsedType can only by used in a ArrayGuard
1029+
unsafe fn free(_raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
1030+
unreachable!()
1031+
}
1032+
1033+
unsafe fn wrap_raw<'b>(raw: &'b Self::Raw, _context: &'b Self::Context) -> Self::Wrapped<'b> {
1034+
ParsedType::clone_from_raw(raw)
1035+
}
1036+
}
1037+
10081038
#[derive(Clone)]
10091039
pub struct TypeDefinitionLine {
10101040
pub line_type: TypeDefinitionLineType,
@@ -1238,8 +1268,7 @@ unsafe extern "C" fn cb_parse_types_from_source<T: TypeParser>(
12381268
&auto_type_source.to_string_lossy(),
12391269
) {
12401270
Ok(inner_result) => {
1241-
let inner_result_raw = inner_result.into_raw();
1242-
let inner_result_ffi = inner_result_raw.into_raw();
1271+
let inner_result_ffi = inner_result.into_user_raw();
12431272
// SAFETY drop by the function cb_free_result
12441273
*result = inner_result_ffi;
12451274
*errors = ptr::null_mut();
@@ -1297,7 +1326,7 @@ unsafe extern "C" fn cb_free_string(_ctxt: *mut ffi::c_void, string: *mut ffi::c
12971326
}
12981327

12991328
unsafe extern "C" fn cb_free_result(_ctxt: *mut ffi::c_void, result: *mut BNTypeParserResult) {
1300-
drop(TypeParserResultRaw(*result))
1329+
drop(TypeParserResultUser::from_user_raw(*result))
13011330
}
13021331

13031332
unsafe extern "C" fn cb_free_error_list(

0 commit comments

Comments
 (0)