5 #include "src/json-parser.h" 7 #include "src/char-predicates-inl.h" 8 #include "src/conversions.h" 9 #include "src/debug/debug.h" 10 #include "src/field-type.h" 11 #include "src/message-template.h" 12 #include "src/objects-inl.h" 13 #include "src/objects/hash-table-inl.h" 14 #include "src/property-descriptor.h" 15 #include "src/string-hasher.h" 16 #include "src/transitions.h" 27 template <
typename Container>
30 using value_type =
typename Container::value_type;
32 explicit VectorSegment(Container* container)
33 : container_(*container), begin_(container->size()) {}
34 ~VectorSegment() { container_.resize(begin_); }
36 Vector<const value_type> GetVector()
const {
37 return VectorOf(container_) + begin_;
41 void push_back(T&& value) {
42 container_.push_back(std::forward<T>(value));
46 Container& container_;
47 const typename Container::size_type begin_;
52 MaybeHandle<Object> JsonParseInternalizer::Internalize(Isolate* isolate,
53 Handle<Object>
object,
54 Handle<Object> reviver) {
55 DCHECK(reviver->IsCallable());
56 JsonParseInternalizer internalizer(isolate,
57 Handle<JSReceiver>::cast(reviver));
58 Handle<JSObject> holder =
59 isolate->factory()->NewJSObject(isolate->object_function());
60 Handle<String> name = isolate->factory()->empty_string();
61 JSObject::AddProperty(isolate, holder, name,
object, NONE);
62 return internalizer.InternalizeJsonProperty(holder, name);
65 MaybeHandle<Object> JsonParseInternalizer::InternalizeJsonProperty(
66 Handle<JSReceiver> holder, Handle<String> name) {
67 HandleScope outer_scope(isolate_);
69 ASSIGN_RETURN_ON_EXCEPTION(
70 isolate_, value, Object::GetPropertyOrElement(isolate_, holder, name),
72 if (value->IsJSReceiver()) {
73 Handle<JSReceiver>
object = Handle<JSReceiver>::cast(value);
74 Maybe<bool> is_array = Object::IsArray(
object);
75 if (is_array.IsNothing())
return MaybeHandle<Object>();
76 if (is_array.FromJust()) {
77 Handle<Object> length_object;
78 ASSIGN_RETURN_ON_EXCEPTION(
79 isolate_, length_object,
80 Object::GetLengthFromArrayLike(isolate_,
object), Object);
81 double length = length_object->Number();
82 for (
double i = 0;
i < length;
i++) {
83 HandleScope inner_scope(isolate_);
84 Handle<Object> index = isolate_->factory()->NewNumber(
i);
85 Handle<String> name = isolate_->factory()->NumberToString(index);
86 if (!RecurseAndApply(
object, name))
return MaybeHandle<Object>();
89 Handle<FixedArray> contents;
90 ASSIGN_RETURN_ON_EXCEPTION(
92 KeyAccumulator::GetKeys(
object, KeyCollectionMode::kOwnOnly,
94 GetKeysConversion::kConvertToString),
96 for (
int i = 0;
i < contents->length();
i++) {
97 HandleScope inner_scope(isolate_);
98 Handle<String> name(String::cast(contents->get(
i)), isolate_);
99 if (!RecurseAndApply(
object, name))
return MaybeHandle<Object>();
103 Handle<Object> argv[] = {name, value};
104 Handle<Object> result;
105 ASSIGN_RETURN_ON_EXCEPTION(
106 isolate_, result, Execution::Call(isolate_, reviver_, holder, 2, argv),
108 return outer_scope.CloseAndEscape(result);
111 bool JsonParseInternalizer::RecurseAndApply(Handle<JSReceiver> holder,
112 Handle<String> name) {
113 STACK_CHECK(isolate_,
false);
115 Handle<Object> result;
116 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
117 isolate_, result, InternalizeJsonProperty(holder, name),
false);
118 Maybe<bool> change_result = Nothing<bool>();
119 if (result->IsUndefined(isolate_)) {
120 change_result = JSReceiver::DeletePropertyOrElement(holder, name,
121 LanguageMode::kSloppy);
123 PropertyDescriptor desc;
124 desc.set_value(result);
125 desc.set_configurable(
true);
126 desc.set_enumerable(
true);
127 desc.set_writable(
true);
128 change_result = JSReceiver::DefineOwnProperty(isolate_, holder, name, &desc,
131 MAYBE_RETURN(change_result,
false);
135 template <
bool seq_one_byte>
136 JsonParser<seq_one_byte>::JsonParser(Isolate* isolate, Handle<String> source)
138 source_length_(source->length()),
140 zone_(isolate_->allocator(), ZONE_NAME),
141 object_constructor_(isolate_->native_context()->object_function(),
144 properties_(&zone_) {
145 source_ = String::Flatten(isolate, source_);
146 pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED;
150 seq_source_ = Handle<SeqOneByteString>::cast(source_);
154 template <
bool seq_one_byte>
155 MaybeHandle<Object> JsonParser<seq_one_byte>::ParseJson() {
157 AdvanceSkipWhitespace();
158 Handle<Object> result = ParseJsonValue();
159 if (result.is_null() || c0_ != kEndOfString) {
161 if (isolate_->has_pending_exception())
return Handle<Object>::null();
164 Factory* factory = this->factory();
165 MessageTemplate message;
166 Handle<Object> arg1 = Handle<Smi>(Smi::FromInt(position_), isolate());
171 message = MessageTemplate::kJsonParseUnexpectedEOS;
184 message = MessageTemplate::kJsonParseUnexpectedTokenNumber;
187 message = MessageTemplate::kJsonParseUnexpectedTokenString;
190 message = MessageTemplate::kJsonParseUnexpectedToken;
192 arg1 = factory->LookupSingleCharacterStringFromCode(c0_);
196 Handle<Script> script(factory->NewScript(source_));
197 if (isolate()->NeedsSourcePositionsForProfiling()) {
198 Script::InitLineEnds(script);
202 isolate()->debug()->OnCompileError(script);
203 MessageLocation location(script, position_, position_ + 1);
204 Handle<Object> error = factory->NewSyntaxError(message, arg1, arg2);
205 return isolate()->template Throw<Object>(error, &location);
210 MaybeHandle<Object> InternalizeJsonProperty(Handle<JSObject> holder,
213 template <
bool seq_one_byte>
214 void JsonParser<seq_one_byte>::Advance() {
216 if (position_ >= source_length_) {
218 }
else if (seq_one_byte) {
219 c0_ = seq_source_->SeqOneByteStringGet(position_);
221 c0_ = source_->Get(position_);
225 template <
bool seq_one_byte>
226 void JsonParser<seq_one_byte>::AdvanceSkipWhitespace() {
229 }
while (c0_ ==
' ' || c0_ ==
'\t' || c0_ ==
'\n' || c0_ ==
'\r');
232 template <
bool seq_one_byte>
233 void JsonParser<seq_one_byte>::SkipWhitespace() {
234 while (c0_ ==
' ' || c0_ ==
'\t' || c0_ ==
'\n' || c0_ ==
'\r') {
239 template <
bool seq_one_byte>
240 uc32 JsonParser<seq_one_byte>::AdvanceGetChar() {
245 template <
bool seq_one_byte>
246 bool JsonParser<seq_one_byte>::MatchSkipWhiteSpace(uc32 c) {
248 AdvanceSkipWhitespace();
254 template <
bool seq_one_byte>
255 bool JsonParser<seq_one_byte>::ParseJsonString(Handle<String> expected) {
256 int length = expected->length();
257 if (source_->length() - position_ - 1 > length) {
258 DisallowHeapAllocation no_gc;
259 String::FlatContent content = expected->GetFlatContent();
260 if (content.IsOneByte()) {
262 const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1;
263 const uint8_t* expected_chars = content.ToOneByteVector().start();
264 for (
int i = 0;
i < length;
i++) {
265 uint8_t c0 = input_chars[
i];
266 if (c0 != expected_chars[
i] || c0 ==
'"' || c0 < 0x20 || c0 ==
'\\') {
270 if (input_chars[length] ==
'"') {
271 position_ = position_ + length + 1;
272 AdvanceSkipWhitespace();
281 template <
bool seq_one_byte>
282 Handle<Object> JsonParser<seq_one_byte>::ParseJsonValue() {
283 StackLimitCheck stack_check(isolate_);
284 if (stack_check.HasOverflowed()) {
285 isolate_->StackOverflow();
286 return Handle<Object>::null();
289 if (stack_check.InterruptRequested() &&
290 isolate_->stack_guard()->HandleInterrupts()->IsException(isolate_)) {
291 return Handle<Object>::null();
294 if (c0_ ==
'"')
return ParseJsonString();
295 if ((c0_ >=
'0' && c0_ <=
'9') || c0_ ==
'-')
return ParseJsonNumber();
296 if (c0_ ==
'{')
return ParseJsonObject();
297 if (c0_ ==
'[')
return ParseJsonArray();
299 if (AdvanceGetChar() ==
'a' && AdvanceGetChar() ==
'l' &&
300 AdvanceGetChar() ==
's' && AdvanceGetChar() ==
'e') {
301 AdvanceSkipWhitespace();
302 return factory()->false_value();
304 return ReportUnexpectedCharacter();
307 if (AdvanceGetChar() ==
'r' && AdvanceGetChar() ==
'u' &&
308 AdvanceGetChar() ==
'e') {
309 AdvanceSkipWhitespace();
310 return factory()->true_value();
312 return ReportUnexpectedCharacter();
315 if (AdvanceGetChar() ==
'u' && AdvanceGetChar() ==
'l' &&
316 AdvanceGetChar() ==
'l') {
317 AdvanceSkipWhitespace();
318 return factory()->null_value();
320 return ReportUnexpectedCharacter();
322 return ReportUnexpectedCharacter();
325 template <
bool seq_one_byte>
326 ParseElementResult JsonParser<seq_one_byte>::ParseElement(
327 Handle<JSObject> json_object) {
336 if (index > 429496729U - ((d + 3) >> 3))
break;
337 index = (index * 10) + d;
339 }
while (IsDecimalDigit(c0_));
344 AdvanceSkipWhitespace();
347 AdvanceSkipWhitespace();
348 Handle<Object> value = ParseJsonValue();
349 if (!value.is_null()) {
350 JSObject::SetOwnElementIgnoreAttributes(json_object, index, value, NONE)
352 return kElementFound;
358 return kElementNotFound;
362 template <
bool seq_one_byte>
363 Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
364 HandleScope scope(isolate());
365 Handle<JSObject> json_object =
366 factory()->NewJSObject(object_constructor(), pretenure_);
367 Handle<Map> map(json_object->map(), isolate());
369 VectorSegment<ZoneVector<Handle<Object>>> properties(&properties_);
372 bool transitioning =
true;
374 AdvanceSkipWhitespace();
377 if (c0_ !=
'"')
return ReportUnexpectedCharacter();
379 int start_position = position_;
382 if (IsDecimalDigit(c0_)) {
383 ParseElementResult element_result = ParseElement(json_object);
384 if (element_result == kNullHandle)
return Handle<Object>::null();
385 if (element_result == kElementFound)
continue;
389 position_ = start_position;
395 Handle<Object> value;
399 DCHECK(transitioning);
402 bool follow_expected =
false;
405 DisallowHeapAllocation no_gc;
406 TransitionsAccessor transitions(isolate(), *map, &no_gc);
407 key = transitions.ExpectedTransitionKey();
408 follow_expected = !key.is_null() && ParseJsonString(key);
410 if (follow_expected) {
411 target = transitions.ExpectedTransitionTarget();
414 if (!follow_expected) {
417 key = ParseJsonString();
418 if (key.is_null())
return ReportUnexpectedCharacter();
421 transitioning = TransitionsAccessor(isolate(), map)
422 .FindTransitionToField(key)
425 if (c0_ !=
':')
return ReportUnexpectedCharacter();
427 AdvanceSkipWhitespace();
428 value = ParseJsonValue();
429 if (value.is_null())
return ReportUnexpectedCharacter();
432 PropertyDetails details =
433 target->instance_descriptors()->GetDetails(descriptor);
434 Representation expected_representation = details.representation();
436 if (value->FitsRepresentation(expected_representation)) {
437 if (expected_representation.IsHeapObject() &&
438 !target->instance_descriptors()
439 ->GetFieldType(descriptor)
440 ->NowContains(value)) {
441 Handle<FieldType> value_type(
442 value->OptimalType(isolate(), expected_representation));
443 Map::GeneralizeField(isolate(), target, descriptor,
444 details.constness(), expected_representation,
447 DCHECK(target->instance_descriptors()
448 ->GetFieldType(descriptor)
449 ->NowContains(value));
450 properties.push_back(value);
455 transitioning =
false;
459 DCHECK(!transitioning);
462 CommitStateToJsonObject(json_object, map, properties.GetVector());
464 JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key, value)
466 }
while (transitioning && MatchSkipWhiteSpace(
','));
470 CommitStateToJsonObject(json_object, map, properties.GetVector());
472 while (MatchSkipWhiteSpace(
',')) {
473 HandleScope local_scope(isolate());
474 if (c0_ !=
'"')
return ReportUnexpectedCharacter();
476 int start_position = position_;
479 if (IsDecimalDigit(c0_)) {
480 ParseElementResult element_result = ParseElement(json_object);
481 if (element_result == kNullHandle)
return Handle<Object>::null();
482 if (element_result == kElementFound)
continue;
486 position_ = start_position;
492 Handle<Object> value;
494 key = ParseJsonString();
495 if (key.is_null() || c0_ !=
':')
return ReportUnexpectedCharacter();
497 AdvanceSkipWhitespace();
498 value = ParseJsonValue();
499 if (value.is_null())
return ReportUnexpectedCharacter();
501 JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key,
508 return ReportUnexpectedCharacter();
511 AdvanceSkipWhitespace();
512 return scope.CloseAndEscape(json_object);
515 template <
bool seq_one_byte>
516 void JsonParser<seq_one_byte>::CommitStateToJsonObject(
517 Handle<JSObject> json_object, Handle<Map> map,
518 Vector<
const Handle<Object>> properties) {
519 JSObject::AllocateStorageForMap(json_object, map);
520 DCHECK(!json_object->map()->is_dictionary_map());
522 DisallowHeapAllocation no_gc;
523 DescriptorArray* descriptors = json_object->map()->instance_descriptors();
524 for (
int i = 0;
i < properties.length();
i++) {
525 Handle<Object> value = properties[
i];
527 json_object->WriteToField(
i, descriptors->GetDetails(
i), *value);
545 }
else if (o->IsHeapNumber()) {
546 if (value_ < NUMBER_ELEMENTS) value_ = NUMBER_ELEMENTS;
548 DCHECK(!o->IsNumber());
549 value_ = OBJECT_ELEMENTS;
553 ElementsKind GetElementsKind()
const {
556 return PACKED_SMI_ELEMENTS;
557 case NUMBER_ELEMENTS:
558 return PACKED_DOUBLE_ELEMENTS;
559 case OBJECT_ELEMENTS:
560 return PACKED_ELEMENTS;
563 return PACKED_ELEMENTS;
572 template <
bool seq_one_byte>
580 AdvanceSkipWhitespace();
584 if (element.is_null())
return ReportUnexpectedCharacter();
585 elements.push_back(element);
586 lattice.Update(element);
587 }
while (MatchSkipWhiteSpace(
','));
589 return ReportUnexpectedCharacter();
592 AdvanceSkipWhitespace();
596 Handle<Object> json_array;
597 const ElementsKind kind = lattice.GetElementsKind();
598 int elements_size =
static_cast<int>(elements.size());
601 case PACKED_ELEMENTS:
602 case PACKED_SMI_ELEMENTS: {
603 Handle<FixedArray> elems =
604 factory()->NewFixedArray(elements_size, pretenure_);
605 for (
int i = 0;
i < elements_size;
i++) elems->set(
i, *elements[
i]);
606 json_array = factory()->NewJSArrayWithElements(elems, kind, pretenure_);
609 case PACKED_DOUBLE_ELEMENTS: {
610 Handle<FixedDoubleArray> elems = Handle<FixedDoubleArray>::cast(
611 factory()->NewFixedDoubleArray(elements_size, pretenure_));
612 for (
int i = 0;
i < elements_size;
i++) {
613 elems->set(
i, elements[
i]->Number());
615 json_array = factory()->NewJSArrayWithElements(elems, kind, pretenure_);
622 return scope.CloseAndEscape(json_array);
625 template <
bool seq_one_byte>
626 Handle<Object> JsonParser<seq_one_byte>::ParseJsonNumber() {
627 bool negative =
false;
628 int beg_pos = position_;
637 if (IsDecimalDigit(c0_))
return ReportUnexpectedCharacter();
641 if (c0_ < '1' || c0_ >
'9')
return ReportUnexpectedCharacter();
643 i =
i * 10 + c0_ -
'0';
646 }
while (IsDecimalDigit(c0_));
647 if (c0_ !=
'.' && c0_ !=
'e' && c0_ !=
'E' && digits < 10) {
649 return Handle<Smi>(Smi::FromInt((negative ? -
i :
i)), isolate());
654 if (!IsDecimalDigit(c0_))
return ReportUnexpectedCharacter();
657 }
while (IsDecimalDigit(c0_));
659 if (AsciiAlphaToLower(c0_) ==
'e') {
661 if (c0_ ==
'-' || c0_ ==
'+') Advance();
662 if (!IsDecimalDigit(c0_))
return ReportUnexpectedCharacter();
665 }
while (IsDecimalDigit(c0_));
667 int length = position_ - beg_pos;
670 DisallowHeapAllocation no_gc;
671 Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length);
672 number = StringToDouble(chars,
674 std::numeric_limits<double>::quiet_NaN());
676 Vector<uint8_t> buffer = Vector<uint8_t>::New(length);
677 String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
678 Vector<const uint8_t> result =
679 Vector<const uint8_t>(buffer.start(), length);
680 number = StringToDouble(result,
686 return factory()->NewNumber(number, pretenure_);
689 template <
typename StringType>
690 inline void SeqStringSet(Handle<StringType> seq_str,
int i, uc32 c);
693 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str,
int i, uc32 c) {
694 seq_str->SeqTwoByteStringSet(
i, c);
698 inline void SeqStringSet(Handle<SeqOneByteString> seq_str,
int i, uc32 c) {
699 seq_str->SeqOneByteStringSet(
i, c);
702 template <
typename StringType>
703 inline Handle<StringType> NewRawString(Factory* factory,
int length,
704 PretenureFlag pretenure);
707 inline Handle<SeqTwoByteString> NewRawString(Factory* factory,
int length,
708 PretenureFlag pretenure) {
709 return factory->NewRawTwoByteString(length, pretenure).ToHandleChecked();
713 inline Handle<SeqOneByteString> NewRawString(Factory* factory,
int length,
714 PretenureFlag pretenure) {
715 return factory->NewRawOneByteString(length, pretenure).ToHandleChecked();
721 template <
bool seq_one_byte>
722 template <
typename StringType,
typename SinkChar>
723 Handle<String> JsonParser<seq_one_byte>::SlowScanJsonString(
724 Handle<String> prefix,
int start,
int end) {
725 int count = end - start;
726 int max_length = count + source_length_ - position_;
727 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
728 Handle<StringType> seq_string =
729 NewRawString<StringType>(factory(), length, pretenure_);
732 DisallowHeapAllocation no_gc;
734 SinkChar* dest = seq_string->GetChars();
735 String::WriteToFlat(*prefix, dest, start, end);
740 if (c0_ < 0x20)
return Handle<String>::null();
741 if (count >= length) {
743 return SlowScanJsonString<StringType, SinkChar>(seq_string, 0, count);
750 if (
sizeof(SinkChar) == kUC16Size || seq_one_byte ||
751 c0_ <= String::kMaxOneByteCharCode) {
752 SeqStringSet(seq_string, count++, c0_);
756 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0, count);
764 SeqStringSet(seq_string, count++, c0_);
767 SeqStringSet(seq_string, count++,
'\x08');
770 SeqStringSet(seq_string, count++,
'\x0C');
773 SeqStringSet(seq_string, count++,
'\x0A');
776 SeqStringSet(seq_string, count++,
'\x0D');
779 SeqStringSet(seq_string, count++,
'\x09');
783 for (
int i = 0;
i < 4;
i++) {
785 int digit = HexValue(c0_);
787 return Handle<String>::null();
789 value = value * 16 + digit;
791 if (
sizeof(SinkChar) == kUC16Size ||
792 value <= String::kMaxOneByteCharCode) {
793 SeqStringSet(seq_string, count++, value);
800 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0,
805 return Handle<String>::null();
813 AdvanceSkipWhitespace();
816 return SeqString::Truncate(seq_string, count);
819 template <
bool seq_one_byte>
820 Handle<String> JsonParser<seq_one_byte>::ScanJsonString() {
824 AdvanceSkipWhitespace();
825 return factory()->empty_string();
837 int position = position_;
840 static_cast<uint32_t>(isolate()->heap()->HashSeed());
842 bool is_array_index =
true;
847 int beg_pos = position_;
848 position_ = position;
849 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos,
854 position_ = position;
855 return Handle<String>::null();
857 if (is_array_index) {
859 if (!IsDecimalDigit(c0) || (position > position_ && index == 0)) {
860 is_array_index =
false;
863 is_array_index = index <= 429496729U - ((d + 3) >> 3);
864 index = (index * 10) + d;
867 running_hash = StringHasher::AddCharacterCore(running_hash,
868 static_cast<uint16_t>(c0));
870 if (position >= source_length_) {
872 position_ = position;
873 return Handle<String>::null();
875 c0 = seq_source_->SeqOneByteStringGet(position);
877 int length = position - position_;
879 if (is_array_index) {
881 StringHasher::MakeArrayIndexHash(index, length) >> String::kHashShift;
882 }
else if (length <= String::kMaxHashCalcLength) {
883 hash = StringHasher::GetHashCore(running_hash);
885 hash =
static_cast<uint32_t>(length);
887 StringTable string_table = isolate()->heap()->string_table();
888 uint32_t capacity = string_table->Capacity();
889 uint32_t entry = StringTable::FirstProbe(hash, capacity);
891 Handle<String> result;
893 Object* element = string_table->KeyAt(entry);
894 if (element->IsUndefined(isolate())) {
897 factory()->InternalizeOneByteString(seq_source_, position_, length);
900 if (!element->IsTheHole(isolate())) {
901 DisallowHeapAllocation no_gc;
902 Vector<const uint8_t> string_vector(seq_source_->GetChars() + position_,
904 if (String::cast(element)->IsOneByteEqualTo(string_vector)) {
905 result = Handle<String>(String::cast(element), isolate());
906 DCHECK_EQ(result->Hash(),
907 (hash << String::kHashShift) >> String::kHashShift);
911 entry = StringTable::NextProbe(entry, count++, capacity);
913 position_ = position;
915 AdvanceSkipWhitespace();
919 int beg_pos = position_;
923 if (c0_ < 0x20)
return Handle<String>::null();
925 if (seq_one_byte || c0_ <= String::kMaxOneByteCharCode) {
928 return SlowScanJsonString<SeqTwoByteString, uc16>(source_, beg_pos,
932 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos,
935 }
while (c0_ !=
'"');
936 int length = position_ - beg_pos;
937 Handle<String> result =
938 factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked();
939 DisallowHeapAllocation no_gc;
940 uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
941 String::WriteToFlat(*source_, dest, beg_pos, position_);
945 AdvanceSkipWhitespace();
950 template class JsonParser<true>;
951 template class JsonParser<false>;