Commit 3ac7a3e5 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

More LookupIterator fixes after r65078

(1) One more place in ic.cc must guard against "lookup->name()" calls
when the LookupIterator might be in indexed mode.

(2) Rather than burdening LookupIterator users with specifying
"kGuaranteedNoTypedArray", we can do the corresponding calculation in
the LookupIterator itself, which makes it robust towards any callers
that haven't been updated (specifically, in Object.values).

Bug: chromium:1027461,chromium:1028213
Change-Id: I76b5d08e309fc2a694955b537adbeb5a30e681f7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1936474Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65177}
parent 95e9ac05
......@@ -742,7 +742,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
// `in` cannot be called on strings, and will always return true for string
// wrapper length and function prototypes. The latter two cases are given
// LoadHandler::LoadNativeDataProperty below.
if (!IsAnyHas()) {
if (!IsAnyHas() && !lookup->IsElement()) {
if (receiver->IsString() && *lookup->name() == roots.length_string()) {
TRACE_HANDLER_STATS(isolate(), LoadIC_StringLength);
return BUILTIN_CODE(isolate(), LoadIC_StringLength);
......
......@@ -648,8 +648,7 @@ Handle<Object> JsonParser<Char>::BuildJsonObject(
DCHECK(!key->AsArrayIndex(&index));
#endif
Handle<Object> value = property.value;
LookupIterator it(isolate_, object, key, object,
LookupIterator::OWN_NO_TYPEDARRAY);
LookupIterator it(isolate_, object, key, object, LookupIterator::OWN);
JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE).Check();
}
......
......@@ -42,7 +42,10 @@ LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
index_(kInvalidIndex) {
#ifdef DEBUG
// Assert that the name is not an index.
if (configuration & kGuaranteedNotTypedArray) {
// If we're not looking at the prototype chain and the initial holder is
// not a typed array, then this means "array index", otherwise we need to
// ensure the full generality so that typed arrays are handled correctly.
if (!check_prototype_chain() && !holder->IsJSTypedArray()) {
uint32_t index;
DCHECK(!name->AsArrayIndex(&index));
} else {
......
......@@ -22,18 +22,10 @@ class V8_EXPORT_PRIVATE LookupIterator final {
// Configuration bits.
kInterceptor = 1 << 0,
kPrototypeChain = 1 << 1,
// For lookups on arbitrary objects, keys that are strings representing
// integers larger than kMaxArrayIndex but still in size_t range must
// be treated as "elements" lookups, even though for non-TypedArray holders
// such keys are converted back to strings. For efficiency, we allow
// annotating use cases where it is guaranteed that no TypedArrays will be
// encountered by the LookupIterator, so they can run in "property" mode.
kGuaranteedNotTypedArray = 1 << 2,
// Convenience combinations of bits.
OWN_SKIP_INTERCEPTOR = 0,
OWN = kInterceptor,
OWN_NO_TYPEDARRAY = OWN | kGuaranteedNotTypedArray,
PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kPrototypeChain,
PROTOTYPE_CHAIN = kPrototypeChain | kInterceptor,
DEFAULT = PROTOTYPE_CHAIN
......
......@@ -417,15 +417,14 @@ Handle<JSObject> CreateObjectLiteral(
if (value->IsUninitialized(isolate)) {
value = handle(Smi::zero(), isolate);
}
LookupIterator it(isolate, boilerplate, element_index, boilerplate,
LookupIterator::OWN_NO_TYPEDARRAY);
JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE).Check();
JSObject::SetOwnElementIgnoreAttributes(boilerplate, element_index, value,
NONE)
.Check();
} else {
Handle<String> name = Handle<String>::cast(key);
DCHECK(!name->AsArrayIndex(&element_index));
LookupIterator it(boilerplate, name, boilerplate,
LookupIterator::OWN_NO_TYPEDARRAY);
JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE).Check();
JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, value, NONE)
.Check();
}
}
......
......@@ -58,3 +58,42 @@
var target = {};
Reflect.set(target, key, value, receiver);
})();
// crbug.com/1028213
(function() {
function load(obj, key) {
return obj[key];
}
%PrepareFunctionForOptimization(load);
let obj = function() {};
obj.__proto__ = new Int8Array(1);
let key = Object(4294967297);
for (let i = 0; i < 3; i++) {
load(obj, key);
}
})();
(function() {
function load(obj, key) {
return obj[key];
}
%PrepareFunctionForOptimization(load);
let obj = new String("abc");
obj.__proto__ = new Int8Array(1);
let key = Object(4294967297);
for (let i = 0; i < 3; i++) {
load(obj, key);
}
})();
// crbug.com/1027461#c12
(function() {
let arr = new Int32Array(2);
Object.defineProperty(arr, "foo", {get:function() { this.valueOf = 1; }});
arr[9007199254740991] = 1;
Object.values(arr);
let obj = [1, 2, 3];
Object.defineProperty(obj, 2, {get:function() { this.valueOf = 1; }});
obj[9007199254740991] = 1;
Object.values(obj);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment