OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/json-stringifier.h" | 5 #include "src/json-stringifier.h" |
6 | 6 |
7 #include "src/conversions.h" | 7 #include "src/conversions.h" |
8 #include "src/lookup.h" | 8 #include "src/lookup.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 // Call toJSON function. | 205 // Call toJSON function. |
206 if (key->IsSmi()) key = factory()->NumberToString(key); | 206 if (key->IsSmi()) key = factory()->NumberToString(key); |
207 Handle<Object> argv[] = {key}; | 207 Handle<Object> argv[] = {key}; |
208 ASSIGN_RETURN_ON_EXCEPTION(isolate_, object, | 208 ASSIGN_RETURN_ON_EXCEPTION(isolate_, object, |
209 Execution::Call(isolate_, fun, object, 1, argv), | 209 Execution::Call(isolate_, fun, object, 1, argv), |
210 Object); | 210 Object); |
211 return scope.CloseAndEscape(object); | 211 return scope.CloseAndEscape(object); |
212 } | 212 } |
213 | 213 |
214 MaybeHandle<Object> JsonStringifier::ApplyReplacerFunction( | 214 MaybeHandle<Object> JsonStringifier::ApplyReplacerFunction( |
215 Handle<Object> object, Handle<Object> key) { | 215 Handle<Object> value, Handle<Object> key, Handle<Object> initial_holder) { |
216 HandleScope scope(isolate_); | 216 HandleScope scope(isolate_); |
217 if (key->IsSmi()) key = factory()->NumberToString(key); | 217 if (key->IsSmi()) key = factory()->NumberToString(key); |
218 Handle<Object> argv[] = {key, object}; | 218 Handle<Object> argv[] = {key, value}; |
219 Handle<JSReceiver> holder = CurrentHolder(object); | 219 Handle<JSReceiver> holder = CurrentHolder(value, initial_holder); |
220 ASSIGN_RETURN_ON_EXCEPTION( | 220 ASSIGN_RETURN_ON_EXCEPTION( |
221 isolate_, object, | 221 isolate_, value, |
222 Execution::Call(isolate_, replacer_function_, holder, 2, argv), Object); | 222 Execution::Call(isolate_, replacer_function_, holder, 2, argv), Object); |
223 return scope.CloseAndEscape(object); | 223 return scope.CloseAndEscape(value); |
224 } | 224 } |
225 | 225 |
226 Handle<JSReceiver> JsonStringifier::CurrentHolder(Handle<Object> value) { | 226 Handle<JSReceiver> JsonStringifier::CurrentHolder( |
| 227 Handle<Object> value, Handle<Object> initial_holder) { |
227 int length = Smi::cast(stack_->length())->value(); | 228 int length = Smi::cast(stack_->length())->value(); |
228 if (length == 0) { | 229 if (length == 0) { |
229 Handle<JSObject> holder = | 230 Handle<JSObject> holder = |
230 factory()->NewJSObject(isolate_->object_function()); | 231 factory()->NewJSObject(isolate_->object_function()); |
231 JSObject::AddProperty(holder, factory()->empty_string(), value, NONE); | 232 JSObject::AddProperty(holder, factory()->empty_string(), initial_holder, |
| 233 NONE); |
232 return holder; | 234 return holder; |
233 } else { | 235 } else { |
234 FixedArray* elements = FixedArray::cast(stack_->elements()); | 236 FixedArray* elements = FixedArray::cast(stack_->elements()); |
235 return Handle<JSReceiver>(JSReceiver::cast(elements->get(length - 1)), | 237 return Handle<JSReceiver>(JSReceiver::cast(elements->get(length - 1)), |
236 isolate_); | 238 isolate_); |
237 } | 239 } |
238 } | 240 } |
239 | 241 |
240 JsonStringifier::Result JsonStringifier::StackPush(Handle<Object> object) { | 242 JsonStringifier::Result JsonStringifier::StackPush(Handle<Object> object) { |
241 StackLimitCheck check(isolate_); | 243 StackLimitCheck check(isolate_); |
(...skipping 24 matching lines...) Expand all Loading... |
266 void JsonStringifier::StackPop() { | 268 void JsonStringifier::StackPop() { |
267 int length = Smi::cast(stack_->length())->value(); | 269 int length = Smi::cast(stack_->length())->value(); |
268 stack_->set_length(Smi::FromInt(length - 1)); | 270 stack_->set_length(Smi::FromInt(length - 1)); |
269 } | 271 } |
270 | 272 |
271 template <bool deferred_string_key> | 273 template <bool deferred_string_key> |
272 JsonStringifier::Result JsonStringifier::Serialize_(Handle<Object> object, | 274 JsonStringifier::Result JsonStringifier::Serialize_(Handle<Object> object, |
273 bool comma, | 275 bool comma, |
274 Handle<Object> key) { | 276 Handle<Object> key) { |
275 StackLimitCheck interrupt_check(isolate_); | 277 StackLimitCheck interrupt_check(isolate_); |
| 278 Handle<Object> initial_value = object; |
276 if (interrupt_check.InterruptRequested() && | 279 if (interrupt_check.InterruptRequested() && |
277 isolate_->stack_guard()->HandleInterrupts()->IsException(isolate_)) { | 280 isolate_->stack_guard()->HandleInterrupts()->IsException(isolate_)) { |
278 return EXCEPTION; | 281 return EXCEPTION; |
279 } | 282 } |
280 if (object->IsJSReceiver()) { | 283 if (object->IsJSReceiver()) { |
281 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 284 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
282 isolate_, object, ApplyToJsonFunction(object, key), EXCEPTION); | 285 isolate_, object, ApplyToJsonFunction(object, key), EXCEPTION); |
283 } | 286 } |
284 if (!replacer_function_.is_null()) { | 287 if (!replacer_function_.is_null()) { |
285 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 288 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
286 isolate_, object, ApplyReplacerFunction(object, key), EXCEPTION); | 289 isolate_, object, ApplyReplacerFunction(object, key, initial_value), |
| 290 EXCEPTION); |
287 } | 291 } |
288 | 292 |
289 if (object->IsSmi()) { | 293 if (object->IsSmi()) { |
290 if (deferred_string_key) SerializeDeferredKey(comma, key); | 294 if (deferred_string_key) SerializeDeferredKey(comma, key); |
291 return SerializeSmi(Smi::cast(*object)); | 295 return SerializeSmi(Smi::cast(*object)); |
292 } | 296 } |
293 | 297 |
294 switch (HeapObject::cast(*object)->map()->instance_type()) { | 298 switch (HeapObject::cast(*object)->map()->instance_type()) { |
295 case HEAP_NUMBER_TYPE: | 299 case HEAP_NUMBER_TYPE: |
296 case MUTABLE_HEAP_NUMBER_TYPE: | 300 case MUTABLE_HEAP_NUMBER_TYPE: |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 if (object->IsOneByteRepresentationUnderneath()) { | 713 if (object->IsOneByteRepresentationUnderneath()) { |
710 SerializeString_<uint8_t, uc16>(object); | 714 SerializeString_<uint8_t, uc16>(object); |
711 } else { | 715 } else { |
712 SerializeString_<uc16, uc16>(object); | 716 SerializeString_<uc16, uc16>(object); |
713 } | 717 } |
714 } | 718 } |
715 } | 719 } |
716 | 720 |
717 } // namespace internal | 721 } // namespace internal |
718 } // namespace v8 | 722 } // namespace v8 |
OLD | NEW |