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