Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(743)

Unified Diff: src/json-parser.h

Issue 1052593002: Revert of Fix JSON parser Handle leak (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap/heap.cc ('k') | test/mjsunit/regress/regress-3976.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
« no previous file with comments | « src/heap/heap.cc ('k') | test/mjsunit/regress/regress-3976.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698