1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch(function() { 63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch"use strict"; 73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A more universal stringify that supports more types than JSON. 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Used by the d8 shell to output results. 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar stringifyDepthLimit = 4; // To avoid crashing on cyclic objects 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Hacky solution to circumvent forcing --allow-natives-syntax for d8 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction isProxy(o) { return false }; 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction JSProxyGetTarget(proxy) { }; 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction JSProxyGetHandler(proxy) { }; 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtry { 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isProxy = Function(['object'], 'return %_IsJSProxy(object)'); 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSProxyGetTarget = Function(['proxy'], 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 'return %JSProxyGetTarget(proxy)'); 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSProxyGetHandler = Function(['proxy'], 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 'return %JSProxyGetHandler(proxy)'); 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} catch(e) {}; 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction Stringify(x, depth) { 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (depth === undefined) 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch depth = stringifyDepthLimit; 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else if (depth === 0) 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return "..."; 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isProxy(x)) { 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return StringifyProxy(x, depth); 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (typeof x) { 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case "undefined": 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "undefined"; 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case "boolean": 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case "number": 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case "function": 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return x.toString(); 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case "string": 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "\"" + x.toString() + "\""; 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case "symbol": 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return x.toString(); 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case "object": 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IS_NULL(x)) return "null"; 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (x.constructor && x.constructor.name === "Array") { 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var elems = []; 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (var i = 0; i < x.length; ++i) { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elems.push( 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch {}.hasOwnProperty.call(x, i) ? Stringify(x[i], depth - 1) : ""); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "[" + elems.join(", ") + "]"; 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch try { 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var string = String(x); 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (string && string !== "[object Object]") return string; 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } catch(e) {} 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var props = []; 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var names = Object.getOwnPropertyNames(x); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch names = names.concat(Object.getOwnPropertySymbols(x)); 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (var i in names) { 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var name = names[i]; 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var desc = Object.getOwnPropertyDescriptor(x, name); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IS_UNDEFINED(desc)) continue; 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IS_SYMBOL(name)) name = "[" + Stringify(name) + "]"; 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ("value" in desc) { 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch props.push(name + ": " + Stringify(desc.value, depth - 1)); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (desc.get) { 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var getter = Stringify(desc.get); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch props.push("get " + name + getter.slice(getter.indexOf('('))); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (desc.set) { 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var setter = Stringify(desc.set); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch props.push("set " + name + setter.slice(setter.indexOf('('))); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "{" + props.join(", ") + "}"; 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return "[crazy non-standard value]"; 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction StringifyProxy(proxy, depth) { 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch var proxy_type = typeof proxy; 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch var info_object = { 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target: JSProxyGetTarget(proxy), 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch handler: JSProxyGetHandler(proxy) 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return '[' + proxy_type + ' Proxy ' + Stringify(info_object, depth-1) + ']'; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochreturn Stringify; 953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch})(); 96