• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2008 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(function() {
6"use strict";
7
8// A more universal stringify that supports more types than JSON.
9// Used by the d8 shell to output results.
10var stringifyDepthLimit = 4;  // To avoid crashing on cyclic objects
11
12// Hacky solution to circumvent forcing --allow-natives-syntax for d8
13function isProxy(o) { return false };
14function JSProxyGetTarget(proxy) { };
15function JSProxyGetHandler(proxy) { };
16
17try {
18  isProxy = Function(['object'], 'return %_IsJSProxy(object)');
19  JSProxyGetTarget = Function(['proxy'],
20    'return %JSProxyGetTarget(proxy)');
21  JSProxyGetHandler = Function(['proxy'],
22    'return %JSProxyGetHandler(proxy)');
23} catch(e) {};
24
25
26function Stringify(x, depth) {
27  if (depth === undefined)
28    depth = stringifyDepthLimit;
29  else if (depth === 0)
30    return "...";
31  if (isProxy(x)) {
32    return StringifyProxy(x, depth);
33  }
34  switch (typeof x) {
35    case "undefined":
36      return "undefined";
37    case "boolean":
38    case "number":
39    case "function":
40    case "symbol":
41      return x.toString();
42    case "string":
43      return "\"" + x.toString() + "\"";
44    case "bigint":
45      return x.toString() + "n";
46    case "object":
47      if (IS_NULL(x)) return "null";
48      if (x.constructor && x.constructor.name === "Array") {
49        var elems = [];
50        for (var i = 0; i < x.length; ++i) {
51          elems.push(
52            {}.hasOwnProperty.call(x, i) ? Stringify(x[i], depth - 1) : "");
53        }
54        return "[" + elems.join(", ") + "]";
55      }
56      try {
57        var string = String(x);
58        if (string && string !== "[object Object]") return string;
59      } catch(e) {}
60      var props = [];
61      var names = Object.getOwnPropertyNames(x);
62      names = names.concat(Object.getOwnPropertySymbols(x));
63      for (var i in names) {
64        var name = names[i];
65        var desc = Object.getOwnPropertyDescriptor(x, name);
66        if (IS_UNDEFINED(desc)) continue;
67        if (IS_SYMBOL(name)) name = "[" + Stringify(name) + "]";
68        if ("value" in desc) {
69          props.push(name + ": " + Stringify(desc.value, depth - 1));
70        }
71        if (desc.get) {
72          var getter = Stringify(desc.get);
73          props.push("get " + name + getter.slice(getter.indexOf('(')));
74        }
75        if (desc.set) {
76          var setter = Stringify(desc.set);
77          props.push("set " + name + setter.slice(setter.indexOf('(')));
78        }
79      }
80      return "{" + props.join(", ") + "}";
81    default:
82      return "[crazy non-standard value]";
83  }
84}
85
86function StringifyProxy(proxy, depth) {
87  var proxy_type = typeof proxy;
88  var info_object = {
89    target: JSProxyGetTarget(proxy),
90    handler: JSProxyGetHandler(proxy)
91  }
92  return '[' + proxy_type + ' Proxy ' + Stringify(info_object, depth-1) + ']';
93}
94
95return Stringify;
96})();
97