summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/warp/typeof-is.js
blob: df41185769d10f34c2af3cbf87112c330778f2b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Test case |typeof| folding in simple comparison contexts.

// Create functions to test if |typeof x| is equal to a constant string.
// - Covers all possible |typeof| results, plus the invalid string "bad".
// - Covers all four possible equality comparison operators.
function createFunctions() {
  return [
    "undefined",
    "object",
    "function",
    "string",
    "number",
    "boolean",
    "symbol",
    "bigint",
    "bad",
  ].flatMap(type => [
    "==",
    "===",
    "!=",
    "!=="
  ].map(op => ({
    type,
    equal: op[0] === "=",
    fn: Function("thing", `return typeof thing ${op} "${type}"`)
  })));
}

let functions = createFunctions();

function test() {
  const ccwGlobal = newGlobal({newCompartment: true});
  const xs = [
    // "undefined"
    // Plain undefined and object emulating undefined, including various proxy wrapper cases.
    undefined,
    createIsHTMLDDA(),
    wrapWithProto(createIsHTMLDDA(), null),
    ccwGlobal.eval("createIsHTMLDDA()"),

    // "object"
    // Plain object and various proxy wrapper cases.
    {},
    this,
    new Proxy({}, {}),
    wrapWithProto({}, null),
    transplantableObject({proxy: true}).object,
    ccwGlobal.Object(),

    // "function"
    // Plain function and various proxy wrapper cases.
    function(){},
    new Proxy(function(){}, {}),
    new Proxy(createIsHTMLDDA(), {}),
    wrapWithProto(function(){}, null),
    ccwGlobal.Function(),

    // "string"
    "",

    // "number"
    // Int32 and Double numbers.
    0,
    1.23,

    // "boolean"
    true,

    // "symbol"
    Symbol(),

    // "bigint"
    0n,
  ];

  for (let i = 0; i < 200; ++i) {
    let x = xs[i % xs.length];
    for (let {type, equal, fn} of functions) {
      assertEq(fn(x), (typeof x === type) === equal);
    }
  }
}
for (let i = 0; i < 2; ++i) test();

// Fresh set of functions to gather new type info.
let functionsObject = createFunctions();

// Additional test when the input is always an object.
function testObject() {
  const ccwGlobal = newGlobal({newCompartment: true});

  // All elements of this array are objects to cover the case when |MTypeOf| has
  // a |MIRType::Object| input.
  const xs = [
    // "undefined"
    // Object emulating undefined, including various proxy wrapper cases.
    createIsHTMLDDA(),
    wrapWithProto(createIsHTMLDDA(), null),
    ccwGlobal.eval("createIsHTMLDDA()"),

    // "object"
    // Plain object and various proxy wrapper cases.
    {},
    this,
    new Proxy({}, {}),
    wrapWithProto({}, null),
    transplantableObject({proxy: true}).object,
    ccwGlobal.Object(),

    // "function"
    // Plain function and various proxy wrapper cases.
    function(){},
    new Proxy(function(){}, {}),
    new Proxy(createIsHTMLDDA(), {}),
    wrapWithProto(function(){}, null),
    ccwGlobal.Function(),
  ];

  for (let i = 0; i < 200; ++i) {
    let x = xs[i % xs.length];
    for (let {type, equal, fn} of functionsObject) {
      assertEq(fn(x), (typeof x === type) === equal);
    }
  }
}
for (let i = 0; i < 2; ++i) testObject();