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