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-parser.h" | 5 #include "src/json-parser.h" |
6 | 6 |
7 #include "src/char-predicates-inl.h" | 7 #include "src/char-predicates-inl.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
11 #include "src/field-type.h" | 11 #include "src/field-type.h" |
12 #include "src/messages.h" | 12 #include "src/messages.h" |
13 #include "src/objects-inl.h" | 13 #include "src/objects-inl.h" |
14 #include "src/parsing/scanner.h" | 14 #include "src/parsing/scanner.h" |
15 #include "src/parsing/token.h" | 15 #include "src/parsing/token.h" |
| 16 #include "src/property-descriptor.h" |
16 #include "src/transitions.h" | 17 #include "src/transitions.h" |
17 | 18 |
18 namespace v8 { | 19 namespace v8 { |
19 namespace internal { | 20 namespace internal { |
20 | 21 |
| 22 MaybeHandle<Object> JsonParseInternalizer::Internalize(Isolate* isolate, |
| 23 Handle<Object> object, |
| 24 Handle<Object> reviver) { |
| 25 DCHECK(reviver->IsCallable()); |
| 26 JsonParseInternalizer internalizer(isolate, |
| 27 Handle<JSReceiver>::cast(reviver)); |
| 28 Handle<JSObject> holder = |
| 29 isolate->factory()->NewJSObject(isolate->object_function()); |
| 30 Handle<String> name = isolate->factory()->empty_string(); |
| 31 JSObject::AddProperty(holder, name, object, NONE); |
| 32 return internalizer.InternalizeJsonProperty(holder, name); |
| 33 } |
| 34 |
| 35 MaybeHandle<Object> JsonParseInternalizer::InternalizeJsonProperty( |
| 36 Handle<JSReceiver> holder, Handle<String> name) { |
| 37 HandleScope outer_scope(isolate_); |
| 38 Handle<Object> value; |
| 39 ASSIGN_RETURN_ON_EXCEPTION( |
| 40 isolate_, value, Object::GetPropertyOrElement(holder, name), Object); |
| 41 if (value->IsJSReceiver()) { |
| 42 Handle<JSReceiver> object = Handle<JSReceiver>::cast(value); |
| 43 Maybe<bool> is_array = Object::IsArray(object); |
| 44 if (is_array.IsNothing()) return MaybeHandle<Object>(); |
| 45 if (is_array.FromJust()) { |
| 46 Handle<Object> length_object; |
| 47 ASSIGN_RETURN_ON_EXCEPTION( |
| 48 isolate_, length_object, |
| 49 Object::GetLengthFromArrayLike(isolate_, object), Object); |
| 50 double length = length_object->Number(); |
| 51 for (double i = 0; i < length; i++) { |
| 52 HandleScope inner_scope(isolate_); |
| 53 Handle<Object> index = isolate_->factory()->NewNumber(i); |
| 54 Handle<String> name = isolate_->factory()->NumberToString(index); |
| 55 if (!RecurseAndApply(object, name)) return MaybeHandle<Object>(); |
| 56 } |
| 57 } else { |
| 58 Handle<FixedArray> contents; |
| 59 ASSIGN_RETURN_ON_EXCEPTION( |
| 60 isolate_, contents, |
| 61 KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, |
| 62 ENUMERABLE_STRINGS, |
| 63 GetKeysConversion::kConvertToString), |
| 64 Object); |
| 65 for (int i = 0; i < contents->length(); i++) { |
| 66 HandleScope inner_scope(isolate_); |
| 67 Handle<String> name(String::cast(contents->get(i)), isolate_); |
| 68 if (!RecurseAndApply(object, name)) return MaybeHandle<Object>(); |
| 69 } |
| 70 } |
| 71 } |
| 72 Handle<Object> argv[] = {name, value}; |
| 73 Handle<Object> result; |
| 74 ASSIGN_RETURN_ON_EXCEPTION( |
| 75 isolate_, result, Execution::Call(isolate_, reviver_, holder, 2, argv), |
| 76 Object); |
| 77 return outer_scope.CloseAndEscape(result); |
| 78 } |
| 79 |
| 80 bool JsonParseInternalizer::RecurseAndApply(Handle<JSReceiver> holder, |
| 81 Handle<String> name) { |
| 82 Handle<Object> result; |
| 83 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 84 isolate_, result, InternalizeJsonProperty(holder, name), false); |
| 85 Maybe<bool> change_result = Nothing<bool>(); |
| 86 if (result->IsUndefined()) { |
| 87 change_result = JSReceiver::DeletePropertyOrElement(holder, name, SLOPPY); |
| 88 } else { |
| 89 PropertyDescriptor desc; |
| 90 desc.set_value(result); |
| 91 desc.set_configurable(true); |
| 92 desc.set_enumerable(true); |
| 93 desc.set_writable(true); |
| 94 change_result = JSReceiver::DefineOwnProperty(isolate_, holder, name, &desc, |
| 95 Object::DONT_THROW); |
| 96 } |
| 97 MAYBE_RETURN(change_result, false); |
| 98 return true; |
| 99 } |
| 100 |
21 template <bool seq_one_byte> | 101 template <bool seq_one_byte> |
22 JsonParser<seq_one_byte>::JsonParser(Handle<String> source) | 102 JsonParser<seq_one_byte>::JsonParser(Isolate* isolate, Handle<String> source) |
23 : source_(source), | 103 : source_(source), |
24 source_length_(source->length()), | 104 source_length_(source->length()), |
25 isolate_(source->map()->GetHeap()->isolate()), | 105 isolate_(isolate), |
26 factory_(isolate_->factory()), | 106 factory_(isolate_->factory()), |
27 zone_(isolate_->allocator()), | 107 zone_(isolate_->allocator()), |
28 object_constructor_(isolate_->native_context()->object_function(), | 108 object_constructor_(isolate_->native_context()->object_function(), |
29 isolate_), | 109 isolate_), |
30 position_(-1) { | 110 position_(-1) { |
31 source_ = String::Flatten(source_); | 111 source_ = String::Flatten(source_); |
32 pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED; | 112 pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED; |
33 | 113 |
34 // Optimized fast case where we only have Latin1 characters. | 114 // Optimized fast case where we only have Latin1 characters. |
35 if (seq_one_byte) { | 115 if (seq_one_byte) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // We should sent compile error event because we compile JSON object in | 163 // We should sent compile error event because we compile JSON object in |
84 // separated source file. | 164 // separated source file. |
85 isolate()->debug()->OnCompileError(script); | 165 isolate()->debug()->OnCompileError(script); |
86 MessageLocation location(script, position_, position_ + 1); | 166 MessageLocation location(script, position_, position_ + 1); |
87 Handle<Object> error = factory->NewSyntaxError(message, arg1, arg2); | 167 Handle<Object> error = factory->NewSyntaxError(message, arg1, arg2); |
88 return isolate()->template Throw<Object>(error, &location); | 168 return isolate()->template Throw<Object>(error, &location); |
89 } | 169 } |
90 return result; | 170 return result; |
91 } | 171 } |
92 | 172 |
| 173 MaybeHandle<Object> InternalizeJsonProperty(Handle<JSObject> holder, |
| 174 Handle<String> key); |
| 175 |
93 template <bool seq_one_byte> | 176 template <bool seq_one_byte> |
94 void JsonParser<seq_one_byte>::Advance() { | 177 void JsonParser<seq_one_byte>::Advance() { |
95 position_++; | 178 position_++; |
96 if (position_ >= source_length_) { | 179 if (position_ >= source_length_) { |
97 c0_ = kEndOfString; | 180 c0_ = kEndOfString; |
98 } else if (seq_one_byte) { | 181 } else if (seq_one_byte) { |
99 c0_ = seq_source_->SeqOneByteStringGet(position_); | 182 c0_ = seq_source_->SeqOneByteStringGet(position_); |
100 } else { | 183 } else { |
101 c0_ = source_->Get(position_); | 184 c0_ = source_->Get(position_); |
102 } | 185 } |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 AdvanceSkipWhitespace(); | 804 AdvanceSkipWhitespace(); |
722 return result; | 805 return result; |
723 } | 806 } |
724 | 807 |
725 // Explicit instantiation. | 808 // Explicit instantiation. |
726 template class JsonParser<true>; | 809 template class JsonParser<true>; |
727 template class JsonParser<false>; | 810 template class JsonParser<false>; |
728 | 811 |
729 } // namespace internal | 812 } // namespace internal |
730 } // namespace v8 | 813 } // namespace v8 |
OLD | NEW |