Skip to content

Commit 21944e8

Browse files
targosMylesBorins
authored andcommitted
deps: backport e427300 from upstream V8
Original commit message: Properly handle holes following spreads in array literals Before this change, the spread desugaring would naively call `%AppendElement($R, the_hole)` and in some cases $R would have a non-holey elements kind, putting the array into the bad state of exposing holes to author code. This patch avoids calling %AppendElement with a hole, instead simply incrementing $R.length when it sees a hole in the literal (this is safe because $R is known to be an Array). The existing logic for elements transitions takes care of giving the array a holey ElementsKind. BUG=chromium:644215 Review-Url: https://codereview.chromium.org/2321533003 Cr-Commit-Position: refs/heads/master@{#39294} Fixes: #12018 PR-URL: #12037 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Myles Borins <[email protected]>
1 parent ba105fd commit 21944e8

File tree

5 files changed

+44
-10
lines changed

5 files changed

+44
-10
lines changed

deps/v8/include/v8-version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#define V8_MAJOR_VERSION 5
1212
#define V8_MINOR_VERSION 1
1313
#define V8_BUILD_NUMBER 281
14-
#define V8_PATCH_LEVEL 97
14+
#define V8_PATCH_LEVEL 98
1515

1616
// Use 1 for candidates and 0 otherwise.
1717
// (Boolean macro values are not supported by all preprocessors.)

deps/v8/src/ast/ast-value-factory.h

+1
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ class AstValue : public ZoneObject {
257257
F(eval, "eval") \
258258
F(function, "function") \
259259
F(get_space, "get ") \
260+
F(length, "length") \
260261
F(let, "let") \
261262
F(native, "native") \
262263
F(new_target, ".new.target") \

deps/v8/src/parsing/parser.cc

+28-9
Original file line numberDiff line numberDiff line change
@@ -5582,16 +5582,35 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
55825582
if (spread == nullptr) {
55835583
// If the element is not a spread, we're adding a single:
55845584
// %AppendElement($R, value)
5585-
ZoneList<Expression*>* append_element_args = NewExpressionList(2, zone());
5586-
append_element_args->Add(factory()->NewVariableProxy(result), zone());
5587-
append_element_args->Add(value, zone());
5588-
do_block->statements()->Add(
5589-
factory()->NewExpressionStatement(
5590-
factory()->NewCallRuntime(Runtime::kAppendElement,
5591-
append_element_args,
5585+
// or, in case of a hole,
5586+
// ++($R.length)
5587+
if (!value->IsLiteral() ||
5588+
!value->AsLiteral()->raw_value()->IsTheHole()) {
5589+
ZoneList<Expression*>* append_element_args =
5590+
NewExpressionList(2, zone());
5591+
append_element_args->Add(factory()->NewVariableProxy(result), zone());
5592+
append_element_args->Add(value, zone());
5593+
do_block->statements()->Add(
5594+
factory()->NewExpressionStatement(
5595+
factory()->NewCallRuntime(Runtime::kAppendElement,
5596+
append_element_args,
5597+
RelocInfo::kNoPosition),
5598+
RelocInfo::kNoPosition),
5599+
zone());
5600+
} else {
5601+
Property* length_property = factory()->NewProperty(
5602+
factory()->NewVariableProxy(result),
5603+
factory()->NewStringLiteral(ast_value_factory()->length_string(),
55925604
RelocInfo::kNoPosition),
5593-
RelocInfo::kNoPosition),
5594-
zone());
5605+
RelocInfo::kNoPosition);
5606+
CountOperation* count_op = factory()->NewCountOperation(
5607+
Token::INC, true /* prefix */, length_property,
5608+
RelocInfo::kNoPosition);
5609+
do_block->statements()->Add(
5610+
factory()->NewExpressionStatement(count_op,
5611+
RelocInfo::kNoPosition),
5612+
zone());
5613+
}
55955614
} else {
55965615
// If it's a spread, we're adding a for/of loop iterating through it.
55975616
Variable* each =

deps/v8/src/runtime/runtime-object.cc

+1
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ RUNTIME_FUNCTION(Runtime_AppendElement) {
543543

544544
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
545545
CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
546+
CHECK(!value->IsTheHole());
546547

547548
uint32_t index;
548549
CHECK(array->length()->ToArrayIndex(&index));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2016 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --allow-natives-syntax
6+
7+
var arr = [...[],,];
8+
assertTrue(%HasFastHoleyElements(arr));
9+
assertEquals(1, arr.length);
10+
assertFalse(arr.hasOwnProperty(0));
11+
assertEquals(undefined, arr[0]);
12+
// Should not crash.
13+
assertThrows(() => arr[0][0], TypeError);

0 commit comments

Comments
 (0)