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.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 | |