blob: 47ff214130f142d54bc65811fbe5f07d77a7776a [file] [log] [blame]
// Copyright 2019 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.
#include 'src/builtins/builtins-regexp-gen.h'
namespace runtime {
extern transitioning runtime
RegExpSplit(implicit context: Context)(JSReceiver, String, Object): JSAny;
} // namespace runtime
namespace regexp {
const kMaxValueSmi: constexpr int31
generates 'Smi::kMaxValue';
extern transitioning macro RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
implicit context: Context)(JSRegExp, String, Smi): JSArray;
// Helper that skips a few initial checks.
transitioning builtin
RegExpSplit(implicit context: Context)(
regexp: FastJSRegExp, string: String, limit: JSAny): JSAny {
let sanitizedLimit: Smi;
// We need to be extra-strict and require the given limit to be either
// undefined or a positive smi. We can't call ToUint32(maybe_limit) since
// that might move us onto the slow path, resulting in ordering spec
// violations (see https://crbug.com/801171).
if (limit == Undefined) {
// TODO(jgruber): In this case, we can probably avoid generation of limit
// checks in Generate_RegExpPrototypeSplitBody.
sanitizedLimit = SmiConstant(kMaxValueSmi);
} else if (!TaggedIsPositiveSmi(limit)) {
return runtime::RegExpSplit(regexp, string, limit);
} else {
sanitizedLimit = UnsafeCast<Smi>(limit);
}
// Due to specific shortcuts we take on the fast path (specifically, we
// don't allocate a new regexp instance as specced), we need to ensure that
// the given regexp is non-sticky to avoid invalid results. See
// crbug.com/v8/6706.
if (FastFlagGetter(regexp, Flag::kSticky)) {
return runtime::RegExpSplit(regexp, string, sanitizedLimit);
}
// We're good to go on the fast path, which is inlined here.
return RegExpPrototypeSplitBody(regexp, string, sanitizedLimit);
}
// ES#sec-regexp.prototype-@@split
// RegExp.prototype [ @@split ] ( string, limit )
transitioning javascript builtin RegExpPrototypeSplit(
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
ThrowIfNotJSReceiver(
receiver, MessageTemplate::kIncompatibleMethodReceiver,
'RegExp.prototype.@@split');
const receiver = UnsafeCast<JSReceiver>(receiver);
const string: String = ToString_Inline(arguments[0]);
const limit = arguments[1];
// Strict: Reads the flags property.
// TODO(jgruber): Handle slow flag accesses on the fast path and make this
// permissive.
const fastRegExp = Cast<FastJSRegExp>(receiver)
otherwise return runtime::RegExpSplit(receiver, string, limit);
return RegExpSplit(fastRegExp, string, limit);
}
}