OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 27 matching lines...) Expand all Loading... |
38 class BasicJsonStringifier BASE_EMBEDDED { | 38 class BasicJsonStringifier BASE_EMBEDDED { |
39 public: | 39 public: |
40 explicit BasicJsonStringifier(Isolate* isolate); | 40 explicit BasicJsonStringifier(Isolate* isolate); |
41 | 41 |
42 MaybeObject* Stringify(Handle<Object> object); | 42 MaybeObject* Stringify(Handle<Object> object); |
43 | 43 |
44 private: | 44 private: |
45 static const int kInitialPartLength = 32; | 45 static const int kInitialPartLength = 32; |
46 static const int kMaxPartLength = 16 * 1024; | 46 static const int kMaxPartLength = 16 * 1024; |
47 static const int kPartLengthGrowthFactor = 2; | 47 static const int kPartLengthGrowthFactor = 2; |
48 static const int kStackLimit = 4 * 1024; | |
49 | 48 |
50 enum Result { UNCHANGED, SUCCESS, BAILOUT, CIRCULAR, STACK_OVERFLOW }; | 49 enum Result { UNCHANGED, SUCCESS, BAILOUT, CIRCULAR, STACK_OVERFLOW }; |
51 | 50 |
52 template <bool is_ascii> void Extend(); | 51 template <bool is_ascii> void Extend(); |
53 | 52 |
54 void ChangeEncoding(); | 53 void ChangeEncoding(); |
55 | 54 |
56 void ShrinkCurrentPart(); | 55 void ShrinkCurrentPart(); |
57 | 56 |
58 template <bool is_ascii, typename Char> | 57 template <bool is_ascii, typename Char> |
(...skipping 11 matching lines...) Expand all Loading... |
70 } | 69 } |
71 | 70 |
72 INLINE(void Append(const char* chars)) { | 71 INLINE(void Append(const char* chars)) { |
73 if (is_ascii_) { | 72 if (is_ascii_) { |
74 Append_<true>(chars); | 73 Append_<true>(chars); |
75 } else { | 74 } else { |
76 Append_<false>(chars); | 75 Append_<false>(chars); |
77 } | 76 } |
78 } | 77 } |
79 | 78 |
80 INLINE(Handle<Object> GetProperty(Handle<JSObject> object, | 79 Handle<Object> GetProperty(Handle<JSObject> object, |
81 Handle<String> key)); | 80 Handle<String> key); |
82 | 81 |
83 INLINE(bool MayHaveToJsonFunction(Handle<JSObject> object)); | 82 bool MayHaveToJsonFunction(Handle<JSObject> object); |
84 | 83 |
85 INLINE(Result Serialize(Handle<Object> object)) { | 84 INLINE(Result Serialize(Handle<Object> object)) { |
86 return Serialize_<false>(object); | 85 return Serialize_<false>(object); |
87 } | 86 } |
88 | 87 |
89 INLINE(Result SerializeDeferred(Handle<Object> object, | 88 INLINE(Result SerializeDeferred(Handle<Object> object, |
90 bool deferred_comma, | 89 bool deferred_comma, |
91 Handle<String> deferred_key)) { | 90 Handle<String> deferred_key)) { |
92 ASSERT(!deferred_key.is_null()); | 91 ASSERT(!deferred_key.is_null()); |
93 return Serialize_<true>(object, deferred_comma, deferred_key); | 92 return Serialize_<true>(object, deferred_comma, deferred_key); |
94 } | 93 } |
95 | 94 |
96 template <bool deferred_key> | 95 template <bool deferred_key> |
97 Result Serialize_(Handle<Object> object, | 96 Result Serialize_(Handle<Object> object, |
98 bool comma = false, | 97 bool comma = false, |
99 Handle<String> key = Handle<String>::null()); | 98 Handle<String> key = Handle<String>::null()); |
100 | 99 |
101 INLINE(void SerializeDeferredKey(bool deferred_comma, | 100 void SerializeDeferredKey(bool deferred_comma, Handle<String> deferred_key) { |
102 Handle<String> deferred_key)) { | |
103 if (deferred_comma) Append(','); | 101 if (deferred_comma) Append(','); |
104 SerializeString(deferred_key); | 102 SerializeString(deferred_key); |
105 Append(':'); | 103 Append(':'); |
106 } | 104 } |
107 | 105 |
108 INLINE(Result SerializeSmi(Smi* object)); | 106 Result SerializeSmi(Smi* object); |
109 | 107 |
110 INLINE(Result SerializeDouble(double number)); | 108 Result SerializeDouble(double number); |
111 INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) { | 109 INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) { |
112 return SerializeDouble(object->value()); | 110 return SerializeDouble(object->value()); |
113 } | 111 } |
114 | 112 |
115 Result SerializeArray(Handle<JSArray> object); | 113 INLINE(Result SerializeArray(Handle<JSArray> object)); |
116 Result SerializeObject(Handle<JSObject> object); | 114 INLINE(Result SerializeObject(Handle<JSObject> object)); |
117 | 115 |
118 void SerializeString(Handle<String> object); | 116 void SerializeString(Handle<String> object); |
119 | 117 |
120 template <typename SrcChar, typename DestChar> | 118 template <typename SrcChar, typename DestChar> |
121 INLINE(void SerializeStringUnchecked_(const SrcChar* src, | 119 INLINE(void SerializeStringUnchecked_(const SrcChar* src, |
122 DestChar* dest, | 120 DestChar* dest, |
123 int length)); | 121 int length)); |
124 | 122 |
125 template <bool is_ascii, typename Char> | 123 template <bool is_ascii, typename Char> |
126 INLINE(void SerializeString_(Vector<const Char> vector, | 124 INLINE(void SerializeString_(Vector<const Char> vector, |
127 Handle<String> string)); | 125 Handle<String> string)); |
128 | 126 |
129 template <typename Char> | 127 template <typename Char> |
130 INLINE(bool DoNotEscape(Char c)); | 128 INLINE(bool DoNotEscape(Char c)); |
131 | 129 |
132 template <typename Char> | 130 template <typename Char> |
133 INLINE(Vector<const Char> GetCharVector(Handle<String> string)); | 131 INLINE(Vector<const Char> GetCharVector(Handle<String> string)); |
134 | 132 |
135 INLINE(Result StackPush(Handle<Object> object)); | 133 Result StackPush(Handle<Object> object); |
136 INLINE(void StackPop()); | 134 void StackPop(); |
137 | 135 |
138 INLINE(Handle<String> accumulator()) { | 136 INLINE(Handle<String> accumulator()) { |
139 return Handle<String>(String::cast(accumulator_store_->value())); | 137 return Handle<String>(String::cast(accumulator_store_->value())); |
140 } | 138 } |
141 | 139 |
142 INLINE(void set_accumulator(Handle<String> string)) { | 140 INLINE(void set_accumulator(Handle<String> string)) { |
143 return accumulator_store_->set_value(*string); | 141 return accumulator_store_->set_value(*string); |
144 } | 142 } |
145 | 143 |
146 Isolate* isolate_; | 144 Isolate* isolate_; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 default: | 289 default: |
292 return true; | 290 return true; |
293 } | 291 } |
294 ASSERT(!value->IsTheHole()); | 292 ASSERT(!value->IsTheHole()); |
295 return value->IsSpecFunction(); | 293 return value->IsSpecFunction(); |
296 } | 294 } |
297 | 295 |
298 | 296 |
299 BasicJsonStringifier::Result BasicJsonStringifier::StackPush( | 297 BasicJsonStringifier::Result BasicJsonStringifier::StackPush( |
300 Handle<Object> object) { | 298 Handle<Object> object) { |
| 299 StackLimitCheck check(isolate_); |
| 300 if (check.HasOverflowed()) return STACK_OVERFLOW; |
| 301 |
301 int length = Smi::cast(stack_->length())->value(); | 302 int length = Smi::cast(stack_->length())->value(); |
302 if (length > kStackLimit) return STACK_OVERFLOW; | |
303 FixedArray* elements = FixedArray::cast(stack_->elements()); | 303 FixedArray* elements = FixedArray::cast(stack_->elements()); |
304 for (int i = 0; i < length; i++) { | 304 for (int i = 0; i < length; i++) { |
305 if (elements->get(i) == *object) { | 305 if (elements->get(i) == *object) { |
306 return CIRCULAR; | 306 return CIRCULAR; |
307 } | 307 } |
308 } | 308 } |
309 stack_->EnsureSize(length + 1); | 309 stack_->EnsureSize(length + 1); |
310 FixedArray::cast(stack_->elements())->set(length, *object); | 310 FixedArray::cast(stack_->elements())->set(length, *object); |
311 stack_->set_length(Smi::FromInt(length + 1)); | 311 stack_->set_length(Smi::FromInt(length + 1)); |
312 return SUCCESS; | 312 return SUCCESS; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 Handle<JSObject> object) { | 466 Handle<JSObject> object) { |
467 HandleScope handle_scope(isolate_); | 467 HandleScope handle_scope(isolate_); |
468 Result stack_push = StackPush(object); | 468 Result stack_push = StackPush(object); |
469 if (stack_push != SUCCESS) return stack_push; | 469 if (stack_push != SUCCESS) return stack_push; |
470 if (object->IsJSGlobalProxy()) return BAILOUT; | 470 if (object->IsJSGlobalProxy()) return BAILOUT; |
471 bool threw = false; | 471 bool threw = false; |
472 Handle<FixedArray> contents = | 472 Handle<FixedArray> contents = |
473 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); | 473 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); |
474 if (threw) return BAILOUT; | 474 if (threw) return BAILOUT; |
475 Append('{'); | 475 Append('{'); |
476 int length = contents->length(); | |
477 bool comma = false; | 476 bool comma = false; |
478 for (int i = 0; i < length; i++) { | 477 for (int i = 0; i < contents->length(); i++) { |
479 Object* key = contents->get(i); | 478 Object* key = contents->get(i); |
480 Handle<String> key_handle; | 479 Handle<String> key_handle; |
481 Handle<Object> property; | 480 Handle<Object> property; |
482 if (key->IsString()) { | 481 if (key->IsString()) { |
483 key_handle = Handle<String>(String::cast(key)); | 482 key_handle = Handle<String>(String::cast(key)); |
484 property = GetProperty(object, key_handle); | 483 property = GetProperty(object, key_handle); |
485 } else { | 484 } else { |
486 ASSERT(key->IsNumber()); | 485 ASSERT(key->IsNumber()); |
487 key_handle = isolate_->factory()->NumberToString(Handle<Object>(key)); | 486 key_handle = isolate_->factory()->NumberToString(Handle<Object>(key)); |
488 uint32_t index; | 487 uint32_t index; |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 SerializeString_<false, char>(flat.ToAsciiVector(), object); | 677 SerializeString_<false, char>(flat.ToAsciiVector(), object); |
679 } else { | 678 } else { |
680 SerializeString_<false, uc16>(flat.ToUC16Vector(), object); | 679 SerializeString_<false, uc16>(flat.ToUC16Vector(), object); |
681 } | 680 } |
682 } | 681 } |
683 } | 682 } |
684 | 683 |
685 } } // namespace v8::internal | 684 } } // namespace v8::internal |
686 | 685 |
687 #endif // V8_JSON_STRINGIFIER_H_ | 686 #endif // V8_JSON_STRINGIFIER_H_ |
OLD | NEW |