@@ -12,6 +12,7 @@ use lune_utils::fmt::{pretty_format_value, ValueFormatConfig};
12
12
use mlua:: prelude:: * ;
13
13
14
14
use crate :: association:: { get_association, set_association} ;
15
+ use crate :: carr:: CArr ;
15
16
use crate :: cstruct:: CStruct ;
16
17
use crate :: FFI_STATUS_NAMES ;
17
18
// use libffi::raw::{ffi_cif, ffi_ptrarray_to_raw};
@@ -26,38 +27,32 @@ pub struct CType {
26
27
}
27
28
28
29
impl CType {
29
- pub fn new ( libffi_type : Type , name : Option < String > ) -> Self {
30
+ pub fn new ( libffi_type : Type , name : Option < String > ) -> LuaResult < Self > {
30
31
let libffi_cfi = Cif :: new ( vec ! [ libffi_type. clone( ) ] , Type :: void ( ) ) ;
31
- let size = unsafe { ( * libffi_type. as_raw_ptr ( ) ) . size } ;
32
- Self {
32
+ let size = libffi_type_ensured_size ( libffi_type. as_raw_ptr ( ) ) ? ;
33
+ Ok ( Self {
33
34
libffi_cif : libffi_cfi,
34
35
libffi_type,
35
36
size,
36
37
name,
37
- }
38
+ } )
38
39
}
39
40
40
41
pub fn get_type ( & self ) -> Type {
41
42
self . libffi_type . clone ( )
42
43
}
43
44
45
+ // Create pointer type with '.inner' field
46
+ // inner can be CArr, CType or CStruct
44
47
pub fn pointer < ' lua > ( lua : & ' lua Lua , inner : & LuaAnyUserData ) -> LuaResult < LuaValue < ' lua > > {
45
48
let value = Self {
46
49
libffi_cif : Cif :: new ( vec ! [ Type :: pointer( ) ] , Type :: void ( ) ) ,
47
50
libffi_type : Type :: pointer ( ) ,
48
51
size : size_of :: < usize > ( ) ,
49
52
name : Some ( format ! (
50
53
"Ptr<{}({})>" ,
51
- {
52
- if inner. is:: <CStruct >( ) {
53
- "CStruct"
54
- } else if inner. is:: <CType >( ) {
55
- "CType"
56
- } else {
57
- "unnamed"
58
- }
59
- } ,
60
- type_name_from_userdata( inner) ?
54
+ type_name_from_userdata( inner) ,
55
+ type_userdata_stringify( inner) ?
61
56
) ) ,
62
57
}
63
58
. into_lua ( lua) ?;
@@ -92,7 +87,10 @@ impl LuaUserData for CType {
92
87
let pointer = CType :: pointer ( lua, & this) ?;
93
88
Ok ( pointer)
94
89
} ) ;
95
-
90
+ methods. add_function ( "arr" , |lua, ( this, length) : ( LuaAnyUserData , usize ) | {
91
+ let carr = CArr :: from_lua_userdata ( lua, & this, length) ?;
92
+ Ok ( carr)
93
+ } ) ;
96
94
methods. add_meta_method ( LuaMetaMethod :: ToString , |_, this, ( ) | {
97
95
let name = this. stringify ( ) ;
98
96
Ok ( name)
@@ -105,47 +103,47 @@ pub fn create_all_types(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
105
103
Ok ( vec ! [
106
104
(
107
105
"u8" ,
108
- CType :: new( Type :: u8 ( ) , Some ( String :: from( "u8" ) ) ) . into_lua( lua) ?,
106
+ CType :: new( Type :: u8 ( ) , Some ( String :: from( "u8" ) ) ) ? . into_lua( lua) ?,
109
107
) ,
110
108
(
111
109
"u16" ,
112
- CType :: new( Type :: u16 ( ) , Some ( String :: from( "u16" ) ) ) . into_lua( lua) ?,
110
+ CType :: new( Type :: u16 ( ) , Some ( String :: from( "u16" ) ) ) ? . into_lua( lua) ?,
113
111
) ,
114
112
(
115
113
"u32" ,
116
- CType :: new( Type :: u32 ( ) , Some ( String :: from( "u32" ) ) ) . into_lua( lua) ?,
114
+ CType :: new( Type :: u32 ( ) , Some ( String :: from( "u32" ) ) ) ? . into_lua( lua) ?,
117
115
) ,
118
116
(
119
117
"u64" ,
120
- CType :: new( Type :: u64 ( ) , Some ( String :: from( "u64" ) ) ) . into_lua( lua) ?,
118
+ CType :: new( Type :: u64 ( ) , Some ( String :: from( "u64" ) ) ) ? . into_lua( lua) ?,
121
119
) ,
122
120
(
123
121
"i8" ,
124
- CType :: new( Type :: i8 ( ) , Some ( String :: from( "i8" ) ) ) . into_lua( lua) ?,
122
+ CType :: new( Type :: i8 ( ) , Some ( String :: from( "i8" ) ) ) ? . into_lua( lua) ?,
125
123
) ,
126
124
(
127
125
"i16" ,
128
- CType :: new( Type :: i16 ( ) , Some ( String :: from( "i16" ) ) ) . into_lua( lua) ?,
126
+ CType :: new( Type :: i16 ( ) , Some ( String :: from( "i16" ) ) ) ? . into_lua( lua) ?,
129
127
) ,
130
128
(
131
129
"i32" ,
132
- CType :: new( Type :: i32 ( ) , Some ( String :: from( "i32" ) ) ) . into_lua( lua) ?,
130
+ CType :: new( Type :: i32 ( ) , Some ( String :: from( "i32" ) ) ) ? . into_lua( lua) ?,
133
131
) ,
134
132
(
135
133
"i64" ,
136
- CType :: new( Type :: i64 ( ) , Some ( String :: from( "i64" ) ) ) . into_lua( lua) ?,
134
+ CType :: new( Type :: i64 ( ) , Some ( String :: from( "i64" ) ) ) ? . into_lua( lua) ?,
137
135
) ,
138
136
(
139
137
"f32" ,
140
- CType :: new( Type :: f32 ( ) , Some ( String :: from( "f32" ) ) ) . into_lua( lua) ?,
138
+ CType :: new( Type :: f32 ( ) , Some ( String :: from( "f32" ) ) ) ? . into_lua( lua) ?,
141
139
) ,
142
140
(
143
141
"f64" ,
144
- CType :: new( Type :: f64 ( ) , Some ( String :: from( "f64" ) ) ) . into_lua( lua) ?,
142
+ CType :: new( Type :: f64 ( ) , Some ( String :: from( "f64" ) ) ) ? . into_lua( lua) ?,
145
143
) ,
146
144
(
147
145
"void" ,
148
- CType :: new( Type :: void( ) , Some ( String :: from( "void" ) ) ) . into_lua( lua) ?,
146
+ CType :: new( Type :: void( ) , Some ( String :: from( "void" ) ) ) ? . into_lua( lua) ?,
149
147
) ,
150
148
] )
151
149
}
@@ -180,9 +178,11 @@ pub fn libffi_type_from_userdata(userdata: &LuaAnyUserData) -> LuaResult<Type> {
180
178
Ok ( userdata. borrow :: < CStruct > ( ) ?. get_type ( ) )
181
179
} else if userdata. is :: < CType > ( ) {
182
180
Ok ( userdata. borrow :: < CType > ( ) ?. get_type ( ) )
181
+ } else if userdata. is :: < CArr > ( ) {
182
+ Ok ( userdata. borrow :: < CArr > ( ) ?. get_type ( ) )
183
183
} else {
184
184
Err ( LuaError :: external ( format ! (
185
- "Unexpected field. CStruct, CType or CArr is required for element but got {}" ,
185
+ "Unexpected field. CStruct, CType, CString or CArr is required for element but got {}" ,
186
186
pretty_format_value(
187
187
// Since the data is in the Lua location,
188
188
// there is no problem with the clone.
@@ -194,18 +194,33 @@ pub fn libffi_type_from_userdata(userdata: &LuaAnyUserData) -> LuaResult<Type> {
194
194
}
195
195
196
196
// stringify any c-types userdata (for recursive)
197
- pub fn type_name_from_userdata ( userdata : & LuaAnyUserData ) -> LuaResult < String > {
197
+ pub fn type_userdata_stringify ( userdata : & LuaAnyUserData ) -> LuaResult < String > {
198
198
if userdata. is :: < CType > ( ) {
199
199
let name = userdata. borrow :: < CType > ( ) ?. stringify ( ) ;
200
200
Ok ( name)
201
201
} else if userdata. is :: < CStruct > ( ) {
202
202
let name = CStruct :: stringify ( userdata) ?;
203
203
Ok ( name)
204
+ } else if userdata. is :: < CArr > ( ) {
205
+ let name = CArr :: stringify ( userdata) ?;
206
+ Ok ( name)
204
207
} else {
205
208
Ok ( String :: from ( "unnamed" ) )
206
209
}
207
210
}
208
211
212
+ pub fn type_name_from_userdata ( userdata : & LuaAnyUserData ) -> String {
213
+ if userdata. is :: < CStruct > ( ) {
214
+ String :: from ( "CStruct" )
215
+ } else if userdata. is :: < CType > ( ) {
216
+ String :: from ( "CType" )
217
+ } else if userdata. is :: < CArr > ( ) {
218
+ String :: from ( "CArr" )
219
+ } else {
220
+ String :: from ( "unnamed" )
221
+ }
222
+ }
223
+
209
224
// Ensure sizeof c-type (raw::libffi_type)
210
225
// See: http://www.chiark.greenend.org.uk/doc/libffi-dev/html/Size-and-Alignment.html
211
226
pub fn libffi_type_ensured_size ( ffi_type : * mut raw:: ffi_type ) -> LuaResult < usize > {
0 commit comments