1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 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.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function(global) {
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var GetProperties = function(this_name, object) {
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var result = {};
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    try {
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var names = Object.getOwnPropertyNames(object);
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } catch(e) {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < names.length; ++i) {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var name = names[i];
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (typeof object === "function") {
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (name === "length" ||
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            name === "name" ||
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            name === "arguments" ||
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            name === "caller" ||
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            name === "prototype") {
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          continue;
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Avoid endless recursion.
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (this_name === "prototype" && name === "constructor") continue;
2713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Avoid needless duplication.
2813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (this_name === "__PROTO__" && name === "constructor") continue;
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Could get this from the parent, but having it locally is easier.
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var property = { "name": name };
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      try {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var value = object[name];
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } catch(e) {
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        property.type = "getter";
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        result[name] = property;
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue;
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var type = typeof value;
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      property.type = type;
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (type === "function") {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        property.length = value.length;
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        property.prototype = GetProperties("prototype", value.prototype);
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (type === "string" || type === "number") {
4513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        property.value = value;
4613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      } else {
4713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        property.properties = GetProperties(name, value);
4813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result[name] = property;
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Print the __proto__ if it's not the default Object prototype.
5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (typeof object === "object" && object.__proto__ !== null &&
5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        !object.__proto__.hasOwnProperty("__proto__")) {
5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      result.__PROTO__ = GetProperties("__PROTO__", object.__proto__);
5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var g = GetProperties("", global, "");
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  print(JSON.stringify(g, undefined, 2));
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})(this);  // Must wrap in anonymous closure or it'll detect itself as builtin.
63