Skip to content

Commit 519f72a

Browse files
committed
Split CPtr impl from ctype
1 parent 5c49dad commit 519f72a

File tree

5 files changed

+97
-33
lines changed

5 files changed

+97
-33
lines changed

crates/lune-std-ffi/src/carr.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use libffi::middle::Type;
22
use mlua::prelude::*;
33

44
use crate::association::{get_association, set_association};
5+
use crate::cptr::CPtr;
56
use crate::ctype::{
67
libffi_type_ensured_size, libffi_type_from_userdata, type_userdata_stringify, CType,
78
};
@@ -88,6 +89,7 @@ impl LuaUserData for CArr {
8889
Ok(inner)
8990
});
9091
}
92+
9193
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
9294
methods.add_method("offset", |_, this, offset: isize| {
9395
if this.length > (offset as usize) && offset >= 0 {
@@ -97,7 +99,7 @@ impl LuaUserData for CArr {
9799
}
98100
});
99101
methods.add_function("ptr", |lua, this: LuaAnyUserData| {
100-
let pointer = CType::pointer(lua, &this)?;
102+
let pointer = CPtr::from_lua_userdata(lua, &this)?;
101103
Ok(pointer)
102104
});
103105
methods.add_meta_function(LuaMetaMethod::ToString, |_, this: LuaAnyUserData| {

crates/lune-std-ffi/src/cptr.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#![allow(clippy::cargo_common_metadata)]
2+
3+
use std::borrow::Borrow;
4+
5+
use libffi::middle::Type;
6+
use mlua::prelude::*;
7+
8+
use crate::association::{get_association, set_association};
9+
use crate::carr::CArr;
10+
use crate::ctype::{type_name_from_userdata, type_userdata_stringify};
11+
12+
const POINTER_INNER: &str = "__pointer_inner";
13+
14+
pub struct CPtr();
15+
16+
impl CPtr {
17+
// Create pointer type with '.inner' field
18+
// inner can be CArr, CType or CStruct
19+
pub fn from_lua_userdata<'lua>(
20+
lua: &'lua Lua,
21+
inner: &LuaAnyUserData,
22+
) -> LuaResult<LuaValue<'lua>> {
23+
let value = Self().into_lua(lua)?;
24+
25+
set_association(lua, POINTER_INNER, value.borrow(), inner)?;
26+
27+
Ok(value)
28+
}
29+
30+
// Stringify CPtr with inner ctype
31+
pub fn stringify(userdata: &LuaAnyUserData) -> LuaResult<String> {
32+
let inner: LuaValue = userdata.get("inner")?;
33+
34+
if inner.is_userdata() {
35+
let inner = inner
36+
.as_userdata()
37+
.ok_or(LuaError::external("failed to get inner type userdata."))?;
38+
Ok(format!(
39+
" <{}({})> ",
40+
type_name_from_userdata(inner),
41+
type_userdata_stringify(inner)?,
42+
))
43+
} else {
44+
Err(LuaError::external("failed to get inner type userdata."))
45+
}
46+
}
47+
48+
// Return void*
49+
pub fn get_type() -> Type {
50+
Type::pointer()
51+
}
52+
}
53+
54+
impl LuaUserData for CPtr {
55+
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
56+
fields.add_field_method_get("size", |_, _| Ok(size_of::<usize>()));
57+
fields.add_field_function_get("inner", |lua, this| {
58+
let inner = get_association(lua, POINTER_INNER, this)?
59+
.ok_or(LuaError::external("inner type not found"))?;
60+
Ok(inner)
61+
});
62+
}
63+
64+
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
65+
methods.add_function("ptr", |lua, this: LuaAnyUserData| {
66+
let pointer = CPtr::from_lua_userdata(lua, &this)?;
67+
Ok(pointer)
68+
});
69+
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {
70+
let carr = CArr::from_lua_userdata(lua, &this, length)?;
71+
Ok(carr)
72+
});
73+
methods.add_meta_function(LuaMetaMethod::ToString, |_, this: LuaAnyUserData| {
74+
let name: Result<String, LuaError> = CPtr::stringify(&this);
75+
Ok(name)
76+
});
77+
}
78+
}

crates/lune-std-ffi/src/cstruct.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ use libffi::{
99
};
1010
use mlua::prelude::*;
1111

12-
use crate::carr::CArr;
1312
use crate::ctype::{libffi_types_from_table, type_userdata_stringify, CType};
1413
use crate::FFI_STATUS_NAMES;
1514
use crate::{
1615
association::{get_association, set_association},
1716
ctype::type_name_from_userdata,
1817
};
18+
use crate::{carr::CArr, cptr::CPtr};
1919

