[elements] Handlify SloppyArguments IndexOfValueImpl
The raw pointer to the parameter_map might get stale in case of accessors present on the arguments object. Drive-by-fix: use nullptr instead of the_hole with isolate access. BUG=chromium:645680 Review-Url: https://codereview.chromium.org/2332503002 Cr-Commit-Position: refs/heads/master@{#39359}
This commit is contained in:
parent
e031451cd7
commit
621f4af720
@ -2946,8 +2946,7 @@ class SloppyArgumentsElementsAccessor
|
|||||||
FixedArray* parameter_map = FixedArray::cast(parameters);
|
FixedArray* parameter_map = FixedArray::cast(parameters);
|
||||||
uint32_t length = parameter_map->length() - 2;
|
uint32_t length = parameter_map->length() - 2;
|
||||||
if (entry < length) {
|
if (entry < length) {
|
||||||
return !GetParameterMapArg(parameter_map, entry)
|
return HasParameterMapArg(parameter_map, entry);
|
||||||
->IsTheHole(parameter_map->GetIsolate());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
|
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
|
||||||
@ -2975,8 +2974,7 @@ class SloppyArgumentsElementsAccessor
|
|||||||
FixedArrayBase* parameters,
|
FixedArrayBase* parameters,
|
||||||
uint32_t index, PropertyFilter filter) {
|
uint32_t index, PropertyFilter filter) {
|
||||||
FixedArray* parameter_map = FixedArray::cast(parameters);
|
FixedArray* parameter_map = FixedArray::cast(parameters);
|
||||||
Object* probe = GetParameterMapArg(parameter_map, index);
|
if (HasParameterMapArg(parameter_map, index)) return index;
|
||||||
if (!probe->IsTheHole(holder->GetIsolate())) return index;
|
|
||||||
|
|
||||||
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
|
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
|
||||||
uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments,
|
uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments,
|
||||||
@ -2995,11 +2993,11 @@ class SloppyArgumentsElementsAccessor
|
|||||||
return ArgumentsAccessor::GetDetailsImpl(arguments, entry - length);
|
return ArgumentsAccessor::GetDetailsImpl(arguments, entry - length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t index) {
|
static bool HasParameterMapArg(FixedArray* parameter_map, uint32_t index) {
|
||||||
uint32_t length = parameter_map->length() - 2;
|
uint32_t length = parameter_map->length() - 2;
|
||||||
return index < length
|
if (index >= length) return false;
|
||||||
? parameter_map->get(index + 2)
|
return !parameter_map->get(index + 2)->IsTheHole(
|
||||||
: Object::cast(parameter_map->GetHeap()->the_hole_value());
|
parameter_map->GetIsolate());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
|
static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
|
||||||
@ -3102,16 +3100,17 @@ class SloppyArgumentsElementsAccessor
|
|||||||
uint32_t start_from, uint32_t length) {
|
uint32_t start_from, uint32_t length) {
|
||||||
DCHECK(JSObject::PrototypeHasNoElements(isolate, *object));
|
DCHECK(JSObject::PrototypeHasNoElements(isolate, *object));
|
||||||
Handle<Map> original_map = handle(object->map(), isolate);
|
Handle<Map> original_map = handle(object->map(), isolate);
|
||||||
FixedArray* parameter_map = FixedArray::cast(object->elements());
|
Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()),
|
||||||
|
isolate);
|
||||||
|
|
||||||
for (uint32_t k = start_from; k < length; ++k) {
|
for (uint32_t k = start_from; k < length; ++k) {
|
||||||
uint32_t entry =
|
uint32_t entry =
|
||||||
GetEntryForIndexImpl(*object, parameter_map, k, ALL_PROPERTIES);
|
GetEntryForIndexImpl(*object, *parameter_map, k, ALL_PROPERTIES);
|
||||||
if (entry == kMaxUInt32) {
|
if (entry == kMaxUInt32) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> element_k = GetImpl(parameter_map, entry);
|
Handle<Object> element_k = GetImpl(*parameter_map, entry);
|
||||||
|
|
||||||
if (element_k->IsAccessorPair()) {
|
if (element_k->IsAccessorPair()) {
|
||||||
LookupIterator it(isolate, object, k, LookupIterator::OWN);
|
LookupIterator it(isolate, object, k, LookupIterator::OWN);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
// Flags: --allow-natives-syntax
|
// Flags: --allow-natives-syntax --expose-gc
|
||||||
|
|
||||||
// Ensure `Array.prototype.indexOf` functions correctly for numerous elements
|
// Ensure `Array.prototype.indexOf` functions correctly for numerous elements
|
||||||
// kinds, and various exotic receiver types,
|
// kinds, and various exotic receiver types,
|
||||||
@ -107,7 +107,7 @@ var kTests = {
|
|||||||
|
|
||||||
DICTIONARY_ELEMENTS() {
|
DICTIONARY_ELEMENTS() {
|
||||||
var array = [];
|
var array = [];
|
||||||
Object.defineProperty(array, 4, { get() { return NaN; } });
|
Object.defineProperty(array, 4, { get() { gc(); return NaN; } });
|
||||||
Object.defineProperty(array, 7, { value: Function });
|
Object.defineProperty(array, 7, { value: Function });
|
||||||
|
|
||||||
assertTrue(%HasDictionaryElements(array));
|
assertTrue(%HasDictionaryElements(array));
|
||||||
@ -226,7 +226,7 @@ var kTests = {
|
|||||||
|
|
||||||
DICTIONARY_ELEMENTS() {
|
DICTIONARY_ELEMENTS() {
|
||||||
var object = { length: 8 };
|
var object = { length: 8 };
|
||||||
Object.defineProperty(object, 4, { get() { return NaN; } });
|
Object.defineProperty(object, 4, { get() { gc(); return NaN; } });
|
||||||
Object.defineProperty(object, 7, { value: Function });
|
Object.defineProperty(object, 7, { value: Function });
|
||||||
|
|
||||||
assertTrue(%HasDictionaryElements(object));
|
assertTrue(%HasDictionaryElements(object));
|
||||||
@ -244,8 +244,10 @@ var kTests = {
|
|||||||
return {
|
return {
|
||||||
__proto__: {},
|
__proto__: {},
|
||||||
get 0() {
|
get 0() {
|
||||||
|
gc();
|
||||||
this.__proto__.__proto__ = {
|
this.__proto__.__proto__ = {
|
||||||
get 1() {
|
get 1() {
|
||||||
|
gc();
|
||||||
this[2] = "c";
|
this[2] = "c";
|
||||||
return "b";
|
return "b";
|
||||||
}
|
}
|
||||||
@ -313,7 +315,7 @@ var kTests = {
|
|||||||
|
|
||||||
SLOW_SLOPPY_ARGUMENTS_ELEMENTS() {
|
SLOW_SLOPPY_ARGUMENTS_ELEMENTS() {
|
||||||
var args = (function(a, a) { return arguments; })("foo", NaN, "bar");
|
var args = (function(a, a) { return arguments; })("foo", NaN, "bar");
|
||||||
Object.defineProperty(args, 3, { get() { return "silver"; } });
|
Object.defineProperty(args, 3, { get() { gc(); return "silver"; } });
|
||||||
Object.defineProperty(args, "length", { value: 4 });
|
Object.defineProperty(args, "length", { value: 4 });
|
||||||
assertTrue(%HasSloppyArgumentsElements(args));
|
assertTrue(%HasSloppyArgumentsElements(args));
|
||||||
|
|
||||||
|
20
test/mjsunit/regress/regress-645680.js
Normal file
20
test/mjsunit/regress/regress-645680.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2016 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: --expose-gc
|
||||||
|
//
|
||||||
|
function getRandomProperty(v, rand) {
|
||||||
|
var properties = Object.getOwnPropertyNames(v);
|
||||||
|
if ("constructor" && v.constructor.hasOwnProperty()) {; }
|
||||||
|
if (properties.length == 0) { return "0"; }
|
||||||
|
return properties[rand % properties.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
var __v_18 = (function( b) { return arguments; })("foo", NaN, "bar");
|
||||||
|
__v_18.__p_293850326 = "foo";
|
||||||
|
__v_18.__defineGetter__(getRandomProperty( 990787501), function() {
|
||||||
|
gc();
|
||||||
|
return __v_18.__p_293850326;
|
||||||
|
});
|
||||||
|
Array.prototype.indexOf.call(__v_18)
|
Loading…
Reference in New Issue
Block a user