11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include 'src/builtins/builtins-regexp-gen.h'
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cinamespace runtime {
81cb0ef41Sopenharmony_ciextern transitioning runtime
91cb0ef41Sopenharmony_ciRegExpSplit(implicit context: Context)(JSReceiver, String, Object): JSAny;
101cb0ef41Sopenharmony_ci}  // namespace runtime
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace regexp {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst kMaxValueSmi: constexpr int31
151cb0ef41Sopenharmony_ci    generates 'Smi::kMaxValue';
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciextern transitioning macro RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
181cb0ef41Sopenharmony_ci    implicit context: Context)(JSRegExp, String, Smi): JSArray;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci// Helper that skips a few initial checks.
211cb0ef41Sopenharmony_citransitioning builtin
221cb0ef41Sopenharmony_ciRegExpSplit(implicit context: Context)(
231cb0ef41Sopenharmony_ci    regexp: FastJSRegExp, string: String, limit: JSAny): JSAny {
241cb0ef41Sopenharmony_ci  let sanitizedLimit: Smi;
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  // We need to be extra-strict and require the given limit to be either
271cb0ef41Sopenharmony_ci  // undefined or a positive smi. We can't call ToUint32(maybe_limit) since
281cb0ef41Sopenharmony_ci  // that might move us onto the slow path, resulting in ordering spec
291cb0ef41Sopenharmony_ci  // violations (see https://crbug.com/801171).
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci  if (limit == Undefined) {
321cb0ef41Sopenharmony_ci    // TODO(jgruber): In this case, we can probably avoid generation of limit
331cb0ef41Sopenharmony_ci    // checks in Generate_RegExpPrototypeSplitBody.
341cb0ef41Sopenharmony_ci    sanitizedLimit = SmiConstant(kMaxValueSmi);
351cb0ef41Sopenharmony_ci  } else if (!TaggedIsPositiveSmi(limit)) {
361cb0ef41Sopenharmony_ci    return runtime::RegExpSplit(regexp, string, limit);
371cb0ef41Sopenharmony_ci  } else {
381cb0ef41Sopenharmony_ci    sanitizedLimit = UnsafeCast<Smi>(limit);
391cb0ef41Sopenharmony_ci  }
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  // Due to specific shortcuts we take on the fast path (specifically, we
421cb0ef41Sopenharmony_ci  // don't allocate a new regexp instance as specced), we need to ensure that
431cb0ef41Sopenharmony_ci  // the given regexp is non-sticky to avoid invalid results. See
441cb0ef41Sopenharmony_ci  // crbug.com/v8/6706.
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  if (FastFlagGetter(regexp, Flag::kSticky)) {
471cb0ef41Sopenharmony_ci    return runtime::RegExpSplit(regexp, string, sanitizedLimit);
481cb0ef41Sopenharmony_ci  }
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  // We're good to go on the fast path, which is inlined here.
511cb0ef41Sopenharmony_ci  return RegExpPrototypeSplitBody(regexp, string, sanitizedLimit);
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci// ES#sec-regexp.prototype-@@split
551cb0ef41Sopenharmony_ci// RegExp.prototype [ @@split ] ( string, limit )
561cb0ef41Sopenharmony_citransitioning javascript builtin RegExpPrototypeSplit(
571cb0ef41Sopenharmony_ci    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
581cb0ef41Sopenharmony_ci  ThrowIfNotJSReceiver(
591cb0ef41Sopenharmony_ci      receiver, MessageTemplate::kIncompatibleMethodReceiver,
601cb0ef41Sopenharmony_ci      'RegExp.prototype.@@split');
611cb0ef41Sopenharmony_ci  const receiver = UnsafeCast<JSReceiver>(receiver);
621cb0ef41Sopenharmony_ci  const string: String = ToString_Inline(arguments[0]);
631cb0ef41Sopenharmony_ci  const limit = arguments[1];
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  // Strict: Reads the flags property.
661cb0ef41Sopenharmony_ci  // TODO(jgruber): Handle slow flag accesses on the fast path and make this
671cb0ef41Sopenharmony_ci  // permissive.
681cb0ef41Sopenharmony_ci  const fastRegExp = Cast<FastJSRegExp>(receiver)
691cb0ef41Sopenharmony_ci      otherwise return runtime::RegExpSplit(receiver, string, limit);
701cb0ef41Sopenharmony_ci  return RegExpSplit(fastRegExp, string, limit);
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci}
73