lust/vm/
tasks.rs

1use super::*;
2use crate::bytecode::{LustMap, ValueKey};
3use crate::vm::task::TaskKind;
4use crate::LustInt;
5use alloc::{format, string::ToString};
6use core::{array, cell::RefCell, mem};
7impl VM {
8    pub(super) fn run_task_internal(
9        &mut self,
10        task_id: TaskId,
11        resume_value: Option<Value>,
12    ) -> Result<()> {
13        let mut task = match self.task_manager.detach(task_id) {
14            Some(task) => task,
15            None => {
16                return Err(LustError::RuntimeError {
17                    message: format!("Invalid task handle {}", task_id.as_u64()),
18                })
19            }
20        };
21        if matches!(task.kind(), TaskKind::NativeFuture { .. }) {
22            let message = format!(
23                "Task {} is managed by the host runtime and cannot be resumed manually",
24                task_id.as_u64()
25            );
26            self.task_manager.attach(task);
27            return Err(LustError::RuntimeError { message });
28        }
29
30        match task.state {
31            TaskState::Completed | TaskState::Failed | TaskState::Stopped => {
32                let message = format!(
33                    "Task {} cannot be resumed (state: {})",
34                    task_id.as_u64(),
35                    task.state.as_str()
36                );
37                self.task_manager.attach(task);
38                return Err(LustError::RuntimeError { message });
39            }
40
41            TaskState::Running => {
42                self.task_manager.attach(task);
43                return Err(LustError::RuntimeError {
44                    message: format!("Task {} is already running", task_id.as_u64()),
45                });
46            }
47
48            _ => {}
49        }
50
51        task.state = TaskState::Running;
52        task.last_yield = None;
53        let mut resume_value_opt = resume_value;
54        if let Some(dest) = task.yield_dest.take() {
55            let value = resume_value_opt.take().unwrap_or(Value::Nil);
56            if let Some(frame) = task.call_stack.last_mut() {
57                frame.registers[dest as usize] = value;
58            }
59        } else if resume_value_opt.is_some() {
60            let message = format!(
61                "Task {} is not waiting for a resume value",
62                task_id.as_u64()
63            );
64            self.task_manager.attach(task);
65            return Err(LustError::RuntimeError { message });
66        }
67
68        mem::swap(&mut self.call_stack, &mut task.call_stack);
69        mem::swap(
70            &mut self.pending_return_value,
71            &mut task.pending_return_value,
72        );
73        mem::swap(&mut self.pending_return_dest, &mut task.pending_return_dest);
74        self.current_task = Some(task_id);
75        self.last_task_signal = None;
76        let run_result = self.run();
77        let signal = self.last_task_signal.take();
78        self.current_task = None;
79        let mut error_result: Option<LustError> = None;
80        match run_result {
81            Ok(value) => {
82                if let Some(signal) = signal {
83                    match signal {
84                        TaskSignal::Yield {
85                            dest,
86                            value: yielded,
87                        } => {
88                            task.state = TaskState::Yielded;
89                            task.last_yield = Some(yielded);
90                            task.last_result = None;
91                            task.yield_dest = Some(dest);
92                        }
93
94                        TaskSignal::Stop { value: stop_value } => {
95                            task.state = TaskState::Stopped;
96                            task.last_result = Some(stop_value);
97                            task.last_yield = None;
98                            task.call_stack.clear();
99                            task.pending_return_value = None;
100                            task.pending_return_dest = None;
101                        }
102                    }
103                } else {
104                    task.state = TaskState::Completed;
105                    task.last_result = Some(value);
106                    task.last_yield = None;
107                }
108            }
109
110            Err(err) => {
111                let annotated = self.annotate_runtime_error(err);
112                task.state = TaskState::Failed;
113                task.error = Some(annotated.clone());
114                task.last_yield = None;
115                error_result = Some(annotated);
116            }
117        }
118
119        mem::swap(&mut self.call_stack, &mut task.call_stack);
120        mem::swap(
121            &mut self.pending_return_value,
122            &mut task.pending_return_value,
123        );
124        mem::swap(&mut self.pending_return_dest, &mut task.pending_return_dest);
125        self.task_manager.attach(task);
126        if let Some(err) = error_result {
127            Err(err)
128        } else {
129            Ok(())
130        }
131    }
132
133    pub(super) fn task_id_from_handle(&self, handle: TaskHandle) -> Result<TaskId> {
134        let id = TaskId(handle.id());
135        if self.task_manager.contains(id) {
136            Ok(id)
137        } else {
138            Err(LustError::RuntimeError {
139                message: format!("Invalid task handle {}", handle.id()),
140            })
141        }
142    }
143
144    pub(super) fn prepare_task_frame(
145        &mut self,
146        func: Value,
147        args: Vec<Value>,
148    ) -> Result<CallFrame> {
149        match func {
150            Value::Function(func_idx) => {
151                let function = &self.functions[func_idx];
152                if args.len() != function.param_count as usize {
153                    return Err(LustError::RuntimeError {
154                        message: format!(
155                            "Task entry expects {} arguments, got {}",
156                            function.param_count,
157                            args.len()
158                        ),
159                    });
160                }
161
162                let mut frame = CallFrame {
163                    function_idx: func_idx,
164                    ip: 0,
165                    registers: array::from_fn(|_| Value::Nil),
166                    base_register: 0,
167                    return_dest: None,
168                    upvalues: Vec::new(),
169                };
170                for (i, arg) in args.into_iter().enumerate() {
171                    frame.registers[i] = arg;
172                }
173
174                Ok(frame)
175            }
176
177            Value::Closure {
178                function_idx,
179                upvalues,
180            } => {
181                let function = &self.functions[function_idx];
182                if args.len() != function.param_count as usize {
183                    return Err(LustError::RuntimeError {
184                        message: format!(
185                            "Task entry expects {} arguments, got {}",
186                            function.param_count,
187                            args.len()
188                        ),
189                    });
190                }
191
192                let captured: Vec<Value> = upvalues.iter().map(|uv| uv.get()).collect();
193                let mut frame = CallFrame {
194                    function_idx,
195                    ip: 0,
196                    registers: array::from_fn(|_| Value::Nil),
197                    base_register: 0,
198                    return_dest: None,
199                    upvalues: captured,
200                };
201                for (i, arg) in args.into_iter().enumerate() {
202                    frame.registers[i] = arg;
203                }
204
205                Ok(frame)
206            }
207
208            other => Err(LustError::RuntimeError {
209                message: format!("task.run() expects a function or closure, got {:?}", other),
210            }),
211        }
212    }
213
214    pub(super) fn create_task_value(
215        &mut self,
216        func: Value,
217        args: Vec<Value>,
218    ) -> Result<TaskHandle> {
219        let frame = self.prepare_task_frame(func, args)?;
220        let task_id = self.task_manager.next_id();
221        let task = TaskInstance::new(task_id, frame);
222        self.task_manager.insert(task);
223        Ok(task_id.to_handle())
224    }
225
226    pub fn spawn_task_value(&mut self, func: Value, args: Vec<Value>) -> Result<TaskHandle> {
227        let handle = self.create_task_value(func, args)?;
228        let task_id = TaskId(handle.id());
229        if let Err(err) = self.run_task_internal(task_id, None) {
230            let _ = self.task_manager.detach(task_id);
231            return Err(err);
232        }
233
234        Ok(handle)
235    }
236
237    pub fn resume_task_handle(
238        &mut self,
239        handle: TaskHandle,
240        resume_value: Option<Value>,
241    ) -> Result<()> {
242        let task_id = self.task_id_from_handle(handle)?;
243        self.run_task_internal(task_id, resume_value)
244    }
245
246    pub(super) fn stop_task_handle(&mut self, handle: TaskHandle) -> Result<()> {
247        let task_id = self.task_id_from_handle(handle)?;
248        let mut task = match self.task_manager.detach(task_id) {
249            Some(task) => task,
250            None => {
251                return Err(LustError::RuntimeError {
252                    message: format!("Invalid task handle {}", handle.id()),
253                })
254            }
255        };
256        match task.state {
257            TaskState::Stopped | TaskState::Completed | TaskState::Failed => {
258                self.task_manager.attach(task);
259                return Ok(());
260            }
261
262            TaskState::Running => {
263                self.task_manager.attach(task);
264                return Err(LustError::RuntimeError {
265                    message: format!("Task {} is currently running", handle.id()),
266                });
267            }
268
269            _ => {}
270        }
271
272        task.state = TaskState::Stopped;
273        task.call_stack.clear();
274        task.pending_return_value = None;
275        task.pending_return_dest = None;
276        task.yield_dest = None;
277        task.last_yield = None;
278        self.task_manager.attach(task);
279        Ok(())
280    }
281
282    pub(super) fn restart_task_handle(&mut self, handle: TaskHandle) -> Result<()> {
283        let task_id = self.task_id_from_handle(handle)?;
284        let mut task = match self.task_manager.detach(task_id) {
285            Some(task) => task,
286            None => {
287                return Err(LustError::RuntimeError {
288                    message: format!("Invalid task handle {}", handle.id()),
289                })
290            }
291        };
292        task.reset();
293        self.task_manager.insert(task);
294        if let Err(err) = self.run_task_internal(task_id, None) {
295            return Err(err);
296        }
297
298        Ok(())
299    }
300
301    pub fn get_task_instance(&self, handle: TaskHandle) -> Result<&TaskInstance> {
302        let task_id = self.task_id_from_handle(handle)?;
303        self.task_manager
304            .get(task_id)
305            .ok_or_else(|| LustError::RuntimeError {
306                message: format!("Invalid task handle {}", handle.id()),
307            })
308    }
309
310    pub fn current_task_handle(&self) -> Option<TaskHandle> {
311        self.current_task.map(|id| id.to_handle())
312    }
313
314    pub fn create_native_future_task(&mut self) -> TaskHandle {
315        let id = self.task_manager.next_id();
316        let task = TaskInstance::new_native_future(id);
317        let handle = task.handle();
318        self.task_manager.insert(task);
319        handle
320    }
321
322    pub fn complete_native_future_task(
323        &mut self,
324        handle: TaskHandle,
325        outcome: std::result::Result<Value, String>,
326    ) -> Result<()> {
327        let task_id = self.task_id_from_handle(handle)?;
328        let mut task = match self.task_manager.detach(task_id) {
329            Some(task) => task,
330            None => {
331                return Err(LustError::RuntimeError {
332                    message: format!("Invalid task handle {}", handle.id()),
333                })
334            }
335        };
336
337        match task.kind_mut() {
338            TaskKind::NativeFuture { .. } => {
339                match outcome {
340                    Ok(value) => {
341                        task.state = TaskState::Completed;
342                        task.last_result = Some(value);
343                        task.error = None;
344                    }
345                    Err(err_msg) => {
346                        task.state = TaskState::Failed;
347                        task.last_result = None;
348                        task.error = Some(LustError::RuntimeError { message: err_msg });
349                    }
350                }
351                task.last_yield = None;
352                task.pending_return_value = None;
353                task.pending_return_dest = None;
354                task.yield_dest = None;
355                self.task_manager.attach(task);
356                Ok(())
357            }
358
359            TaskKind::Script => {
360                self.task_manager.attach(task);
361                Err(LustError::RuntimeError {
362                    message: "Attempted to complete a script task using native future completion"
363                        .to_string(),
364                })
365            }
366        }
367    }
368
369    pub(super) fn call_builtin_method(
370        &mut self,
371        object: &Value,
372        method_name: &str,
373        args: Vec<Value>,
374    ) -> Result<Value> {
375        #[cfg(feature = "std")]
376        if std::env::var_os("LUST_LUA_SOCKET_TRACE").is_some() && method_name == "settimeout" {
377            match object {
378                Value::Enum {
379                    enum_name,
380                    variant,
381                    ..
382                } => {
383                    eprintln!(
384                        "[lua-socket] CallMethod enum={} variant={} method={}",
385                        enum_name, variant, method_name
386                    );
387                }
388                other => {
389                    eprintln!(
390                        "[lua-socket] CallMethod type={:?} method={}",
391                        other.type_of(),
392                        method_name
393                    );
394                }
395            }
396        }
397
398        if let Value::Enum {
399            enum_name,
400            variant,
401            ..
402        } = object
403        {
404            if enum_name == "LuaValue" && variant == "Userdata" {
405                if let Some(result) = self.try_call_lua_dynamic_method(object, method_name, &args)?
406                {
407                    return Ok(result);
408                }
409                #[cfg(feature = "std")]
410                if std::env::var_os("LUST_LUA_SOCKET_TRACE").is_some() {
411                    let indexer = self.lua_index_metamethod(object);
412                    eprintln!(
413                        "[lua-socket] userdata missing method '{}' indexer={:?} userdata={:?}",
414                        method_name,
415                        indexer.as_ref().map(|v| v.type_of()),
416                        object
417                    );
418                }
419            }
420        }
421
422        if let Value::Struct { name, .. } = object {
423            if name == "LuaTable" {
424                if let Some(result) = self.try_call_lua_dynamic_method(object, method_name, &args)?
425                {
426                    return Ok(result);
427                }
428            }
429        }
430
431        if let Value::Enum {
432            enum_name,
433            variant,
434            values,
435        } = object
436        {
437            if enum_name == "LuaValue" && variant == "Table" {
438                if let Some(inner) = values.as_ref().and_then(|vals| vals.get(0)) {
439                    return self.call_builtin_method(inner, method_name, args);
440                }
441            }
442        }
443
444        if let Value::Struct {
445            name: struct_name, ..
446        } = object
447        {
448            let mangled_name = format!("{}:{}", struct_name, method_name);
449            if let Some(func_idx) = self.functions.iter().position(|f| f.name == mangled_name) {
450                let mut method_args = vec![object.clone()];
451                method_args.extend(args.clone());
452                return self.call_value(&Value::Function(func_idx), method_args);
453            }
454
455            let mut candidate_names = vec![mangled_name.clone()];
456            if let Some(simple) = struct_name.rsplit(|c| c == '.' || c == ':').next() {
457                candidate_names.push(format!("{}:{}", simple, method_name));
458            }
459
460            for candidate in candidate_names {
461                let mut resolved = None;
462                for variant in [candidate.clone(), candidate.replace('.', "::")] {
463                    if let Some(value) = self.get_global(&variant) {
464                        resolved = Some(value);
465                        break;
466                    }
467                }
468
469                if let Some(global_func) = resolved {
470                    let mut method_args = vec![object.clone()];
471                    method_args.extend(args.clone());
472                    return self.call_value(&global_func, method_args);
473                }
474            }
475        }
476
477        match object {
478            Value::Struct { name, .. } if name == "LuaTable" => {
479                let Some(map_rc) = lua_table_map_rc(object) else {
480                    return Err(LustError::RuntimeError {
481                        message: "LuaTable is missing 'table' map field".to_string(),
482                    });
483                };
484                match method_name {
485                    "len" => {
486                        if !args.is_empty() {
487                            return Err(LustError::RuntimeError {
488                                message: "len() takes no arguments".to_string(),
489                            });
490                        }
491                        let seq = lua_table_read_sequence(&map_rc.borrow());
492                        Ok(Value::Int(seq.len() as LustInt))
493                    }
494                    "push" => {
495                        if args.len() != 1 {
496                            return Err(LustError::RuntimeError {
497                                message: "push() requires 1 argument (value)".to_string(),
498                            });
499                        }
500                        let value = super::corelib::unwrap_lua_value(args[0].clone());
501                        let mut map = map_rc.borrow_mut();
502                        let len = lua_table_sequence_len(&map);
503                        let key = ValueKey::from_value(&Value::Int((len as LustInt) + 1));
504                        map.insert(key, value);
505                        Ok(Value::Nil)
506                    }
507                    "insert" => {
508                        if args.len() != 2 {
509                            return Err(LustError::RuntimeError {
510                                message: "insert() requires 2 arguments (pos, value)".to_string(),
511                            });
512                        }
513                        let pos_raw = super::corelib::unwrap_lua_value(args[0].clone());
514                        let pos = pos_raw.as_int().unwrap_or(0).max(1) as usize;
515                        let value = super::corelib::unwrap_lua_value(args[1].clone());
516                        let mut seq = lua_table_read_sequence(&map_rc.borrow());
517                        let idx = pos.saturating_sub(1);
518                        if idx > seq.len() {
519                            seq.push(value);
520                        } else {
521                            seq.insert(idx, value);
522                        }
523                        lua_table_write_sequence(&map_rc, &seq);
524                        Ok(Value::Nil)
525                    }
526                    "remove" => {
527                        if args.len() != 1 {
528                            return Err(LustError::RuntimeError {
529                                message: "remove() requires 1 argument (pos)".to_string(),
530                            });
531                        }
532                        let pos_raw = super::corelib::unwrap_lua_value(args[0].clone());
533                        let mut seq = lua_table_read_sequence(&map_rc.borrow());
534                        if seq.is_empty() {
535                            return Ok(Value::Nil);
536                        }
537                        let pos = pos_raw.as_int().unwrap_or(seq.len() as LustInt);
538                        let idx =
539                            ((pos - 1).max(0) as usize).min(seq.len().saturating_sub(1));
540                        let removed = seq.remove(idx);
541                        lua_table_write_sequence(&map_rc, &seq);
542                        Ok(removed)
543                    }
544                    "concat" => {
545                        if args.len() != 3 {
546                            return Err(LustError::RuntimeError {
547                                message: "concat() requires 3 arguments (sep, i, j)".to_string(),
548                            });
549                        }
550                        let sep_raw = super::corelib::unwrap_lua_value(args[0].clone());
551                        let sep = sep_raw.as_string().unwrap_or_default();
552                        let seq = lua_table_read_sequence(&map_rc.borrow());
553                        let start = super::corelib::unwrap_lua_value(args[1].clone())
554                            .as_int()
555                            .unwrap_or(1);
556                        let end = super::corelib::unwrap_lua_value(args[2].clone())
557                            .as_int()
558                            .unwrap_or(seq.len() as LustInt);
559                        let start_idx = (start - 1).max(0) as usize;
560                        let end_idx = end.max(0) as usize;
561                        let mut pieces: Vec<String> = Vec::new();
562                        for (i, val) in seq.iter().enumerate() {
563                            if i < start_idx || i >= end_idx {
564                                continue;
565                            }
566                            let raw = super::corelib::unwrap_lua_value(val.clone());
567                            pieces.push(format!("{}", raw));
568                        }
569                        Ok(Value::string(pieces.join(&sep)))
570                    }
571                    "unpack" => {
572                        if args.len() != 2 {
573                            return Err(LustError::RuntimeError {
574                                message: "unpack() requires 2 arguments (i, j)".to_string(),
575                            });
576                        }
577                        let unpack = super::stdlib::create_table_unpack_fn();
578                        let Value::NativeFunction(func) = unpack else {
579                            return Err(LustError::RuntimeError {
580                                message: "unpack() builtin is not a native function".to_string(),
581                            });
582                        };
583                        let call_args = vec![object.clone(), args[0].clone(), args[1].clone()];
584                        match func(&call_args).map_err(|e| LustError::RuntimeError { message: e })? {
585                            NativeCallResult::Return(value) => Ok(value),
586                            NativeCallResult::Yield(_) => Err(LustError::RuntimeError {
587                                message: "unpack() unexpectedly yielded".to_string(),
588                            }),
589                            NativeCallResult::Stop(_) => Err(LustError::RuntimeError {
590                                message: "unpack() unexpectedly stopped execution".to_string(),
591                            }),
592                        }
593                    }
594                    "sort" => {
595                        if args.len() != 1 {
596                            return Err(LustError::RuntimeError {
597                                message: "sort() requires 1 argument (comp)".to_string(),
598                            });
599                        }
600                        let mut seq = lua_table_read_sequence(&map_rc.borrow());
601                        seq.sort_by(|a, b| {
602                            let la = format!("{}", super::corelib::unwrap_lua_value(a.clone()));
603                            let lb = format!("{}", super::corelib::unwrap_lua_value(b.clone()));
604                            la.cmp(&lb)
605                        });
606                        lua_table_write_sequence(&map_rc, &seq);
607                        Ok(Value::Nil)
608                    }
609                    "maxn" => {
610                        if !args.is_empty() {
611                            return Err(LustError::RuntimeError {
612                                message: "maxn() takes no arguments".to_string(),
613                            });
614                        }
615                        let map = map_rc.borrow();
616                        let mut max_idx: LustInt = 0;
617                        for key in map.keys() {
618                            if let Value::Int(i) = key.to_value() {
619                                if i > max_idx && i > 0 {
620                                    max_idx = i;
621                                }
622                            }
623                        }
624                        Ok(Value::Int(max_idx))
625                    }
626                    _ => Err(LustError::RuntimeError {
627                        message: format!("LuaTable has no method '{}'", method_name),
628                    }),
629                }
630            }
631            Value::Enum {
632                enum_name,
633                variant,
634                values,
635            } if enum_name == "Option" => match method_name {
636                "is_some" => Ok(Value::Bool(variant == "Some")),
637                "is_none" => Ok(Value::Bool(variant == "None")),
638                "unwrap" => {
639                    if variant == "Some" {
640                        if let Some(vals) = values {
641                            if !vals.is_empty() {
642                                Ok(vals[0].clone())
643                            } else {
644                                Err(LustError::RuntimeError {
645                                    message: "Option::Some has no value".to_string(),
646                                })
647                            }
648                        } else {
649                            Err(LustError::RuntimeError {
650                                message: "Option::Some has no value".to_string(),
651                            })
652                        }
653                    } else {
654                        Err(LustError::RuntimeError {
655                            message: "Called unwrap() on Option::None".to_string(),
656                        })
657                    }
658                }
659
660                "unwrap_or" => {
661                    if args.is_empty() {
662                        return Err(LustError::RuntimeError {
663                            message: "unwrap_or requires a default value".to_string(),
664                        });
665                    }
666
667                    if variant == "Some" {
668                        if let Some(vals) = values {
669                            if !vals.is_empty() {
670                                Ok(vals[0].clone())
671                            } else {
672                                Ok(args[0].clone())
673                            }
674                        } else {
675                            Ok(args[0].clone())
676                        }
677                    } else {
678                        Ok(args[0].clone())
679                    }
680                }
681
682                _ => Err(LustError::RuntimeError {
683                    message: format!("Option has no method '{}'", method_name),
684                }),
685            },
686            Value::Enum {
687                enum_name,
688                variant,
689                values,
690            } if enum_name == "Result" => match method_name {
691                "is_ok" => Ok(Value::Bool(variant == "Ok")),
692                "is_err" => Ok(Value::Bool(variant == "Err")),
693                "unwrap" => {
694                    if variant == "Ok" {
695                        if let Some(vals) = values {
696                            if !vals.is_empty() {
697                                Ok(vals[0].clone())
698                            } else {
699                                Err(LustError::RuntimeError {
700                                    message: "Result::Ok has no value".to_string(),
701                                })
702                            }
703                        } else {
704                            Err(LustError::RuntimeError {
705                                message: "Result::Ok has no value".to_string(),
706                            })
707                        }
708                    } else {
709                        Err(LustError::RuntimeError {
710                            message: "Called unwrap() on Result::Err".to_string(),
711                        })
712                    }
713                }
714
715                "unwrap_or" => {
716                    if args.is_empty() {
717                        return Err(LustError::RuntimeError {
718                            message: "unwrap_or requires a default value".to_string(),
719                        });
720                    }
721
722                    if variant == "Ok" {
723                        if let Some(vals) = values {
724                            if !vals.is_empty() {
725                                Ok(vals[0].clone())
726                            } else {
727                                Ok(args[0].clone())
728                            }
729                        } else {
730                            Ok(args[0].clone())
731                        }
732                    } else {
733                        Ok(args[0].clone())
734                    }
735                }
736
737                _ => Err(LustError::RuntimeError {
738                    message: format!("Result has no method '{}'", method_name),
739                }),
740            },
741            Value::Array(arr) => match method_name {
742                "iter" => {
743                    let items = arr.borrow().clone();
744                    let iter = crate::bytecode::value::IteratorState::Array { items, index: 0 };
745                    Ok(Value::Iterator(Rc::new(RefCell::new(iter))))
746                }
747
748                "len" => Ok(Value::Int(int_from_usize(arr.borrow().len()))),
749                "get" => {
750                    if args.is_empty() {
751                        return Err(LustError::RuntimeError {
752                            message: "get requires an index argument".to_string(),
753                        });
754                    }
755
756                    let index = args[0].as_int().ok_or_else(|| LustError::RuntimeError {
757                        message: "Array index must be an integer".to_string(),
758                    })?;
759                    let borrowed = arr.borrow();
760                    if index < 0 || index as usize >= borrowed.len() {
761                        Ok(Value::none())
762                    } else {
763                        Ok(Value::some(borrowed[index as usize].clone()))
764                    }
765                }
766
767                "first" => {
768                    let borrowed = arr.borrow();
769                    if borrowed.is_empty() {
770                        Ok(Value::none())
771                    } else {
772                        Ok(Value::some(borrowed[0].clone()))
773                    }
774                }
775
776                "last" => {
777                    let borrowed = arr.borrow();
778                    if borrowed.is_empty() {
779                        Ok(Value::none())
780                    } else {
781                        Ok(Value::some(borrowed[borrowed.len() - 1].clone()))
782                    }
783                }
784
785                "push" => {
786                    if args.is_empty() {
787                        return Err(LustError::RuntimeError {
788                            message: "push requires a value argument".to_string(),
789                        });
790                    }
791
792                    arr.borrow_mut().push(args[0].clone());
793                    Ok(Value::Nil)
794                }
795
796                "pop" => {
797                    let popped = arr.borrow_mut().pop();
798                    match popped {
799                        Some(val) => Ok(Value::some(val)),
800                        None => Ok(Value::none()),
801                    }
802                }
803
804                "map" => {
805                    if args.is_empty() {
806                        return Err(LustError::RuntimeError {
807                            message: "map requires a function argument".to_string(),
808                        });
809                    }
810
811                    let func = &args[0];
812                    let borrowed = arr.borrow();
813                    let mut result = Vec::new();
814                    for elem in borrowed.iter() {
815                        let mapped_value = self.call_value(func, vec![elem.clone()])?;
816                        result.push(mapped_value);
817                    }
818
819                    Ok(Value::array(result))
820                }
821
822                "filter" => {
823                    if args.is_empty() {
824                        return Err(LustError::RuntimeError {
825                            message: "filter requires a function argument".to_string(),
826                        });
827                    }
828
829                    let func = &args[0];
830                    let borrowed = arr.borrow();
831                    let mut result = Vec::new();
832                    for elem in borrowed.iter() {
833                        let keep = self.call_value(func, vec![elem.clone()])?;
834                        if keep.is_truthy() {
835                            result.push(elem.clone());
836                        }
837                    }
838
839                    Ok(Value::array(result))
840                }
841
842                "reduce" => {
843                    if args.len() < 2 {
844                        return Err(LustError::RuntimeError {
845                            message: "reduce requires an initial value and function".to_string(),
846                        });
847                    }
848
849                    let init_value = &args[0];
850                    let func = &args[1];
851                    let borrowed = arr.borrow();
852                    let mut accumulator = init_value.clone();
853                    for elem in borrowed.iter() {
854                        accumulator = self.call_value(func, vec![accumulator, elem.clone()])?;
855                    }
856
857                    Ok(accumulator)
858                }
859
860                "slice" => {
861                    if args.len() < 2 {
862                        return Err(LustError::RuntimeError {
863                            message: "slice requires start and end indices".to_string(),
864                        });
865                    }
866
867                    let start = args[0].as_int().ok_or_else(|| LustError::RuntimeError {
868                        message: "Start index must be an integer".to_string(),
869                    })? as usize;
870                    let end = args[1].as_int().ok_or_else(|| LustError::RuntimeError {
871                        message: "End index must be an integer".to_string(),
872                    })? as usize;
873                    let borrowed = arr.borrow();
874                    if start > borrowed.len() || end > borrowed.len() || start > end {
875                        return Err(LustError::RuntimeError {
876                            message: "Invalid slice indices".to_string(),
877                        });
878                    }
879
880                    let sliced = borrowed[start..end].to_vec();
881                    Ok(Value::array(sliced))
882                }
883
884                "clear" => {
885                    arr.borrow_mut().clear();
886                    Ok(Value::Nil)
887                }
888
889                "is_empty" => Ok(Value::Bool(arr.borrow().is_empty())),
890                _ => Err(LustError::RuntimeError {
891                    message: format!("Array has no method '{}'", method_name),
892                }),
893            },
894            Value::String(s) => match method_name {
895                "iter" => {
896                    let items: Vec<Value> =
897                        s.chars().map(|c| Value::string(c.to_string())).collect();
898                    let iter = crate::bytecode::value::IteratorState::Array { items, index: 0 };
899                    Ok(Value::Iterator(Rc::new(RefCell::new(iter))))
900                }
901
902                "len" => Ok(Value::Int(int_from_usize(s.len()))),
903                "substring" => {
904                    if args.len() < 2 {
905                        return Err(LustError::RuntimeError {
906                            message: "substring requires start and end indices".to_string(),
907                        });
908                    }
909
910                    let start = args[0].as_int().ok_or_else(|| LustError::RuntimeError {
911                        message: "Start index must be an integer".to_string(),
912                    })? as usize;
913                    let end = args[1].as_int().ok_or_else(|| LustError::RuntimeError {
914                        message: "End index must be an integer".to_string(),
915                    })? as usize;
916                    if start > s.len() || end > s.len() || start > end {
917                        return Err(LustError::RuntimeError {
918                            message: "Invalid substring indices".to_string(),
919                        });
920                    }
921
922                    Ok(Value::string(&s[start..end]))
923                }
924
925                "find" => {
926                    if args.is_empty() {
927                        return Err(LustError::RuntimeError {
928                            message: "find requires a search string".to_string(),
929                        });
930                    }
931
932                    let search = args[0].as_string().ok_or_else(|| LustError::RuntimeError {
933                        message: "Search string must be a string".to_string(),
934                    })?;
935                    match s.find(search) {
936                        Some(pos) => Ok(Value::some(Value::Int(int_from_usize(pos)))),
937                        None => Ok(Value::none()),
938                    }
939                }
940
941                "starts_with" => {
942                    if args.is_empty() {
943                        return Err(LustError::RuntimeError {
944                            message: "starts_with requires a prefix string".to_string(),
945                        });
946                    }
947
948                    let prefix = args[0].as_string().ok_or_else(|| LustError::RuntimeError {
949                        message: "Prefix must be a string".to_string(),
950                    })?;
951                    Ok(Value::Bool(s.starts_with(prefix)))
952                }
953
954                "ends_with" => {
955                    if args.is_empty() {
956                        return Err(LustError::RuntimeError {
957                            message: "ends_with requires a suffix string".to_string(),
958                        });
959                    }
960
961                    let suffix = args[0].as_string().ok_or_else(|| LustError::RuntimeError {
962                        message: "Suffix must be a string".to_string(),
963                    })?;
964                    Ok(Value::Bool(s.ends_with(suffix)))
965                }
966
967                "split" => {
968                    if args.is_empty() {
969                        return Err(LustError::RuntimeError {
970                            message: "split requires a separator string".to_string(),
971                        });
972                    }
973
974                    let separator = args[0].as_string().ok_or_else(|| LustError::RuntimeError {
975                        message: "Separator must be a string".to_string(),
976                    })?;
977                    let parts: Vec<Value> =
978                        s.split(separator).map(|part| Value::string(part)).collect();
979                    Ok(Value::array(parts))
980                }
981
982                "trim" => Ok(Value::string(s.trim())),
983                "trim_start" => Ok(Value::string(s.trim_start())),
984                "trim_end" => Ok(Value::string(s.trim_end())),
985                "replace" => {
986                    if args.len() < 2 {
987                        return Err(LustError::RuntimeError {
988                            message: "replace requires 'from' and 'to' string arguments"
989                                .to_string(),
990                        });
991                    }
992
993                    let from = args[0].as_string().ok_or_else(|| LustError::RuntimeError {
994                        message: "First argument must be a string".to_string(),
995                    })?;
996                    let to = args[1].as_string().ok_or_else(|| LustError::RuntimeError {
997                        message: "Second argument must be a string".to_string(),
998                    })?;
999                    Ok(Value::string(&s.replace(from, to)))
1000                }
1001
1002                "to_upper" => Ok(Value::string(&s.to_uppercase())),
1003                "to_lower" => Ok(Value::string(&s.to_lowercase())),
1004                "contains" => {
1005                    if args.is_empty() {
1006                        return Err(LustError::RuntimeError {
1007                            message: "contains requires a search string".to_string(),
1008                        });
1009                    }
1010
1011                    let search = args[0].as_string().ok_or_else(|| LustError::RuntimeError {
1012                        message: "Search string must be a string".to_string(),
1013                    })?;
1014                    Ok(Value::Bool(s.contains(search)))
1015                }
1016
1017                "is_empty" => Ok(Value::Bool(s.is_empty())),
1018                "chars" => {
1019                    let chars: Vec<Value> =
1020                        s.chars().map(|c| Value::string(&c.to_string())).collect();
1021                    Ok(Value::array(chars))
1022                }
1023
1024                "lines" => {
1025                    let lines: Vec<Value> = s.lines().map(|line| Value::string(line)).collect();
1026                    Ok(Value::array(lines))
1027                }
1028
1029                _ => Err(LustError::RuntimeError {
1030                    message: format!("String has no method '{}'", method_name),
1031                }),
1032            },
1033            Value::Map(map) => {
1034                use crate::bytecode::ValueKey;
1035                match method_name {
1036                    "iter" => {
1037                        let items: Vec<(ValueKey, Value)> = map
1038                            .borrow()
1039                            .iter()
1040                            .map(|(k, v)| (k.clone(), v.clone()))
1041                            .collect();
1042                        let iter =
1043                            crate::bytecode::value::IteratorState::MapPairs { items, index: 0 };
1044                        return Ok(Value::Iterator(Rc::new(RefCell::new(iter))));
1045                    }
1046
1047                    "len" => Ok(Value::Int(int_from_usize(map.borrow().len()))),
1048                    "get" => {
1049                        if args.is_empty() {
1050                            return Err(LustError::RuntimeError {
1051                                message: "get requires a key argument".to_string(),
1052                            });
1053                        }
1054
1055                        let key = self.make_hash_key(&args[0])?;
1056                        match map.borrow().get(&key) {
1057                            Some(value) => Ok(Value::some(value.clone())),
1058                            None => Ok(Value::none()),
1059                        }
1060                    }
1061
1062                    "set" => {
1063                        if args.len() < 2 {
1064                            return Err(LustError::RuntimeError {
1065                                message: "set requires key and value arguments".to_string(),
1066                            });
1067                        }
1068
1069                        let key = self.make_hash_key(&args[0])?;
1070                        let value = args[1].clone();
1071                        map.borrow_mut().insert(key, value);
1072                        Ok(Value::Nil)
1073                    }
1074
1075                    "has" => {
1076                        if args.is_empty() {
1077                            return Err(LustError::RuntimeError {
1078                                message: "has requires a key argument".to_string(),
1079                            });
1080                        }
1081
1082                        let key = self.make_hash_key(&args[0])?;
1083                        Ok(Value::Bool(map.borrow().contains_key(&key)))
1084                    }
1085
1086                    "delete" => {
1087                        if args.is_empty() {
1088                            return Err(LustError::RuntimeError {
1089                                message: "delete requires a key argument".to_string(),
1090                            });
1091                        }
1092
1093                        let key = self.make_hash_key(&args[0])?;
1094                        match map.borrow_mut().remove(&key) {
1095                            Some(value) => Ok(Value::some(value)),
1096                            None => Ok(Value::none()),
1097                        }
1098                    }
1099
1100                    "keys" => {
1101                        let keys: Vec<Value> = map.borrow().keys().map(|k| k.to_value()).collect();
1102                        Ok(Value::array(keys))
1103                    }
1104
1105                    "values" => {
1106                        let values: Vec<Value> = map.borrow().values().cloned().collect();
1107                        Ok(Value::array(values))
1108                    }
1109
1110                    _ => Err(LustError::RuntimeError {
1111                        message: format!("Map has no method '{}'", method_name),
1112                    }),
1113                }
1114            }
1115
1116            Value::Iterator(state_rc) => match method_name {
1117                "iter" => Ok(Value::Iterator(state_rc.clone())),
1118                "next" => {
1119                    use crate::bytecode::value::IteratorState;
1120                    let mut state = state_rc.borrow_mut();
1121                    match &mut *state {
1122                        IteratorState::Array { items, index } => {
1123                            if *index < items.len() {
1124                                let v = items[*index].clone();
1125                                *index += 1;
1126                                Ok(Value::some(v))
1127                            } else {
1128                                Ok(Value::none())
1129                            }
1130                        }
1131
1132                        IteratorState::MapPairs { items, index } => {
1133                            if *index < items.len() {
1134                                let (k, v) = items[*index].clone();
1135                                *index += 1;
1136                                Ok(Value::some(Value::array(vec![k.to_value(), v])))
1137                            } else {
1138                                Ok(Value::none())
1139                            }
1140                        }
1141                    }
1142                }
1143
1144                _ => Err(LustError::RuntimeError {
1145                    message: format!("Iterator has no method '{}'", method_name),
1146                }),
1147            },
1148            Value::Float(f) => match method_name {
1149                "to_int" => {
1150                    if !args.is_empty() {
1151                        return Err(LustError::RuntimeError {
1152                            message: "to_int() takes no arguments".to_string(),
1153                        });
1154                    }
1155
1156                    Ok(Value::Int(int_from_float(*f)))
1157                }
1158
1159                "floor" => {
1160                    if !args.is_empty() {
1161                        return Err(LustError::RuntimeError {
1162                            message: "floor() takes no arguments".to_string(),
1163                        });
1164                    }
1165
1166                    Ok(Value::Float(float_floor(*f)))
1167                }
1168
1169                "ceil" => {
1170                    if !args.is_empty() {
1171                        return Err(LustError::RuntimeError {
1172                            message: "ceil() takes no arguments".to_string(),
1173                        });
1174                    }
1175
1176                    Ok(Value::Float(float_ceil(*f)))
1177                }
1178
1179                "round" => {
1180                    if !args.is_empty() {
1181                        return Err(LustError::RuntimeError {
1182                            message: "round() takes no arguments".to_string(),
1183                        });
1184                    }
1185
1186                    Ok(Value::Float(float_round(*f)))
1187                }
1188
1189                "sqrt" => {
1190                    if !args.is_empty() {
1191                        return Err(LustError::RuntimeError {
1192                            message: "sqrt() takes no arguments".to_string(),
1193                        });
1194                    }
1195
1196                    if *f < 0.0 {
1197                        return Err(LustError::RuntimeError {
1198                            message: "sqrt() requires a non-negative number".to_string(),
1199                        });
1200                    }
1201
1202                    Ok(Value::Float(float_sqrt(*f)))
1203                }
1204
1205                "abs" => {
1206                    if !args.is_empty() {
1207                        return Err(LustError::RuntimeError {
1208                            message: "abs() takes no arguments".to_string(),
1209                        });
1210                    }
1211
1212                    Ok(Value::Float(float_abs(*f)))
1213                }
1214
1215                "min" => {
1216                    if args.len() != 1 {
1217                        return Err(LustError::RuntimeError {
1218                            message: "min() requires 1 argument (other)".to_string(),
1219                        });
1220                    }
1221                    let other = args[0]
1222                        .as_float()
1223                        .or_else(|| args[0].as_int().map(float_from_int))
1224                        .ok_or_else(|| LustError::RuntimeError {
1225                            message: "min() other must be a number".to_string(),
1226                        })?;
1227                    Ok(Value::Float(f.min(other)))
1228                }
1229
1230                "max" => {
1231                    if args.len() != 1 {
1232                        return Err(LustError::RuntimeError {
1233                            message: "max() requires 1 argument (other)".to_string(),
1234                        });
1235                    }
1236                    let other = args[0]
1237                        .as_float()
1238                        .or_else(|| args[0].as_int().map(float_from_int))
1239                        .ok_or_else(|| LustError::RuntimeError {
1240                            message: "max() other must be a number".to_string(),
1241                        })?;
1242                    Ok(Value::Float(f.max(other)))
1243                }
1244
1245                "clamp" => {
1246                    if args.len() != 2 {
1247                        return Err(LustError::RuntimeError {
1248                            message: "clamp() requires 2 arguments (min, max)".to_string(),
1249                        });
1250                    }
1251
1252                    let min = args[0].as_float().ok_or_else(|| LustError::RuntimeError {
1253                        message: "clamp() min must be a number".to_string(),
1254                    })?;
1255                    let max = args[1].as_float().ok_or_else(|| LustError::RuntimeError {
1256                        message: "clamp() max must be a number".to_string(),
1257                    })?;
1258                    if min > max {
1259                        return Err(LustError::RuntimeError {
1260                            message: "clamp() min must be less than or equal to max".to_string(),
1261                        });
1262                    }
1263
1264                    Ok(Value::Float(float_clamp(*f, min, max)))
1265                }
1266
1267                _ => Err(LustError::RuntimeError {
1268                    message: format!("Float has no method '{}'", method_name),
1269                }),
1270            },
1271            Value::Int(i) => match method_name {
1272                "to_float" => {
1273                    if !args.is_empty() {
1274                        return Err(LustError::RuntimeError {
1275                            message: "to_float() takes no arguments".to_string(),
1276                        });
1277                    }
1278
1279                    Ok(Value::Float(float_from_int(*i)))
1280                }
1281
1282                "abs" => {
1283                    if !args.is_empty() {
1284                        return Err(LustError::RuntimeError {
1285                            message: "abs() takes no arguments".to_string(),
1286                        });
1287                    }
1288
1289                    Ok(Value::Int(i.abs()))
1290                }
1291
1292                "min" => {
1293                    if args.len() != 1 {
1294                        return Err(LustError::RuntimeError {
1295                            message: "min() requires 1 argument (other)".to_string(),
1296                        });
1297                    }
1298                    if let Some(other) = args[0].as_int() {
1299                        return Ok(Value::Int((*i).min(other)));
1300                    }
1301                    if let Some(other) = args[0].as_float() {
1302                        return Ok(Value::Float(float_from_int(*i).min(other)));
1303                    }
1304                    Err(LustError::RuntimeError {
1305                        message: "min() other must be a number".to_string(),
1306                    })
1307                }
1308
1309                "max" => {
1310                    if args.len() != 1 {
1311                        return Err(LustError::RuntimeError {
1312                            message: "max() requires 1 argument (other)".to_string(),
1313                        });
1314                    }
1315                    if let Some(other) = args[0].as_int() {
1316                        return Ok(Value::Int((*i).max(other)));
1317                    }
1318                    if let Some(other) = args[0].as_float() {
1319                        return Ok(Value::Float(float_from_int(*i).max(other)));
1320                    }
1321                    Err(LustError::RuntimeError {
1322                        message: "max() other must be a number".to_string(),
1323                    })
1324                }
1325
1326                "clamp" => {
1327                    if args.len() != 2 {
1328                        return Err(LustError::RuntimeError {
1329                            message: "clamp() requires 2 arguments (min, max)".to_string(),
1330                        });
1331                    }
1332
1333                    let min = args[0].as_int().ok_or_else(|| LustError::RuntimeError {
1334                        message: "clamp() min must be an integer".to_string(),
1335                    })?;
1336                    let max = args[1].as_int().ok_or_else(|| LustError::RuntimeError {
1337                        message: "clamp() max must be an integer".to_string(),
1338                    })?;
1339                    if min > max {
1340                        return Err(LustError::RuntimeError {
1341                            message: "clamp() min must be less than or equal to max".to_string(),
1342                        });
1343                    }
1344
1345                    Ok(Value::Int((*i).clamp(min, max)))
1346                }
1347
1348                _ => Err(LustError::RuntimeError {
1349                    message: format!("Int has no method '{}'", method_name),
1350                }),
1351            },
1352            _ => Err(LustError::RuntimeError {
1353                message: format!(
1354                    "Type {:?} has no method '{}'",
1355                    object.type_of(),
1356                    method_name
1357                ),
1358            }),
1359        }
1360    }
1361
1362    fn try_call_lua_dynamic_method(
1363        &mut self,
1364        receiver: &Value,
1365        method_name: &str,
1366        args: &[Value],
1367    ) -> Result<Option<Value>> {
1368        let key = Value::string(method_name.to_string());
1369        let method = self.lua_resolve_index(receiver, &key, 8)?;
1370        if matches!(method, Value::Nil) {
1371            return Ok(None);
1372        }
1373
1374        let mut call_args = Vec::with_capacity(1 + args.len());
1375        call_args.push(receiver.clone());
1376        call_args.extend_from_slice(args);
1377        let result = self.call_value(&method, call_args)?;
1378        Ok(Some(result))
1379    }
1380
1381    fn lua_resolve_index(&mut self, receiver: &Value, key: &Value, depth: usize) -> Result<Value> {
1382        if depth == 0 {
1383            return Ok(Value::Nil);
1384        }
1385
1386        if let Some(direct) = self.lua_direct_index(receiver, key) {
1387            if !matches!(direct, Value::Nil) {
1388                return Ok(direct);
1389            }
1390        }
1391
1392        let Some(indexer) = self.lua_index_metamethod(receiver) else {
1393            return Ok(Value::Nil);
1394        };
1395        if matches!(indexer, Value::Nil) {
1396            return Ok(Value::Nil);
1397        }
1398
1399        let is_callable = matches!(
1400            indexer,
1401            Value::Function(_) | Value::Closure { .. } | Value::NativeFunction(_)
1402        ) || matches!(
1403            &indexer,
1404            Value::Enum {
1405                enum_name,
1406                variant,
1407                ..
1408            } if enum_name == "LuaValue" && variant == "Function"
1409        );
1410
1411        if is_callable {
1412            self.call_value(&indexer, vec![receiver.clone(), key.clone()])
1413        } else {
1414            self.lua_resolve_index(&indexer, key, depth - 1)
1415        }
1416    }
1417
1418    fn lua_direct_index(&self, receiver: &Value, key: &Value) -> Option<Value> {
1419        if let Value::Enum {
1420            enum_name,
1421            variant,
1422            values,
1423        } = receiver
1424        {
1425            if enum_name == "LuaValue" && variant == "Table" {
1426                if let Some(inner) = values.as_ref().and_then(|vals| vals.get(0)) {
1427                    return self.lua_direct_index(inner, key);
1428                }
1429            }
1430        }
1431
1432        match receiver {
1433            Value::Struct { name, .. } if name == "LuaTable" => {
1434                let Some(Value::Map(map_rc)) = receiver.struct_get_field("table") else {
1435                    return None;
1436                };
1437                let raw_key = super::corelib::unwrap_lua_value(key.clone());
1438                let lookup_key = ValueKey::from_value(&raw_key);
1439                let value = map_rc.borrow().get(&lookup_key).cloned();
1440                value
1441            }
1442            Value::Map(map_rc) => {
1443                let raw_key = super::corelib::unwrap_lua_value(key.clone());
1444                let lookup_key = ValueKey::from_value(&raw_key);
1445                let value = map_rc.borrow().get(&lookup_key).cloned();
1446                value
1447            }
1448            _ => None,
1449        }
1450    }
1451
1452    fn lua_index_metamethod(&self, receiver: &Value) -> Option<Value> {
1453        if let Value::Enum {
1454            enum_name,
1455            variant,
1456            values,
1457        } = receiver
1458        {
1459            if enum_name == "LuaValue" && variant == "Table" {
1460                if let Some(inner) = values.as_ref().and_then(|vals| vals.get(0)) {
1461                    return self.lua_index_metamethod(inner);
1462                }
1463            }
1464            if enum_name == "LuaValue" && variant == "Userdata" {
1465                if let Some(inner) = values.as_ref().and_then(|vals| vals.get(0)) {
1466                    return self.lua_index_metamethod(inner);
1467                }
1468            }
1469        }
1470
1471        let Value::Struct { name, .. } = receiver else {
1472            return None;
1473        };
1474        let Some(Value::Map(meta_rc)) = receiver.struct_get_field("metamethods") else {
1475            return None;
1476        };
1477        if name != "LuaTable" && name != "LuaUserdata" {
1478            return None;
1479        }
1480        let value = meta_rc
1481            .borrow()
1482            .get(&ValueKey::string("__index".to_string()))
1483            .cloned();
1484        value
1485    }
1486}
1487
1488fn lua_table_map_rc(table: &Value) -> Option<Rc<RefCell<LustMap>>> {
1489    match table.struct_get_field("table") {
1490        Some(Value::Map(map_rc)) => Some(map_rc),
1491        _ => None,
1492    }
1493}
1494
1495fn lua_table_sequence_len(map: &LustMap) -> usize {
1496    let mut idx: LustInt = 1;
1497    loop {
1498        let key = ValueKey::from_value(&Value::Int(idx));
1499        if map.contains_key(&key) {
1500            idx += 1;
1501        } else {
1502            break;
1503        }
1504    }
1505    (idx - 1) as usize
1506}
1507
1508fn lua_table_read_sequence(map: &LustMap) -> Vec<Value> {
1509    let mut seq: Vec<Value> = Vec::new();
1510    let mut idx: LustInt = 1;
1511    loop {
1512        let key = ValueKey::from_value(&Value::Int(idx));
1513        if let Some(val) = map.get(&key) {
1514            seq.push(val.clone());
1515            idx += 1;
1516        } else {
1517            break;
1518        }
1519    }
1520    seq
1521}
1522
1523fn lua_table_write_sequence(map_rc: &Rc<RefCell<LustMap>>, seq: &[Value]) {
1524    let mut map = map_rc.borrow_mut();
1525    let mut idx: LustInt = 1;
1526    loop {
1527        let key = ValueKey::from_value(&Value::Int(idx));
1528        if map.remove(&key).is_some() {
1529            idx += 1;
1530        } else {
1531            break;
1532        }
1533    }
1534    for (i, val) in seq.iter().enumerate() {
1535        let key = ValueKey::from_value(&Value::Int((i as LustInt) + 1));
1536        map.insert(key, val.clone());
1537    }
1538}