Upgrade to 3.29

Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.

Bug: 17370214

Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/test/mjsunit/json.js b/test/mjsunit/json.js
index bead376..c72c153 100644
--- a/test/mjsunit/json.js
+++ b/test/mjsunit/json.js
@@ -225,23 +225,28 @@
 
 // Stringify
 
-assertEquals("true", JSON.stringify(true));
-assertEquals("false", JSON.stringify(false));
-assertEquals("null", JSON.stringify(null));
-assertEquals("false", JSON.stringify({toJSON: function () { return false; }}));
-assertEquals("4", JSON.stringify(4));
-assertEquals('"foo"', JSON.stringify("foo"));
-assertEquals("null", JSON.stringify(Infinity));
-assertEquals("null", JSON.stringify(-Infinity));
-assertEquals("null", JSON.stringify(NaN));
-assertEquals("4", JSON.stringify(new Number(4)));
-assertEquals('"bar"', JSON.stringify(new String("bar")));
+function TestStringify(expected, input) {
+  assertEquals(expected, JSON.stringify(input));
+  assertEquals(expected, JSON.stringify(input, null, 0));
+}
 
-assertEquals('"foo\\u0000bar"', JSON.stringify("foo\0bar"));
-assertEquals('"f\\"o\'o\\\\b\\ba\\fr\\nb\\ra\\tz"',
-             JSON.stringify("f\"o\'o\\b\ba\fr\nb\ra\tz"));
+TestStringify("true", true);
+TestStringify("false", false);
+TestStringify("null", null);
+TestStringify("false", {toJSON: function () { return false; }});
+TestStringify("4", 4);
+TestStringify('"foo"', "foo");
+TestStringify("null", Infinity);
+TestStringify("null", -Infinity);
+TestStringify("null", NaN);
+TestStringify("4", new Number(4));
+TestStringify('"bar"', new String("bar"));
 
-assertEquals("[1,2,3]", JSON.stringify([1, 2, 3]));
+TestStringify('"foo\\u0000bar"', "foo\0bar");
+TestStringify('"f\\"o\'o\\\\b\\ba\\fr\\nb\\ra\\tz"',
+              "f\"o\'o\\b\ba\fr\nb\ra\tz");
+
+TestStringify("[1,2,3]", [1, 2, 3]);
 assertEquals("[\n 1,\n 2,\n 3\n]", JSON.stringify([1, 2, 3], null, 1));
 assertEquals("[\n  1,\n  2,\n  3\n]", JSON.stringify([1, 2, 3], null, 2));
 assertEquals("[\n  1,\n  2,\n  3\n]",
@@ -256,17 +261,59 @@
              JSON.stringify([1, 2, [3, [4], 5], 6, 7], null));
 assertEquals("[2,4,[6,[8],10],12,14]",
              JSON.stringify([1, 2, [3, [4], 5], 6, 7], DoubleNumbers));
-assertEquals('["a","ab","abc"]', JSON.stringify(["a","ab","abc"]));
+TestStringify('["a","ab","abc"]', ["a","ab","abc"]);
+TestStringify('{"a":1,"c":true}', { a : 1,
+                                    b : function() { 1 },
+                                    c : true,
+                                    d : function() { 2 } });
+TestStringify('[1,null,true,null]',
+              [1, function() { 1 }, true, function() { 2 }]);
+TestStringify('"toJSON 123"',
+              { toJSON : function() { return 'toJSON 123'; } });
+TestStringify('{"a":321}',
+              { a : { toJSON : function() { return 321; } } });
+var counter = 0;
+assertEquals('{"getter":123}',
+             JSON.stringify({ get getter() { counter++; return 123; } }));
+assertEquals(1, counter);
+assertEquals('{"getter":123}',
+             JSON.stringify({ get getter() { counter++; return 123; } },
+                            null,
+                            0));
+assertEquals(2, counter);
+
+TestStringify('{"a":"abc","b":"\u1234bc"}',
+              { a : "abc", b : "\u1234bc" });
+
+
+var a = { a : 1, b : 2 };
+delete a.a;
+TestStringify('{"b":2}', a);
+
+var b = {};
+b.__proto__ = { toJSON : function() { return 321;} };
+TestStringify("321", b);
+
+var array = [""];
+var expected = '""';
+for (var i = 0; i < 10000; i++) {
+  array.push("");
+  expected = '"",' + expected;
+}
+expected = '[' + expected + ']';
+TestStringify(expected, array);
+
 
 var circular = [1, 2, 3];
 circular[2] = circular;
 assertThrows(function () { JSON.stringify(circular); }, TypeError);
+assertThrows(function () { JSON.stringify(circular, null, 0); }, TypeError);
 
 var singleton = [];
 var multiOccurrence = [singleton, singleton, singleton];
-assertEquals("[[],[],[]]", JSON.stringify(multiOccurrence));
+TestStringify("[[],[],[]]", multiOccurrence);
 
