v8/test/mjsunit/regress/regress-v8-6706.js
jgruber 27fd52abad [regexp] Send sticky @@splits to the slow path
Due to shortcuts we take on the RegExp.p[@@split] fast path (we don't allocate
a new instance), we need to send sticky regexps to the slow path.

The problem is a slight impedance mismatch between the spec and our fast-path
implementation.

Spec: Creates a new regexp instance `splitter` that is guaranteed to be sticky,
uses `splitter.lastIndex` to advance the search range, advances by itself using
AdvanceStringIndex if `splitter` did not match at the current position.

Our fast path: Uses the given regexp instance and does not modify stickyness,
uses last_match_info to advance search range, returns (and assumes no more
matches) once RegExpExecInternal fails to match.

This is fine if the given regexp is non-sticky, since 1. the value of lastIndex
is ignored, and 2. non-sticky regexps match if a match is found anywhere in the
string, not just exactly at the current lastIndex.

Sticky regexps though are a problem. If no match is found exactly at the current
position, @@split assumes no more matches and exits.

In a follow-up, we could explore other options, such as allocating a new
instance or saving/restoring flags and lastIndex.

Bug: v8:6706
Change-Id: I6da2266df72b2f80f00c1ce3cd7c8655de91f680
Reviewed-on: https://chromium-review.googlesource.com/626065
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47543}
2017-08-23 09:55:21 +00:00

38 lines
589 B
JavaScript

// Copyright 2017 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.
const str = "a-b-c";
function test(re) {
assertArrayEquals(["a", "b", "c"], re[Symbol.split](str));
}
!function() {
const re = /-/y;
re.lastIndex = 1;
test(re);
}();
!function() {
const re = /-/y;
re.lastIndex = 3;
test(re);
}();
!function() {
const re = /-/y;
re.lastIndex = -1;
test(re);
}();
!function() {
const re = /-/y;
test(re);
}();
!function() {
const re = /-/g;
test(re);
}();