|
| 1 | +#![allow(clippy::inline_always)] |
| 2 | + |
1 | 3 | use std::ptr::{self, null_mut};
|
2 | 4 |
|
3 | 5 | use libffi::{low, middle::Type, raw};
|
4 | 6 | use lune_utils::fmt::{pretty_format_value, ValueFormatConfig};
|
5 | 7 | use mlua::prelude::*;
|
6 | 8 |
|
7 | 9 | use super::association_names::CTYPE_STATIC;
|
8 |
| -use super::c_arr::CArr; |
9 |
| -use super::c_ptr::CPtr; |
10 |
| -use super::c_struct::CStruct; |
11 | 10 | use super::c_type::CTypeStatic;
|
12 |
| -use crate::ffi::ffi_association::get_association; |
13 |
| -use crate::ffi::ffi_helper::FFI_STATUS_NAMES; |
| 11 | +use super::types::get_ctype_conv; |
| 12 | +use super::{CArr, CPtr, CStruct}; |
| 13 | +use crate::ffi::{ffi_association::get_association, NativeConvert, FFI_STATUS_NAMES}; |
| 14 | + |
| 15 | +// Get the NativeConvert handle from the type UserData |
| 16 | +// this is intended to avoid constant table lookups. (eg: struct) |
| 17 | +// userdata must live longer than the NativeConvert handle. |
| 18 | +// However, c_struct is a strong reference to each field, so this is not a problem. |
| 19 | +pub unsafe fn get_conv(userdata: &LuaAnyUserData) -> LuaResult<*const dyn NativeConvert> { |
| 20 | + if userdata.is::<CStruct>() { |
| 21 | + Ok(userdata.to_pointer().cast::<CStruct>() as *const dyn NativeConvert) |
| 22 | + } else { |
| 23 | + unsafe { get_ctype_conv(userdata) } |
| 24 | + } |
| 25 | +} |
| 26 | +pub unsafe fn get_conv_list_from_table( |
| 27 | + table: &LuaTable, |
| 28 | +) -> LuaResult<Vec<*const dyn NativeConvert>> { |
| 29 | + let len: usize = table.raw_len(); |
| 30 | + let mut conv_list = Vec::<*const dyn NativeConvert>::with_capacity(len); |
| 31 | + |
| 32 | + for i in 0..len { |
| 33 | + let value: LuaValue = table.raw_get(i + 1)?; |
| 34 | + |
| 35 | + if let LuaValue::UserData(field_type) = value { |
| 36 | + conv_list.push(get_conv(&field_type)?); |
| 37 | + } else { |
| 38 | + return Err(LuaError::external(format!( |
| 39 | + "Unexpected field. CStruct, CType or CArr is required for element but got {}", |
| 40 | + pretty_format_value(&value, &ValueFormatConfig::new()) |
| 41 | + ))); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + Ok(conv_list) |
| 46 | +} |
| 47 | + |
| 48 | +// #[inline(always)] |
| 49 | +// pub fn type_size_from_userdata(this: &LuaAnyUserData) -> LuaResult<usize> { |
| 50 | +// if this.is::<CStruct>() { |
| 51 | +// Ok(this.borrow::<CStruct>()?.get_size()) |
| 52 | +// } else if this.is::<CArr>() { |
| 53 | +// Ok(this.borrow::<CArr>()?.get_size()) |
| 54 | +// } else { |
| 55 | +// ctype_size_from_userdata(this) |
| 56 | +// } |
| 57 | +// } |
14 | 58 |
|
15 | 59 | // get Vec<libffi_type> from table(array) of c-types userdata
|
16 |
| -pub fn type_list_from_table(lua: &Lua, table: &LuaTable) -> LuaResult<Vec<Type>> { |
| 60 | +pub fn libffi_type_list_from_table(lua: &Lua, table: &LuaTable) -> LuaResult<Vec<Type>> { |
17 | 61 | let len: usize = table.raw_len();
|
18 | 62 | let mut fields = Vec::with_capacity(len);
|
19 | 63 |
|
20 | 64 | for i in 0..len {
|
21 | 65 | // Test required
|
22 | 66 | let value = table.raw_get(i + 1)?;
|
23 |
| - match value { |
24 |
| - LuaValue::UserData(field_type) => { |
25 |
| - fields.push(type_from_userdata(lua, &field_type)?); |
26 |
| - } |
27 |
| - _ => { |
28 |
| - return Err(LuaError::external(format!( |
29 |
| - "Unexpected field. CStruct, CType or CArr is required for element but got {}", |
30 |
| - pretty_format_value(&value, &ValueFormatConfig::new()) |
31 |
| - ))); |
32 |
| - } |
| 67 | + if let LuaValue::UserData(field_type) = value { |
| 68 | + fields.push(libffi_type_from_userdata(lua, &field_type)?); |
| 69 | + } else { |
| 70 | + return Err(LuaError::external(format!( |
| 71 | + "Unexpected field. CStruct, CType or CArr is required for element but got {}", |
| 72 | + value.type_name() |
| 73 | + ))); |
33 | 74 | }
|
34 | 75 | }
|
35 | 76 |
|
36 | 77 | Ok(fields)
|
37 | 78 | }
|
38 | 79 |
|
39 | 80 | // get libffi_type from any c-type userdata
|
40 |
| -pub fn type_from_userdata(lua: &Lua, userdata: &LuaAnyUserData) -> LuaResult<Type> { |
| 81 | +pub fn libffi_type_from_userdata(lua: &Lua, userdata: &LuaAnyUserData) -> LuaResult<Type> { |
41 | 82 | if userdata.is::<CStruct>() {
|
42 | 83 | Ok(userdata.borrow::<CStruct>()?.get_type().to_owned())
|
43 | 84 | } else if let Some(t) = get_association(lua, CTYPE_STATIC, userdata)? {
|
|
0 commit comments