-assertEquals('{"x":5,"y":6}', JSON.stringify({x:5,y:6}));
+TestStringify('{"x":5,"y":6}', {x:5,y:6});
 assertEquals('{"x":5}', JSON.stringify({x:5,y:6}, ['x']));
 assertEquals('{\n "a": "b",\n "c": "d"\n}',
              JSON.stringify({a:"b",c:"d"}, null, 1));
@@ -276,7 +323,7 @@
 var checker = {};
 var array = [checker];
 checker.toJSON = function(key) { return 1 + key; };
-assertEquals('["10"]', JSON.stringify(array));
+TestStringify('["10"]', array);
 
 // The gap is capped at ten characters if specified as string.
 assertEquals('{\n          "a": "b",\n          "c": "d"\n}',
@@ -293,12 +340,11 @@
 assertEquals('{"x":42}', JSON.stringify({x: Number}, newx));
 assertEquals('{"x":true}', JSON.stringify({x: Boolean}, newx));
 
-assertEquals(undefined, JSON.stringify(undefined));
-assertEquals(undefined, JSON.stringify(function () { }));
+TestStringify(undefined, undefined);
+TestStringify(undefined, function () { });
 // Arrays with missing, undefined or function elements have those elements
 // replaced by null.
-assertEquals("[null,null,null]",
-             JSON.stringify([undefined,,function(){}]));
+TestStringify("[null,null,null]", [undefined,,function(){}]);
 
 // Objects with undefined or function properties (including replaced properties)
 // have those properties ignored.
@@ -379,16 +425,15 @@
 var reJSON = /Is callable/;
 reJSON.toJSON = function() { return "has toJSON"; };
 
-assertEquals(
-    '[37,null,1,"foo","37","true",null,"has toJSON",{},"has toJSON"]',
-    JSON.stringify([num37, numFoo, numTrue,
-                    strFoo, str37, strTrue,
-                    func, funcJSON, re, reJSON]));
+TestStringify('[37,null,1,"foo","37","true",null,"has toJSON",{},"has toJSON"]',
+              [num37, numFoo, numTrue,
+               strFoo, str37, strTrue,
+               func, funcJSON, re, reJSON]);
 
 
 var oddball = Object(42);
 oddball.__proto__ = { __proto__: null, toString: function() { return true; } };
-assertEquals('1', JSON.stringify(oddball));
+TestStringify('1', oddball);
 
 var getCount = 0;
 var callCount = 0;
@@ -397,10 +442,10 @@
                                                    return 42; }; } };
 
 // RegExps are not callable, so they are stringified as objects.
-assertEquals('{}', JSON.stringify(/regexp/));
-assertEquals('42', JSON.stringify(counter));
-assertEquals(1, getCount);
-assertEquals(1, callCount);
+TestStringify('{}', /regexp/);
+TestStringify('42', counter);
+assertEquals(2, getCount);
+assertEquals(2, callCount);
 
 var oddball2 = Object(42);
 var oddball3 = Object("foo");
@@ -409,24 +454,31 @@
                        valueOf: function() { return true; } };
 oddball2.__proto__ = { __proto__: null,
                        toJSON: function () { return oddball3; } }
-assertEquals('"true"', JSON.stringify(oddball2));
+TestStringify('"true"', oddball2);
 
 
 var falseNum = Object("37");
 falseNum.__proto__ = Number.prototype;
 falseNum.toString = function() { return 42; };
-assertEquals('"42"', JSON.stringify(falseNum));
+TestStringify('"42"', falseNum);
 
-// We don't currently allow plain properties called __proto__ in JSON
-// objects in JSON.parse. Instead we read them as we would JS object
-// literals. If we change that, this test should change with it.
-//
-// Parse a non-object value as __proto__. This must not create a
-// __proto__ property different from the original, and should not
-// change the original.
-var o = JSON.parse('{"__proto__":5}');
-assertEquals(Object.prototype, o.__proto__);  // __proto__ isn't changed.
-assertEquals(0, Object.keys(o).length);  // __proto__ isn't added as enumerable.
+// Parse an object value as __proto__.
+var o1 = JSON.parse('{"__proto__":[]}');
+assertEquals([], o1.__proto__);
+assertEquals(["__proto__"], Object.keys(o1));
+assertEquals([], Object.getOwnPropertyDescriptor(o1, "__proto__").value);
+assertEquals(["__proto__"], Object.getOwnPropertyNames(o1));
+assertTrue(o1.hasOwnProperty("__proto__"));
+assertTrue(Object.prototype.isPrototypeOf(o1));
 
+// Parse a non-object value as __proto__.
+var o2 = JSON.parse('{"__proto__":5}');
+assertEquals(5, o2.__proto__);
+assertEquals(["__proto__"], Object.keys(o2));
+assertEquals(5, Object.getOwnPropertyDescriptor(o2, "__proto__").value);
+assertEquals(["__proto__"], Object.getOwnPropertyNames(o2));
+assertTrue(o2.hasOwnProperty("__proto__"));
+assertTrue(Object.prototype.isPrototypeOf(o2));
 
-
+var json = '{"stuff before slash\\\\stuff after slash":"whatever"}';
+TestStringify(json, JSON.parse(json));