172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// Redistribution and use in source and binary forms, with or without
372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// modification, are permitted provided that the following conditions are
472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// met:
572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//
672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//     * Redistributions of source code must retain the above copyright
772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//       notice, this list of conditions and the following disclaimer.
872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//     * Redistributions in binary form must reproduce the above
972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//       copyright notice, this list of conditions and the following
1072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//       disclaimer in the documentation and/or other materials provided
1172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//       with the distribution.
1272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//     * Neither the name of Google Inc. nor the names of its
1372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//       contributors may be used to endorse or promote products derived
1472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//       from this software without specific prior written permission.
1572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org//
1672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
2872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org#ifndef V8_JSON_STRINGIFIER_H_
2972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org#define V8_JSON_STRINGIFIER_H_
3072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
3172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org#include "v8.h"
3272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org#include "v8utils.h"
3372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org#include "v8conversions.h"
3472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
3572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgnamespace v8 {
3672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgnamespace internal {
3772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
3872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgclass BasicJsonStringifier BASE_EMBEDDED {
3972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org public:
4072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  explicit BasicJsonStringifier(Isolate* isolate);
4172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
4272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  MaybeObject* Stringify(Handle<Object> object);
4372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
44f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  INLINE(static MaybeObject* StringifyString(Isolate* isolate,
45f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                             Handle<String> object));
46f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
4772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org private:
4872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  static const int kInitialPartLength = 32;
4972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  static const int kMaxPartLength = 16 * 1024;
5072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  static const int kPartLengthGrowthFactor = 2;
5172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
52e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW };
5372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
54e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void Extend();
5572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
5672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  void ChangeEncoding();
5772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
58f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  INLINE(void ShrinkCurrentPart());
5972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
6072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  template <bool is_ascii, typename Char>
6172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  INLINE(void Append_(Char c));
6272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
6372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  template <bool is_ascii, typename Char>
6472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  INLINE(void Append_(const Char* chars));
6572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
6659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  INLINE(void Append(uint8_t c)) {
6772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (is_ascii_) {
6872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      Append_<true>(c);
6972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    } else {
7072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      Append_<false>(c);
7172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
7272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
7372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
7459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  INLINE(void AppendAscii(const char* chars)) {
7572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (is_ascii_) {
7659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Append_<true>(reinterpret_cast<const uint8_t*>(chars));
7772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    } else {
7859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Append_<false>(reinterpret_cast<const uint8_t*>(chars));
7972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
8072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
8172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
82e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Handle<Object> ApplyToJsonFunction(Handle<Object> object,
83e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                                     Handle<Object> key);
8472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
85e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Result SerializeGeneric(Handle<Object> object,
86e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                          Handle<Object> key,
87e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                          bool deferred_comma,
88e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                          bool deferred_key);
89e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
90f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  template <typename ResultType, typename Char>
91f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  INLINE(static MaybeObject* StringifyString_(Isolate* isolate,
92f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                              Vector<Char> vector,
93f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                              Handle<String> result));
94f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
95e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Entry point to serialize the object.
96e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  INLINE(Result SerializeObject(Handle<Object> obj)) {
97e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    return Serialize_<false>(obj, false, factory_->empty_string());
98e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
99e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
100e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Serialize an array element.
101e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // The index may serve as argument for the toJSON function.
10209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  INLINE(Result SerializeElement(Isolate* isolate,
10309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                 Handle<Object> object,
10409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                 int i)) {
10509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    return Serialize_<false>(object,
10609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             false,
10709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             Handle<Object>(Smi::FromInt(i), isolate));
10872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
10972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
110e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Serialize a object property.
111e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // The key may or may not be serialized depending on the property.
112e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // The key may also serve as argument for the toJSON function.
113e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  INLINE(Result SerializeProperty(Handle<Object> object,
114e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                                  bool deferred_comma,
115e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                                  Handle<String> deferred_key)) {
11672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    ASSERT(!deferred_key.is_null());
11772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    return Serialize_<true>(object, deferred_comma, deferred_key);
11872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
11972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
120e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  template <bool deferred_string_key>
121e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Result Serialize_(Handle<Object> object, bool comma, Handle<Object> key);
12272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
123e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void SerializeDeferredKey(bool deferred_comma, Handle<Object> deferred_key) {
12472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (deferred_comma) Append(',');
125e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    SerializeString(Handle<String>::cast(deferred_key));
12672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    Append(':');
12772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
12872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
12972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Result SerializeSmi(Smi* object);
13072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
13172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Result SerializeDouble(double number);
13272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) {
13372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    return SerializeDouble(object->value());
13472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
13572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
136e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Result SerializeJSValue(Handle<JSValue> object);
137e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
138e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  INLINE(Result SerializeJSArray(Handle<JSArray> object));
139e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  INLINE(Result SerializeJSObject(Handle<JSObject> object));
140e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
141e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Result SerializeJSArraySlow(Handle<JSArray> object, int length);
14272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
14372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  void SerializeString(Handle<String> object);
14472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
14572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  template <typename SrcChar, typename DestChar>
146f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  INLINE(static int SerializeStringUnchecked_(const SrcChar* src,
147f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                              DestChar* dest,
148f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                              int length));
14972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
15072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  template <bool is_ascii, typename Char>
15149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  INLINE(void SerializeString_(Handle<String> string));
15272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
15372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  template <typename Char>
154f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  INLINE(static bool DoNotEscape(Char c));
15572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
15672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  template <typename Char>
157f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  INLINE(static Vector<const Char> GetCharVector(Handle<String> string));
15872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
15972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Result StackPush(Handle<Object> object);
16072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  void StackPop();
16172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
16272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  INLINE(Handle<String> accumulator()) {
163e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    return Handle<String>(String::cast(accumulator_store_->value()), isolate_);
16472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
16572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
16672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  INLINE(void set_accumulator(Handle<String> string)) {
16772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    return accumulator_store_->set_value(*string);
16872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
16972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
17072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Isolate* isolate_;
171e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Factory* factory_;
17272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  // We use a value wrapper for the string accumulator to keep the
17372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  // (indirect) handle to it in the outermost handle scope.
17472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Handle<JSValue> accumulator_store_;
17572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Handle<String> current_part_;
1764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> tojson_string_;
17772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Handle<JSArray> stack_;
17872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  int current_index_;
17972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  int part_length_;
18072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  bool is_ascii_;
18172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
18272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  static const int kJsonEscapeTableEntrySize = 8;
18372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  static const char* const JsonEscapeTable;
18472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org};
18572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
18672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
18772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// Translation table to escape ASCII characters.
18872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// Table entries start at a multiple of 8 and are null-terminated.
18972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgconst char* const BasicJsonStringifier::JsonEscapeTable =
19072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\u0000\0 \\u0001\0 \\u0002\0 \\u0003\0 "
19172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\u0004\0 \\u0005\0 \\u0006\0 \\u0007\0 "
19272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\b\0     \\t\0     \\n\0     \\u000b\0 "
19372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\f\0     \\r\0     \\u000e\0 \\u000f\0 "
19472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\u0010\0 \\u0011\0 \\u0012\0 \\u0013\0 "
19572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\u0014\0 \\u0015\0 \\u0016\0 \\u0017\0 "
19672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\u0018\0 \\u0019\0 \\u001a\0 \\u001b\0 "
19772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\u001c\0 \\u001d\0 \\u001e\0 \\u001f\0 "
19872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    " \0      !\0      \\\"\0     #\0      "
19972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "$\0      %\0      &\0      '\0      "
20072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "(\0      )\0      *\0      +\0      "
20172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    ",\0      -\0      .\0      /\0      "
20272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "0\0      1\0      2\0      3\0      "
20372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "4\0      5\0      6\0      7\0      "
20472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "8\0      9\0      :\0      ;\0      "
20572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "<\0      =\0      >\0      ?\0      "
20672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "@\0      A\0      B\0      C\0      "
20772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "D\0      E\0      F\0      G\0      "
20872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "H\0      I\0      J\0      K\0      "
20972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "L\0      M\0      N\0      O\0      "
21072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "P\0      Q\0      R\0      S\0      "
21172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "T\0      U\0      V\0      W\0      "
21272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "X\0      Y\0      Z\0      [\0      "
21372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "\\\\\0     ]\0      ^\0      _\0      "
21472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "`\0      a\0      b\0      c\0      "
21572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "d\0      e\0      f\0      g\0      "
21672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "h\0      i\0      j\0      k\0      "
21772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "l\0      m\0      n\0      o\0      "
21872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "p\0      q\0      r\0      s\0      "
21972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "t\0      u\0      v\0      w\0      "
22072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    "x\0      y\0      z\0      {\0      "
2217c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "|\0      }\0      ~\0      \177\0      "
2227c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\200\0      \201\0      \202\0      \203\0      "
2237c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\204\0      \205\0      \206\0      \207\0      "
2247c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\210\0      \211\0      \212\0      \213\0      "
2257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\214\0      \215\0      \216\0      \217\0      "
2267c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\220\0      \221\0      \222\0      \223\0      "
2277c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\224\0      \225\0      \226\0      \227\0      "
2287c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\230\0      \231\0      \232\0      \233\0      "
2297c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\234\0      \235\0      \236\0      \237\0      "
2307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\240\0      \241\0      \242\0      \243\0      "
2317c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\244\0      \245\0      \246\0      \247\0      "
2327c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\250\0      \251\0      \252\0      \253\0      "
2337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\254\0      \255\0      \256\0      \257\0      "
2347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\260\0      \261\0      \262\0      \263\0      "
2357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\264\0      \265\0      \266\0      \267\0      "
2367c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\270\0      \271\0      \272\0      \273\0      "
2377c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\274\0      \275\0      \276\0      \277\0      "
2387c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\300\0      \301\0      \302\0      \303\0      "
2397c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\304\0      \305\0      \306\0      \307\0      "
2407c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\310\0      \311\0      \312\0      \313\0      "
2417c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\314\0      \315\0      \316\0      \317\0      "
2427c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\320\0      \321\0      \322\0      \323\0      "
2437c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\324\0      \325\0      \326\0      \327\0      "
2447c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\330\0      \331\0      \332\0      \333\0      "
2457c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\334\0      \335\0      \336\0      \337\0      "
2467c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\340\0      \341\0      \342\0      \343\0      "
2477c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\344\0      \345\0      \346\0      \347\0      "
2487c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\350\0      \351\0      \352\0      \353\0      "
2497c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\354\0      \355\0      \356\0      \357\0      "
2507c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\360\0      \361\0      \362\0      \363\0      "
2517c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\364\0      \365\0      \366\0      \367\0      "
2527c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\370\0      \371\0      \372\0      \373\0      "
2537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    "\374\0      \375\0      \376\0      \377\0      ";
25472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
255f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
25672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgBasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
25772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    : isolate_(isolate), current_index_(0), is_ascii_(true) {
258e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  factory_ = isolate_->factory();
25972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  accumulator_store_ = Handle<JSValue>::cast(
260e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                           factory_->ToObject(factory_->empty_string()));
26172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  part_length_ = kInitialPartLength;
262f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  current_part_ = factory_->NewRawOneByteString(part_length_);
263f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  tojson_string_ = factory_->toJSON_string();
264e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  stack_ = factory_->NewJSArray(8);
26572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
26672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
26772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
26872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgMaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) {
269e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  switch (SerializeObject(object)) {
27072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    case UNCHANGED:
27172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      return isolate_->heap()->undefined_value();
272e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    case SUCCESS:
273e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      ShrinkCurrentPart();
274e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return *factory_->NewConsString(accumulator(), current_part_);
27572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    case CIRCULAR:
276e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return isolate_->Throw(*factory_->NewTypeError(
27772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org                 "circular_structure", HandleVector<Object>(NULL, 0)));
27872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    case STACK_OVERFLOW:
27972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      return isolate_->StackOverflow();
28072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    default:
281e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return Failure::Exception();
28272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
28372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
28472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
28572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
286f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgMaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
287f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                                   Handle<String> object) {
288f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  static const int kJsonQuoteWorstCaseBlowup = 6;
289f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  static const int kSpaceForQuotes = 2;
290f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int worst_case_length =
291f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
292f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
293f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (worst_case_length > 32 * KB) {  // Slow path if too large.
294f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    BasicJsonStringifier stringifier(isolate);
295f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return stringifier.Stringify(object);
296f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
297f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
298043355a99d9a79f9f03e6ad1f451d392356632c7yangguo@chromium.org  FlattenString(object);
29940ce96b9446ccab86d0d80ee90bb86a9cca33aa7mvstanton@chromium.org  ASSERT(object->IsFlat());
300043355a99d9a79f9f03e6ad1f451d392356632c7yangguo@chromium.org  if (object->IsOneByteRepresentationUnderneath()) {
30140ce96b9446ccab86d0d80ee90bb86a9cca33aa7mvstanton@chromium.org    Handle<String> result =
30240ce96b9446ccab86d0d80ee90bb86a9cca33aa7mvstanton@chromium.org        isolate->factory()->NewRawOneByteString(worst_case_length);
30379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
304f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return StringifyString_<SeqOneByteString>(
305f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        isolate,
306043355a99d9a79f9f03e6ad1f451d392356632c7yangguo@chromium.org        object->GetFlatContent().ToOneByteVector(),
30740ce96b9446ccab86d0d80ee90bb86a9cca33aa7mvstanton@chromium.org        result);
308f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else {
30940ce96b9446ccab86d0d80ee90bb86a9cca33aa7mvstanton@chromium.org    Handle<String> result =
31040ce96b9446ccab86d0d80ee90bb86a9cca33aa7mvstanton@chromium.org        isolate->factory()->NewRawTwoByteString(worst_case_length);
31179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
312f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return StringifyString_<SeqTwoByteString>(
313f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        isolate,
314043355a99d9a79f9f03e6ad1f451d392356632c7yangguo@chromium.org        object->GetFlatContent().ToUC16Vector(),
31540ce96b9446ccab86d0d80ee90bb86a9cca33aa7mvstanton@chromium.org        result);
316f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
317f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
318f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
319f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
320f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgtemplate <typename ResultType, typename Char>
321f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgMaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
322f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                                    Vector<Char> vector,
323f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                                    Handle<String> result) {
32479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
325f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int final_size = 0;
326f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ResultType* dest = ResultType::cast(*result);
327f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  dest->Set(final_size++, '\"');
328f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  final_size += SerializeStringUnchecked_(vector.start(),
329f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                          dest->GetChars() + 1,
330f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                          vector.length());
331f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  dest->Set(final_size++, '\"');
332f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return *SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
333f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
334f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
335f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
33672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgtemplate <bool is_ascii, typename Char>
33772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvoid BasicJsonStringifier::Append_(Char c) {
33872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (is_ascii) {
339fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    SeqOneByteString::cast(*current_part_)->SeqOneByteStringSet(
34072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        current_index_++, c);
34172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  } else {
34272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet(
34372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        current_index_++, c);
34472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
345e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (current_index_ == part_length_) Extend();
34672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
34772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
34872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
34972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgtemplate <bool is_ascii, typename Char>
35072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvoid BasicJsonStringifier::Append_(const Char* chars) {
35172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars);
35272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
35372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
35472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
355e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgHandle<Object> BasicJsonStringifier::ApplyToJsonFunction(
356e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<Object> object, Handle<Object> key) {
35772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  LookupResult lookup(isolate_);
3584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  JSObject::cast(*object)->LookupRealNamedProperty(*tojson_string_, &lookup);
359e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (!lookup.IsProperty()) return object;
360e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  PropertyAttributes attr;
361e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Handle<Object> fun =
3624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      Object::GetProperty(object, object, &lookup, tojson_string_, &attr);
3633c660e485ea372d1076aecdcece69842563d6adfjkummerow@chromium.org  if (fun.is_null()) return Handle<Object>::null();
364e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (!fun->IsJSFunction()) return object;
365e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
366e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Call toJSON function.
367e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (key->IsSmi()) key = factory_->NumberToString(key);
368e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Handle<Object> argv[] = { key };
369e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  bool has_exception = false;
370e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  HandleScope scope(isolate_);
3712c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  object = Execution::Call(isolate_, fun, object, 1, argv, &has_exception);
372e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Return empty handle to signal an exception.
373e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (has_exception) return Handle<Object>::null();
374e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  return scope.CloseAndEscape(object);
37572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
37672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
37772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
37872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::StackPush(
37972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    Handle<Object> object) {
38072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  StackLimitCheck check(isolate_);
38172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (check.HasOverflowed()) return STACK_OVERFLOW;
38272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
38372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  int length = Smi::cast(stack_->length())->value();
38472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  FixedArray* elements = FixedArray::cast(stack_->elements());
38572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  for (int i = 0; i < length; i++) {
38672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (elements->get(i) == *object) {
38772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      return CIRCULAR;
38872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
38972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
39072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  stack_->EnsureSize(length + 1);
39172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  FixedArray::cast(stack_->elements())->set(length, *object);
39272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  stack_->set_length(Smi::FromInt(length + 1));
39372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return SUCCESS;
39472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
39572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
39672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
39772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvoid BasicJsonStringifier::StackPop() {
39872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  int length = Smi::cast(stack_->length())->value();
39972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  stack_->set_length(Smi::FromInt(length - 1));
40072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
40172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
40272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
403e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgtemplate <bool deferred_string_key>
40472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::Serialize_(
405e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<Object> object, bool comma, Handle<Object> key) {
40672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (object->IsJSObject()) {
407e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    object = ApplyToJsonFunction(object, key);
408e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (object.is_null()) return EXCEPTION;
40972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
41072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
411e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (object->IsSmi()) {
412e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (deferred_string_key) SerializeDeferredKey(comma, key);
41372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    return SerializeSmi(Smi::cast(*object));
414e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
415e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
416e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  switch (HeapObject::cast(*object)->map()->instance_type()) {
417e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    case HEAP_NUMBER_TYPE:
418e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (deferred_string_key) SerializeDeferredKey(comma, key);
419e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return SerializeHeapNumber(Handle<HeapNumber>::cast(object));
420e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    case ODDBALL_TYPE:
421e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      switch (Oddball::cast(*object)->kind()) {
422e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        case Oddball::kFalse:
423e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          if (deferred_string_key) SerializeDeferredKey(comma, key);
42459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          AppendAscii("false");
425e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          return SUCCESS;
426e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        case Oddball::kTrue:
427e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          if (deferred_string_key) SerializeDeferredKey(comma, key);
42859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          AppendAscii("true");
429e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          return SUCCESS;
430e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        case Oddball::kNull:
431e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          if (deferred_string_key) SerializeDeferredKey(comma, key);
43259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          AppendAscii("null");
433e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          return SUCCESS;
434e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        default:
435e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          return UNCHANGED;
436e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
437e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    case JS_ARRAY_TYPE:
438169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      if (object->IsAccessCheckNeeded()) break;
439e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (deferred_string_key) SerializeDeferredKey(comma, key);
440e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return SerializeJSArray(Handle<JSArray>::cast(object));
441e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    case JS_VALUE_TYPE:
442e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (deferred_string_key) SerializeDeferredKey(comma, key);
443e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return SerializeJSValue(Handle<JSValue>::cast(object));
444e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    case JS_FUNCTION_TYPE:
445e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return UNCHANGED;
446e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    default:
447e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (object->IsString()) {
448e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        if (deferred_string_key) SerializeDeferredKey(comma, key);
449e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        SerializeString(Handle<String>::cast(object));
45072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        return SUCCESS;
451e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      } else if (object->IsJSObject()) {
452169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        if (object->IsAccessCheckNeeded()) break;
453e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        if (deferred_string_key) SerializeDeferredKey(comma, key);
454e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        return SerializeJSObject(Handle<JSObject>::cast(object));
455e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
45672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
457169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
458169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return SerializeGeneric(object, key, comma, deferred_string_key);
459e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
46072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
461e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
462e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
463e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<Object> object,
464e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<Object> key,
465e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    bool deferred_comma,
466e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    bool deferred_key) {
467e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Handle<JSObject> builtins(isolate_->native_context()->builtins());
4688e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Handle<JSFunction> builtin =
4698e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      Handle<JSFunction>::cast(GetProperty(builtins, "JSONSerializeAdapter"));
470e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
471e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Handle<Object> argv[] = { key, object };
472e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  bool has_exception = false;
473e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Handle<Object> result =
4742c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org      Execution::Call(isolate_, builtin, object, 2, argv, &has_exception);
475e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (has_exception) return EXCEPTION;
476e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (result->IsUndefined()) return UNCHANGED;
477e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (deferred_key) {
478e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (key->IsSmi()) key = factory_->NumberToString(key);
479e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    SerializeDeferredKey(deferred_comma, key);
480e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
481e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
482e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Handle<String> result_string = Handle<String>::cast(result);
483e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Shrink current part, attach it to the accumulator, also attach the result
484e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // string to the accumulator, and allocate a new part.
485e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  ShrinkCurrentPart();  // Shrink.
486e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  part_length_ = kInitialPartLength;  // Allocate conservatively.
487e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Extend();             // Attach current part and allocate new part.
488e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Attach result string to the accumulator.
489e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  set_accumulator(factory_->NewConsString(accumulator(), result_string));
490e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  return SUCCESS;
491e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
492e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
493e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
494e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue(
495e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<JSValue> object) {
496e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  bool has_exception = false;
497e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  String* class_name = object->class_name();
4984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (class_name == isolate_->heap()->String_string()) {
499e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    Handle<Object> value =
500e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        Execution::ToString(isolate_, object, &has_exception);
501e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (has_exception) return EXCEPTION;
502e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    SerializeString(Handle<String>::cast(value));
5034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (class_name == isolate_->heap()->Number_string()) {
504e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    Handle<Object> value =
505e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        Execution::ToNumber(isolate_, object, &has_exception);
506e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (has_exception) return EXCEPTION;
507e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (value->IsSmi()) return SerializeSmi(Smi::cast(*value));
508e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    SerializeHeapNumber(Handle<HeapNumber>::cast(value));
509e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else {
5104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    ASSERT(class_name == isolate_->heap()->Boolean_string());
511e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Object* value = JSValue::cast(*object)->value();
512e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    ASSERT(value->IsBoolean());
51359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    AppendAscii(value->IsTrue() ? "true" : "false");
514e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
515e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  return SUCCESS;
51672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
51772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
51872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
51972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) {
52072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  static const int kBufferSize = 100;
52172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  char chars[kBufferSize];
52272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Vector<char> buffer(chars, kBufferSize);
52359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  AppendAscii(IntToCString(object->value(), buffer));
52472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return SUCCESS;
52572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
52672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
52772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
52872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::SerializeDouble(
52972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    double number) {
53077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isinf(number) || std::isnan(number)) {
53159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    AppendAscii("null");
53272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    return SUCCESS;
53372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
53472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  static const int kBufferSize = 100;
53572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  char chars[kBufferSize];
53672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Vector<char> buffer(chars, kBufferSize);
53759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  AppendAscii(DoubleToCString(number, buffer));
53872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return SUCCESS;
53972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
54072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
54172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
542e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
54372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    Handle<JSArray> object) {
54472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  HandleScope handle_scope(isolate_);
54572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Result stack_push = StackPush(object);
54672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (stack_push != SUCCESS) return stack_push;
54772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  int length = Smi::cast(object->length())->value();
54872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Append('[');
54972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  switch (object->GetElementsKind()) {
55072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    case FAST_SMI_ELEMENTS: {
551e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Handle<FixedArray> elements(
552e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          FixedArray::cast(object->elements()), isolate_);
55372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      for (int i = 0; i < length; i++) {
55472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        if (i > 0) Append(',');
55572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        SerializeSmi(Smi::cast(elements->get(i)));
55672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      }
55772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      break;
55872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
55972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    case FAST_DOUBLE_ELEMENTS: {
560e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Handle<FixedDoubleArray> elements(
561e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          FixedDoubleArray::cast(object->elements()), isolate_);
56272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      for (int i = 0; i < length; i++) {
56372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        if (i > 0) Append(',');
56472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        SerializeDouble(elements->get_scalar(i));
56572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      }
56672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      break;
56772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
56872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    case FAST_ELEMENTS: {
569e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Handle<FixedArray> elements(
570e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org          FixedArray::cast(object->elements()), isolate_);
57172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      for (int i = 0; i < length; i++) {
57272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        if (i > 0) Append(',');
573e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        Result result =
57409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org            SerializeElement(isolate_,
57509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             Handle<Object>(elements->get(i), isolate_),
57609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             i);
57772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        if (result == SUCCESS) continue;
57872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        if (result == UNCHANGED) {
57959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          AppendAscii("null");
58072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        } else {
58172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org          return result;
58272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        }
58372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      }
58472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      break;
58572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
586e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    // TODO(yangguo):  The FAST_HOLEY_* cases could be handled in a faster way.
587e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    // They resemble the non-holey cases except that a prototype chain lookup
588e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    // is necessary for holes.
589e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    default: {
590e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Result result = SerializeJSArraySlow(object, length);
591e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (result != SUCCESS) return result;
592e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      break;
593e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
59472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
59572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Append(']');
59672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  StackPop();
59772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  current_part_ = handle_scope.CloseAndEscape(current_part_);
59872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return SUCCESS;
59972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
60072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
60172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
602e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow(
603e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<JSArray> object, int length) {
604e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  for (int i = 0; i < length; i++) {
605e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (i > 0) Append(',');
6063d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Handle<Object> element = Object::GetElement(isolate_, object, i);
607c16e8281e6e3e3b57e157b62d5a1ca530e23e4bfdanno@chromium.org    RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, element, EXCEPTION);
608e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (element->IsUndefined()) {
60959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      AppendAscii("null");
610e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    } else {
6113d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      Result result = SerializeElement(isolate_, element, i);
612e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (result == SUCCESS) continue;
613e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (result == UNCHANGED) {
61459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        AppendAscii("null");
615e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      } else {
616e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        return result;
617e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
618e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
619e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
620e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  return SUCCESS;
621e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
622e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
623e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
624e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgBasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
62572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    Handle<JSObject> object) {
62672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  HandleScope handle_scope(isolate_);
62772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Result stack_push = StackPush(object);
62872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (stack_push != SUCCESS) return stack_push;
629e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (object->IsJSGlobalProxy()) {
630e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    object = Handle<JSObject>(
631e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                 JSObject::cast(object->GetPrototype()), isolate_);
632e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    ASSERT(object->IsGlobalObject());
633e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
634e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
63572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Append('{');
63672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  bool comma = false;
637e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
638e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (object->HasFastProperties() &&
639e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      !object->HasIndexedInterceptor() &&
640e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      !object->HasNamedInterceptor() &&
641e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      object->elements()->length() == 0) {
642e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<Map> map(object->map());
643e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
644750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      Handle<Name> name(map->instance_descriptors()->GetKey(i), isolate_);
645750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      // TODO(rossberg): Should this throw?
646750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      if (!name->IsString()) continue;
647750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      Handle<String> key = Handle<String>::cast(name);
648e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      PropertyDetails details = map->instance_descriptors()->GetDetails(i);
64979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      if (details.IsDontEnum()) continue;
650e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Handle<Object> property;
651e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (details.type() == FIELD && *map == object->map()) {
652e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        property = Handle<Object>(
65357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                       object->RawFastPropertyAt(
654e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                           map->instance_descriptors()->GetFieldIndex(i)),
655e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                       isolate_);
65672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      } else {
65709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        property = GetProperty(isolate_, object, key);
658e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        if (property.is_null()) return EXCEPTION;
659e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
660e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Result result = SerializeProperty(property, comma, key);
661e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (!comma && result == SUCCESS) comma = true;
662e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (result >= EXCEPTION) return result;
663e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
664e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else {
665e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    bool has_exception = false;
666e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    Handle<FixedArray> contents =
667e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        GetKeysInFixedArrayFor(object, LOCAL_ONLY, &has_exception);
668e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (has_exception) return EXCEPTION;
669e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
670e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    for (int i = 0; i < contents->length(); i++) {
671e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Object* key = contents->get(i);
672e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Handle<String> key_handle;
673e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Handle<Object> property;
674e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (key->IsString()) {
675e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        key_handle = Handle<String>(String::cast(key), isolate_);
67609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        property = GetProperty(isolate_, object, key_handle);
677e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      } else {
678e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        ASSERT(key->IsNumber());
679e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        key_handle = factory_->NumberToString(Handle<Object>(key, isolate_));
680e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        uint32_t index;
681e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        if (key->IsSmi()) {
6823d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org          property = Object::GetElement(
6833d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org              isolate_, object, Smi::cast(key)->value());
684e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        } else if (key_handle->AsArrayIndex(&index)) {
6853d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org          property = Object::GetElement(isolate_, object, index);
686e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        } else {
68709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org          property = GetProperty(isolate_, object, key_handle);
688e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        }
68972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      }
690e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (property.is_null()) return EXCEPTION;
691e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      Result result = SerializeProperty(property, comma, key_handle);
692e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (!comma && result == SUCCESS) comma = true;
693e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (result >= EXCEPTION) return result;
69472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
69572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
696e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
69772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  Append('}');
69872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  StackPop();
69972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  current_part_ = handle_scope.CloseAndEscape(current_part_);
70072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return SUCCESS;
70172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
70272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
70372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
70472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvoid BasicJsonStringifier::ShrinkCurrentPart() {
70572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  ASSERT(current_index_ < part_length_);
706f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  current_part_ = SeqString::Truncate(Handle<SeqString>::cast(current_part_),
707f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                      current_index_);
70872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
70972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
71072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
71172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvoid BasicJsonStringifier::Extend() {
712e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  set_accumulator(factory_->NewConsString(accumulator(), current_part_));
71372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
71472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    part_length_ *= kPartLengthGrowthFactor;
71572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
716e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (is_ascii_) {
717fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    current_part_ = factory_->NewRawOneByteString(part_length_);
71872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  } else {
719e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    current_part_ = factory_->NewRawTwoByteString(part_length_);
72072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
72172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  current_index_ = 0;
72272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
72372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
72472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
72572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvoid BasicJsonStringifier::ChangeEncoding() {
72672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  ShrinkCurrentPart();
727e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  set_accumulator(factory_->NewConsString(accumulator(), current_part_));
728e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  current_part_ = factory_->NewRawTwoByteString(part_length_);
72972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  current_index_ = 0;
73072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  is_ascii_ = false;
73172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
73272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
73372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
73472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgtemplate <typename SrcChar, typename DestChar>
735f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgint BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
736f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                                    DestChar* dest,
737f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                                    int length) {
73872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  DestChar* dest_start = dest;
73972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
74072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  // Assert that uc16 character is not truncated down to 8 bit.
74172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  // The <uc16, char> version of this method must not be called.
74272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  ASSERT(sizeof(*dest) >= sizeof(*src));
74372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
74472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  for (int i = 0; i < length; i++) {
74572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    SrcChar c = src[i];
74672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (DoNotEscape(c)) {
74772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      *(dest++) = static_cast<DestChar>(c);
74872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    } else {
749750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      const uint8_t* chars = reinterpret_cast<const uint8_t*>(
750750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org          &JsonEscapeTable[c * kJsonEscapeTableEntrySize]);
75172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      while (*chars != '\0') *(dest++) = *(chars++);
75272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
75372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
75472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
755f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return static_cast<int>(dest - dest_start);
75672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
75772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
75872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
75972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgtemplate <bool is_ascii, typename Char>
76049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgvoid BasicJsonStringifier::SerializeString_(Handle<String> string) {
76149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  int length = string->length();
762e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Append_<is_ascii, char>('"');
76372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  // We make a rough estimate to find out if the current string can be
76472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  // serialized without allocating a new string part. The worst case length of
765e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // an escaped character is 6.  Shifting the remainin string length right by 3
766e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // is a more pessimistic estimate, but faster to calculate.
767e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
768e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (((part_length_ - current_index_) >> 3) > length) {
76979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
77049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    Vector<const Char> vector = GetCharVector<Char>(string);
77172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    if (is_ascii) {
772f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      current_index_ += SerializeStringUnchecked_(
77372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org          vector.start(),
774f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          SeqOneByteString::cast(*current_part_)->GetChars() + current_index_,
77572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org          length);
77672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    } else {
777f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      current_index_ += SerializeStringUnchecked_(
77872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org          vector.start(),
779f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          SeqTwoByteString::cast(*current_part_)->GetChars() + current_index_,
78072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org          length);
78172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
78272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  } else {
783a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    String* string_location = NULL;
784a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    Vector<const Char> vector(NULL, 0);
78572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    for (int i = 0; i < length; i++) {
786a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      // If GC moved the string, we need to refresh the vector.
787a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      if (*string != string_location) {
78879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org        DisallowHeapAllocation no_gc;
789a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        // This does not actually prevent the string from being relocated later.
790a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        vector = GetCharVector<Char>(string);
791a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        string_location = *string;
792a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      }
79372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      Char c = vector[i];
79472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      if (DoNotEscape(c)) {
79572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org        Append_<is_ascii, Char>(c);
79672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      } else {
797750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        Append_<is_ascii, uint8_t>(reinterpret_cast<const uint8_t*>(
798750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org            &JsonEscapeTable[c * kJsonEscapeTableEntrySize]));
79972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      }
80072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
80172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
802e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
80359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Append_<is_ascii, uint8_t>('"');
80472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
80572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
80672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
8077c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgtemplate <>
8087c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgbool BasicJsonStringifier::DoNotEscape(uint8_t c) {
8097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  return c >= '#' && c <= '~' && c != '\\';
8107c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org}
8117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
8127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
8137c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgtemplate <>
8147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.orgbool BasicJsonStringifier::DoNotEscape(uint16_t c) {
8157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  return c >= '#' && c != '\\' && c != 0x7f;
81672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
81772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
81872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
81972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgtemplate <>
82059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgVector<const uint8_t> BasicJsonStringifier::GetCharVector(
82159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Handle<String> string) {
82272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  String::FlatContent flat = string->GetFlatContent();
82372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  ASSERT(flat.IsAscii());
82459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  return flat.ToOneByteVector();
82572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
82672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
82772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
82872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgtemplate <>
82972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgVector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
83072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  String::FlatContent flat = string->GetFlatContent();
83172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  ASSERT(flat.IsTwoByte());
83272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return flat.ToUC16Vector();
83372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
83472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
83572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
83672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgvoid BasicJsonStringifier::SerializeString(Handle<String> object) {
837a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  object = FlattenGetString(object);
83872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  if (is_ascii_) {
839c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    if (object->IsOneByteRepresentationUnderneath()) {
84059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      SerializeString_<true, uint8_t>(object);
84172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    } else {
84272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      ChangeEncoding();
84372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      SerializeString(object);
84472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
84572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  } else {
846c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    if (object->IsOneByteRepresentationUnderneath()) {
84759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      SerializeString_<false, uint8_t>(object);
84872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    } else {
84949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      SerializeString_<false, uc16>(object);
85072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org    }
85172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  }
85272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
85372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
85472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org} }  // namespace v8::internal
85572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
85672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org#endif  // V8_JSON_STRINGIFIER_H_
857