| Index: src/json-parser.h
|
| diff --git a/src/json-parser.h b/src/json-parser.h
|
| index f0d9e4b8b055d0d042ac9e84386ff22772bd7b3d..1a9a36f283513bab2f3b72d2d6e5a78c6d0d2de8 100644
|
| --- a/src/json-parser.h
|
| +++ b/src/json-parser.h
|
| @@ -154,10 +154,6 @@
|
| // A JSON array doesn't allow numbers and identifiers as keys, like a
|
| // JavaScript array.
|
| Handle<Object> ParseJsonObject();
|
| -
|
| - // Helper for ParseJsonObject. Parses the form "123": obj, which is recorded
|
| - // as an element, not a property.
|
| - bool ParseElement(Handle<JSObject> json_object);
|
|
|
| // Parses a JSON array literal (grammar production JSONArray). An array
|
| // literal is a square-bracketed and comma separated sequence (possibly empty)
|
| @@ -303,38 +299,6 @@
|
| }
|
|
|
|
|
| -template <bool seq_one_byte>
|
| -bool JsonParser<seq_one_byte>::ParseElement(Handle<JSObject> json_object) {
|
| - uint32_t index = 0;
|
| - // Maybe an array index, try to parse it.
|
| - if (c0_ == '0') {
|
| - // With a leading zero, the string has to be "0" only to be an index.
|
| - Advance();
|
| - } else {
|
| - do {
|
| - int d = c0_ - '0';
|
| - if (index > 429496729U - ((d > 5) ? 1 : 0)) break;
|
| - index = (index * 10) + d;
|
| - Advance();
|
| - } while (IsDecimalDigit(c0_));
|
| - }
|
| -
|
| - if (c0_ == '"') {
|
| - // Successfully parsed index, parse and store element.
|
| - AdvanceSkipWhitespace();
|
| -
|
| - if (c0_ == ':') {
|
| - AdvanceSkipWhitespace();
|
| - Handle<Object> value = ParseJsonValue();
|
| - if (!value.is_null()) {
|
| - JSObject::SetOwnElement(json_object, index, value, SLOPPY).Assert();
|
| - return true;
|
| - }
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| // Parse a JSON object. Position must be right at '{'.
|
| template <bool seq_one_byte>
|
| Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
|
| @@ -356,10 +320,35 @@
|
| int start_position = position_;
|
| Advance();
|
|
|
| + uint32_t index = 0;
|
| if (IsDecimalDigit(c0_)) {
|
| - if (ParseElement(json_object)) continue;
|
| - }
|
| - // Not an index, fallback to the slow path.
|
| + // Maybe an array index, try to parse it.
|
| + if (c0_ == '0') {
|
| + // With a leading zero, the string has to be "0" only to be an index.
|
| + Advance();
|
| + } else {
|
| + do {
|
| + int d = c0_ - '0';
|
| + if (index > 429496729U - ((d > 5) ? 1 : 0)) break;
|
| + index = (index * 10) + d;
|
| + Advance();
|
| + } while (IsDecimalDigit(c0_));
|
| + }
|
| +
|
| + if (c0_ == '"') {
|
| + // Successfully parsed index, parse and store element.
|
| + AdvanceSkipWhitespace();
|
| +
|
| + if (c0_ != ':') return ReportUnexpectedCharacter();
|
| + AdvanceSkipWhitespace();
|
| + Handle<Object> value = ParseJsonValue();
|
| + if (value.is_null()) return ReportUnexpectedCharacter();
|
| +
|
| + JSObject::SetOwnElement(json_object, index, value, SLOPPY).Assert();
|
| + continue;
|
| + }
|
| + // Not an index, fallback to the slow path.
|
| + }
|
|
|
| position_ = start_position;
|
| #ifdef DEBUG
|
| @@ -371,106 +360,80 @@
|
|
|
| // Try to follow existing transitions as long as possible. Once we stop
|
| // transitioning, no transition can be found anymore.
|
| - DCHECK(transitioning);
|
| - // First check whether there is a single expected transition. If so, try
|
| - // to parse it first.
|
| - bool follow_expected = false;
|
| - Handle<Map> target;
|
| - if (seq_one_byte) {
|
| - key = TransitionArray::ExpectedTransitionKey(map);
|
| - follow_expected = !key.is_null() && ParseJsonString(key);
|
| - }
|
| - // If the expected transition hits, follow it.
|
| - if (follow_expected) {
|
| - target = TransitionArray::ExpectedTransitionTarget(map);
|
| + if (transitioning) {
|
| + // First check whether there is a single expected transition. If so, try
|
| + // to parse it first.
|
| + bool follow_expected = false;
|
| + Handle<Map> target;
|
| + if (seq_one_byte) {
|
| + key = TransitionArray::ExpectedTransitionKey(map);
|
| + follow_expected = !key.is_null() && ParseJsonString(key);
|
| + }
|
| + // If the expected transition hits, follow it.
|
| + if (follow_expected) {
|
| + target = TransitionArray::ExpectedTransitionTarget(map);
|
| + } else {
|
| + // If the expected transition failed, parse an internalized string and
|
| + // try to find a matching transition.
|
| + key = ParseJsonInternalizedString();
|
| + if (key.is_null()) return ReportUnexpectedCharacter();
|
| +
|
| + target = TransitionArray::FindTransitionToField(map, key);
|
| + // If a transition was found, follow it and continue.
|
| + transitioning = !target.is_null();
|
| + }
|
| + if (c0_ != ':') return ReportUnexpectedCharacter();
|
| +
|
| + AdvanceSkipWhitespace();
|
| + value = ParseJsonValue();
|
| + if (value.is_null()) return ReportUnexpectedCharacter();
|
| +
|
| + if (transitioning) {
|
| + PropertyDetails details =
|
| + target->instance_descriptors()->GetDetails(descriptor);
|
| + Representation expected_representation = details.representation();
|
| +
|
| + if (value->FitsRepresentation(expected_representation)) {
|
| + if (expected_representation.IsHeapObject() &&
|
| + !target->instance_descriptors()
|
| + ->GetFieldType(descriptor)
|
| + ->NowContains(value)) {
|
| + Handle<HeapType> value_type(value->OptimalType(
|
| + isolate(), expected_representation));
|
| + Map::GeneralizeFieldType(target, descriptor,
|
| + expected_representation, value_type);
|
| + }
|
| + DCHECK(target->instance_descriptors()->GetFieldType(
|
| + descriptor)->NowContains(value));
|
| + properties.Add(value, zone());
|
| + map = target;
|
| + descriptor++;
|
| + continue;
|
| + } else {
|
| + transitioning = false;
|
| + }
|
| + }
|
| +
|
| + // Commit the intermediate state to the object and stop transitioning.
|
| + CommitStateToJsonObject(json_object, map, &properties);
|
| } else {
|
| - // If the expected transition failed, parse an internalized string and
|
| - // try to find a matching transition.
|
| key = ParseJsonInternalizedString();
|
| - if (key.is_null()) return ReportUnexpectedCharacter();
|
| -
|
| - target = TransitionArray::FindTransitionToField(map, key);
|
| - // If a transition was found, follow it and continue.
|
| - transitioning = !target.is_null();
|
| - }
|
| - if (c0_ != ':') return ReportUnexpectedCharacter();
|
| -
|
| - AdvanceSkipWhitespace();
|
| - value = ParseJsonValue();
|
| - if (value.is_null()) return ReportUnexpectedCharacter();
|
| -
|
| - if (transitioning) {
|
| - PropertyDetails details =
|
| - target->instance_descriptors()->GetDetails(descriptor);
|
| - Representation expected_representation = details.representation();
|
| -
|
| - if (value->FitsRepresentation(expected_representation)) {
|
| - if (expected_representation.IsHeapObject() &&
|
| - !target->instance_descriptors()
|
| - ->GetFieldType(descriptor)
|
| - ->NowContains(value)) {
|
| - Handle<HeapType> value_type(
|
| - value->OptimalType(isolate(), expected_representation));
|
| - Map::GeneralizeFieldType(target, descriptor,
|
| - expected_representation, value_type);
|
| - }
|
| - DCHECK(target->instance_descriptors()
|
| - ->GetFieldType(descriptor)
|
| - ->NowContains(value));
|
| - properties.Add(value, zone());
|
| - map = target;
|
| - descriptor++;
|
| - continue;
|
| - } else {
|
| - transitioning = false;
|
| - }
|
| - }
|
| -
|
| - DCHECK(!transitioning);
|
| -
|
| - // Commit the intermediate state to the object and stop transitioning.
|
| - CommitStateToJsonObject(json_object, map, &properties);
|
| + if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
|
| +
|
| + AdvanceSkipWhitespace();
|
| + value = ParseJsonValue();
|
| + if (value.is_null()) return ReportUnexpectedCharacter();
|
| + }
|
|
|
| Runtime::DefineObjectProperty(json_object, key, value, NONE).Check();
|
| - } while (transitioning && MatchSkipWhiteSpace(','));
|
| + } while (MatchSkipWhiteSpace(','));
|
| + if (c0_ != '}') {
|
| + return ReportUnexpectedCharacter();
|
| + }
|
|
|
| // If we transitioned until the very end, transition the map now.
|
| if (transitioning) {
|
| CommitStateToJsonObject(json_object, map, &properties);
|
| - } else {
|
| - while (MatchSkipWhiteSpace(',')) {
|
| - HandleScope local_scope(isolate());
|
| - if (c0_ != '"') return ReportUnexpectedCharacter();
|
| -
|
| - int start_position = position_;
|
| - Advance();
|
| -
|
| - if (IsDecimalDigit(c0_)) {
|
| - if (ParseElement(json_object)) continue;
|
| - }
|
| - // Not an index, fallback to the slow path.
|
| -
|
| - position_ = start_position;
|
| -#ifdef DEBUG
|
| - c0_ = '"';
|
| -#endif
|
| -
|
| - Handle<String> key;
|
| - Handle<Object> value;
|
| -
|
| - key = ParseJsonInternalizedString();
|
| - if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
|
| -
|
| - AdvanceSkipWhitespace();
|
| - value = ParseJsonValue();
|
| - if (value.is_null()) return ReportUnexpectedCharacter();
|
| -
|
| - Runtime::DefineObjectProperty(json_object, key, value, NONE).Check();
|
| - }
|
| - }
|
| -
|
| - if (c0_ != '}') {
|
| - return ReportUnexpectedCharacter();
|
| }
|
| }
|
| AdvanceSkipWhitespace();
|
|
|