Skip to main content

nanvm_lib/vm/array/
argument.rs

1use super::Array;
2use crate::{
3    common::sized_index::SizedIndex,
4    vm::{Any, IVm},
5};
6
7impl<A: IVm> Array<A> {
8    /// The `i`-th argument of a call whose arguments this array holds, or
9    /// `undefined` past the end, as JavaScript binds a parameter the call
10    /// left out. What a built-in and a compiled function's body read their
11    /// fixed arguments with: one bounds check and one clone, where
12    /// `Index<u32>` panics past the end.
13    pub fn argument(&self, i: u32) -> Any<A> {
14        if i < self.length() {
15            self[i].clone()
16        } else {
17            Any::undefined()
18        }
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use crate::{
25        naive::Naive,
26        vm::{Any, ToAny, ToArray},
27    };
28
29    type A = Naive;
30
31    /// An argument the call passed is itself, `undefined` included; one
32    /// past the end is `undefined`.
33    #[test]
34    fn argument() {
35        let args = [1.0.to_any(), Any::<A>::undefined(), "s".into()].to_array();
36        assert_eq!(args.argument(0), 1.0.to_any());
37        assert_eq!(args.argument(1), Any::undefined());
38        assert_eq!(args.argument(2), "s".into());
39        assert_eq!(args.argument(3), Any::undefined());
40        assert_eq!(args.argument(u32::MAX), Any::undefined());
41        assert_eq!([].to_array().argument(0), Any::<A>::undefined());
42    }
43}