• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 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#include 'src/builtins/builtins-regexp-gen.h'
6
7namespace runtime {
8extern transitioning runtime
9RegExpSplit(implicit context: Context)(JSReceiver, String, Object): JSAny;
10}  // namespace runtime
11
12namespace regexp {
13
14const kMaxValueSmi: constexpr int31
15    generates 'Smi::kMaxValue';
16
17extern transitioning macro RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
18    implicit context: Context)(JSRegExp, String, Smi): JSArray;
19
20// Helper that skips a few initial checks.
21transitioning builtin
22RegExpSplit(implicit context: Context)(
23    regexp: FastJSRegExp, string: String, limit: JSAny): JSAny {
24  let sanitizedLimit: Smi;
25
26  // We need to be extra-strict and require the given limit to be either
27  // undefined or a positive smi. We can't call ToUint32(maybe_limit) since
28  // that might move us onto the slow path, resulting in ordering spec
29  // violations (see https://crbug.com/801171).
30
31  if (limit == Undefined) {
32    // TODO(jgruber): In this case, we can probably avoid generation of limit
33    // checks in Generate_RegExpPrototypeSplitBody.
34    sanitizedLimit = SmiConstant(kMaxValueSmi);
35  } else if (!TaggedIsPositiveSmi(limit)) {
36    return runtime::RegExpSplit(regexp, string, limit);
37  } else {
38    sanitizedLimit = UnsafeCast<Smi>(limit);
39  }
40
41  // Due to specific shortcuts we take on the fast path (specifically, we
42  // don't allocate a new regexp instance as specced), we need to ensure that
43  // the given regexp is non-sticky to avoid invalid results. See
44  // crbug.com/v8/6706.
45
46  if (FastFlagGetter(regexp, Flag::kSticky)) {
47    return runtime::RegExpSplit(regexp, string, sanitizedLimit);
48  }
49
50  // We're good to go on the fast path, which is inlined here.
51  return RegExpPrototypeSplitBody(regexp, string, sanitizedLimit);
52}
53
54// ES#sec-regexp.prototype-@@split
55// RegExp.prototype [ @@split ] ( string, limit )
56transitioning javascript builtin RegExpPrototypeSplit(
57    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
58  ThrowIfNotJSReceiver(
59      receiver, MessageTemplate::kIncompatibleMethodReceiver,
60      'RegExp.prototype.@@split');
61  const receiver = UnsafeCast<JSReceiver>(receiver);
62  const string: String = ToString_Inline(arguments[0]);
63  const limit = arguments[1];
64
65  // Strict: Reads the flags property.
66  // TODO(jgruber): Handle slow flag accesses on the fast path and make this
67  // permissive.
68  const fastRegExp = Cast<FastJSRegExp>(receiver)
69      otherwise return runtime::RegExpSplit(receiver, string, limit);
70  return RegExpSplit(fastRegExp, string, limit);
71}
72}
73