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