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 30 matching lines...) Expand all Loading... |
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 | 48 |
49 enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW }; | 49 enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW }; |
50 | 50 |
51 template <bool is_ascii> void Extend(); | 51 void Extend(); |
52 | 52 |
53 void ChangeEncoding(); | 53 void ChangeEncoding(); |
54 | 54 |
55 void ShrinkCurrentPart(); | 55 void ShrinkCurrentPart(); |
56 | 56 |
57 template <bool is_ascii, typename Char> | 57 template <bool is_ascii, typename Char> |
58 INLINE(void Append_(Char c)); | 58 INLINE(void Append_(Char c)); |
59 | 59 |
60 template <bool is_ascii, typename Char> | 60 template <bool is_ascii, typename Char> |
61 INLINE(void Append_(const Char* chars)); | 61 INLINE(void Append_(const Char* chars)); |
(...skipping 13 matching lines...) Expand all Loading... |
75 Append_<false>(chars); | 75 Append_<false>(chars); |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
79 Handle<Object> GetProperty(Handle<JSObject> object, | 79 Handle<Object> GetProperty(Handle<JSObject> object, |
80 Handle<String> key); | 80 Handle<String> key); |
81 | 81 |
82 Handle<Object> ApplyToJsonFunction(Handle<Object> object, | 82 Handle<Object> ApplyToJsonFunction(Handle<Object> object, |
83 Handle<Object> key); | 83 Handle<Object> key); |
84 | 84 |
| 85 Result SerializeGeneric(Handle<Object> object, |
| 86 Handle<Object> key, |
| 87 bool deferred_comma, |
| 88 bool deferred_key); |
| 89 |
85 // Entry point to serialize the object. | 90 // Entry point to serialize the object. |
86 INLINE(Result SerializeObject(Handle<Object> obj)) { | 91 INLINE(Result SerializeObject(Handle<Object> obj)) { |
87 return Serialize_<false>(obj, false, isolate_->factory()->empty_string()); | 92 return Serialize_<false>(obj, false, factory_->empty_string()); |
88 } | 93 } |
89 | 94 |
90 // Serialize an array element. | 95 // Serialize an array element. |
91 // The index may serve as argument for the toJSON function. | 96 // The index may serve as argument for the toJSON function. |
92 INLINE(Result SerializeElement(Handle<Object> object, int i)) { | 97 INLINE(Result SerializeElement(Handle<Object> object, int i)) { |
93 return Serialize_<false>(object, false, Handle<Object>(Smi::FromInt(i))); | 98 return Serialize_<false>(object, false, Handle<Object>(Smi::FromInt(i))); |
94 } | 99 } |
95 | 100 |
96 // Serialize a object property. | 101 // Serialize a object property. |
97 // The key may or may not be serialized depending on the property. | 102 // The key may or may not be serialized depending on the property. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 template <typename Char> | 145 template <typename Char> |
141 INLINE(bool DoNotEscape(Char c)); | 146 INLINE(bool DoNotEscape(Char c)); |
142 | 147 |
143 template <typename Char> | 148 template <typename Char> |
144 INLINE(Vector<const Char> GetCharVector(Handle<String> string)); | 149 INLINE(Vector<const Char> GetCharVector(Handle<String> string)); |
145 | 150 |
146 Result StackPush(Handle<Object> object); | 151 Result StackPush(Handle<Object> object); |
147 void StackPop(); | 152 void StackPop(); |
148 | 153 |
149 INLINE(Handle<String> accumulator()) { | 154 INLINE(Handle<String> accumulator()) { |
150 return Handle<String>(String::cast(accumulator_store_->value())); | 155 return Handle<String>(String::cast(accumulator_store_->value()), isolate_); |
151 } | 156 } |
152 | 157 |
153 INLINE(void set_accumulator(Handle<String> string)) { | 158 INLINE(void set_accumulator(Handle<String> string)) { |
154 return accumulator_store_->set_value(*string); | 159 return accumulator_store_->set_value(*string); |
155 } | 160 } |
156 | 161 |
157 Isolate* isolate_; | 162 Isolate* isolate_; |
| 163 Factory* factory_; |
158 // We use a value wrapper for the string accumulator to keep the | 164 // We use a value wrapper for the string accumulator to keep the |
159 // (indirect) handle to it in the outermost handle scope. | 165 // (indirect) handle to it in the outermost handle scope. |
160 Handle<JSValue> accumulator_store_; | 166 Handle<JSValue> accumulator_store_; |
161 Handle<String> current_part_; | 167 Handle<String> current_part_; |
162 Handle<String> tojson_symbol_; | 168 Handle<String> tojson_symbol_; |
163 Handle<JSArray> stack_; | 169 Handle<JSArray> stack_; |
164 int current_index_; | 170 int current_index_; |
165 int part_length_; | 171 int part_length_; |
166 bool is_ascii_; | 172 bool is_ascii_; |
167 | 173 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 "h\0 i\0 j\0 k\0 " | 208 "h\0 i\0 j\0 k\0 " |
203 "l\0 m\0 n\0 o\0 " | 209 "l\0 m\0 n\0 o\0 " |
204 "p\0 q\0 r\0 s\0 " | 210 "p\0 q\0 r\0 s\0 " |
205 "t\0 u\0 v\0 w\0 " | 211 "t\0 u\0 v\0 w\0 " |
206 "x\0 y\0 z\0 {\0 " | 212 "x\0 y\0 z\0 {\0 " |
207 "|\0 }\0 ~\0 \177\0 "; | 213 "|\0 }\0 ~\0 \177\0 "; |
208 | 214 |
209 | 215 |
210 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate) | 216 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate) |
211 : isolate_(isolate), current_index_(0), is_ascii_(true) { | 217 : isolate_(isolate), current_index_(0), is_ascii_(true) { |
| 218 factory_ = isolate_->factory(); |
212 accumulator_store_ = Handle<JSValue>::cast( | 219 accumulator_store_ = Handle<JSValue>::cast( |
213 isolate_->factory()->ToObject(isolate_->factory()->empty_string())); | 220 factory_->ToObject(factory_->empty_string())); |
214 part_length_ = kInitialPartLength; | 221 part_length_ = kInitialPartLength; |
215 current_part_ = | 222 current_part_ = factory_->NewRawAsciiString(kInitialPartLength); |
216 isolate_->factory()->NewRawAsciiString(kInitialPartLength); | 223 tojson_symbol_ = factory_->LookupAsciiSymbol("toJSON"); |
217 tojson_symbol_ = isolate_->factory()->LookupAsciiSymbol("toJSON"); | 224 stack_ = factory_->NewJSArray(8); |
218 stack_ = isolate_->factory()->NewJSArray(8); | |
219 } | 225 } |
220 | 226 |
221 | 227 |
222 MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) { | 228 MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) { |
223 switch (SerializeObject(object)) { | 229 switch (SerializeObject(object)) { |
224 case UNCHANGED: | 230 case UNCHANGED: |
225 return isolate_->heap()->undefined_value(); | 231 return isolate_->heap()->undefined_value(); |
226 case SUCCESS: | 232 case SUCCESS: |
227 ShrinkCurrentPart(); | 233 ShrinkCurrentPart(); |
228 return *isolate_->factory()->NewConsString(accumulator(), current_part_); | 234 return *factory_->NewConsString(accumulator(), current_part_); |
229 case CIRCULAR: | 235 case CIRCULAR: |
230 return isolate_->Throw(*isolate_->factory()->NewTypeError( | 236 return isolate_->Throw(*factory_->NewTypeError( |
231 "circular_structure", HandleVector<Object>(NULL, 0))); | 237 "circular_structure", HandleVector<Object>(NULL, 0))); |
232 case STACK_OVERFLOW: | 238 case STACK_OVERFLOW: |
233 return isolate_->StackOverflow(); | 239 return isolate_->StackOverflow(); |
234 default: | 240 default: |
235 return Failure::Exception(); | 241 return Failure::Exception(); |
236 } | 242 } |
237 } | 243 } |
238 | 244 |
239 | 245 |
240 template <bool is_ascii, typename Char> | 246 template <bool is_ascii, typename Char> |
241 void BasicJsonStringifier::Append_(Char c) { | 247 void BasicJsonStringifier::Append_(Char c) { |
242 if (is_ascii) { | 248 if (is_ascii) { |
243 SeqAsciiString::cast(*current_part_)->SeqAsciiStringSet( | 249 SeqAsciiString::cast(*current_part_)->SeqAsciiStringSet( |
244 current_index_++, c); | 250 current_index_++, c); |
245 } else { | 251 } else { |
246 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( | 252 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( |
247 current_index_++, c); | 253 current_index_++, c); |
248 } | 254 } |
249 if (current_index_ == part_length_) Extend<is_ascii>(); | 255 if (current_index_ == part_length_) Extend(); |
250 } | 256 } |
251 | 257 |
252 | 258 |
253 template <bool is_ascii, typename Char> | 259 template <bool is_ascii, typename Char> |
254 void BasicJsonStringifier::Append_(const Char* chars) { | 260 void BasicJsonStringifier::Append_(const Char* chars) { |
255 for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars); | 261 for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars); |
256 } | 262 } |
257 | 263 |
258 | 264 |
259 Handle<Object> BasicJsonStringifier::GetProperty(Handle<JSObject> object, | 265 Handle<Object> BasicJsonStringifier::GetProperty(Handle<JSObject> object, |
260 Handle<String> key) { | 266 Handle<String> key) { |
261 LookupResult lookup(isolate_); | 267 LookupResult lookup(isolate_); |
262 object->LocalLookupRealNamedProperty(*key, &lookup); | 268 object->LocalLookupRealNamedProperty(*key, &lookup); |
263 if (!lookup.IsProperty()) return isolate_->factory()->undefined_value(); | 269 if (!lookup.IsProperty()) return factory_->undefined_value(); |
264 switch (lookup.type()) { | 270 switch (lookup.type()) { |
265 case NORMAL: { | 271 case NORMAL: { |
266 Object* value = lookup.holder()->GetNormalizedProperty(&lookup); | 272 Object* value = lookup.holder()->GetNormalizedProperty(&lookup); |
267 ASSERT(!value->IsTheHole()); | 273 ASSERT(!value->IsTheHole()); |
268 return Handle<Object>(value); | 274 return Handle<Object>(value, isolate_); |
269 } | 275 } |
270 case FIELD: { | 276 case FIELD: { |
271 Object* value = lookup.holder()->FastPropertyAt(lookup.GetFieldIndex()); | 277 Object* value = lookup.holder()->FastPropertyAt(lookup.GetFieldIndex()); |
272 ASSERT(!value->IsTheHole()); | 278 ASSERT(!value->IsTheHole()); |
273 return Handle<Object>(value); | 279 return Handle<Object>(value, isolate_); |
274 } | 280 } |
275 case CONSTANT_FUNCTION: | 281 case CONSTANT_FUNCTION: |
276 return Handle<Object>(lookup.GetConstantFunction()); | 282 return Handle<Object>(lookup.GetConstantFunction(), isolate_); |
277 default: { | 283 default: { |
278 PropertyAttributes attr; | 284 PropertyAttributes attr; |
279 return Object::GetProperty(object, object, &lookup, key, &attr); | 285 return Object::GetProperty(object, object, &lookup, key, &attr); |
280 } | 286 } |
281 } | 287 } |
282 return Handle<Object>::null(); | 288 return Handle<Object>::null(); |
283 } | 289 } |
284 | 290 |
285 | 291 |
286 Handle<Object> BasicJsonStringifier::ApplyToJsonFunction( | 292 Handle<Object> BasicJsonStringifier::ApplyToJsonFunction( |
287 Handle<Object> object, Handle<Object> key) { | 293 Handle<Object> object, Handle<Object> key) { |
288 LookupResult lookup(isolate_); | 294 LookupResult lookup(isolate_); |
289 JSObject::cast(*object)->LookupRealNamedProperty(*tojson_symbol_, &lookup); | 295 JSObject::cast(*object)->LookupRealNamedProperty(*tojson_symbol_, &lookup); |
290 if (!lookup.IsProperty()) return object; | 296 if (!lookup.IsProperty()) return object; |
291 PropertyAttributes attr; | 297 PropertyAttributes attr; |
292 Handle<Object> fun = | 298 Handle<Object> fun = |
293 Object::GetProperty(object, object, &lookup, tojson_symbol_, &attr); | 299 Object::GetProperty(object, object, &lookup, tojson_symbol_, &attr); |
294 if (!fun->IsJSFunction()) return object; | 300 if (!fun->IsJSFunction()) return object; |
295 | 301 |
296 // Call toJSON function. | 302 // Call toJSON function. |
297 if (key->IsSmi()) key = isolate_->factory()->NumberToString(key); | 303 if (key->IsSmi()) key = factory_->NumberToString(key); |
298 Handle<Object> argv[] = { key }; | 304 Handle<Object> argv[] = { key }; |
299 bool has_exception = false; | 305 bool has_exception = false; |
300 HandleScope scope(isolate_); | 306 HandleScope scope(isolate_); |
301 object = Execution::Call(fun, object, 1, argv, &has_exception); | 307 object = Execution::Call(fun, object, 1, argv, &has_exception); |
302 // Return empty handle to signal an exception. | 308 // Return empty handle to signal an exception. |
303 if (has_exception) return Handle<Object>::null(); | 309 if (has_exception) return Handle<Object>::null(); |
304 return scope.CloseAndEscape(object); | 310 return scope.CloseAndEscape(object); |
305 } | 311 } |
306 | 312 |
307 | 313 |
(...skipping 23 matching lines...) Expand all Loading... |
331 | 337 |
332 | 338 |
333 template <bool deferred_string_key> | 339 template <bool deferred_string_key> |
334 BasicJsonStringifier::Result BasicJsonStringifier::Serialize_( | 340 BasicJsonStringifier::Result BasicJsonStringifier::Serialize_( |
335 Handle<Object> object, bool comma, Handle<Object> key) { | 341 Handle<Object> object, bool comma, Handle<Object> key) { |
336 if (object->IsJSObject()) { | 342 if (object->IsJSObject()) { |
337 object = ApplyToJsonFunction(object, key); | 343 object = ApplyToJsonFunction(object, key); |
338 if (object.is_null()) return EXCEPTION; | 344 if (object.is_null()) return EXCEPTION; |
339 } | 345 } |
340 | 346 |
341 if (object->IsJSObject()) { | 347 if (object->IsSmi()) { |
342 if (object->IsJSFunction()) return UNCHANGED; | |
343 if (deferred_string_key) SerializeDeferredKey(comma, key); | 348 if (deferred_string_key) SerializeDeferredKey(comma, key); |
344 if (object->IsJSArray()) { | 349 return SerializeSmi(Smi::cast(*object)); |
345 return SerializeJSArray(Handle<JSArray>::cast(object)); | |
346 } else if (object->IsJSValue()) { | |
347 return SerializeJSValue(Handle<JSValue>::cast(object)); | |
348 } else { | |
349 return SerializeJSObject(Handle<JSObject>::cast(object)); | |
350 } | |
351 } | 350 } |
352 | 351 |
353 // Handle non-JSObject. | 352 switch (HeapObject::cast(*object)->map()->instance_type()) { |
354 if (object->IsString()) { | 353 case HEAP_NUMBER_TYPE: |
355 if (deferred_string_key) SerializeDeferredKey(comma, key); | 354 if (deferred_string_key) SerializeDeferredKey(comma, key); |
356 SerializeString(Handle<String>::cast(object)); | 355 return SerializeHeapNumber(Handle<HeapNumber>::cast(object)); |
357 return SUCCESS; | 356 case ODDBALL_TYPE: |
358 } else if (object->IsSmi()) { | 357 switch (Oddball::cast(*object)->kind()) { |
359 if (deferred_string_key) SerializeDeferredKey(comma, key); | 358 case Oddball::kFalse: |
360 return SerializeSmi(Smi::cast(*object)); | 359 if (deferred_string_key) SerializeDeferredKey(comma, key); |
361 } else if (object->IsHeapNumber()) { | 360 Append("false"); |
362 if (deferred_string_key) SerializeDeferredKey(comma, key); | 361 return SUCCESS; |
363 return SerializeHeapNumber(Handle<HeapNumber>::cast(object)); | 362 case Oddball::kTrue: |
364 } else if (object->IsOddball()) { | 363 if (deferred_string_key) SerializeDeferredKey(comma, key); |
365 switch (Oddball::cast(*object)->kind()) { | 364 Append("true"); |
366 case Oddball::kFalse: | 365 return SUCCESS; |
| 366 case Oddball::kNull: |
| 367 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 368 Append("null"); |
| 369 return SUCCESS; |
| 370 default: |
| 371 return UNCHANGED; |
| 372 } |
| 373 case JS_ARRAY_TYPE: |
| 374 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 375 return SerializeJSArray(Handle<JSArray>::cast(object)); |
| 376 case JS_VALUE_TYPE: |
| 377 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 378 return SerializeJSValue(Handle<JSValue>::cast(object)); |
| 379 case JS_FUNCTION_TYPE: |
| 380 return UNCHANGED; |
| 381 default: |
| 382 if (object->IsString()) { |
367 if (deferred_string_key) SerializeDeferredKey(comma, key); | 383 if (deferred_string_key) SerializeDeferredKey(comma, key); |
368 Append("false"); | 384 SerializeString(Handle<String>::cast(object)); |
369 return SUCCESS; | 385 return SUCCESS; |
370 case Oddball::kTrue: | 386 } else if (object->IsJSObject()) { |
371 if (deferred_string_key) SerializeDeferredKey(comma, key); | 387 if (deferred_string_key) SerializeDeferredKey(comma, key); |
372 Append("true"); | 388 return SerializeJSObject(Handle<JSObject>::cast(object)); |
373 return SUCCESS; | 389 } else { |
374 case Oddball::kNull: | 390 return SerializeGeneric(object, key, comma, deferred_string_key); |
375 if (deferred_string_key) SerializeDeferredKey(comma, key); | 391 } |
376 Append("null"); | |
377 return SUCCESS; | |
378 } | |
379 } | 392 } |
380 | |
381 return UNCHANGED; | |
382 } | 393 } |
383 | 394 |
384 | 395 |
| 396 BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric( |
| 397 Handle<Object> object, |
| 398 Handle<Object> key, |
| 399 bool deferred_comma, |
| 400 bool deferred_key) { |
| 401 Handle<JSObject> builtins(isolate_->native_context()->builtins()); |
| 402 Handle<JSFunction> builtin = Handle<JSFunction>::cast( |
| 403 v8::internal::GetProperty(builtins, "JSONSerializeAdapter")); |
| 404 |
| 405 Handle<Object> argv[] = { key, object }; |
| 406 bool has_exception = false; |
| 407 Handle<Object> result = |
| 408 Execution::Call(builtin, object, 2, argv, &has_exception); |
| 409 if (has_exception) return EXCEPTION; |
| 410 if (result->IsUndefined()) return UNCHANGED; |
| 411 if (deferred_key) { |
| 412 if (key->IsSmi()) key = factory_->NumberToString(key); |
| 413 SerializeDeferredKey(deferred_comma, key); |
| 414 } |
| 415 |
| 416 Handle<String> result_string = Handle<String>::cast(result); |
| 417 // Shrink current part, attach it to the accumulator, also attach the result |
| 418 // string to the accumulator, and allocate a new part. |
| 419 ShrinkCurrentPart(); // Shrink. |
| 420 part_length_ = kInitialPartLength; // Allocate conservatively. |
| 421 Extend(); // Attach current part and allocate new part. |
| 422 // Attach result string to the accumulator. |
| 423 set_accumulator(factory_->NewConsString(accumulator(), result_string)); |
| 424 return SUCCESS; |
| 425 } |
| 426 |
| 427 |
385 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( | 428 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( |
386 Handle<JSValue> object) { | 429 Handle<JSValue> object) { |
387 bool has_exception = false; | 430 bool has_exception = false; |
388 String* class_name = object->class_name(); | 431 String* class_name = object->class_name(); |
389 if (class_name == isolate_->heap()->String_symbol()) { | 432 if (class_name == isolate_->heap()->String_symbol()) { |
390 Handle<Object> value = Execution::ToString(object, &has_exception); | 433 Handle<Object> value = Execution::ToString(object, &has_exception); |
391 if (has_exception) return EXCEPTION; | 434 if (has_exception) return EXCEPTION; |
392 SerializeString(Handle<String>::cast(value)); | 435 SerializeString(Handle<String>::cast(value)); |
393 } else if (class_name == isolate_->heap()->Number_symbol()) { | 436 } else if (class_name == isolate_->heap()->Number_symbol()) { |
394 Handle<Object> value = Execution::ToNumber(object, &has_exception); | 437 Handle<Object> value = Execution::ToNumber(object, &has_exception); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 | 473 |
431 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( | 474 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
432 Handle<JSArray> object) { | 475 Handle<JSArray> object) { |
433 HandleScope handle_scope(isolate_); | 476 HandleScope handle_scope(isolate_); |
434 Result stack_push = StackPush(object); | 477 Result stack_push = StackPush(object); |
435 if (stack_push != SUCCESS) return stack_push; | 478 if (stack_push != SUCCESS) return stack_push; |
436 int length = Smi::cast(object->length())->value(); | 479 int length = Smi::cast(object->length())->value(); |
437 Append('['); | 480 Append('['); |
438 switch (object->GetElementsKind()) { | 481 switch (object->GetElementsKind()) { |
439 case FAST_SMI_ELEMENTS: { | 482 case FAST_SMI_ELEMENTS: { |
440 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 483 Handle<FixedArray> elements( |
| 484 FixedArray::cast(object->elements()), isolate_); |
441 for (int i = 0; i < length; i++) { | 485 for (int i = 0; i < length; i++) { |
442 if (i > 0) Append(','); | 486 if (i > 0) Append(','); |
443 SerializeSmi(Smi::cast(elements->get(i))); | 487 SerializeSmi(Smi::cast(elements->get(i))); |
444 } | 488 } |
445 break; | 489 break; |
446 } | 490 } |
447 case FAST_DOUBLE_ELEMENTS: { | 491 case FAST_DOUBLE_ELEMENTS: { |
448 Handle<FixedDoubleArray> elements( | 492 Handle<FixedDoubleArray> elements( |
449 FixedDoubleArray::cast(object->elements())); | 493 FixedDoubleArray::cast(object->elements()), isolate_); |
450 for (int i = 0; i < length; i++) { | 494 for (int i = 0; i < length; i++) { |
451 if (i > 0) Append(','); | 495 if (i > 0) Append(','); |
452 SerializeDouble(elements->get_scalar(i)); | 496 SerializeDouble(elements->get_scalar(i)); |
453 } | 497 } |
454 break; | 498 break; |
455 } | 499 } |
456 case FAST_ELEMENTS: { | 500 case FAST_ELEMENTS: { |
457 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 501 Handle<FixedArray> elements( |
| 502 FixedArray::cast(object->elements()), isolate_); |
458 for (int i = 0; i < length; i++) { | 503 for (int i = 0; i < length; i++) { |
459 if (i > 0) Append(','); | 504 if (i > 0) Append(','); |
460 Result result = SerializeElement(Handle<Object>(elements->get(i)), i); | 505 Result result = |
| 506 SerializeElement(Handle<Object>(elements->get(i), isolate_), i); |
461 if (result == SUCCESS) continue; | 507 if (result == SUCCESS) continue; |
462 if (result == UNCHANGED) { | 508 if (result == UNCHANGED) { |
463 Append("null"); | 509 Append("null"); |
464 } else { | 510 } else { |
465 return result; | 511 return result; |
466 } | 512 } |
467 } | 513 } |
468 break; | 514 break; |
469 } | 515 } |
470 // TODO(yangguo): The FAST_HOLEY_* cases could be handled in a faster way. | 516 // TODO(yangguo): The FAST_HOLEY_* cases could be handled in a faster way. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 return SUCCESS; | 549 return SUCCESS; |
504 } | 550 } |
505 | 551 |
506 | 552 |
507 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( | 553 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( |
508 Handle<JSObject> object) { | 554 Handle<JSObject> object) { |
509 HandleScope handle_scope(isolate_); | 555 HandleScope handle_scope(isolate_); |
510 Result stack_push = StackPush(object); | 556 Result stack_push = StackPush(object); |
511 if (stack_push != SUCCESS) return stack_push; | 557 if (stack_push != SUCCESS) return stack_push; |
512 if (object->IsJSGlobalProxy()) { | 558 if (object->IsJSGlobalProxy()) { |
513 object = Handle<JSObject>(JSObject::cast(object->GetPrototype())); | 559 object = Handle<JSObject>( |
| 560 JSObject::cast(object->GetPrototype()), isolate_); |
514 ASSERT(object->IsGlobalObject()); | 561 ASSERT(object->IsGlobalObject()); |
515 } | 562 } |
516 bool has_exception = false; | 563 bool has_exception = false; |
517 Handle<FixedArray> contents = | 564 Handle<FixedArray> contents = |
518 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &has_exception); | 565 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &has_exception); |
519 if (has_exception) return EXCEPTION; | 566 if (has_exception) return EXCEPTION; |
520 Append('{'); | 567 Append('{'); |
521 bool comma = false; | 568 bool comma = false; |
522 for (int i = 0; i < contents->length(); i++) { | 569 for (int i = 0; i < contents->length(); i++) { |
523 Object* key = contents->get(i); | 570 Object* key = contents->get(i); |
524 Handle<String> key_handle; | 571 Handle<String> key_handle; |
525 Handle<Object> property; | 572 Handle<Object> property; |
526 if (key->IsString()) { | 573 if (key->IsString()) { |
527 key_handle = Handle<String>(String::cast(key)); | 574 key_handle = Handle<String>(String::cast(key), isolate_); |
528 property = GetProperty(object, key_handle); | 575 property = GetProperty(object, key_handle); |
529 } else { | 576 } else { |
530 ASSERT(key->IsNumber()); | 577 ASSERT(key->IsNumber()); |
531 key_handle = isolate_->factory()->NumberToString(Handle<Object>(key)); | 578 key_handle = factory_->NumberToString(Handle<Object>(key, isolate_)); |
532 uint32_t index; | 579 uint32_t index; |
533 if (key->IsSmi()) { | 580 if (key->IsSmi()) { |
534 property = Object::GetElement(object, Smi::cast(key)->value()); | 581 property = Object::GetElement(object, Smi::cast(key)->value()); |
535 } else if (key_handle->AsArrayIndex(&index)) { | 582 } else if (key_handle->AsArrayIndex(&index)) { |
536 property = Object::GetElement(object, index); | 583 property = Object::GetElement(object, index); |
537 } else { | 584 } else { |
538 property = GetProperty(object, key_handle); | 585 property = GetProperty(object, key_handle); |
539 } | 586 } |
540 } | 587 } |
541 if (property.is_null()) return EXCEPTION; | 588 if (property.is_null()) return EXCEPTION; |
542 Result result = SerializeProperty(property, comma, key_handle); | 589 Result result = SerializeProperty(property, comma, key_handle); |
543 if (!comma && result == SUCCESS) comma = true; | 590 if (!comma && result == SUCCESS) comma = true; |
544 if (result >= EXCEPTION) return result; | 591 if (result >= EXCEPTION) return result; |
545 } | 592 } |
546 Append('}'); | 593 Append('}'); |
547 StackPop(); | 594 StackPop(); |
548 current_part_ = handle_scope.CloseAndEscape(current_part_); | 595 current_part_ = handle_scope.CloseAndEscape(current_part_); |
549 return SUCCESS; | 596 return SUCCESS; |
550 } | 597 } |
551 | 598 |
552 | 599 |
553 void BasicJsonStringifier::ShrinkCurrentPart() { | 600 void BasicJsonStringifier::ShrinkCurrentPart() { |
554 ASSERT(current_index_ < part_length_); | 601 ASSERT(current_index_ < part_length_); |
555 if (current_index_ == 0) { | 602 if (current_index_ == 0) { |
556 current_part_ = isolate_->factory()->empty_string(); | 603 current_part_ = factory_->empty_string(); |
557 return; | 604 return; |
558 } | 605 } |
559 | 606 |
560 int string_size, allocated_string_size; | 607 int string_size, allocated_string_size; |
561 if (is_ascii_) { | 608 if (is_ascii_) { |
562 allocated_string_size = SeqAsciiString::SizeFor(part_length_); | 609 allocated_string_size = SeqAsciiString::SizeFor(part_length_); |
563 string_size = SeqAsciiString::SizeFor(current_index_); | 610 string_size = SeqAsciiString::SizeFor(current_index_); |
564 } else { | 611 } else { |
565 allocated_string_size = SeqTwoByteString::SizeFor(part_length_); | 612 allocated_string_size = SeqTwoByteString::SizeFor(part_length_); |
566 string_size = SeqTwoByteString::SizeFor(current_index_); | 613 string_size = SeqTwoByteString::SizeFor(current_index_); |
567 } | 614 } |
568 | 615 |
569 int delta = allocated_string_size - string_size; | 616 int delta = allocated_string_size - string_size; |
570 current_part_->set_length(current_index_); | 617 current_part_->set_length(current_index_); |
571 | 618 |
572 // String sizes are pointer size aligned, so that we can use filler objects | 619 // String sizes are pointer size aligned, so that we can use filler objects |
573 // that are a multiple of pointer size. | 620 // that are a multiple of pointer size. |
574 Address end_of_string = current_part_->address() + string_size; | 621 Address end_of_string = current_part_->address() + string_size; |
575 isolate_->heap()->CreateFillerObjectAt(end_of_string, delta); | 622 isolate_->heap()->CreateFillerObjectAt(end_of_string, delta); |
576 if (Marking::IsBlack(Marking::MarkBitFrom(*current_part_))) { | 623 if (Marking::IsBlack(Marking::MarkBitFrom(*current_part_))) { |
577 MemoryChunk::IncrementLiveBytesFromMutator( | 624 MemoryChunk::IncrementLiveBytesFromMutator( |
578 current_part_->address(), -delta); | 625 current_part_->address(), -delta); |
579 } | 626 } |
580 } | 627 } |
581 | 628 |
582 | 629 |
583 template <bool is_ascii> | |
584 void BasicJsonStringifier::Extend() { | 630 void BasicJsonStringifier::Extend() { |
585 set_accumulator( | 631 set_accumulator(factory_->NewConsString(accumulator(), current_part_)); |
586 isolate_->factory()->NewConsString(accumulator(), current_part_)); | |
587 if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) { | 632 if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) { |
588 part_length_ *= kPartLengthGrowthFactor; | 633 part_length_ *= kPartLengthGrowthFactor; |
589 } | 634 } |
590 if (is_ascii) { | 635 if (is_ascii_) { |
591 current_part_ = | 636 current_part_ = factory_->NewRawAsciiString(part_length_); |
592 isolate_->factory()->NewRawAsciiString(part_length_); | |
593 } else { | 637 } else { |
594 current_part_ = | 638 current_part_ = factory_->NewRawTwoByteString(part_length_); |
595 isolate_->factory()->NewRawTwoByteString(part_length_); | |
596 } | 639 } |
597 current_index_ = 0; | 640 current_index_ = 0; |
598 } | 641 } |
599 | 642 |
600 | 643 |
601 void BasicJsonStringifier::ChangeEncoding() { | 644 void BasicJsonStringifier::ChangeEncoding() { |
602 ShrinkCurrentPart(); | 645 ShrinkCurrentPart(); |
603 set_accumulator( | 646 set_accumulator(factory_->NewConsString(accumulator(), current_part_)); |
604 isolate_->factory()->NewConsString(accumulator(), current_part_)); | 647 current_part_ = factory_->NewRawTwoByteString(part_length_); |
605 current_part_ = | |
606 isolate_->factory()->NewRawTwoByteString(part_length_); | |
607 current_index_ = 0; | 648 current_index_ = 0; |
608 is_ascii_ = false; | 649 is_ascii_ = false; |
609 } | 650 } |
610 | 651 |
611 | 652 |
612 template <typename SrcChar, typename DestChar> | 653 template <typename SrcChar, typename DestChar> |
613 void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src, | 654 void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src, |
614 DestChar* dest, | 655 DestChar* dest, |
615 int length) { | 656 int length) { |
616 dest += current_index_; | 657 dest += current_index_; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 SerializeString_<false, char>(flat.ToAsciiVector(), object); | 763 SerializeString_<false, char>(flat.ToAsciiVector(), object); |
723 } else { | 764 } else { |
724 SerializeString_<false, uc16>(flat.ToUC16Vector(), object); | 765 SerializeString_<false, uc16>(flat.ToUC16Vector(), object); |
725 } | 766 } |
726 } | 767 } |
727 } | 768 } |
728 | 769 |
729 } } // namespace v8::internal | 770 } } // namespace v8::internal |
730 | 771 |
731 #endif // V8_JSON_STRINGIFIER_H_ | 772 #endif // V8_JSON_STRINGIFIER_H_ |
OLD | NEW |