1
1
use std:: boxed:: Box ;
2
- use std:: sync:: OnceLock ;
3
2
4
3
use mlua:: prelude:: * ;
5
4
6
5
use super :: {
7
6
association_names:: REF_INNER ,
8
7
ffi_association:: set_association,
9
- ffi_ref:: { FfiRef , FfiRefBounds , FfiRefFlag , FfiRefFlagList } ,
8
+ ffi_ref:: { FfiRef , FfiRefBounds , FfiRefFlag , FfiRefFlagList , UNSIZED_BOUNDS } ,
10
9
NativeDataHandle ,
11
10
} ;
12
11
13
- static BOX_REF_FLAGS : OnceLock < FfiRefFlagList > = OnceLock :: new ( ) ;
14
- fn get_box_ref_flags ( ) -> FfiRefFlagList {
15
- BOX_REF_FLAGS
16
- . get_or_init ( || {
17
- FfiRefFlagList :: new ( & [
18
- FfiRefFlag :: Offsetable ,
19
- FfiRefFlag :: Readable ,
20
- FfiRefFlag :: Writable ,
21
- ] )
22
- } )
23
- . to_owned ( )
24
- }
12
+ const BOX_REF_FLAGS : FfiRefFlagList = FfiRefFlagList :: new (
13
+ FfiRefFlag :: Offsetable . value ( ) | FfiRefFlag :: Readable . value ( ) | FfiRefFlag :: Writable . value ( ) ,
14
+ ) ;
25
15
26
16
// It is an untyped, sized memory area that Lua can manage.
27
17
// This area is safe within Lua. Operations have their boundaries checked.
@@ -35,6 +25,7 @@ fn get_box_ref_flags() -> FfiRefFlagList {
35
25
struct RefData {
36
26
address : usize ,
37
27
offset : usize ,
28
+ lua_inner_id : i32 ,
38
29
}
39
30
40
31
pub struct FfiBox {
@@ -77,7 +68,7 @@ impl FfiBox {
77
68
this : LuaAnyUserData < ' lua > ,
78
69
offset : Option < isize > ,
79
70
) -> LuaResult < LuaAnyUserData < ' lua > > {
80
- let mut target = this. borrow_mut :: < FfiBox > ( ) ?;
71
+ let target = this. borrow :: < FfiBox > ( ) ?;
81
72
let mut bounds = FfiRefBounds :: new ( 0 , target. size ( ) ) ;
82
73
let mut ptr = target. get_ptr ( ) ;
83
74
@@ -98,14 +89,35 @@ impl FfiBox {
98
89
// To deref a box space is to allow lua to read any space,
99
90
// which has security issues and is ultimately dangerous.
100
91
// Therefore, box:ref():deref() is not allowed.
101
- let luaref = lua. create_userdata ( FfiRef :: new ( ptr. cast ( ) , get_box_ref_flags ( ) , bounds) ) ?;
92
+ let luaref = lua. create_userdata ( FfiRef :: new ( ptr. cast ( ) , BOX_REF_FLAGS , bounds) ) ?;
102
93
103
94
// Makes box alive longer then ref
104
95
set_association ( lua, REF_INNER , & luaref, & this) ?;
105
96
106
97
Ok ( luaref)
107
98
}
108
99
100
+ // Make FfiRef from box, without any safe features
101
+ pub fn luaref_unsafe < ' lua > (
102
+ lua : & ' lua Lua ,
103
+ this : LuaAnyUserData < ' lua > ,
104
+ offset : Option < isize > ,
105
+ ) -> LuaResult < LuaAnyUserData < ' lua > > {
106
+ let target = this. borrow :: < FfiBox > ( ) ?;
107
+ let mut ptr = target. get_ptr ( ) ;
108
+
109
+ // Calculate offset
110
+ if let Some ( t) = offset {
111
+ ptr = unsafe { target. get_ptr ( ) . byte_offset ( t) } ;
112
+ }
113
+
114
+ lua. create_userdata ( FfiRef :: new (
115
+ ptr. cast ( ) ,
116
+ FfiRefFlagList :: all ( ) ,
117
+ UNSIZED_BOUNDS ,
118
+ ) )
119
+ }
120
+
109
121
// Fill every field with 0
110
122
pub fn zero ( & mut self ) {
111
123
self . data . fill ( 0u8 ) ;
@@ -130,13 +142,16 @@ impl NativeDataHandle for FfiBox {
130
142
self . size ( ) > ( ( offset as usize ) + size)
131
143
}
132
144
// FIXME
133
- fn checek_writable ( & self , userdata : & LuaAnyUserData , offset : isize , size : usize ) -> bool {
145
+ fn checek_writable ( & self , offset : isize , size : usize ) -> bool {
134
146
true
135
147
}
136
148
// FIXME
137
- fn check_readable ( & self , userdata : & LuaAnyUserData , offset : isize , size : usize ) -> bool {
149
+ fn check_readable ( & self , offset : isize , size : usize ) -> bool {
138
150
true
139
151
}
152
+ fn mark_ref ( & self , userdata : & LuaAnyUserData , offset : isize , ptr : usize ) -> LuaResult < ( ) > {
153
+ Ok ( ( ) )
154
+ }
140
155
unsafe fn get_pointer ( & self , offset : isize ) -> * mut ( ) {
141
156
self . get_ptr ( ) . byte_offset ( offset) . cast :: < ( ) > ( )
142
157
}
@@ -155,8 +170,13 @@ impl LuaUserData for FfiBox {
155
170
methods. add_function (
156
171
"ref" ,
157
172
|lua, ( this, offset) : ( LuaAnyUserData , Option < isize > ) | {
158
- let luaref = FfiBox :: luaref ( lua, this, offset) ?;
159
- Ok ( luaref)
173
+ FfiBox :: luaref ( lua, this, offset)
174
+ } ,
175
+ ) ;
176
+ methods. add_function (
177
+ "unsafeRef" ,
178
+ |lua, ( this, offset) : ( LuaAnyUserData , Option < isize > ) | {
179
+ FfiBox :: luaref_unsafe ( lua, this, offset)
160
180
} ,
161
181
) ;
162
182
methods. add_meta_method ( LuaMetaMethod :: ToString , |_, this, ( ) | Ok ( this. stringify ( ) ) ) ;
0 commit comments