@@ -24,6 +24,65 @@ impl Drop for StateGuard<'_> {
24
24
}
25
25
}
26
26
27
+ pub ( crate ) enum PreallocatedFailure {
28
+ New ( * mut WrappedFailure ) ,
29
+ Reserved ,
30
+ }
31
+
32
+ impl PreallocatedFailure {
33
+ unsafe fn reserve ( state : * mut ffi:: lua_State , extra : * mut ExtraData ) -> Self {
34
+ if ( * extra) . wrapped_failure_top > 0 {
35
+ ( * extra) . wrapped_failure_top -= 1 ;
36
+ return PreallocatedFailure :: Reserved ;
37
+ }
38
+
39
+ // We need to check stack for Luau in case when callback is called from interrupt
40
+ // See https://github.com/luau-lang/luau/issues/446 and mlua #142 and #153
41
+ #[ cfg( feature = "luau" ) ]
42
+ ffi:: lua_rawcheckstack ( state, 2 ) ;
43
+ // Place it to the beginning of the stack
44
+ let ud = WrappedFailure :: new_userdata ( state) ;
45
+ ffi:: lua_insert ( state, 1 ) ;
46
+ PreallocatedFailure :: New ( ud)
47
+ }
48
+
49
+ #[ cold]
50
+ unsafe fn r#use ( & self , state : * mut ffi:: lua_State , extra : * mut ExtraData ) -> * mut WrappedFailure {
51
+ let ref_thread = ( * extra) . ref_thread ;
52
+ match * self {
53
+ PreallocatedFailure :: New ( ud) => {
54
+ ffi:: lua_settop ( state, 1 ) ;
55
+ ud
56
+ }
57
+ PreallocatedFailure :: Reserved => {
58
+ let index = ( * extra) . wrapped_failure_pool . pop ( ) . unwrap ( ) ;
59
+ ffi:: lua_settop ( state, 0 ) ;
60
+ #[ cfg( feature = "luau" ) ]
61
+ ffi:: lua_rawcheckstack ( state, 2 ) ;
62
+ ffi:: lua_xpush ( ref_thread, state, index) ;
63
+ ffi:: lua_pushnil ( ref_thread) ;
64
+ ffi:: lua_replace ( ref_thread, index) ;
65
+ ( * extra) . ref_free . push ( index) ;
66
+ ffi:: lua_touserdata ( state, -1 ) as * mut WrappedFailure
67
+ }
68
+ }
69
+ }
70
+
71
+ unsafe fn release ( self , state : * mut ffi:: lua_State , extra : * mut ExtraData ) {
72
+ let ref_thread = ( * extra) . ref_thread ;
73
+ match self {
74
+ PreallocatedFailure :: New ( _) => {
75
+ ffi:: lua_rotate ( state, 1 , -1 ) ;
76
+ ffi:: lua_xmove ( state, ref_thread, 1 ) ;
77
+ let index = ref_stack_pop ( extra) ;
78
+ ( * extra) . wrapped_failure_pool . push ( index) ;
79
+ ( * extra) . wrapped_failure_top += 1 ;
80
+ }
81
+ PreallocatedFailure :: Reserved => ( * extra) . wrapped_failure_top += 1 ,
82
+ }
83
+ }
84
+ }
85
+
27
86
// An optimized version of `callback_error` that does not allocate `WrappedFailure` userdata
28
87
// and instead reuses unused values from previous calls (or allocates new).
29
88
pub ( crate ) unsafe fn callback_error_ext < F , R > (
@@ -41,65 +100,6 @@ where
41
100
42
101
let nargs = ffi:: lua_gettop ( state) ;
43
102
44
- enum PreallocatedFailure {
45
- New ( * mut WrappedFailure ) ,
46
- Reserved ,
47
- }
48
-
49
- impl PreallocatedFailure {
50
- unsafe fn reserve ( state : * mut ffi:: lua_State , extra : * mut ExtraData ) -> Self {
51
- if ( * extra) . wrapped_failure_top > 0 {
52
- ( * extra) . wrapped_failure_top -= 1 ;
53
- return PreallocatedFailure :: Reserved ;
54
- }
55
-
56
- // We need to check stack for Luau in case when callback is called from interrupt
57
- // See https://github.com/luau-lang/luau/issues/446 and mlua #142 and #153
58
- #[ cfg( feature = "luau" ) ]
59
- ffi:: lua_rawcheckstack ( state, 2 ) ;
60
- // Place it to the beginning of the stack
61
- let ud = WrappedFailure :: new_userdata ( state) ;
62
- ffi:: lua_insert ( state, 1 ) ;
63
- PreallocatedFailure :: New ( ud)
64
- }
65
-
66
- #[ cold]
67
- unsafe fn r#use ( & self , state : * mut ffi:: lua_State , extra : * mut ExtraData ) -> * mut WrappedFailure {
68
- let ref_thread = ( * extra) . ref_thread ;
69
- match * self {
70
- PreallocatedFailure :: New ( ud) => {
71
- ffi:: lua_settop ( state, 1 ) ;
72
- ud
73
- }
74
- PreallocatedFailure :: Reserved => {
75
- let index = ( * extra) . wrapped_failure_pool . pop ( ) . unwrap ( ) ;
76
- ffi:: lua_settop ( state, 0 ) ;
77
- #[ cfg( feature = "luau" ) ]
78
- ffi:: lua_rawcheckstack ( state, 2 ) ;
79
- ffi:: lua_xpush ( ref_thread, state, index) ;
80
- ffi:: lua_pushnil ( ref_thread) ;
81
- ffi:: lua_replace ( ref_thread, index) ;
82
- ( * extra) . ref_free . push ( index) ;
83
- ffi:: lua_touserdata ( state, -1 ) as * mut WrappedFailure
84
- }
85
- }
86
- }
87
-
88
- unsafe fn release ( self , state : * mut ffi:: lua_State , extra : * mut ExtraData ) {
89
- let ref_thread = ( * extra) . ref_thread ;
90
- match self {
91
- PreallocatedFailure :: New ( _) => {
92
- ffi:: lua_rotate ( state, 1 , -1 ) ;
93
- ffi:: lua_xmove ( state, ref_thread, 1 ) ;
94
- let index = ref_stack_pop ( extra) ;
95
- ( * extra) . wrapped_failure_pool . push ( index) ;
96
- ( * extra) . wrapped_failure_top += 1 ;
97
- }
98
- PreallocatedFailure :: Reserved => ( * extra) . wrapped_failure_top += 1 ,
99
- }
100
- }
101
- }
102
-
103
103
// We cannot shadow Rust errors with Lua ones, so we need to reserve pre-allocated memory
104
104
// to store a wrapped failure (error or panic) *before* we proceed.
105
105
let prealloc_failure = PreallocatedFailure :: reserve ( state, extra) ;
@@ -167,81 +167,22 @@ pub(crate) unsafe fn callback_error_ext_yieldable<F>(
167
167
f : F ,
168
168
) -> c_int
169
169
where
170
- F : FnOnce ( * mut ExtraData , * mut ffi :: lua_State , c_int ) -> Result < c_int > ,
170
+ F : FnOnce ( * mut ExtraData , c_int ) -> Result < c_int > ,
171
171
{
172
172
if extra. is_null ( ) {
173
173
extra = ExtraData :: get ( state) ;
174
174
}
175
175
176
176
let nargs = ffi:: lua_gettop ( state) ;
177
177
178
- enum PreallocatedFailure {
179
- New ( * mut WrappedFailure ) ,
180
- Reserved ,
181
- }
182
-
183
- impl PreallocatedFailure {
184
- unsafe fn reserve ( state : * mut ffi:: lua_State , extra : * mut ExtraData ) -> Self {
185
- if ( * extra) . wrapped_failure_top > 0 {
186
- ( * extra) . wrapped_failure_top -= 1 ;
187
- return PreallocatedFailure :: Reserved ;
188
- }
189
-
190
- // We need to check stack for Luau in case when callback is called from interrupt
191
- // See https://github.com/luau-lang/luau/issues/446 and mlua #142 and #153
192
- #[ cfg( feature = "luau" ) ]
193
- ffi:: lua_rawcheckstack ( state, 2 ) ;
194
- // Place it to the beginning of the stack
195
- let ud = WrappedFailure :: new_userdata ( state) ;
196
- ffi:: lua_insert ( state, 1 ) ;
197
- PreallocatedFailure :: New ( ud)
198
- }
199
-
200
- #[ cold]
201
- unsafe fn r#use ( & self , state : * mut ffi:: lua_State , extra : * mut ExtraData ) -> * mut WrappedFailure {
202
- let ref_thread = ( * extra) . ref_thread ;
203
- match * self {
204
- PreallocatedFailure :: New ( ud) => {
205
- ffi:: lua_settop ( state, 1 ) ;
206
- ud
207
- }
208
- PreallocatedFailure :: Reserved => {
209
- let index = ( * extra) . wrapped_failure_pool . pop ( ) . unwrap ( ) ;
210
- ffi:: lua_settop ( state, 0 ) ;
211
- #[ cfg( feature = "luau" ) ]
212
- ffi:: lua_rawcheckstack ( state, 2 ) ;
213
- ffi:: lua_xpush ( ref_thread, state, index) ;
214
- ffi:: lua_pushnil ( ref_thread) ;
215
- ffi:: lua_replace ( ref_thread, index) ;
216
- ( * extra) . ref_free . push ( index) ;
217
- ffi:: lua_touserdata ( state, -1 ) as * mut WrappedFailure
218
- }
219
- }
220
- }
221
-
222
- unsafe fn release ( self , state : * mut ffi:: lua_State , extra : * mut ExtraData ) {
223
- let ref_thread = ( * extra) . ref_thread ;
224
- match self {
225
- PreallocatedFailure :: New ( _) => {
226
- ffi:: lua_rotate ( state, 1 , -1 ) ;
227
- ffi:: lua_xmove ( state, ref_thread, 1 ) ;
228
- let index = ref_stack_pop ( extra) ;
229
- ( * extra) . wrapped_failure_pool . push ( index) ;
230
- ( * extra) . wrapped_failure_top += 1 ;
231
- }
232
- PreallocatedFailure :: Reserved => ( * extra) . wrapped_failure_top += 1 ,
233
- }
234
- }
235
- }
236
-
237
178
// We cannot shadow Rust errors with Lua ones, so we need to reserve pre-allocated memory
238
179
// to store a wrapped failure (error or panic) *before* we proceed.
239
180
let prealloc_failure = PreallocatedFailure :: reserve ( state, extra) ;
240
181
241
182
match catch_unwind ( AssertUnwindSafe ( || {
242
183
let rawlua = ( * extra) . raw_lua ( ) ;
243
184
let _guard = StateGuard :: new ( rawlua, state) ;
244
- f ( extra, state , nargs)
185
+ f ( extra, nargs)
245
186
} ) ) {
246
187
Ok ( Ok ( r) ) => {
247
188
let raw = extra. as_ref ( ) . unwrap_unchecked ( ) . raw_lua ( ) ;
0 commit comments