2020
pub struct CStruct {
2121
libffi_cif: Cif,
@@ -138,13 +138,14 @@ impl LuaUserData for CStruct {
138138
Ok(table)
139139
});
140140
}
141+
141142
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
142143
methods.add_method("offset", |_, this, index: usize| {
143144
let offset = this.offset(index)?;
144145
Ok(offset)
145146
});
146147
methods.add_function("ptr", |lua, this: LuaAnyUserData| {
147-
let pointer = CType::pointer(lua, &this)?;
148+
let pointer = CPtr::from_lua_userdata(lua, &this)?;
148149
Ok(pointer)
149150
});
150151
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {

crates/lune-std-ffi/src/ctype.rs

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use mlua::prelude::*;
1313

1414
use crate::association::{get_association, set_association};
1515
use crate::carr::CArr;
16+
use crate::cptr::CPtr;
1617
use crate::cstruct::CStruct;
1718
use crate::FFI_STATUS_NAMES;
1819
// use libffi::raw::{ffi_cif, ffi_ptrarray_to_raw};
@@ -42,26 +43,6 @@ impl CType {
4243
self.libffi_type.clone()
4344
}
4445

45-
// Create pointer type with '.inner' field
46-
// inner can be CArr, CType or CStruct
47-
pub fn pointer<'lua>(lua: &'lua Lua, inner: &LuaAnyUserData) -> LuaResult<LuaValue<'lua>> {
48-
let value = Self {
49-
libffi_cif: Cif::new(vec![Type::pointer()], Type::void()),
50-
libffi_type: Type::pointer(),
51-
size: size_of::<usize>(),
52-
name: Some(format!(
53-
"Ptr<{}({})>",
54-
type_name_from_userdata(inner),
55-
type_userdata_stringify(inner)?
56-
)),
57-
}
58-
.into_lua(lua)?;
59-
60-
set_association(lua, POINTER_INNER, value.borrow(), inner)?;
61-
62-
Ok(value)
63-
}
64-
6546
pub fn stringify(&self) -> String {
6647
match &self.name {
6748
Some(t) => t.to_owned(),
@@ -73,18 +54,11 @@ impl CType {
7354
impl LuaUserData for CType {
7455
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
7556
fields.add_field_method_get("size", |_, this| Ok(this.size));
76-
fields.add_field_function_get("inner", |lua, this| {
77-
let inner = get_association(lua, POINTER_INNER, this)?;
78-
match inner {
79-
Some(t) => Ok(t),
80-
None => Ok(LuaNil),
81-
}
82-
});
8357
}
8458

8559
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
8660
methods.add_function("ptr", |lua, this: LuaAnyUserData| {
87-
let pointer = CType::pointer(lua, &this)?;
61+
let pointer = CPtr::from_lua_userdata(lua, &this)?;
8862
Ok(pointer)
8963
});
9064
methods.add_function("arr", |lua, (this, length): (LuaAnyUserData, usize)| {
@@ -172,14 +146,16 @@ pub fn libffi_types_from_table(table: &LuaTable) -> LuaResult<Vec<Type>> {
172146
Ok(fields)
173147
}
174148

175-
// get libffi_type from any c-types userdata
149+
// get libffi_type from any c-type userdata
176150
pub fn libffi_type_from_userdata(userdata: &LuaAnyUserData) -> LuaResult<Type> {
177151
if userdata.is::<CStruct>() {
178152
Ok(userdata.borrow::<CStruct>()?.get_type())
179153
} else if userdata.is::<CType>() {
180154
Ok(userdata.borrow::<CType>()?.get_type())
181155
} else if userdata.is::<CArr>() {
182156
Ok(userdata.borrow::<CArr>()?.get_type())
157+
} else if userdata.is::<CPtr>() {
158+
Ok(CPtr::get_type())
183159
} else {
184160
Err(LuaError::external(format!(
185161
"Unexpected field. CStruct, CType, CString or CArr is required for element but got {}",
@@ -193,7 +169,7 @@ pub fn libffi_type_from_userdata(userdata: &LuaAnyUserData) -> LuaResult<Type> {
193169
}
194170
}
195171

196-
// stringify any c-types userdata (for recursive)
172+
// stringify any c-type userdata (for recursive)
197173
pub fn type_userdata_stringify(userdata: &LuaAnyUserData) -> LuaResult<String> {
198174
if userdata.is::<CType>() {
199175
let name = userdata.borrow::<CType>()?.stringify();
@@ -204,18 +180,24 @@ pub fn type_userdata_stringify(userdata: &LuaAnyUserData) -> LuaResult<String> {
204180
} else if userdata.is::<CArr>() {
205181
let name = CArr::stringify(userdata)?;
206182
Ok(name)
183+
} else if userdata.is::<CPtr>() {
184+
let name: String = CPtr::stringify(userdata)?;
185+
Ok(name)
207186
} else {
208187
Ok(String::from("unnamed"))
209188
}
210189
}
211190

191+
// get name tag for any c-type userdata
212192
pub fn type_name_from_userdata(userdata: &LuaAnyUserData) -> String {
213193
if userdata.is::<CStruct>() {
214194
String::from("CStruct")
215195
} else if userdata.is::<CType>() {
216196
String::from("CType")
217197
} else if userdata.is::<CArr>() {
218198
String::from("CArr")
199+
} else if userdata.is::<CPtr>() {
200+
String::from("CPtr")
219201
} else {
220202
String::from("unnamed")
221203
}

crates/lune-std-ffi/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use mlua::prelude::*;
66
mod association;
77
mod carr;
88
mod cfn;
9+
mod cptr;
910
mod cstring;
1011
mod cstruct;
1112
mod ctype;

0 commit comments

Comments
 (0)