Fixed mutable heap numbers leak in JSON parser.
BUG=chromium:423687 LOG=N R=verwaest@chromium.org Review URL: https://codereview.chromium.org/669403002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24849 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c7685a59f0
commit
5509cc2c07
@ -182,6 +182,9 @@ class JsonParser BASE_EMBEDDED {
|
||||
private:
|
||||
Zone* zone() { return &zone_; }
|
||||
|
||||
void CommitStateToJsonObject(Handle<JSObject> json_object, Handle<Map> map,
|
||||
ZoneList<Handle<Object> >* properties);
|
||||
|
||||
Handle<String> source_;
|
||||
int source_length_;
|
||||
Handle<SeqOneByteString> seq_source_;
|
||||
@ -410,13 +413,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
|
||||
}
|
||||
|
||||
// Commit the intermediate state to the object and stop transitioning.
|
||||
JSObject::AllocateStorageForMap(json_object, map);
|
||||
int length = properties.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
Handle<Object> value = properties[i];
|
||||
FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
|
||||
json_object->FastPropertyAtPut(index, *value);
|
||||
}
|
||||
CommitStateToJsonObject(json_object, map, &properties);
|
||||
} else {
|
||||
key = ParseJsonInternalizedString();
|
||||
if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
|
||||
@ -434,19 +431,50 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
|
||||
|
||||
// If we transitioned until the very end, transition the map now.
|
||||
if (transitioning) {
|
||||
JSObject::AllocateStorageForMap(json_object, map);
|
||||
int length = properties.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
Handle<Object> value = properties[i];
|
||||
FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
|
||||
json_object->FastPropertyAtPut(index, *value);
|
||||
}
|
||||
CommitStateToJsonObject(json_object, map, &properties);
|
||||
}
|
||||
}
|
||||
AdvanceSkipWhitespace();
|
||||
return scope.CloseAndEscape(json_object);
|
||||
}
|
||||
|
||||
|
||||
template <bool seq_one_byte>
|
||||
void JsonParser<seq_one_byte>::CommitStateToJsonObject(
|
||||
Handle<JSObject> json_object, Handle<Map> map,
|
||||
ZoneList<Handle<Object> >* properties) {
|
||||
JSObject::AllocateStorageForMap(json_object, map);
|
||||
DCHECK(!json_object->map()->is_dictionary_map());
|
||||
|
||||
DisallowHeapAllocation no_gc;
|
||||
Factory* factory = isolate()->factory();
|
||||
// If the |json_object|'s map is exactly the same as |map| then the
|
||||
// |properties| values correspond to the |map| and nothing more has to be
|
||||
// done. But if the |json_object|'s map is different then we have to
|
||||
// iterate descriptors to ensure that properties still correspond to the
|
||||
// map.
|
||||
bool slow_case = json_object->map() != *map;
|
||||
DescriptorArray* descriptors = NULL;
|
||||
|
||||
int length = properties->length();
|
||||
if (slow_case) {
|
||||
descriptors = json_object->map()->instance_descriptors();
|
||||
DCHECK(json_object->map()->NumberOfOwnDescriptors() == length);
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
Handle<Object> value = (*properties)[i];
|
||||
if (slow_case && value->IsMutableHeapNumber() &&
|
||||
!descriptors->GetDetails(i).representation().IsDouble()) {
|
||||
// Turn mutable heap numbers into immutable if the field representation
|
||||
// is not double.
|
||||
HeapNumber::cast(*value)->set_map(*factory->heap_number_map());
|
||||
}
|
||||
FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
|
||||
json_object->FastPropertyAtPut(index, *value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse a JSON array. Position must be right at '['.
|
||||
template <bool seq_one_byte>
|
||||
Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() {
|
||||
|
10
test/mjsunit/regress/regress-crbug-423687.js
Normal file
10
test/mjsunit/regress/regress-crbug-423687.js
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var json = '{"a":{"c":2.1,"d":0},"b":{"c":7,"1024":8}}';
|
||||
var data = JSON.parse(json);
|
||||
|
||||
data.b.c++;
|
Loading…
Reference in New Issue
Block a user