| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 "use strict"; | 5 "use strict"; |
| 6 | 6 |
| 7 // A more universal stringify that supports more types than JSON. | 7 // A more universal stringify that supports more types than JSON. |
| 8 // Used by the d8 shell to output results. | 8 // Used by the d8 shell to output results. |
| 9 var stringifyDepthLimit = 4; // To avoid crashing on cyclic objects | 9 var stringifyDepthLimit = 4; // To avoid crashing on cyclic objects |
| 10 | 10 |
| 11 function Stringify(x, depth) { | 11 function Stringify(x, depth) { |
| 12 if (depth === undefined) | 12 if (depth === undefined) |
| 13 depth = stringifyDepthLimit; | 13 depth = stringifyDepthLimit; |
| 14 else if (depth === 0) | 14 else if (depth === 0) |
| 15 return "*"; | 15 return "*"; |
| 16 if (IS_PROXY(x)) { | |
| 17 return StringifyProxy(x, depth); | |
| 18 } | |
| 19 switch (typeof x) { | 16 switch (typeof x) { |
| 20 case "undefined": | 17 case "undefined": |
| 21 return "undefined"; | 18 return "undefined"; |
| 22 case "boolean": | 19 case "boolean": |
| 23 case "number": | 20 case "number": |
| 24 case "function": | 21 case "function": |
| 25 return x.toString(); | 22 return x.toString(); |
| 26 case "string": | 23 case "string": |
| 27 return "\"" + x.toString() + "\""; | 24 return "\"" + x.toString() + "\""; |
| 28 case "symbol": | 25 case "symbol": |
| 29 return x.toString(); | 26 return x.toString(); |
| 30 case "object": | 27 case "object": |
| 31 if (IS_NULL(x)) return "null"; | 28 if (IS_NULL(x)) return "null"; |
| 29 if (x.constructor && x.constructor.name === "Array") { |
| 30 var elems = []; |
| 31 for (var i = 0; i < x.length; ++i) { |
| 32 elems.push( |
| 33 {}.hasOwnProperty.call(x, i) ? Stringify(x[i], depth - 1) : ""); |
| 34 } |
| 35 return "[" + elems.join(", ") + "]"; |
| 36 } |
| 32 try { | 37 try { |
| 33 return StringifyObject(x, depth); | 38 var string = String(x); |
| 34 } catch(RangeError) { | 39 if (string && string !== "[object Object]") return string; |
| 35 return "{*}" | 40 } catch(e) {} |
| 41 var props = []; |
| 42 var names = Object.getOwnPropertyNames(x); |
| 43 names = names.concat(Object.getOwnPropertySymbols(x)); |
| 44 for (var i in names) { |
| 45 var name = names[i]; |
| 46 var desc = Object.getOwnPropertyDescriptor(x, name); |
| 47 if (IS_UNDEFINED(desc)) continue; |
| 48 if (IS_SYMBOL(name)) name = "[" + Stringify(name) + "]"; |
| 49 if ("value" in desc) { |
| 50 props.push(name + ": " + Stringify(desc.value, depth - 1)); |
| 51 } |
| 52 if (desc.get) { |
| 53 var getter = Stringify(desc.get); |
| 54 props.push("get " + name + getter.slice(getter.indexOf('('))); |
| 55 } |
| 56 if (desc.set) { |
| 57 var setter = Stringify(desc.set); |
| 58 props.push("set " + name + setter.slice(setter.indexOf('('))); |
| 59 } |
| 36 } | 60 } |
| 61 return "{" + props.join(", ") + "}"; |
| 37 default: | 62 default: |
| 38 return "[crazy non-standard value]"; | 63 return "[crazy non-standard value]"; |
| 39 } | 64 } |
| 40 } | 65 } |
| 41 | |
| 42 function StringifyObject(x, depth) { | |
| 43 if (x.constructor && x.constructor.name === "Array") { | |
| 44 var elems = []; | |
| 45 for (var i = 0; i < x.length; ++i) { | |
| 46 elems.push( | |
| 47 {}.hasOwnProperty.call(x, i) ? Stringify(x[i], depth - 1) : ""); | |
| 48 } | |
| 49 return "[" + elems.join(", ") + "]"; | |
| 50 } | |
| 51 try { | |
| 52 var string = String(x); | |
| 53 if (string && string !== "[object Object]") return string; | |
| 54 } catch(e) {} | |
| 55 var props = []; | |
| 56 var names = Object.getOwnPropertyNames(x); | |
| 57 names = names.concat(Object.getOwnPropertySymbols(x)); | |
| 58 for (var i in names) { | |
| 59 var name = names[i]; | |
| 60 var desc = Object.getOwnPropertyDescriptor(x, name); | |
| 61 if (IS_UNDEFINED(desc)) continue; | |
| 62 if (IS_SYMBOL(name)) name = "[" + Stringify(name) + "]"; | |
| 63 if ("value" in desc) { | |
| 64 props.push(name + ": " + Stringify(desc.value, depth - 1)); | |
| 65 } | |
| 66 if (desc.get) { | |
| 67 var getter = Stringify(desc.get); | |
| 68 props.push("get " + name + getter.slice(getter.indexOf('('))); | |
| 69 } | |
| 70 if (desc.set) { | |
| 71 var setter = Stringify(desc.set); | |
| 72 props.push("set " + name + setter.slice(setter.indexOf('('))); | |
| 73 } | |
| 74 } | |
| 75 return "{" + props.join(", ") + "}"; | |
| 76 } | |
| 77 | |
| 78 function StringifyProxy(proxy, depth) { | |
| 79 var proxy_type = typeof proxy; | |
| 80 return '[' + proxy_type + ' Proxy ' + Stringify({ | |
| 81 target: %JSProxyGetTarget(proxy), | |
| 82 handler: %JSProxyGetHandler(proxy) | |
| 83 }, depth-1) + ']'; | |
| 84 } | |
| OLD | NEW |