13a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// Copyright 2009 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
43a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
5a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org"use strict";
6a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
7e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// This file relies on the fact that the following declarations have been made
8e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// in runtime.js:
9e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// var $Array = global.Array;
10e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// var $String = global.String;
11e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
123a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvar $JSON = global.JSON;
133a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
14e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// -------------------------------------------------------------------
15e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
163a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction Revive(holder, name, reviver) {
173a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var val = holder[name];
183a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  if (IS_OBJECT(val)) {
193a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    if (IS_ARRAY(val)) {
203a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      var length = val.length;
213a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      for (var i = 0; i < length; i++) {
223a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        var newElement = Revive(val, $String(i), reviver);
233a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        val[i] = newElement;
243a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      }
253a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    } else {
263a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      for (var p in val) {
277a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org        if (%_CallFunction(val, p, ObjectHasOwnProperty)) {
283a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          var newElement = Revive(val, p, reviver);
293a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          if (IS_UNDEFINED(newElement)) {
303a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org            delete val[p];
313a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          } else {
323a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org            val[p] = newElement;
333a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          }
343a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        }
353a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      }
363a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    }
373a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
388f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  return %_CallFunction(holder, name, val, reviver);
393a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
403a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
413a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction JSONParse(text, reviver) {
429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  var unfiltered = %ParseJson(TO_STRING_INLINE(text));
4334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (IS_SPEC_FUNCTION(reviver)) {
443a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    return Revive({'': unfiltered}, '', reviver);
453a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else {
463a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    return unfiltered;
473a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
483a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
493a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
503a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction SerializeArray(value, replacer, stack, indent, gap) {
515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (!%PushIfAbsent(stack, value)) {
528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    throw MakeTypeError('circular_structure', $Array());
535c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
543a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var stepback = indent;
553a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  indent += gap;
568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  var partial = new InternalArray();
573a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var len = value.length;
583a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  for (var i = 0; i < len; i++) {
593a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    var strP = JSONSerialize($String(i), value, replacer, stack,
605c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             indent, gap);
615c838251403b0be9a882540f1922577abba4c872ager@chromium.org    if (IS_UNDEFINED(strP)) {
623a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      strP = "null";
635c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
643a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    partial.push(strP);
653a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
663a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var final;
673a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  if (gap == "") {
683a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    final = "[" + partial.join(",") + "]";
693a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else if (partial.length > 0) {
703a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    var separator = ",\n" + indent;
713a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    final = "[\n" + indent + partial.join(separator) + "\n" +
723a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        stepback + "]";
733a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else {
743a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    final = "[]";
753a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
763a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  stack.pop();
773a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  return final;
783a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
793a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
803a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction SerializeObject(value, replacer, stack, indent, gap) {
815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (!%PushIfAbsent(stack, value)) {
828f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    throw MakeTypeError('circular_structure', $Array());
835c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
843a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var stepback = indent;
853a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  indent += gap;
868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  var partial = new InternalArray();
873a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  if (IS_ARRAY(replacer)) {
883a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    var length = replacer.length;
893a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    for (var i = 0; i < length; i++) {
907a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org      if (%_CallFunction(replacer, i, ObjectHasOwnProperty)) {
913a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        var p = replacer[i];
923a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
933a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        if (!IS_UNDEFINED(strP)) {
94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          var member = %QuoteJSONString(p) + ":";
953a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          if (gap != "") member += " ";
963a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          member += strP;
973a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          partial.push(member);
983a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        }
993a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      }
1003a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    }
1013a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else {
1023a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    for (var p in value) {
1037a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org      if (%_CallFunction(value, p, ObjectHasOwnProperty)) {
1043a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
1053a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        if (!IS_UNDEFINED(strP)) {
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          var member = %QuoteJSONString(p) + ":";
1073a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          if (gap != "") member += " ";
1083a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          member += strP;
1093a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org          partial.push(member);
1103a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        }
1113a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org      }
1123a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    }
1133a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
1143a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var final;
1153a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  if (gap == "") {
1163a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    final = "{" + partial.join(",") + "}";
1173a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else if (partial.length > 0) {
1183a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    var separator = ",\n" + indent;
1193a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    final = "{\n" + indent + partial.join(separator) + "\n" +
1203a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        stepback + "}";
1213a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else {
1223a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    final = "{}";
1233a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
1243a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  stack.pop();
1253a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  return final;
1263a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
1273a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
1283a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction JSONSerialize(key, holder, replacer, stack, indent, gap) {
1293a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var value = holder[key];
1305f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (IS_SPEC_OBJECT(value)) {
1313a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    var toJSON = value.toJSON;
13234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    if (IS_SPEC_FUNCTION(toJSON)) {
1335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      value = %_CallFunction(value, key, toJSON);
1345c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
1353a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
13634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (IS_SPEC_FUNCTION(replacer)) {
1375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    value = %_CallFunction(holder, key, value, replacer);
1385c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
1395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (IS_STRING(value)) {
1405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    return %QuoteJSONString(value);
1415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else if (IS_NUMBER(value)) {
142d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    return JSON_NUMBER_TO_STRING(value);
1435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else if (IS_BOOLEAN(value)) {
1445f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    return value ? "true" : "false";
1455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else if (IS_NULL(value)) {
1465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    return "null";
1475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } else if (IS_SPEC_OBJECT(value) && !(typeof value == "function")) {
1485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // Non-callable object. If it's a primitive wrapper, it must be unwrapped.
1495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    if (IS_ARRAY(value)) {
1505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      return SerializeArray(value, replacer, stack, indent, gap);
1515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    } else if (IS_NUMBER_WRAPPER(value)) {
1525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      value = ToNumber(value);
153d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org      return JSON_NUMBER_TO_STRING(value);
1543a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    } else if (IS_STRING_WRAPPER(value)) {
1555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      return %QuoteJSONString(ToString(value));
1565c838251403b0be9a882540f1922577abba4c872ager@chromium.org    } else if (IS_BOOLEAN_WRAPPER(value)) {
1575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      return %_ValueOf(value) ? "true" : "false";
1585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    } else {
1595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      return SerializeObject(value, replacer, stack, indent, gap);
1603a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    }
1613a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
1625f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Undefined or a callable object.
163690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org  return UNDEFINED;
1643a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
1653a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1673a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgfunction JSONStringify(value, replacer, space) {
1685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  if (%_ArgumentsLength() == 1) {
169e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    return %BasicJSONStringify(value);
170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1713a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  if (IS_OBJECT(space)) {
1723a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    // Unwrap 'space' if it is wrapped
1733a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    if (IS_NUMBER_WRAPPER(space)) {
1745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      space = ToNumber(space);
1753a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    } else if (IS_STRING_WRAPPER(space)) {
1765f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      space = ToString(space);
1773a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    }
1783a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
1793a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  var gap;
1803a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  if (IS_NUMBER(space)) {
1815f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    space = MathMax(0, MathMin(ToInteger(space), 10));
1822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    gap = %_SubString("          ", 0, space);
1833a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else if (IS_STRING(space)) {
1845c838251403b0be9a882540f1922577abba4c872ager@chromium.org    if (space.length > 10) {
1852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      gap = %_SubString(space, 0, 10);
1865c838251403b0be9a882540f1922577abba4c872ager@chromium.org    } else {
1875c838251403b0be9a882540f1922577abba4c872ager@chromium.org      gap = space;
1885c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
1893a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  } else {
1903a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    gap = "";
1913a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  }
192f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (IS_ARRAY(replacer)) {
193f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // Deduplicate replacer array items.
194f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    var property_list = new InternalArray();
19550bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org    var seen_properties = { __proto__: null };
19650bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org    var seen_sentinel = {};
197f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    var length = replacer.length;
198f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    for (var i = 0; i < length; i++) {
199f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      var item = replacer[i];
20050bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org      if (IS_STRING_WRAPPER(item)) {
20150bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org        item = ToString(item);
20250bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org      } else {
20350bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org        if (IS_NUMBER_WRAPPER(item)) item = ToNumber(item);
20450bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org        if (IS_NUMBER(item)) item = %_NumberToString(item);
20550bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org      }
20650bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org      if (IS_STRING(item) && seen_properties[item] != seen_sentinel) {
207f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        property_list.push(item);
20850bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org        // We cannot use true here because __proto__ needs to be an object.
20950bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org        seen_properties[item] = seen_sentinel;
210f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      }
211f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
212f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    replacer = property_list;
213f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
2148f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  return JSONSerialize('', {'': value}, replacer, new InternalArray(), "", gap);
2153a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
2163a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
217e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
218e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// -------------------------------------------------------------------
219e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2201805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgfunction SetUpJSON() {
2211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  %CheckIsBootstrapping();
222e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
223e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Set up non-enumerable properties of the JSON object.
2243a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  InstallFunctions($JSON, DONT_ENUM, $Array(
2253a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    "parse", JSONParse,
2263a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    "stringify", JSONStringify
2273a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  ));
2283a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org}
2293a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org
230e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgSetUpJSON();
231e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
232e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
233e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// -------------------------------------------------------------------
234e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// JSON Builtins
235e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
236e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgfunction JSONSerializeAdapter(key, object) {
237e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  var holder = {};
238e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  holder[key] = object;
239e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // No need to pass the actual holder since there is no replacer function.
240690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org  return JSONSerialize(key, holder, UNDEFINED, new InternalArray(), "", "");
241e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
242