1#![allow(dead_code, unused_variables, clippy::too_many_arguments)]
19
20use lua_types::{
21 arith::ArithOp,
22 closure::{LuaCFnPtr, LuaClosure},
23 error::LuaError,
24 gc::GcRef,
25 string::LuaString,
26 userdata::LuaUserData,
27 value::{LuaThread, LuaValue},
28 CallInfoIdx,
29 LuaType,
30 LuaStatus,
31};
32
33pub use lua_vm::state::LuaState;
34use lua_vm::state::LuaCallable;
35
36#[allow(non_camel_case_types)]
38pub type lua_CFunction = fn(&mut LuaState) -> Result<usize, LuaError>;
39
40pub fn upvalue_index(i: i32) -> i32 {
42 -1_001_000 - i
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47pub enum CompareOp {
48 Eq,
49 Lt,
50 Le,
51}
52
53pub type LuaReader<'a> = dyn FnMut() -> Option<Vec<u8>> + 'a;
55
56pub type LuaWriter<'a> = dyn FnMut(&[u8]) -> Result<(), LuaError> + 'a;
58
59#[derive(Debug, Default, Clone)]
61pub struct LuaDebug {
62 pub name: Option<Vec<u8>>,
63 pub namewhat: Vec<u8>,
64 pub what: u8,
65 pub source: Vec<u8>,
66 pub short_src: Vec<u8>,
67 pub linedefined: i32,
68 pub lastlinedefined: i32,
69 pub currentline: i32,
70 pub nups: u8,
71 pub nparams: u8,
72 pub isvararg: bool,
73 pub istailcall: bool,
74 pub ftransfer: u16,
75 pub ntransfer: u16,
76 pub(crate) i_ci_idx: Option<CallInfoIdx>,
80}
81
82impl LuaDebug {
83 pub fn name_bytes(&self) -> &[u8] { self.name.as_deref().unwrap_or(b"?") }
84 pub fn namewhat_bytes(&self) -> &[u8] { &self.namewhat }
85 pub fn what_bytes(&self) -> &[u8] { match self.what { b'L' => b"Lua", b'C' => b"C", b'm' => b"main", _ => b"?" } }
86 pub fn short_src_bytes(&self) -> &[u8] { &self.short_src }
87 pub fn source_bytes(&self) -> &[u8] { &self.source }
88}
89
90pub trait LuaStateStubExt {
98 fn push_value(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_value") }
99 fn push_copy(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_copy") }
100 fn push_string(&mut self, s: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_string") }
101 fn push_bytes(&mut self, s: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_bytes") }
102 fn push_fstring(&mut self, args: std::fmt::Arguments<'_>) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_fstring") }
103 fn push_c_function(&mut self, f: lua_CFunction) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_c_function") }
104 fn push_c_closure(&mut self, f: lua_CFunction, n: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_c_closure") }
105 fn push_where(&mut self, level: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_where") }
106 fn push_globals(&mut self) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_globals") }
107
108 fn pop_bytes(&mut self) -> Vec<u8> { todo!("phase-b-reconcile: pop_bytes") }
109
110 fn top(&mut self) -> i32 { todo!("phase-b-reconcile: top") }
111 fn top_count(&mut self) -> i32 { todo!("phase-b-reconcile: top_count") }
112
113 fn insert(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: insert") }
114 fn remove(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: remove") }
115 fn replace(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: replace") }
116 fn rotate(&mut self, idx: i32, n: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: rotate") }
117 fn copy_value(&mut self, from: i32, to: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: copy_value") }
118 fn abs_index(&mut self, idx: i32) -> i32 { todo!("phase-b-reconcile: abs_index") }
119 fn ensure_stack<S: AsRef<[u8]> + ?Sized>(&mut self, n: i32, msg: &S) -> Result<(), LuaError> { let _ = msg.as_ref(); todo!("phase-b-reconcile: ensure_stack") }
120 fn check_stack_space(&mut self, n: i32) -> bool { todo!("phase-b-reconcile: check_stack_space") }
121
122 fn type_at(&mut self, idx: i32) -> LuaType { todo!("phase-b-reconcile: type_at") }
123 fn type_name(&mut self, t: LuaType) -> &'static [u8] { todo!("phase-b-reconcile: type_name") }
124 fn type_name_at(&mut self, idx: i32) -> &'static [u8] { todo!("phase-b-reconcile: type_name_at") }
125 fn value_at(&mut self, idx: i32) -> LuaValue { todo!("phase-b-reconcile: value_at") }
126 fn is_none_or_nil(&mut self, idx: i32) -> bool { todo!("phase-b-reconcile: is_none_or_nil") }
127 fn is_integer(&mut self, idx: i32) -> bool { todo!("phase-b-reconcile: is_integer") }
128 fn is_number(&mut self, idx: i32) -> bool { todo!("phase-b-reconcile: is_number") }
129
130 fn to_lua_string(&mut self, idx: i32) -> Option<GcRef<LuaString>> { todo!("phase-b-reconcile: to_lua_string") }
131 fn to_lua_string_bytes(&mut self, idx: i32) -> Option<Vec<u8>> { todo!("phase-b-reconcile: to_lua_string_bytes") }
132 fn to_lua_string_len(&mut self, idx: i32) -> Option<usize> { todo!("phase-b-reconcile: to_lua_string_len") }
133 fn to_integer_x(&mut self, idx: i32) -> Option<i64> { todo!("phase-b-reconcile: to_integer_x") }
134 fn to_number_x(&mut self, idx: i32) -> Option<f64> { todo!("phase-b-reconcile: to_number_x") }
135 fn to_boolean(&mut self, idx: i32) -> bool { todo!("phase-b-reconcile: to_boolean") }
136 fn to_userdata(&mut self, idx: i32) -> Option<GcRef<LuaUserData>> { todo!("phase-b-reconcile: to_userdata") }
137 fn to_display_string(&mut self, idx: i32) -> Result<Vec<u8>, LuaError> { todo!("phase-b-reconcile: to_display_string") }
138
139 fn check_arg_any(&mut self, arg: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: check_arg_any") }
140 fn check_arg_integer(&mut self, arg: i32) -> Result<i64, LuaError> { todo!("phase-b-reconcile: check_arg_integer") }
141 fn check_arg_string(&mut self, arg: i32) -> Result<Vec<u8>, LuaError> { todo!("phase-b-reconcile: check_arg_string") }
142 fn check_arg_type(&mut self, arg: i32, t: LuaType) -> Result<(), LuaError> { todo!("phase-b-reconcile: check_arg_type") }
143 fn check_arg_option(&mut self, arg: i32, def: Option<&[u8]>, lst: &[&[u8]]) -> Result<usize, LuaError> { todo!("phase-b-reconcile: check_arg_option") }
144
145 fn opt_arg_integer(&mut self, arg: i32, def: i64) -> Result<i64, LuaError> { todo!("phase-b-reconcile: opt_arg_integer") }
146 fn opt_arg_string_bytes(&mut self, arg: i32) -> Result<Vec<u8>, LuaError> { todo!("phase-b-reconcile: opt_arg_string_bytes") }
147 fn opt_arg_string(&mut self, arg: i32, def: &[u8]) -> Result<Vec<u8>, LuaError> { todo!("phase-b-reconcile: opt_arg_string") }
148 fn arg_to_bool(&mut self, arg: i32) -> bool { todo!("phase-b-reconcile: arg_to_bool") }
149
150 fn get_field(&mut self, idx: i32, k: &[u8]) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: get_field") }
151 fn set_field(&mut self, idx: i32, k: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: set_field") }
152 fn raw_get(&mut self, idx: i32) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: raw_get") }
153 fn raw_set(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: raw_set") }
154 fn raw_get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: raw_get_i") }
155 fn raw_set_i(&mut self, idx: i32, n: i64) -> Result<(), LuaError> { todo!("phase-b-reconcile: raw_set_i") }
156 fn raw_equal(&mut self, idx1: i32, idx2: i32) -> Result<bool, LuaError> { todo!("phase-b-reconcile: raw_equal") }
157 fn raw_len(&mut self, idx: i32) -> i64 { todo!("phase-b-reconcile: raw_len") }
158 fn get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: get_i") }
159 fn get_metafield(&mut self, idx: i32, name: &[u8]) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: get_metafield") }
160 fn get_meta_field(&mut self, idx: i32, name: &[u8]) -> Result<bool, LuaError> { todo!("phase-b-reconcile: get_meta_field") }
161 fn get_metatable(&mut self, idx: i32) -> Result<bool, LuaError> { todo!("phase-b-reconcile: get_metatable") }
162 fn set_metatable(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: set_metatable") }
163 fn table_next(&mut self, idx: i32) -> Result<bool, LuaError> { todo!("phase-b-reconcile: table_next") }
164 fn create_table(&mut self, narr: i32, nrec: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: create_table") }
165
166 fn gc_control_simple(&mut self, op: i32) -> Result<i32, LuaError> { todo!("phase-b-reconcile: gc_control_simple") }
167 fn gc_count(&mut self) -> Result<i32, LuaError> { todo!("phase-b-reconcile: gc_count") }
168 fn gc_count_b(&mut self) -> Result<i32, LuaError> { todo!("phase-b-reconcile: gc_count_b") }
169 fn gc_step(&mut self, data: i32) -> Result<i32, LuaError> { todo!("phase-b-reconcile: gc_step") }
170 fn gc_set_param(&mut self, op: i32, value: i32) -> Result<i32, LuaError> { todo!("phase-b-reconcile: gc_set_param") }
171 fn gc_is_running(&mut self) -> Result<bool, LuaError> { todo!("phase-b-reconcile: gc_is_running") }
172 fn gc_gen(&mut self, minor_mul: i32, major_mul: i32) -> Result<i32, LuaError> { todo!("phase-b-reconcile: gc_gen") }
173 fn gc_inc(&mut self, pause: i32, step_mul: i32, step_size: i32) -> Result<i32, LuaError> { todo!("phase-b-reconcile: gc_inc") }
174 fn gc_param(&mut self, param: usize, value: i64) -> Result<i64, LuaError> { todo!("phase-b-reconcile: gc_param") }
175
176 fn call(&mut self, nargs: i32, nresults: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: call") }
177 fn call_k(
178 &mut self,
179 nargs: i32,
180 nresults: i32,
181 ctx: isize,
182 k: Option<fn(&mut LuaState, i32, isize) -> Result<usize, LuaError>>,
183 ) -> Result<(), LuaError> {
184 let _ = (nargs, nresults, ctx, k);
185 todo!("phase-b-reconcile: call_k")
186 }
187 fn protected_call(&mut self, nargs: i32, nresults: i32, msgh: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: protected_call") }
188 fn protected_call_k(
189 &mut self,
190 nargs: i32,
191 nresults: i32,
192 msgh: i32,
193 ctx: isize,
194 k: Option<fn(&mut LuaState, i32, isize) -> Result<usize, LuaError>>,
195 ) -> Result<(), LuaError> {
196 let _ = (nargs, nresults, msgh, ctx, k);
197 todo!("phase-b-reconcile: protected_call_k")
198 }
199 fn len_op(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: len_op") }
200 fn arith(&mut self, op: ArithOp) -> Result<(), LuaError> { todo!("phase-b-reconcile: arith") }
201
202 fn load(&mut self, chunk: &[u8], name: &[u8], mode: Option<&[u8]>) -> Result<bool, LuaError> { todo!("phase-b-reconcile: load") }
203 fn load_buffer_ex<M: ?Sized>(&mut self, buf: &[u8], name: &[u8], mode: &M) -> Result<bool, LuaError>
204 where
205 M: AsRef<[u8]>,
206 { let _ = (buf, name, mode); todo!("phase-b-reconcile: load_buffer_ex") }
207 fn load_file(&mut self, path: Option<&[u8]>) -> Result<bool, LuaError> { todo!("phase-b-reconcile: load_file") }
208 fn load_file_ex(&mut self, path: Option<&[u8]>, mode: Option<&[u8]>) -> Result<bool, LuaError> { todo!("phase-b-reconcile: load_file_ex") }
209 fn load_with_reader<F, M: ?Sized>(&mut self, reader: F, name: &[u8], mode: &M) -> Result<bool, LuaError>
210 where
211 F: FnMut(&mut LuaState) -> Result<Option<Vec<u8>>, LuaError>,
212 M: AsRef<[u8]>,
213 { let _ = (reader, name, mode); todo!("phase-b-reconcile: load_with_reader") }
214 fn dump_function(&mut self, strip: bool) -> Result<Vec<u8>, LuaError> { todo!("phase-b-reconcile: dump_function") }
215
216 fn warning(&mut self, msg: &[u8], to_cont: bool) -> Result<(), LuaError> { todo!("phase-b-reconcile: warning") }
217 fn write_output(&mut self, msg: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: write_output") }
218 fn set_warn_fn(&mut self, f: Option<lua_CFunction>, ud: Option<LuaValue>) -> Result<(), LuaError> { todo!("phase-b-reconcile: set_warn_fn") }
219 fn set_funcs(&mut self, funcs: &[(&[u8], lua_CFunction)], nup: i32) -> Result<(), LuaError> {
220 let _ = (funcs, nup);
221 todo!("phase-b-reconcile: set_funcs")
222 }
223 fn set_global(&mut self, name: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: set_global") }
224 fn set_upvalue(&mut self, fidx: i32, n: i32) -> Result<Option<Vec<u8>>, LuaError> { todo!("phase-b-reconcile: set_upvalue") }
225 fn get_info(&mut self, what: &[u8], ar: &mut LuaDebug) -> Result<(), LuaError> { todo!("phase-b-reconcile: get_info") }
226 fn get_stack(&mut self, level: i32, ar: &mut LuaDebug) -> bool { todo!("phase-b-reconcile: get_stack") }
227 fn lua_version(&mut self) -> f64 { todo!("phase-b-reconcile: lua_version") }
228 fn string_to_number(&mut self, idx: i32) -> Option<usize> { todo!("phase-b-reconcile: string_to_number") }
229 fn string_to_number_push<S: AsRef<[u8]> + ?Sized>(&mut self, s: &S) -> Result<usize, LuaError> { let _ = s.as_ref(); todo!("phase-b-reconcile: string_to_number_push") }
230 fn require_lib(&mut self, name: &[u8], openf: lua_CFunction, glb: bool) -> Result<(), LuaError> { todo!("phase-b-reconcile: require_lib") }
231 fn peek_bytes(&mut self, idx: i32) -> Option<Vec<u8>> { todo!("phase-b-reconcile: peek_bytes") }
232
233 fn check_number(&mut self, arg: i32) -> Result<f64, LuaError> { todo!("phase-b-reconcile: check_number") }
234 fn check_integer(&mut self, arg: i32) -> Result<i64, LuaError> { todo!("phase-b-reconcile: check_integer") }
235 fn check_any(&mut self, arg: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: check_any") }
236 fn check_arg_number(&mut self, arg: i32) -> Result<f64, LuaError> { todo!("phase-b-reconcile: check_arg_number") }
237 fn check_arg_userdata(&mut self, arg: i32, name: &[u8]) -> Result<GcRef<LuaUserData>, LuaError> { todo!("phase-b-reconcile: check_arg_userdata") }
238 fn check_stack_growth(&mut self, n: i32) -> bool { todo!("phase-b-reconcile: check_stack_growth") }
239 fn opt_integer(&mut self, arg: i32, def: i64) -> Result<i64, LuaError> { todo!("phase-b-reconcile: opt_integer") }
240 fn opt_number(&mut self, arg: i32, def: f64) -> Result<f64, LuaError> { todo!("phase-b-reconcile: opt_number") }
241 fn opt_arg_lstring(&mut self, arg: i32, def: Option<&[u8]>) -> Result<Option<Vec<u8>>, LuaError> { todo!("phase-b-reconcile: opt_arg_lstring") }
242
243 fn table_get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: table_get_i") }
244 fn table_set_i(&mut self, idx: i32, n: i64) -> Result<(), LuaError> { todo!("phase-b-reconcile: table_set_i") }
245 fn table_get_i_value(&mut self, t: &LuaValue, n: i64) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: table_get_i_value") }
246 fn table_set_i_value(&mut self, t: &LuaValue, n: i64) -> Result<(), LuaError> { todo!("phase-b-reconcile: table_set_i_value") }
247 fn get_table(&mut self, idx: i32) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: get_table") }
248 fn raw_geti(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: raw_geti") }
249 fn raw_seti(&mut self, idx: i32, n: i64) -> Result<(), LuaError> { todo!("phase-b-reconcile: raw_seti") }
250 fn len_at(&mut self, idx: i32) -> i64 { todo!("phase-b-reconcile: len_at") }
251 fn length_at(&mut self, idx: i32) -> Result<i64, LuaError> { todo!("phase-b-reconcile: length_at") }
252 fn stack_top(&mut self) -> i32 { todo!("phase-b-reconcile: stack_top") }
253 fn get_top(&mut self) -> i32 { todo!("phase-b-reconcile: get_top") }
254
255 fn push_value_at(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_value_at") }
256 fn push_fail(&mut self) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_fail") }
257 fn push_lstring(&mut self, s: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_lstring") }
258 fn push_thread(&mut self) -> Result<bool, LuaError> { todo!("phase-b-reconcile: push_thread") }
259 fn push_cclosure(&mut self, f: lua_CFunction, n: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_cclosure") }
260 fn push_upvalue(&mut self, idx: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_upvalue") }
261 fn push_registry(&mut self) -> Result<(), LuaError> { todo!("phase-b-reconcile: push_registry") }
262
263 fn to_integer(&mut self, idx: i32) -> Option<i64> { todo!("phase-b-reconcile: to_integer") }
264 fn to_integer_opt(&mut self, idx: i32) -> Option<i64> { todo!("phase-b-reconcile: to_integer_opt") }
265 fn to_number(&mut self, idx: i32) -> Option<f64> { todo!("phase-b-reconcile: to_number") }
266 fn to_bytes(&mut self, idx: i32) -> Option<Vec<u8>> { todo!("phase-b-reconcile: to_bytes") }
267 fn to_bytes_at(&mut self, idx: i32) -> Option<Vec<u8>> { todo!("phase-b-reconcile: to_bytes_at") }
268 fn to_string_coerced(&mut self, idx: i32) -> Option<Vec<u8>> { todo!("phase-b-reconcile: to_string_coerced") }
269 fn to_light_userdata(&mut self, idx: i32) -> Option<*mut std::ffi::c_void> { todo!("phase-b-reconcile: to_light_userdata") }
270 fn to_thread(&mut self, idx: i32) -> Option<GcRef<LuaThread>> { todo!("phase-b-reconcile: to_thread") }
271 fn to_thread_at(&mut self, idx: i32) -> Option<GcRef<LuaThread>> { todo!("phase-b-reconcile: to_thread_at") }
272 fn type_name_str_at(&mut self, idx: i32) -> &'static [u8] { todo!("phase-b-reconcile: type_name_str_at") }
273 fn is_c_function_at(&mut self, idx: i32) -> bool { todo!("phase-b-reconcile: is_c_function_at") }
274
275 fn compare(&mut self, idx1: i32, idx2: i32, op: CompareOp) -> Result<bool, LuaError> { todo!("phase-b-reconcile: compare") }
276 fn compare_lt(&mut self, idx1: i32, idx2: i32) -> Result<bool, LuaError> { todo!("phase-b-reconcile: compare_lt") }
277
278 fn get_field_registry(&mut self, name: &[u8]) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: get_field_registry") }
279 fn get_registry_field(&mut self, name: &[u8]) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: get_registry_field") }
280 fn get_subtable_registry(&mut self, name: &[u8]) -> Result<bool, LuaError> { todo!("phase-b-reconcile: get_subtable_registry") }
281 fn get_or_create_registry_subtable(&mut self, name: &[u8]) -> Result<bool, LuaError> { todo!("phase-b-reconcile: get_or_create_registry_subtable") }
282 fn registry_get(&mut self, key: &[u8]) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: registry_get") }
283 fn registry_set(&mut self, key: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: registry_set") }
284
285 fn new_lib<F: Copy>(&mut self, funcs: &[(&[u8], F)]) -> Result<(), LuaError> { todo!("phase-b-reconcile: new_lib") }
286 fn new_lib_table<F: Copy>(&mut self, funcs: &[(&[u8], F)]) -> Result<(), LuaError> { todo!("phase-b-reconcile: new_lib_table") }
287 fn new_metatable(&mut self, name: &[u8]) -> Result<bool, LuaError> { todo!("phase-b-reconcile: new_metatable") }
288 fn set_metatable_by_name(&mut self, name: &[u8]) -> Result<(), LuaError> { todo!("phase-b-reconcile: set_metatable_by_name") }
289 fn register_funcs<F: Copy>(&mut self, funcs: &[(&[u8], F)]) -> Result<(), LuaError> { todo!("phase-b-reconcile: register_funcs") }
290 fn register_lib<F: Copy>(&mut self, name: &[u8], funcs: &[(&[u8], F)]) -> Result<(), LuaError> { todo!("phase-b-reconcile: register_lib") }
291 fn set_funcs_with_upvalues<F: Copy>(&mut self, funcs: &[(&[u8], F)], nup: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: set_funcs_with_upvalues") }
292
293 fn new_userdata_typed(&mut self, name: &[u8], size: usize, nuvalue: i32) -> Result<GcRef<LuaUserData>, LuaError> { todo!("phase-b-reconcile: new_userdata_typed") }
294 fn get_iuservalue(&mut self, idx: i32, n: i32) -> Result<LuaType, LuaError> { todo!("phase-b-reconcile: get_iuservalue") }
295 fn set_iuservalue(&mut self, idx: i32, n: i32) -> Result<bool, LuaError> { todo!("phase-b-reconcile: set_iuservalue") }
296 fn test_arg_userdata(&mut self, arg: i32, name: &[u8]) -> Option<GcRef<LuaUserData>> { todo!("phase-b-reconcile: test_arg_userdata") }
297
298 fn get_upvalue(&mut self, fidx: i32, n: i32) -> Result<Option<Vec<u8>>, LuaError> { todo!("phase-b-reconcile: get_upvalue") }
299 fn upvalue_id(&mut self, fidx: i32, n: i32) -> Result<*mut std::ffi::c_void, LuaError> { todo!("phase-b-reconcile: upvalue_id") }
300 fn join_upvalues(&mut self, fidx1: i32, n1: i32, fidx2: i32, n2: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: join_upvalues") }
301 fn upvalue_index(&mut self, i: i32) -> i32 { upvalue_index(i) }
302 fn close(&mut self) { todo!("phase-b-reconcile: close") }
303 fn set_hook_full(&mut self, f: Option<lua_CFunction>, mask: u32, count: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: set_hook_full") }
304
305 fn get_local_at(&mut self, ar: &LuaDebug, n: i32) -> Result<Option<Vec<u8>>, LuaError> { todo!("phase-b-reconcile: get_local_at") }
306 fn set_local_at(&mut self, ar: &LuaDebug, n: i32) -> Result<Option<Vec<u8>>, LuaError> { todo!("phase-b-reconcile: set_local_at") }
307 fn get_param_name(&mut self, fidx: i32, n: i32) -> Result<Option<Vec<u8>>, LuaError> { todo!("phase-b-reconcile: get_param_name") }
308
309 fn get_debug_info(&mut self, what: &[u8], ar: &mut LuaDebug) -> Result<(), LuaError> { todo!("phase-b-reconcile: get_debug_info") }
310 fn get_stack_level(&mut self, level: i32, ar: &mut LuaDebug) -> bool { todo!("phase-b-reconcile: get_stack_level") }
311 fn has_frames(&mut self) -> bool { todo!("phase-b-reconcile: has_frames") }
312 fn lua_traceback(&mut self, other: &mut LuaState, msg: Option<&[u8]>, level: i32) -> Result<(), LuaError> { todo!("phase-b-reconcile: lua_traceback") }
313
314 fn get_hook_count(&mut self) -> i32 { todo!("phase-b-reconcile: get_hook_count") }
315 fn get_hook_mask(&mut self) -> u32 { todo!("phase-b-reconcile: get_hook_mask") }
316 fn hook_is_set(&mut self) -> bool { todo!("phase-b-reconcile: hook_is_set") }
317 fn hook_is_internal_lua_hook(&mut self) -> bool { todo!("phase-b-reconcile: hook_is_internal_lua_hook") }
318 fn set_c_stack_limit(&mut self, limit: i32) -> Result<i32, LuaError> { todo!("phase-b-reconcile: set_c_stack_limit") }
319
320 fn new_thread(&mut self, initial_body: Option<LuaValue>) -> Result<GcRef<LuaThread>, LuaError> {
321 let _ = initial_body;
322 todo!("phase-b-reconcile: new_thread")
323 }
324 fn is_same_thread(&mut self, other: &LuaState) -> bool { todo!("phase-b-reconcile: is_same_thread") }
325 fn thread_status(&mut self) -> LuaStatus { todo!("phase-b-reconcile: thread_status") }
326
327 fn load_buffer(&mut self, buf: &[u8], name: &[u8], mode: Option<&[u8]>) -> Result<LuaStatus, LuaError> { todo!("phase-b-reconcile: load_buffer") }
328 fn where_error(&mut self, level: i32, msg: &[u8]) -> LuaError { todo!("phase-b-reconcile: where_error") }
329 fn arg(&mut self, n: i32) -> LuaValue { todo!("phase-b-reconcile: arg") }
330 fn as_bytes_or_coerce(&mut self, idx: i32) -> Option<Vec<u8>> { todo!("phase-b-reconcile: as_bytes_or_coerce") }
331 fn as_bytes(&mut self, idx: i32) -> Option<Vec<u8>> { todo!("phase-b-reconcile: as_bytes") }
332}
333
334impl LuaStateStubExt for LuaState {
335 fn require_lib(&mut self, name: &[u8], openf: lua_CFunction, glb: bool) -> Result<(), LuaError> {
336 crate::auxlib::requiref(self, name, openf, glb)
337 }
338
339 fn get_field(&mut self, idx: i32, k: &[u8]) -> Result<LuaType, LuaError> {
340 lua_vm::api::get_field(self, idx, k)
341 }
342
343 fn abs_index(&mut self, idx: i32) -> i32 {
344 lua_vm::api::abs_index(self, idx)
345 }
346
347 fn push_value(&mut self, idx: i32) -> Result<(), LuaError> {
348 lua_vm::api::push_value(self, idx);
349 Ok(())
350 }
351
352 fn set_field(&mut self, idx: i32, k: &[u8]) -> Result<(), LuaError> {
353 lua_vm::api::set_field(self, idx, k)
354 }
355
356 fn set_global(&mut self, name: &[u8]) -> Result<(), LuaError> {
357 lua_vm::api::set_global(self, name)
358 }
359
360 fn to_boolean(&mut self, idx: i32) -> bool {
361 lua_vm::api::to_boolean(self, idx)
362 }
363
364 fn top(&mut self) -> i32 {
365 lua_vm::api::get_top(self)
366 }
367
368 fn push_c_function(&mut self, f: lua_CFunction) -> Result<(), LuaError> {
369 let idx: LuaCFnPtr = {
370 let mut g = self.global_mut();
371 match g.c_functions.iter().position(|existing| {
372 existing
373 .as_bare()
374 .is_some_and(|existing| std::ptr::fn_addr_eq(existing, f))
375 }) {
376 Some(i) => i,
377 None => {
378 let i = g.c_functions.len();
379 g.c_functions.push(LuaCallable::bare(f));
380 i
381 }
382 }
383 };
384 self.push(LuaValue::Function(LuaClosure::LightC(idx)));
385 Ok(())
386 }
387
388 fn push_bytes(&mut self, s: &[u8]) -> Result<(), LuaError> {
389 lua_vm::api::push_lstring(self, s)?;
390 Ok(())
391 }
392
393 fn call(&mut self, nargs: i32, nresults: i32) -> Result<(), LuaError> {
394 lua_vm::api::call_k(self, nargs, nresults, 0, None)
395 }
396
397 fn call_k(
398 &mut self,
399 nargs: i32,
400 nresults: i32,
401 ctx: isize,
402 k: Option<fn(&mut LuaState, i32, isize) -> Result<usize, LuaError>>,
403 ) -> Result<(), LuaError> {
404 lua_vm::api::call_k(self, nargs, nresults, ctx, k)
405 }
406
407 fn remove(&mut self, idx: i32) -> Result<(), LuaError> {
408 lua_vm::api::rotate(self, idx, -1);
409 lua_vm::api::set_top(self, -2)
410 }
411
412 fn get_upvalue(&mut self, fidx: i32, n: i32) -> Result<Option<Vec<u8>>, LuaError> {
413 Ok(lua_vm::api::get_upvalue(self, fidx, n))
414 }
415
416 fn set_upvalue(&mut self, fidx: i32, n: i32) -> Result<Option<Vec<u8>>, LuaError> {
417 Ok(lua_vm::api::setup_value(self, fidx, n))
418 }
419
420 fn load(&mut self, chunk: &[u8], name: &[u8], mode: Option<&[u8]>) -> Result<bool, LuaError> {
421 let mut remaining = Some(chunk.to_vec());
422 let reader: Box<dyn FnMut() -> Option<Vec<u8>>> = Box::new(move || remaining.take());
423 let status = lua_vm::api::load(self, reader, Some(name), mode)?;
424 Ok(status == LuaStatus::Ok)
425 }
426
427 fn push_globals(&mut self) -> Result<(), LuaError> {
428 let g = self.global().globals.clone();
429 self.push(g);
430 Ok(())
431 }
432
433 fn set_funcs(&mut self, funcs: &[(&[u8], lua_CFunction)], nup: i32) -> Result<(), LuaError> {
434 lua_vm::api::check_stack(self, nup);
435 for (name, f) in funcs {
436 for _ in 0..nup {
437 lua_vm::api::push_value(self, -nup);
438 }
439 lua_vm::api::push_cclosure(self, *f, nup)?;
440 lua_vm::api::set_field(self, -(nup + 2), name)?;
441 }
442 self.pop_n(nup as usize);
443 Ok(())
444 }
445
446 fn arg_to_bool(&mut self, arg: i32) -> bool {
447 lua_vm::api::to_boolean(self, arg)
448 }
449
450 fn value_at(&mut self, idx: i32) -> LuaValue {
451 lua_vm::api::push_value(self, idx);
452 self.pop()
453 }
454
455 fn check_arg_type(&mut self, arg: i32, t: LuaType) -> Result<(), LuaError> {
456 if lua_vm::api::lua_type_at(self, arg) != t {
457 lua_vm::api::push_value(self, arg);
458 let got = self.pop();
459 let expected: &str = match t {
460 LuaType::None => "no value",
461 LuaType::Nil => "nil",
462 LuaType::Boolean => "boolean",
463 LuaType::LightUserData => "userdata",
464 LuaType::Number => "number",
465 LuaType::String => "string",
466 LuaType::Table => "table",
467 LuaType::Function => "function",
468 LuaType::UserData => "userdata",
469 LuaType::Thread => "thread",
470 };
471 let got_name = if lua_vm::api::lua_type_at(self, arg) == LuaType::None {
472 b"no value".to_vec()
473 } else {
474 self.full_type_name(&got)?
475 };
476 let extramsg = format!(
477 "{} expected, got {}",
478 expected, String::from_utf8_lossy(&got_name)
479 );
480 return Err(lua_vm::debug::arg_error_impl(self, arg, extramsg.as_bytes()));
481 }
482 Ok(())
483 }
484
485 fn opt_arg_string(&mut self, arg: i32, def: &[u8]) -> Result<Vec<u8>, LuaError> {
486 match lua_vm::api::lua_type_at(self, arg) {
487 LuaType::None | LuaType::Nil => Ok(def.to_vec()),
488 _ => self.check_arg_string(arg),
489 }
490 }
491
492 fn get_metafield(&mut self, idx: i32, name: &[u8]) -> Result<LuaType, LuaError> {
493 let abs = lua_vm::api::abs_index(self, idx);
494 if !lua_vm::api::get_metatable(self, abs) {
495 return Ok(LuaType::Nil);
496 }
497 lua_vm::api::push_lstring(self, name)?;
498 let tt = lua_vm::api::raw_get(self, -2);
499 if tt == LuaType::Nil {
500 self.pop_n(2);
501 } else {
502 self.remove(-2)?;
503 }
504 Ok(tt)
505 }
506
507 fn table_get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> {
508 lua_vm::api::get_i(self, idx, n)
509 }
510
511 fn table_get_i_value(&mut self, t: &LuaValue, n: i64) -> Result<LuaType, LuaError> {
512 lua_vm::api::get_i_value(self, t, n)
513 }
514
515 fn table_set_i_value(&mut self, t: &LuaValue, n: i64) -> Result<(), LuaError> {
516 lua_vm::api::set_i_value(self, t, n)
517 }
518
519 fn compare_lt(&mut self, idx1: i32, idx2: i32) -> Result<bool, LuaError> {
520 lua_vm::api::compare(self, idx1, idx2, 1)
521 }
522
523 fn check_arg_any(&mut self, arg: i32) -> Result<(), LuaError> {
524 if lua_vm::api::lua_type_at(self, arg) == LuaType::None {
525 return Err(LuaError::arg_error(arg, "value expected"));
526 }
527 Ok(())
528 }
529
530 fn check_arg_integer(&mut self, arg: i32) -> Result<i64, LuaError> {
531 match lua_vm::api::to_integer_x(self, arg) {
532 Some(d) => Ok(d),
533 None => {
534 if lua_vm::api::is_number(self, arg) {
535 Err(LuaError::arg_error(
536 arg,
537 "number has no integer representation",
538 ))
539 } else {
540 let got = self.value_at(arg);
541 let got_name = if lua_vm::api::lua_type_at(self, arg) == LuaType::None {
542 b"no value".to_vec()
543 } else {
544 self.full_type_name(&got)?
545 };
546 let extramsg = format!(
547 "number expected, got {}",
548 String::from_utf8_lossy(&got_name)
549 );
550 Err(lua_vm::debug::arg_error_impl(self, arg, extramsg.as_bytes()))
551 }
552 }
553 }
554 }
555
556 fn check_arg_string(&mut self, arg: i32) -> Result<Vec<u8>, LuaError> {
557 match lua_vm::api::to_lua_string(self, arg)? {
558 Some(s) => Ok(s.as_bytes().to_vec()),
559 None => {
560 let got = self.value_at(arg);
561 let got_name = if lua_vm::api::lua_type_at(self, arg) == LuaType::None {
562 b"no value".to_vec()
563 } else {
564 self.full_type_name(&got)?
565 };
566 let extramsg = format!(
567 "string expected, got {}",
568 String::from_utf8_lossy(&got_name)
569 );
570 Err(lua_vm::debug::arg_error_impl(self, arg, extramsg.as_bytes()))
571 }
572 }
573 }
574
575 fn check_arg_number(&mut self, arg: i32) -> Result<f64, LuaError> {
576 match lua_vm::api::to_number_x(self, arg) {
577 Some(d) => Ok(d),
578 None => {
579 let got = self.value_at(arg);
580 let got_name = if lua_vm::api::lua_type_at(self, arg) == LuaType::None {
581 b"no value".to_vec()
582 } else {
583 self.full_type_name(&got)?
584 };
585 let extramsg = format!(
586 "number expected, got {}",
587 String::from_utf8_lossy(&got_name)
588 );
589 Err(lua_vm::debug::arg_error_impl(self, arg, extramsg.as_bytes()))
590 }
591 }
592 }
593
594 fn check_number(&mut self, arg: i32) -> Result<f64, LuaError> {
595 self.check_arg_number(arg)
596 }
597
598 fn check_integer(&mut self, arg: i32) -> Result<i64, LuaError> {
599 self.check_arg_integer(arg)
600 }
601
602 fn check_any(&mut self, arg: i32) -> Result<(), LuaError> {
603 self.check_arg_any(arg)
604 }
605
606 fn opt_arg_integer(&mut self, arg: i32, def: i64) -> Result<i64, LuaError> {
607 match lua_vm::api::lua_type_at(self, arg) {
608 LuaType::None | LuaType::Nil => Ok(def),
609 _ => self.check_arg_integer(arg),
610 }
611 }
612
613 fn opt_integer(&mut self, arg: i32, def: i64) -> Result<i64, LuaError> {
614 self.opt_arg_integer(arg, def)
615 }
616
617 fn opt_number(&mut self, arg: i32, def: f64) -> Result<f64, LuaError> {
618 match lua_vm::api::lua_type_at(self, arg) {
619 LuaType::None | LuaType::Nil => Ok(def),
620 _ => self.check_arg_number(arg),
621 }
622 }
623
624 fn opt_arg_string_bytes(&mut self, arg: i32) -> Result<Vec<u8>, LuaError> {
625 match lua_vm::api::lua_type_at(self, arg) {
626 LuaType::None | LuaType::Nil => Ok(Vec::new()),
627 _ => self.check_arg_string(arg),
628 }
629 }
630
631 fn opt_arg_lstring(&mut self, arg: i32, def: Option<&[u8]>) -> Result<Option<Vec<u8>>, LuaError> {
632 match lua_vm::api::lua_type_at(self, arg) {
633 LuaType::None | LuaType::Nil => Ok(def.map(|d| d.to_vec())),
634 _ => Ok(Some(self.check_arg_string(arg)?)),
635 }
636 }
637
638 fn check_arg_option(
639 &mut self,
640 arg: i32,
641 def: Option<&[u8]>,
642 lst: &[&[u8]],
643 ) -> Result<usize, LuaError> {
644 let name: Vec<u8> = match def {
645 Some(d) if matches!(
646 lua_vm::api::lua_type_at(self, arg),
647 LuaType::None | LuaType::Nil
648 ) =>
649 {
650 d.to_vec()
651 }
652 _ => self.check_arg_string(arg)?,
653 };
654 for (i, entry) in lst.iter().enumerate() {
655 if *entry == name.as_slice() {
656 return Ok(i);
657 }
658 }
659 let extramsg = format!("invalid option '{}'", String::from_utf8_lossy(&name));
660 Err(lua_vm::debug::arg_error_impl(self, arg, extramsg.as_bytes()))
661 }
662
663 fn arg(&mut self, n: i32) -> LuaValue {
664 self.value_at(n)
665 }
666
667 fn type_at(&mut self, idx: i32) -> LuaType {
668 lua_vm::api::lua_type_at(self, idx)
669 }
670
671 fn type_name(&mut self, t: LuaType) -> &'static [u8] {
672 lua_vm::api::type_name(self, t)
673 }
674
675 fn type_name_at(&mut self, idx: i32) -> &'static [u8] {
676 let t = lua_vm::api::lua_type_at(self, idx);
677 lua_vm::api::type_name(self, t)
678 }
679
680 fn is_integer(&mut self, idx: i32) -> bool {
681 lua_vm::api::is_integer(self, idx)
682 }
683
684 fn is_number(&mut self, idx: i32) -> bool {
685 lua_vm::api::is_number(self, idx)
686 }
687
688 fn is_none_or_nil(&mut self, idx: i32) -> bool {
689 matches!(
690 lua_vm::api::lua_type_at(self, idx),
691 LuaType::None | LuaType::Nil
692 )
693 }
694
695 fn to_integer_x(&mut self, idx: i32) -> Option<i64> {
696 lua_vm::api::to_integer_x(self, idx)
697 }
698
699 fn to_number_x(&mut self, idx: i32) -> Option<f64> {
700 lua_vm::api::to_number_x(self, idx)
701 }
702
703 fn to_integer(&mut self, idx: i32) -> Option<i64> {
704 lua_vm::api::to_integer_x(self, idx)
705 }
706
707 fn to_integer_opt(&mut self, idx: i32) -> Option<i64> {
708 lua_vm::api::to_integer_x(self, idx)
709 }
710
711 fn to_number(&mut self, idx: i32) -> Option<f64> {
712 lua_vm::api::to_number_x(self, idx)
713 }
714
715 fn to_lua_string(&mut self, idx: i32) -> Option<GcRef<LuaString>> {
716 lua_vm::api::to_lua_string(self, idx).ok().flatten()
717 }
718
719 fn to_lua_string_bytes(&mut self, idx: i32) -> Option<Vec<u8>> {
720 lua_vm::api::to_lua_string(self, idx)
721 .ok()
722 .flatten()
723 .map(|s| s.as_bytes().to_vec())
724 }
725
726 fn to_lua_string_len(&mut self, idx: i32) -> Option<usize> {
727 lua_vm::api::to_lua_string(self, idx)
728 .ok()
729 .flatten()
730 .map(|s| s.len())
731 }
732
733 fn to_bytes(&mut self, idx: i32) -> Option<Vec<u8>> {
734 self.to_lua_string_bytes(idx)
735 }
736
737 fn to_bytes_at(&mut self, idx: i32) -> Option<Vec<u8>> {
738 self.to_lua_string_bytes(idx)
739 }
740
741 fn raw_equal(&mut self, idx1: i32, idx2: i32) -> Result<bool, LuaError> {
742 Ok(lua_vm::api::raw_equal(self, idx1, idx2))
743 }
744
745 fn raw_geti(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> {
746 Ok(lua_vm::api::raw_get_i(self, idx, n))
747 }
748
749 fn raw_get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> {
750 Ok(lua_vm::api::raw_get_i(self, idx, n))
751 }
752
753 fn raw_seti(&mut self, idx: i32, n: i64) -> Result<(), LuaError> {
754 lua_vm::api::raw_set_i(self, idx, n)
755 }
756
757 fn raw_set_i(&mut self, idx: i32, n: i64) -> Result<(), LuaError> {
758 lua_vm::api::raw_set_i(self, idx, n)
759 }
760
761 fn raw_len(&mut self, idx: i32) -> i64 {
762 lua_vm::api::raw_len(self, idx) as i64
763 }
764
765 fn get_i(&mut self, idx: i32, n: i64) -> Result<LuaType, LuaError> {
766 lua_vm::api::get_i(self, idx, n)
767 }
768
769 fn get_metatable(&mut self, idx: i32) -> Result<bool, LuaError> {
770 Ok(lua_vm::api::get_metatable(self, idx))
771 }
772
773 fn set_metatable(&mut self, idx: i32) -> Result<(), LuaError> {
774 lua_vm::api::set_metatable(self, idx)?;
775 Ok(())
776 }
777
778 fn compare(&mut self, idx1: i32, idx2: i32, op: CompareOp) -> Result<bool, LuaError> {
779 let op_i = match op {
780 CompareOp::Eq => 0,
781 CompareOp::Lt => 1,
782 CompareOp::Le => 2,
783 };
784 lua_vm::api::compare(self, idx1, idx2, op_i)
785 }
786
787 fn protected_call(&mut self, nargs: i32, nresults: i32, msgh: i32) -> Result<(), LuaError> {
788 lua_vm::api::pcall_k(self, nargs, nresults, msgh, 0, None)?;
789 Ok(())
790 }
791 fn protected_call_k(
792 &mut self,
793 nargs: i32,
794 nresults: i32,
795 msgh: i32,
796 ctx: isize,
797 k: Option<fn(&mut LuaState, i32, isize) -> Result<usize, LuaError>>,
798 ) -> Result<(), LuaError> {
799 lua_vm::api::pcall_k(self, nargs, nresults, msgh, ctx, k)?;
800 Ok(())
801 }
802
803 fn push_value_at(&mut self, idx: i32) -> Result<(), LuaError> {
804 lua_vm::api::push_value(self, idx);
805 Ok(())
806 }
807
808 fn push_thread(&mut self) -> Result<bool, LuaError> {
809 Ok(lua_vm::api::push_thread(self))
810 }
811
812 fn push_cclosure(&mut self, f: lua_CFunction, n: i32) -> Result<(), LuaError> {
813 lua_vm::api::push_cclosure(self, f, n)
814 }
815
816 fn push_c_closure(&mut self, f: lua_CFunction, n: i32) -> Result<(), LuaError> {
817 lua_vm::api::push_cclosure(self, f, n)
818 }
819
820 fn push_lstring(&mut self, s: &[u8]) -> Result<(), LuaError> {
821 lua_vm::api::push_lstring(self, s)?;
822 Ok(())
823 }
824
825 fn push_string(&mut self, s: &[u8]) -> Result<(), LuaError> {
826 lua_vm::api::push_lstring(self, s)?;
827 Ok(())
828 }
829
830 fn get_top(&mut self) -> i32 {
831 lua_vm::api::get_top(self)
832 }
833
834 fn stack_top(&mut self) -> i32 {
835 lua_vm::api::get_top(self)
836 }
837
838 fn top_count(&mut self) -> i32 {
839 lua_vm::api::get_top(self)
840 }
841
842 fn check_stack_space(&mut self, n: i32) -> bool {
843 lua_vm::api::check_stack(self, n)
844 }
845
846 fn rotate(&mut self, idx: i32, n: i32) -> Result<(), LuaError> {
847 lua_vm::api::rotate(self, idx, n);
848 Ok(())
849 }
850
851 fn insert(&mut self, idx: i32) -> Result<(), LuaError> {
852 lua_vm::api::rotate(self, idx, 1);
853 Ok(())
854 }
855
856 fn copy_value(&mut self, from: i32, to: i32) -> Result<(), LuaError> {
857 lua_vm::api::copy(self, from, to);
858 Ok(())
859 }
860
861 fn replace(&mut self, idx: i32) -> Result<(), LuaError> {
862 lua_vm::api::copy(self, -1, idx);
863 lua_vm::api::set_top(self, -2)
864 }
865
866 fn len_op(&mut self, idx: i32) -> Result<(), LuaError> {
867 lua_vm::api::len(self, idx)
868 }
869
870 fn table_next(&mut self, idx: i32) -> Result<bool, LuaError> {
871 lua_vm::api::next(self, idx)
872 }
873
874 fn create_table(&mut self, narr: i32, nrec: i32) -> Result<(), LuaError> {
875 lua_vm::api::create_table(self, narr, nrec)
876 }
877
878 fn to_userdata(&mut self, idx: i32) -> Option<GcRef<LuaUserData>> {
879 let v = self.value_at(idx);
880 if let LuaValue::UserData(u) = v { Some(u) } else { None }
881 }
882
883 fn to_light_userdata(&mut self, idx: i32) -> Option<*mut std::ffi::c_void> {
884 lua_vm::api::to_userdata(self, idx)
885 }
886
887 fn to_thread(&mut self, idx: i32) -> Option<GcRef<LuaThread>> {
888 lua_vm::api::to_thread(self, idx)
889 }
890
891 fn to_thread_at(&mut self, idx: i32) -> Option<GcRef<LuaThread>> {
892 lua_vm::api::to_thread(self, idx)
893 }
894
895 fn len_at(&mut self, idx: i32) -> i64 {
896 lua_vm::api::raw_len(self, idx) as i64
897 }
898
899 fn length_at(&mut self, idx: i32) -> Result<i64, LuaError> {
900 lua_vm::api::len(self, idx)?;
901 let v = lua_vm::api::to_integer_x(self, -1);
902 self.pop_n(1);
903 match v {
904 Some(l) => Ok(l),
905 None => Err(LuaError::runtime(format_args!(
906 "object length is not an integer"
907 ))),
908 }
909 }
910
911 fn peek_bytes(&mut self, idx: i32) -> Option<Vec<u8>> {
912 self.to_lua_string_bytes(idx)
913 }
914
915 fn to_string_coerced(&mut self, idx: i32) -> Option<Vec<u8>> {
916 self.to_lua_string_bytes(idx)
917 }
918
919 fn raw_get(&mut self, idx: i32) -> Result<LuaType, LuaError> {
920 Ok(lua_vm::api::raw_get(self, idx))
921 }
922
923 fn raw_set(&mut self, idx: i32) -> Result<(), LuaError> {
924 lua_vm::api::raw_set(self, idx)
925 }
926
927 fn is_c_function_at(&mut self, idx: i32) -> bool {
928 lua_vm::api::is_cfunction(self, idx)
929 }
930
931 fn type_name_str_at(&mut self, idx: i32) -> &'static [u8] {
932 let t = lua_vm::api::lua_type_at(self, idx);
933 lua_vm::api::type_name(self, t)
934 }
935
936 fn push_fstring(&mut self, args: std::fmt::Arguments<'_>) -> Result<(), LuaError> {
937 let formatted = std::fmt::format(args);
938 lua_vm::api::push_fstring(self, formatted.as_bytes())?;
939 Ok(())
940 }
941
942 fn arith(&mut self, op: ArithOp) -> Result<(), LuaError> {
943 lua_vm::api::arith(self, op as i32)
944 }
945
946 fn lua_version(&mut self) -> f64 {
947 504.0
948 }
949
950 fn push_fail(&mut self) -> Result<(), LuaError> {
951 self.push(LuaValue::Nil);
952 Ok(())
953 }
954
955 fn push_registry(&mut self) -> Result<(), LuaError> {
956 let r = self.registry_value();
957 self.push(r);
958 Ok(())
959 }
960
961 fn push_upvalue(&mut self, idx: i32) -> Result<(), LuaError> {
962 lua_vm::api::push_value(self, upvalue_index(idx));
963 Ok(())
964 }
965
966 fn pop_bytes(&mut self) -> Vec<u8> {
967 match self.pop() {
968 LuaValue::Str(s) => s.as_bytes().to_vec(),
969 _ => Vec::new(),
970 }
971 }
972
973 fn push_where(&mut self, level: i32) -> Result<(), LuaError> {
974 let mut ar = lua_vm::debug::LuaDebug::default();
975 if lua_vm::debug::get_stack(self, level, &mut ar) {
976 lua_vm::debug::get_info(self, b"Sl", &mut ar);
977 if ar.currentline > 0 {
978 let zero = ar
979 .short_src
980 .iter()
981 .position(|&b| b == 0)
982 .unwrap_or(ar.short_src.len());
983 let mut buf: Vec<u8> = ar.short_src[..zero].to_vec();
984 buf.push(b':');
985 buf.extend_from_slice(ar.currentline.to_string().as_bytes());
986 buf.extend_from_slice(b": ");
987 lua_vm::api::push_lstring(self, &buf)?;
988 return Ok(());
989 }
990 }
991 lua_vm::api::push_lstring(self, b"")?;
992 Ok(())
993 }
994
995 fn where_error(&mut self, level: i32, msg: &[u8]) -> LuaError {
996 if self.push_where(level).is_err() {
997 return LuaError::runtime(format_args!("{}", StubBStr(msg)));
998 }
999 let mut full = self.pop_bytes();
1000 full.extend_from_slice(msg);
1001 LuaError::runtime(format_args!("{}", StubBStr(&full)))
1002 }
1003
1004 fn registry_get(&mut self, key: &[u8]) -> Result<LuaType, LuaError> {
1005 lua_vm::api::get_field(self, STUB_LUA_REGISTRYINDEX, key)
1006 }
1007
1008 fn get_field_registry(&mut self, name: &[u8]) -> Result<LuaType, LuaError> {
1009 lua_vm::api::get_field(self, STUB_LUA_REGISTRYINDEX, name)
1010 }
1011
1012 fn get_registry_field(&mut self, name: &[u8]) -> Result<LuaType, LuaError> {
1013 lua_vm::api::get_field(self, STUB_LUA_REGISTRYINDEX, name)
1014 }
1015
1016 fn get_or_create_registry_subtable(&mut self, name: &[u8]) -> Result<bool, LuaError> {
1017 self.get_subtable_registry(name)
1018 }
1019
1020 fn registry_set(&mut self, key: &[u8]) -> Result<(), LuaError> {
1021 lua_vm::api::set_field(self, STUB_LUA_REGISTRYINDEX, key)
1022 }
1023
1024 fn check_stack_growth(&mut self, n: i32) -> bool {
1025 lua_vm::api::check_stack(self, n)
1026 }
1027
1028 fn ensure_stack<S: AsRef<[u8]> + ?Sized>(&mut self, n: i32, msg: &S) -> Result<(), LuaError> {
1029 if lua_vm::api::check_stack(self, n) {
1030 return Ok(());
1031 }
1032 let m = msg.as_ref();
1033 if m.is_empty() {
1034 Err(LuaError::runtime(format_args!("stack overflow")))
1035 } else {
1036 Err(LuaError::runtime(format_args!(
1037 "stack overflow ({})",
1038 StubBStr(m)
1039 )))
1040 }
1041 }
1042
1043 fn push_copy(&mut self, idx: i32) -> Result<(), LuaError> {
1044 lua_vm::api::push_value(self, idx);
1045 Ok(())
1046 }
1047
1048 fn as_bytes(&mut self, idx: i32) -> Option<Vec<u8>> {
1049 self.to_lua_string_bytes(idx)
1050 }
1051
1052 fn as_bytes_or_coerce(&mut self, idx: i32) -> Option<Vec<u8>> {
1053 self.to_lua_string_bytes(idx)
1054 }
1055
1056 fn thread_status(&mut self) -> LuaStatus {
1057 lua_vm::api::status(self)
1058 }
1059
1060 fn new_thread(&mut self, initial_body: Option<LuaValue>) -> Result<GcRef<LuaThread>, LuaError> {
1061 lua_vm::state::new_thread(self, initial_body)?;
1062 let th = lua_vm::api::to_thread(self, -1)
1063 .ok_or_else(|| LuaError::runtime(format_args!("new_thread: missing thread on top")))?;
1064 Ok(th)
1065 }
1066
1067 fn is_same_thread(&mut self, other: &LuaState) -> bool {
1068 std::ptr::eq(self as *const LuaState, other as *const LuaState)
1069 }
1070
1071 fn load_buffer(&mut self, buf: &[u8], name: &[u8], mode: Option<&[u8]>) -> Result<LuaStatus, LuaError> {
1072 let mut remaining = Some(buf.to_vec());
1073 let reader: Box<dyn FnMut() -> Option<Vec<u8>>> = Box::new(move || remaining.take());
1074 lua_vm::api::load(self, reader, Some(name), mode)
1075 }
1076
1077 fn load_buffer_ex<M: ?Sized>(&mut self, buf: &[u8], name: &[u8], mode: &M) -> Result<bool, LuaError>
1078 where
1079 M: AsRef<[u8]>,
1080 {
1081 let mut remaining = Some(buf.to_vec());
1082 let reader: Box<dyn FnMut() -> Option<Vec<u8>>> = Box::new(move || remaining.take());
1083 let mode_bytes = mode.as_ref();
1084 let status = lua_vm::api::load(self, reader, Some(name), Some(mode_bytes))?;
1085 Ok(status == LuaStatus::Ok)
1086 }
1087
1088 fn dump_function(&mut self, strip: bool) -> Result<Vec<u8>, LuaError> {
1089 let mut out: Vec<u8> = Vec::new();
1090 let mut writer = |chunk: &[u8]| -> Result<(), LuaError> {
1091 out.extend_from_slice(chunk);
1092 Ok(())
1093 };
1094 let ok = lua_vm::api::dump(self, &mut writer, strip)?;
1095 if !ok {
1096 return Err(LuaError::runtime(format_args!(
1097 "unable to dump given function"
1098 )));
1099 }
1100 Ok(out)
1101 }
1102
1103 fn warning(&mut self, msg: &[u8], to_cont: bool) -> Result<(), LuaError> {
1104 lua_vm::api::warning(self, msg, to_cont);
1105 Ok(())
1106 }
1107
1108 fn string_to_number(&mut self, idx: i32) -> Option<usize> {
1109 let bytes = lua_vm::api::to_lua_string(self, idx)
1110 .ok()
1111 .flatten()?
1112 .as_bytes()
1113 .to_vec();
1114 let consumed = lua_vm::api::string_to_number(self, &bytes);
1115 if consumed == 0 {
1116 None
1117 } else {
1118 Some(consumed)
1119 }
1120 }
1121
1122 fn string_to_number_push<S: AsRef<[u8]> + ?Sized>(&mut self, s: &S) -> Result<usize, LuaError> {
1123 Ok(lua_vm::api::string_to_number(self, s.as_ref()))
1124 }
1125
1126 fn gc_count(&mut self) -> Result<i32, LuaError> {
1127 Ok(lua_vm::api::gc(self, lua_vm::api::GcArgs::Count))
1128 }
1129
1130 fn gc_count_b(&mut self) -> Result<i32, LuaError> {
1131 Ok(lua_vm::api::gc(self, lua_vm::api::GcArgs::CountB))
1132 }
1133
1134 fn gc_step(&mut self, data: i32) -> Result<i32, LuaError> {
1135 Ok(lua_vm::api::gc(self, lua_vm::api::GcArgs::Step { data }))
1136 }
1137
1138 fn gc_is_running(&mut self) -> Result<bool, LuaError> {
1139 Ok(lua_vm::api::gc(self, lua_vm::api::GcArgs::IsRunning) != 0)
1140 }
1141
1142 fn gc_control_simple(&mut self, op: i32) -> Result<i32, LuaError> {
1143 let args = match op {
1144 0 => lua_vm::api::GcArgs::Stop,
1145 1 => lua_vm::api::GcArgs::Restart,
1146 2 => lua_vm::api::GcArgs::Collect,
1147 _ => return Err(LuaError::runtime(format_args!(
1148 "invalid GC option {}", op
1149 ))),
1150 };
1151 let res = lua_vm::api::gc(self, args);
1152 if let Some(err) = self.global_mut().gc_finalizer_error.take() {
1155 return Err(LuaError::from_value(err));
1156 }
1157 Ok(res)
1158 }
1159
1160 fn gc_set_param(&mut self, op: i32, value: i32) -> Result<i32, LuaError> {
1161 let args = match op {
1162 6 => lua_vm::api::GcArgs::SetPause { value },
1163 7 => lua_vm::api::GcArgs::SetStepMul { value },
1164 _ => return Err(LuaError::runtime(format_args!(
1165 "invalid GC param option {}", op
1166 ))),
1167 };
1168 Ok(lua_vm::api::gc(self, args))
1169 }
1170
1171 fn gc_gen(&mut self, minor_mul: i32, major_mul: i32) -> Result<i32, LuaError> {
1172 Ok(lua_vm::api::gc(
1173 self,
1174 lua_vm::api::GcArgs::Gen { minormul: minor_mul, majormul: major_mul },
1175 ))
1176 }
1177
1178 fn gc_inc(&mut self, pause: i32, step_mul: i32, step_size: i32) -> Result<i32, LuaError> {
1179 Ok(lua_vm::api::gc(
1180 self,
1181 lua_vm::api::GcArgs::Inc { pause, stepmul: step_mul, stepsize: step_size },
1182 ))
1183 }
1184
1185 fn gc_param(&mut self, param: usize, value: i64) -> Result<i64, LuaError> {
1186 Ok(lua_vm::api::gc(self, lua_vm::api::GcArgs::Param { param, value }) as i64)
1187 }
1188
1189 fn get_meta_field(&mut self, idx: i32, name: &[u8]) -> Result<bool, LuaError> {
1190 Ok(crate::auxlib::get_metafield(self, idx, name)? != LuaType::Nil)
1191 }
1192
1193 fn to_display_string(&mut self, idx: i32) -> Result<Vec<u8>, LuaError> {
1194 crate::auxlib::to_lua_string(self, idx)
1195 }
1196
1197 fn get_subtable_registry(&mut self, name: &[u8]) -> Result<bool, LuaError> {
1198 crate::auxlib::get_subtable(self, STUB_LUA_REGISTRYINDEX, name)
1199 }
1200
1201 fn new_metatable(&mut self, name: &[u8]) -> Result<bool, LuaError> {
1202 crate::auxlib::new_metatable(self, name)
1203 }
1204
1205 fn set_metatable_by_name(&mut self, name: &[u8]) -> Result<(), LuaError> {
1206 crate::auxlib::set_metatable(self, name)
1207 }
1208
1209 fn check_arg_userdata(&mut self, arg: i32, name: &[u8]) -> Result<GcRef<LuaUserData>, LuaError> {
1210 crate::auxlib::check_udata(self, arg, name)
1211 }
1212
1213 fn test_arg_userdata(&mut self, arg: i32, name: &[u8]) -> Option<GcRef<LuaUserData>> {
1214 crate::auxlib::test_udata(self, arg, name).ok().flatten()
1215 }
1216
1217 fn get_table(&mut self, idx: i32) -> Result<LuaType, LuaError> {
1218 lua_vm::api::get_table(self, idx)
1219 }
1220
1221 fn get_stack(&mut self, level: i32, ar: &mut LuaDebug) -> bool {
1222 let mut lvm_ar = lua_vm::debug::LuaDebug::default();
1223 let ok = lua_vm::debug::get_stack(self, level, &mut lvm_ar);
1224 if ok {
1225 ar.i_ci_idx = lvm_ar.i_ci;
1226 } else {
1227 ar.i_ci_idx = None;
1228 }
1229 ok
1230 }
1231
1232 fn get_stack_level(&mut self, level: i32, ar: &mut LuaDebug) -> bool {
1233 LuaStateStubExt::get_stack(self, level, ar)
1234 }
1235
1236 fn get_info(&mut self, what: &[u8], ar: &mut LuaDebug) -> Result<(), LuaError> {
1237 let mut lvm_ar = lua_vm::debug::LuaDebug::default();
1238 lvm_ar.i_ci = ar.i_ci_idx;
1239 let ok = lua_vm::debug::get_info(self, what, &mut lvm_ar);
1240 copy_lvm_debug_to_stub_selective(&lvm_ar, ar, what);
1241 if ok {
1242 Ok(())
1243 } else {
1244 Err(LuaError::runtime(format_args!("invalid option")))
1245 }
1246 }
1247
1248 fn get_debug_info(&mut self, what: &[u8], ar: &mut LuaDebug) -> Result<(), LuaError> {
1249 LuaStateStubExt::get_info(self, what, ar)
1250 }
1251
1252 fn get_local_at(&mut self, ar: &LuaDebug, n: i32) -> Result<Option<Vec<u8>>, LuaError> {
1253 let mut lvm_ar = lua_vm::debug::LuaDebug::default();
1254 lvm_ar.i_ci = ar.i_ci_idx;
1255 Ok(lua_vm::debug::get_local(self, Some(&lvm_ar), n))
1256 }
1257
1258 fn set_local_at(&mut self, ar: &LuaDebug, n: i32) -> Result<Option<Vec<u8>>, LuaError> {
1259 let mut lvm_ar = lua_vm::debug::LuaDebug::default();
1260 lvm_ar.i_ci = ar.i_ci_idx;
1261 Ok(lua_vm::debug::set_local(self, &lvm_ar, n))
1262 }
1263
1264 fn get_param_name(&mut self, fidx: i32, n: i32) -> Result<Option<Vec<u8>>, LuaError> {
1265 let _ = fidx;
1266 Ok(lua_vm::debug::get_local(self, None, n))
1267 }
1268
1269 fn has_frames(&mut self) -> bool {
1270 !self.is_base_ci(self.current_ci_idx())
1271 }
1272
1273 fn lua_traceback(
1274 &mut self,
1275 other: &mut LuaState,
1276 msg: Option<&[u8]>,
1277 level: i32,
1278 ) -> Result<(), LuaError> {
1279 crate::auxlib::traceback(self, Some(other), msg, level)
1280 }
1281
1282 fn upvalue_id(&mut self, fidx: i32, n: i32) -> Result<*mut std::ffi::c_void, LuaError> {
1283 match lua_vm::api::upvalue_id(self, fidx, n) {
1284 Some(id) => Ok(id as *mut std::ffi::c_void),
1285 None => Ok(std::ptr::null_mut()),
1286 }
1287 }
1288
1289 fn join_upvalues(&mut self, fidx1: i32, n1: i32, fidx2: i32, n2: i32) -> Result<(), LuaError> {
1290 lua_vm::api::upvalue_join(self, fidx1, n1, fidx2, n2);
1291 Ok(())
1292 }
1293
1294 fn load_with_reader<F, M: ?Sized>(&mut self, mut reader: F, name: &[u8], mode: &M) -> Result<bool, LuaError>
1303 where
1304 F: FnMut(&mut LuaState) -> Result<Option<Vec<u8>>, LuaError>,
1305 M: AsRef<[u8]>,
1306 {
1307 let mut buf: Vec<u8> = Vec::new();
1308 let mut reader_err: Option<LuaError> = None;
1309 loop {
1310 match reader(self) {
1311 Err(e) => {
1312 reader_err = Some(e);
1313 break;
1314 }
1315 Ok(None) => break,
1316 Ok(Some(piece)) => {
1317 if piece.is_empty() {
1318 break;
1319 }
1320 buf.extend_from_slice(&piece);
1321 }
1322 }
1323 }
1324 if let Some(e) = reader_err {
1325 let msg_value = match e {
1326 LuaError::Runtime(v) | LuaError::Syntax(v) => v,
1327 LuaError::Memory => {
1328 let s = self.intern_str(b"not enough memory")?;
1329 LuaValue::Str(s)
1330 }
1331 _ => {
1332 let s = self.intern_str(b"error in reader function")?;
1333 LuaValue::Str(s)
1334 }
1335 };
1336 self.push(msg_value);
1337 return Ok(false);
1338 }
1339 let mut once = Some(buf);
1340 let boxed: Box<dyn FnMut() -> Option<Vec<u8>>> = Box::new(move || once.take());
1341 let mode_bytes = mode.as_ref();
1342 let status = lua_vm::api::load(self, boxed, Some(name), Some(mode_bytes))?;
1343 Ok(status == LuaStatus::Ok)
1344 }
1345
1346 fn load_file_ex(&mut self, path: Option<&[u8]>, mode: Option<&[u8]>) -> Result<bool, LuaError> {
1347 let status = crate::auxlib::load_filex(self, path, mode)?;
1348 Ok(status == 0)
1349 }
1350
1351 fn load_file(&mut self, path: Option<&[u8]>) -> Result<bool, LuaError> {
1352 LuaStateStubExt::load_file_ex(self, path, None)
1353 }
1354
1355 fn get_iuservalue(&mut self, idx: i32, n: i32) -> Result<LuaType, LuaError> {
1356 Ok(lua_vm::api::get_i_uservalue(self, idx, n))
1357 }
1358
1359 fn set_iuservalue(&mut self, idx: i32, n: i32) -> Result<bool, LuaError> {
1360 lua_vm::api::set_i_uservalue(self, idx, n)
1361 }
1362
1363 fn get_hook_mask(&mut self) -> u32 {
1364 lua_vm::debug::get_hook_mask(self) as u32
1365 }
1366
1367 fn get_hook_count(&mut self) -> i32 {
1368 lua_vm::debug::get_hook_count(self)
1369 }
1370
1371 fn hook_is_set(&mut self) -> bool {
1377 lua_vm::debug::get_hook_mask(self) != 0
1378 }
1379
1380 fn hook_is_internal_lua_hook(&mut self) -> bool {
1383 lua_vm::debug::get_hook_mask(self) != 0
1384 }
1385
1386 fn set_c_stack_limit(&mut self, limit: i32) -> Result<i32, LuaError> {
1387 let clamped = if limit < 0 { 0u32 } else { limit as u32 };
1388 Ok(lua_vm::state::set_c_stack_limit(self, clamped))
1389 }
1390
1391 fn close(&mut self) {
1397 let _ = self;
1398 }
1399
1400 fn set_hook_full(
1413 &mut self,
1414 f: Option<lua_CFunction>,
1415 mask: u32,
1416 count: i32,
1417 ) -> Result<(), LuaError> {
1418 let hook: Option<Box<dyn FnMut(&mut LuaState, &lua_vm::debug::LuaDebug)>> = match f {
1419 None => None,
1420 Some(func) => Some(Box::new(move |state, _ar| {
1421 let _ = func(state);
1422 })),
1423 };
1424 lua_vm::debug::set_hook(self, hook, mask as i32, count);
1425 Ok(())
1426 }
1427
1428 fn write_output(&mut self, msg: &[u8]) -> Result<(), LuaError> {
1436 LuaState::write_output(self, msg)
1437 }
1438
1439 fn table_set_i(&mut self, idx: i32, n: i64) -> Result<(), LuaError> {
1443 LuaState::table_set_i(self, idx, n)
1444 }
1445
1446 fn new_userdata_typed(
1454 &mut self,
1455 name: &[u8],
1456 size: usize,
1457 nuvalue: i32,
1458 ) -> Result<GcRef<LuaUserData>, LuaError> {
1459 LuaState::new_userdata_typed(self, name, size, nuvalue)
1460 }
1461}
1462
1463fn copy_lvm_debug_to_stub_selective(
1475 src: &lua_vm::debug::LuaDebug,
1476 dst: &mut LuaDebug,
1477 what: &[u8],
1478) {
1479 dst.i_ci_idx = src.i_ci;
1480 for &ch in what {
1481 match ch {
1482 b'S' => {
1483 dst.what = match src.what {
1484 Some(b"Lua") => b'L',
1485 Some(b"C") => b'C',
1486 Some(b"main") => b'm',
1487 _ => 0,
1488 };
1489 dst.source = src.source.clone().unwrap_or_default();
1490 let zero = src
1491 .short_src
1492 .iter()
1493 .position(|&b| b == 0)
1494 .unwrap_or(src.short_src.len());
1495 dst.short_src = src.short_src[..zero].to_vec();
1496 dst.linedefined = src.linedefined;
1497 dst.lastlinedefined = src.lastlinedefined;
1498 }
1499 b'l' => {
1500 dst.currentline = src.currentline;
1501 }
1502 b'u' => {
1503 dst.nups = src.nups;
1504 dst.nparams = src.nparams;
1505 dst.isvararg = src.isvararg;
1506 }
1507 b't' => {
1508 dst.istailcall = src.istailcall;
1509 }
1510 b'n' => {
1511 dst.name = src.name.clone();
1512 dst.namewhat = src.namewhat.map(|s| s.to_vec()).unwrap_or_default();
1513 }
1514 b'r' => {
1515 dst.ftransfer = src.ftransfer;
1516 dst.ntransfer = src.ntransfer;
1517 }
1518 _ => {}
1519 }
1520 }
1521}
1522
1523const STUB_LUA_REGISTRYINDEX: i32 = -(1_000_000) - 1000;
1524
1525struct StubBStr<'a>(&'a [u8]);
1526
1527impl<'a> std::fmt::Display for StubBStr<'a> {
1528 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1529 use std::fmt::Write as _;
1530 for &b in self.0 {
1531 if b.is_ascii() {
1532 f.write_char(b as char)?;
1533 } else {
1534 write!(f, "\\x{:02x}", b)?;
1535 }
1536 }
1537 Ok(())
1538 }
1539}
1540
1541