Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: src/json-stringifier.h

Issue 11271021: Correctly check for stack limit in JSON.stringify. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/common.gypi ('k') | test/mjsunit/json-recursive.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « build/common.gypi ('k') | test/mjsunit/json-recursive.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698