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