Skip to main content

nanvm_lib/vm/any/
instanceof_.rs

1use crate::vm::{
2    Any, Array, BigInt, Function, IVm, Number, Object, String, ToAny, dispatch::Dispatch,
3    nullish::Nullish,
4};
5
6/// The constructors `instanceof` may name: the EDAG's `constructorId`, a
7/// closed list — `Array` alone today, where `Map` and `Set` are one variant
8/// each once the VM has such values. A name, not a value: no global is a
9/// value in the EDAG, so the operator's right side is carried as the word
10/// it is, and a variant here rather than an `Any<A>`.
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum Constructor {
13    Array,
14}
15
16/// `x instanceof Array`, over `Unpacked`: `true` of an array and `false` of
17/// every other value, `null` and `undefined` included.
18struct InstanceOfArray;
19
20impl<A: IVm> Dispatch<A> for InstanceOfArray {
21    type Result = bool;
22
23    fn nullish(self, _: Nullish) -> Self::Result {
24        false
25    }
26
27    fn bool(self, _: bool) -> Self::Result {
28        false
29    }
30
31    fn number(self, _: Number) -> Self::Result {
32        false
33    }
34
35    fn string(self, _: String<A>) -> Self::Result {
36        false
37    }
38
39    fn bigint(self, _: BigInt<A>) -> Self::Result {
40        false
41    }
42
43    fn object(self, _: Object<A>) -> Self::Result {
44        false
45    }
46
47    fn array(self, _: Array<A>) -> Self::Result {
48        true
49    }
50
51    fn function(self, _: Function<A>) -> Self::Result {
52        false
53    }
54}
55
56impl<A: IVm> Any<A> {
57    /// `instanceof`, against a built-in constructor. Not a `core::ops`
58    /// trait — Rust has no operator to spell it with — so this is a plain
59    /// method, named as `typeof_` is: a trailing underscore keeps the
60    /// reserved-word spelling recognizable. Never throws: the right side is
61    /// a constructor by construction, so JavaScript's `TypeError` for a
62    /// non-callable right operand has no case here; stays a `Result` to
63    /// match every other operator's shape.
64    /// <https://tc39.es/ecma262/#sec-instanceofoperator>
65    pub fn instanceof_(self, constructor: Constructor) -> Result<Any<A>, Any<A>> {
66        Ok(match constructor {
67            Constructor::Array => self.dispatch(InstanceOfArray),
68        }
69        .to_any())
70    }
71}