Avoid converting key to string for deleting of elements
Additionally rips out (now) unnecessary duplicate code in DefineArrayProperty. BUG= Review URL: https://codereview.chromium.org/1224523002 Cr-Commit-Position: refs/heads/master@{#29450}
This commit is contained in:
parent
dbda22fdd1
commit
d5335cba31
22
src/api.cc
22
src/api.cc
@ -3607,25 +3607,6 @@ bool v8::Object::ForceSet(v8::Handle<Value> key, v8::Handle<Value> value,
|
||||
}
|
||||
|
||||
|
||||
MUST_USE_RESULT
|
||||
static i::MaybeHandle<i::Object> DeleteObjectProperty(
|
||||
i::Isolate* isolate, i::Handle<i::JSReceiver> receiver,
|
||||
i::Handle<i::Object> key, i::LanguageMode language_mode) {
|
||||
// Check if the given key is an array index.
|
||||
uint32_t index = 0;
|
||||
if (key->ToArrayIndex(&index)) {
|
||||
return i::JSReceiver::DeleteElement(receiver, index, language_mode);
|
||||
}
|
||||
|
||||
i::Handle<i::Name> name;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
|
||||
i::Runtime::ToName(isolate, key),
|
||||
i::MaybeHandle<i::Object>());
|
||||
|
||||
return i::JSReceiver::DeletePropertyOrElement(receiver, name, language_mode);
|
||||
}
|
||||
|
||||
|
||||
MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
|
||||
Local<Value> key) {
|
||||
PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
|
||||
@ -3883,7 +3864,8 @@ Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
|
||||
auto key_obj = Utils::OpenHandle(*key);
|
||||
i::Handle<i::Object> obj;
|
||||
has_pending_exception =
|
||||
!DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY).ToHandle(&obj);
|
||||
!i::Runtime::DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY)
|
||||
.ToHandle(&obj);
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||
return Just(obj->IsTrue());
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ function ArrayPop() {
|
||||
|
||||
n--;
|
||||
var value = array[n];
|
||||
Delete(array, $toName(n), true);
|
||||
Delete(array, n, true);
|
||||
array.length = n;
|
||||
return value;
|
||||
}
|
||||
|
@ -259,7 +259,6 @@ class CallSite {
|
||||
"In strong mode, using an undeclared global variable '%' is not allowed") \
|
||||
T(UnsupportedSuper, "Unsupported reference to 'super'") \
|
||||
/* RangeError */ \
|
||||
T(ArrayLengthOutOfRange, "defineProperty() array length out of range") \
|
||||
T(DateRange, "Provided date is not in valid range.") \
|
||||
T(ExpectedLocation, "Expected Area/Location for time zone, got %") \
|
||||
T(InvalidArrayBufferLength, "Invalid array buffer length") \
|
||||
|
@ -5276,7 +5276,8 @@ MaybeHandle<Object> JSReceiver::DeleteProperty(LookupIterator* it,
|
||||
MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
|
||||
uint32_t index,
|
||||
LanguageMode language_mode) {
|
||||
LookupIterator it(object->GetIsolate(), object, index);
|
||||
LookupIterator it(object->GetIsolate(), object, index,
|
||||
LookupIterator::HIDDEN);
|
||||
return DeleteProperty(&it, language_mode);
|
||||
}
|
||||
|
||||
|
@ -509,7 +509,7 @@ SHR_STRONG = function SHR_STRONG(y) {
|
||||
|
||||
// ECMA-262, section 11.4.1, page 46.
|
||||
DELETE = function DELETE(key, language_mode) {
|
||||
return %DeleteProperty(%$toObject(this), %$toName(key), language_mode);
|
||||
return %DeleteProperty(%$toObject(this), key, language_mode);
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,6 +162,23 @@ MaybeHandle<Object> Runtime::KeyedGetObjectProperty(
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
|
||||
Handle<JSReceiver> receiver,
|
||||
Handle<Object> key,
|
||||
LanguageMode language_mode) {
|
||||
// Check if the given key is an array index.
|
||||
uint32_t index = 0;
|
||||
if (key->ToArrayIndex(&index)) {
|
||||
return JSReceiver::DeleteElement(receiver, index, language_mode);
|
||||
}
|
||||
|
||||
Handle<Name> name;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
|
||||
|
||||
return JSReceiver::DeletePropertyOrElement(receiver, name, language_mode);
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
|
||||
Handle<Object> object,
|
||||
Handle<Object> key,
|
||||
@ -591,13 +608,13 @@ RUNTIME_FUNCTION(Runtime_SetProperty) {
|
||||
RUNTIME_FUNCTION(Runtime_DeleteProperty) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 3);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
|
||||
CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, result,
|
||||
JSReceiver::DeletePropertyOrElement(object, key, language_mode));
|
||||
Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode));
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
@ -822,6 +822,10 @@ class Runtime : public AllStatic {
|
||||
Isolate* isolate, Handle<Object> object, uint32_t index,
|
||||
LanguageMode language_mode = SLOPPY);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> DeleteObjectProperty(
|
||||
Isolate* isolate, Handle<JSReceiver> receiver, Handle<Object> key,
|
||||
LanguageMode language_mode);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SetObjectProperty(
|
||||
Isolate* isolate, Handle<Object> object, Handle<Object> key,
|
||||
Handle<Object> value, LanguageMode language_mode);
|
||||
|
@ -802,72 +802,7 @@ function DefineObjectProperty(obj, p, desc, should_throw) {
|
||||
|
||||
// ES5 section 15.4.5.1.
|
||||
function DefineArrayProperty(obj, p, desc, should_throw) {
|
||||
// Note that the length of an array is not actually stored as part of the
|
||||
// property, hence we use generated code throughout this function instead of
|
||||
// DefineObjectProperty() to modify its value.
|
||||
|
||||
// Step 3 - Special handling for length property.
|
||||
if (p === "length") {
|
||||
var length = obj.length;
|
||||
var old_length = length;
|
||||
if (!desc.hasValue()) {
|
||||
return DefineObjectProperty(obj, "length", desc, should_throw);
|
||||
}
|
||||
var new_length = $toUint32(desc.getValue());
|
||||
if (new_length != $toNumber(desc.getValue())) {
|
||||
throw MakeRangeError(kArrayLengthOutOfRange);
|
||||
}
|
||||
var length_desc = GetOwnPropertyJS(obj, "length");
|
||||
if (new_length != length && !length_desc.isWritable()) {
|
||||
if (should_throw) {
|
||||
throw MakeTypeError(kRedefineDisallowed, p);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var threw = false;
|
||||
|
||||
var emit_splice = %IsObserved(obj) && new_length !== old_length;
|
||||
var removed;
|
||||
if (emit_splice) {
|
||||
$observeBeginPerformSplice(obj);
|
||||
removed = [];
|
||||
if (new_length < old_length)
|
||||
removed.length = old_length - new_length;
|
||||
}
|
||||
|
||||
while (new_length < length--) {
|
||||
var index = $toString(length);
|
||||
if (emit_splice) {
|
||||
var deletedDesc = GetOwnPropertyJS(obj, index);
|
||||
if (deletedDesc && deletedDesc.hasValue())
|
||||
removed[length - new_length] = deletedDesc.getValue();
|
||||
}
|
||||
if (!Delete(obj, index, false)) {
|
||||
new_length = length + 1;
|
||||
threw = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
threw = !DefineObjectProperty(obj, "length", desc, should_throw) || threw;
|
||||
if (emit_splice) {
|
||||
$observeEndPerformSplice(obj);
|
||||
$observeEnqueueSpliceRecord(obj,
|
||||
new_length < old_length ? new_length : old_length,
|
||||
removed,
|
||||
new_length > old_length ? new_length - old_length : 0);
|
||||
}
|
||||
if (threw) {
|
||||
if (should_throw) {
|
||||
throw MakeTypeError(kRedefineDisallowed, p);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 4 - Special handling for array index.
|
||||
// Step 3 - Special handling for array index.
|
||||
if (!IS_SYMBOL(p)) {
|
||||
var index = $toUint32(p);
|
||||
var emit_splice = false;
|
||||
|
@ -405,7 +405,7 @@ test(function() {
|
||||
test(function() {
|
||||
"use strict";
|
||||
Object.defineProperty([], "length", { value: 1E100 });
|
||||
}, "defineProperty() array length out of range", RangeError);
|
||||
}, "Invalid array length", RangeError);
|
||||
|
||||
// kInvalidArrayBufferLength
|
||||
test(function() {
|
||||
|
@ -33,6 +33,30 @@
|
||||
'intl402/11.2.3_b': [FAIL],
|
||||
'intl402/12.2.3_b': [FAIL],
|
||||
|
||||
# BUG(v8:4267)
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-116': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-117': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-168': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-169': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-170': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-172': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-173': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-174': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-176': [FAIL],
|
||||
'built-ins/Object/defineProperty/15.2.3.6-4-177': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-112': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-113': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-164': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-165': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-166': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-168': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-169': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-170': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-172': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-173': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-175': [FAIL],
|
||||
'built-ins/Object/defineProperties/15.2.3.7-6-a-176': [FAIL],
|
||||
|
||||
# Unicode canonicalization is not available with i18n turned off.
|
||||
'built-ins/String/prototype/localeCompare/15.5.4.9_CE': [['no_i18n', SKIP]],
|
||||
|
||||
|
@ -36,6 +36,30 @@
|
||||
'11.2.3_b': [FAIL],
|
||||
'12.2.3_b': [FAIL],
|
||||
|
||||
# BUG(v8:4267)
|
||||
'15.2.3.6-4-116': [FAIL],
|
||||
'15.2.3.6-4-117': [FAIL],
|
||||
'15.2.3.6-4-168': [FAIL],
|
||||
'15.2.3.6-4-169': [FAIL],
|
||||
'15.2.3.6-4-170': [FAIL],
|
||||
'15.2.3.6-4-172': [FAIL],
|
||||
'15.2.3.6-4-173': [FAIL],
|
||||
'15.2.3.6-4-174': [FAIL],
|
||||
'15.2.3.6-4-176': [FAIL],
|
||||
'15.2.3.6-4-177': [FAIL],
|
||||
'15.2.3.7-6-a-112': [FAIL],
|
||||
'15.2.3.7-6-a-113': [FAIL],
|
||||
'15.2.3.7-6-a-164': [FAIL],
|
||||
'15.2.3.7-6-a-165': [FAIL],
|
||||
'15.2.3.7-6-a-166': [FAIL],
|
||||
'15.2.3.7-6-a-168': [FAIL],
|
||||
'15.2.3.7-6-a-169': [FAIL],
|
||||
'15.2.3.7-6-a-170': [FAIL],
|
||||
'15.2.3.7-6-a-172': [FAIL],
|
||||
'15.2.3.7-6-a-173': [FAIL],
|
||||
'15.2.3.7-6-a-175': [FAIL],
|
||||
'15.2.3.7-6-a-176': [FAIL],
|
||||
|
||||
############################### ES6 ###################################
|
||||
# ES6 allows block-local functions.
|
||||
'Sbp_A1_T1': [PASS, FAIL_OK],
|
||||
|
Loading…
Reference in New Issue
Block a user