1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Slightly modified variants from http://code.fitness/post/2016/01/javascript-enumerate-methods.html.
6function __isPropertyOfType(obj, name, type) {
7  let desc;
8  try {
9    desc = Object.getOwnPropertyDescriptor(obj, name);
10  } catch(e) {
11    return false;
12  }
13
14  if (!desc)
15    return false;
16
17  return typeof type === 'undefined' || typeof desc.value === type;
18}
19
20function __getProperties(obj, type) {
21  if (typeof obj === "undefined" || obj === null)
22    return [];
23
24  let properties = [];
25  for (let name of Object.getOwnPropertyNames(obj)) {
26    if (__isPropertyOfType(obj, name, type))
27      properties.push(name);
28  }
29
30  let proto = Object.getPrototypeOf(obj);
31  while (proto && proto != Object.prototype) {
32    Object.getOwnPropertyNames(proto)
33      .forEach (name => {
34        if (name !== 'constructor') {
35          if (__isPropertyOfType(proto, name, type))
36            properties.push(name);
37        }
38      });
39    proto = Object.getPrototypeOf(proto);
40  }
41  return properties;
42}
43
44function* __getObjects(root = this, level = 0) {
45    if (level > 4)
46      return;
47
48    let obj_names = __getProperties(root, 'object');
49    for (let obj_name of obj_names) {
50      let obj = root[obj_name];
51      if (obj === root)
52        continue;
53
54      yield obj;
55      yield* __getObjects(obj, level + 1);
56    }
57}
58
59function __getRandomObject(seed) {
60  let objects = [];
61  for (let obj of __getObjects()) {
62    objects.push(obj);
63  }
64
65  return objects[seed % objects.length];
66}
67
68function __getRandomProperty(obj, seed) {
69  let properties = __getProperties(obj);
70  if (!properties.length)
71    return undefined;
72
73  return properties[seed % properties.length];
74}
75
76function __callRandomFunction(obj, seed, ...args)
77{
78  let functions = __getProperties(obj, 'function');
79  if (!functions.length)
80    return;
81
82  let random_function = functions[seed % functions.length];
83  try {
84    obj[random_function](...args);
85  } catch(e) { }
86}
87
88function runNearStackLimit(f) {
89  function t() {
90    try {
91      return t();
92    } catch (e) {
93      return f();
94    }
95  };
96  try {
97    return t();
98  } catch (e) {}
99}
100
101// Limit number of times we cause major GCs in tests to reduce hangs
102// when called within larger loops.
103let __callGC;
104(function() {
105  let countGC = 0;
106  __callGC = function() {
107    if (countGC++ < 50) {
108      gc();
109    }
110  };
111})();
112
113// Neuter common test functions.
114try { this.failWithMessage = nop; } catch(e) { }
115try { this.triggerAssertFalse = nop; } catch(e) { }
116try { this.quit = nop; } catch(e) { }
117