aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/builtins-regexp-gen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/builtins-regexp-gen.cc')
-rw-r--r--deps/v8/src/builtins/builtins-regexp-gen.cc141
1 files changed, 70 insertions, 71 deletions
diff --git a/deps/v8/src/builtins/builtins-regexp-gen.cc b/deps/v8/src/builtins/builtins-regexp-gen.cc
index 51ee2796e6..d53518ff7e 100644
--- a/deps/v8/src/builtins/builtins-regexp-gen.cc
+++ b/deps/v8/src/builtins/builtins-regexp-gen.cc
@@ -15,7 +15,7 @@
#include "src/objects/js-regexp-string-iterator.h"
#include "src/objects/js-regexp.h"
#include "src/objects/regexp-match-info.h"
-#include "src/regexp/regexp-macro-assembler.h"
+#include "src/regexp/regexp.h"
namespace v8 {
namespace internal {
@@ -94,12 +94,12 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpCreate(TNode<Context> context,
TNode<String> pattern = Select<String>(
IsUndefined(maybe_string), [=] { return EmptyStringConstant(); },
[=] { return ToString_Inline(context, maybe_string); });
- TNode<Object> regexp = CAST(AllocateJSObjectFromMap(initial_map));
+ TNode<JSObject> regexp = AllocateJSObjectFromMap(initial_map);
return CallRuntime(Runtime::kRegExpInitializeAndCompile, context, regexp,
pattern, flags);
}
-TNode<Object> RegExpBuiltinsAssembler::FastLoadLastIndex(
+TNode<Object> RegExpBuiltinsAssembler::FastLoadLastIndexBeforeSmiCheck(
TNode<JSRegExp> regexp) {
// Load the in-object field.
static const int field_offset =
@@ -121,23 +121,27 @@ TNode<Object> RegExpBuiltinsAssembler::LoadLastIndex(TNode<Context> context,
// The fast-path of StoreLastIndex when regexp is guaranteed to be an unmodified
// JSRegExp instance.
-void RegExpBuiltinsAssembler::FastStoreLastIndex(Node* regexp, Node* value) {
+void RegExpBuiltinsAssembler::FastStoreLastIndex(TNode<JSRegExp> regexp,
+ TNode<Smi> value) {
// Store the in-object field.
static const int field_offset =
JSRegExp::kSize + JSRegExp::kLastIndexFieldIndex * kTaggedSize;
StoreObjectField(regexp, field_offset, value);
}
-void RegExpBuiltinsAssembler::SlowStoreLastIndex(Node* context, Node* regexp,
- Node* value) {
- Node* const name = HeapConstant(isolate()->factory()->lastIndex_string());
- SetPropertyStrict(CAST(context), CAST(regexp), CAST(name), CAST(value));
+void RegExpBuiltinsAssembler::SlowStoreLastIndex(SloppyTNode<Context> context,
+ SloppyTNode<Object> regexp,
+ SloppyTNode<Number> value) {
+ TNode<Name> name = HeapConstant(isolate()->factory()->lastIndex_string());
+ SetPropertyStrict(context, regexp, name, value);
}
-void RegExpBuiltinsAssembler::StoreLastIndex(Node* context, Node* regexp,
- Node* value, bool is_fastpath) {
+void RegExpBuiltinsAssembler::StoreLastIndex(TNode<Context> context,
+ TNode<Object> regexp,
+ TNode<Number> value,
+ bool is_fastpath) {
if (is_fastpath) {
- FastStoreLastIndex(regexp, value);
+ FastStoreLastIndex(CAST(regexp), CAST(value));
} else {
SlowStoreLastIndex(context, regexp, value);
}
@@ -248,10 +252,10 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
TNode<Context> native_context = LoadNativeContext(context);
TNode<Map> map = CAST(LoadContextElement(
native_context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP));
- TNode<NameDictionary> properties = AllocateNameDictionary(num_properties);
+ TNode<NameDictionary> properties =
+ AllocateNameDictionary(num_properties, kAllowLargeObjectAllocation);
- TNode<JSObject> group_object =
- CAST(AllocateJSObjectFromMap(map, properties));
+ TNode<JSObject> group_object = AllocateJSObjectFromMap(map, properties);
StoreObjectField(result, JSRegExpResult::kGroupsOffset, group_object);
TVARIABLE(IntPtrT, var_i, IntPtrZero());
@@ -534,19 +538,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
// We expect exactly one result since we force the called regexp to behave
// as non-global.
TNode<IntPtrT> int_result = ChangeInt32ToIntPtr(result);
+ GotoIf(
+ IntPtrEqual(int_result, IntPtrConstant(RegExp::kInternalRegExpSuccess)),
+ &if_success);
+ GotoIf(
+ IntPtrEqual(int_result, IntPtrConstant(RegExp::kInternalRegExpFailure)),
+ &if_failure);
GotoIf(IntPtrEqual(int_result,
- IntPtrConstant(NativeRegExpMacroAssembler::SUCCESS)),
- &if_success);
- GotoIf(IntPtrEqual(int_result,
- IntPtrConstant(NativeRegExpMacroAssembler::FAILURE)),
- &if_failure);
- GotoIf(IntPtrEqual(int_result,
- IntPtrConstant(NativeRegExpMacroAssembler::EXCEPTION)),
+ IntPtrConstant(RegExp::kInternalRegExpException)),
&if_exception);
- CSA_ASSERT(this,
- IntPtrEqual(int_result,
- IntPtrConstant(NativeRegExpMacroAssembler::RETRY)));
+ CSA_ASSERT(this, IntPtrEqual(int_result,
+ IntPtrConstant(RegExp::kInternalRegExpRetry)));
Goto(&runtime);
}
@@ -755,7 +758,7 @@ RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
GotoIfNot(should_update_last_index, &out);
// Update the new last index from {match_indices}.
- TNode<Number> new_lastindex = CAST(UnsafeLoadFixedArrayElement(
+ TNode<Smi> new_lastindex = CAST(UnsafeLoadFixedArrayElement(
CAST(match_indices), RegExpMatchInfo::kFirstCaptureIndex + 1));
StoreLastIndex(context, regexp, new_lastindex, is_fastpath);
@@ -852,7 +855,7 @@ Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype(Node* const context,
// The smi check is required to omit ToLength(lastIndex) calls with possible
// user-code execution on the fast path.
- Node* const last_index = FastLoadLastIndex(CAST(object));
+ TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object));
var_result.Bind(TaggedIsPositiveSmi(last_index));
Goto(&out);
@@ -897,7 +900,7 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpWithOriginalExec(
BIND(&check_last_index);
// The smi check is required to omit ToLength(lastIndex) calls with possible
// user-code execution on the fast path.
- TNode<Object> last_index = FastLoadLastIndex(object);
+ TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(object);
var_result = TaggedIsPositiveSmi(last_index);
Goto(&out);
@@ -925,9 +928,9 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExp(
// This should only be needed for String.p.(split||matchAll), but we are
// conservative here.
- GotoIf(IsRegExpSpeciesProtectorCellInvalid(), if_ismodified);
+ TNode<Context> native_context = LoadNativeContext(context);
+ GotoIf(IsRegExpSpeciesProtectorCellInvalid(native_context), if_ismodified);
- Node* const native_context = LoadNativeContext(context);
Node* const regexp_fun =
LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX);
Node* const initial_map =
@@ -954,7 +957,7 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExp(
// The smi check is required to omit ToLength(lastIndex) calls with possible
// user-code execution on the fast path.
- Node* const last_index = FastLoadLastIndex(CAST(object));
+ TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object));
Branch(TaggedIsPositiveSmi(last_index), if_isunmodified, if_ismodified);
}
@@ -1012,7 +1015,7 @@ TF_BUILTIN(RegExpPrototypeExecSlow, RegExpBuiltinsAssembler) {
// Fast path stub for ATOM regexps. String matching is done by StringIndexOf,
// and {match_info} is updated on success.
-// The slow path is implemented in RegExpImpl::AtomExec.
+// The slow path is implemented in RegExp::AtomExec.
TF_BUILTIN(RegExpExecAtom, RegExpBuiltinsAssembler) {
TNode<JSRegExp> regexp = CAST(Parameter(Descriptor::kRegExp));
TNode<String> subject_string = CAST(Parameter(Descriptor::kString));
@@ -1538,7 +1541,8 @@ TNode<Int32T> RegExpBuiltinsAssembler::FastFlagGetter(TNode<JSRegExp> regexp,
JSRegExp::Flag flag) {
TNode<Smi> flags = CAST(LoadObjectField(regexp, JSRegExp::kFlagsOffset));
TNode<Smi> mask = SmiConstant(flag);
- return SmiToInt32(SmiShr(SmiAnd(flags, mask), JSRegExp::FlagShiftBits(flag)));
+ return SmiToInt32(SmiShr(SmiAnd(flags, mask), base::bits::CountTrailingZeros(
+ static_cast<int>(flag))));
}
// Load through the GetProperty stub.
@@ -1807,10 +1811,9 @@ TF_BUILTIN(RegExpPrototypeTestFast, RegExpBuiltinsAssembler) {
Return(FalseConstant());
}
-Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
- Node* const index,
- Node* const is_unicode,
- bool is_fastpath) {
+TNode<Number> RegExpBuiltinsAssembler::AdvanceStringIndex(
+ SloppyTNode<String> string, SloppyTNode<Number> index,
+ SloppyTNode<BoolT> is_unicode, bool is_fastpath) {
CSA_ASSERT(this, IsString(string));
CSA_ASSERT(this, IsNumberNormalized(index));
if (is_fastpath) CSA_ASSERT(this, TaggedIsPositiveSmi(index));
@@ -1818,8 +1821,8 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
// Default to last_index + 1.
// TODO(pwong): Consider using TrySmiAdd for the fast path to reduce generated
// code.
- Node* const index_plus_one = NumberInc(index);
- VARIABLE(var_result, MachineRepresentation::kTagged, index_plus_one);
+ TNode<Number> index_plus_one = NumberInc(index);
+ TVARIABLE(Number, var_result, index_plus_one);
// Advancing the index has some subtle issues involving the distinction
// between Smis and HeapNumbers. There's three cases:
@@ -1846,10 +1849,10 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
BIND(&if_isunicode);
{
TNode<IntPtrT> const string_length = LoadStringLengthAsWord(string);
- TNode<IntPtrT> untagged_plus_one = SmiUntag(index_plus_one);
+ TNode<IntPtrT> untagged_plus_one = SmiUntag(CAST(index_plus_one));
GotoIfNot(IntPtrLessThan(untagged_plus_one, string_length), &out);
- Node* const lead = StringCharCodeAt(string, SmiUntag(index));
+ Node* const lead = StringCharCodeAt(string, SmiUntag(CAST(index)));
GotoIfNot(Word32Equal(Word32And(lead, Int32Constant(0xFC00)),
Int32Constant(0xD800)),
&out);
@@ -1860,8 +1863,8 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
&out);
// At a surrogate pair, return index + 2.
- Node* const index_plus_two = NumberInc(index_plus_one);
- var_result.Bind(index_plus_two);
+ TNode<Number> index_plus_two = NumberInc(index_plus_one);
+ var_result = index_plus_two;
Goto(&out);
}
@@ -1870,31 +1873,30 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
return var_result.value();
}
-void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
- Node* const regexp,
+void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(TNode<Context> context,
+ TNode<Object> regexp,
TNode<String> string,
const bool is_fastpath) {
if (is_fastpath) CSA_ASSERT(this, IsFastRegExp(context, regexp));
Node* const is_global =
- FlagGetter(CAST(context), CAST(regexp), JSRegExp::kGlobal, is_fastpath);
+ FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath);
Label if_isglobal(this), if_isnotglobal(this);
Branch(is_global, &if_isglobal, &if_isnotglobal);
BIND(&if_isnotglobal);
{
- Node* const result =
- is_fastpath
- ? RegExpPrototypeExecBody(CAST(context), CAST(regexp), string, true)
- : RegExpExec(context, regexp, string);
+ Node* const result = is_fastpath ? RegExpPrototypeExecBody(
+ context, CAST(regexp), string, true)
+ : RegExpExec(context, regexp, string);
Return(result);
}
BIND(&if_isglobal);
{
- Node* const is_unicode = FlagGetter(CAST(context), CAST(regexp),
- JSRegExp::kUnicode, is_fastpath);
+ Node* const is_unicode =
+ FlagGetter(context, regexp, JSRegExp::kUnicode, is_fastpath);
StoreLastIndex(context, regexp, SmiZero(), is_fastpath);
@@ -1935,8 +1937,8 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
// On the fast path, grab the matching string from the raw match index
// array.
TNode<RegExpMatchInfo> match_indices =
- RegExpPrototypeExecBodyWithoutResult(CAST(context), CAST(regexp),
- string, &if_didnotmatch, true);
+ RegExpPrototypeExecBodyWithoutResult(context, CAST(regexp), string,
+ &if_didnotmatch, true);
Label dosubstring(this), donotsubstring(this);
Branch(var_atom.value(), &donotsubstring, &dosubstring);
@@ -1988,15 +1990,14 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
TNode<Smi> const match_length = LoadStringLengthAsSmi(match);
GotoIfNot(SmiEqual(match_length, SmiZero()), &loop);
- Node* last_index =
- LoadLastIndex(CAST(context), CAST(regexp), is_fastpath);
+ Node* last_index = LoadLastIndex(context, regexp, is_fastpath);
if (is_fastpath) {
CSA_ASSERT(this, TaggedIsPositiveSmi(last_index));
} else {
last_index = ToLength_Inline(context, last_index);
}
- Node* const new_last_index =
+ TNode<Number> new_last_index =
AdvanceStringIndex(string, last_index, is_unicode, is_fastpath);
if (is_fastpath) {
@@ -2017,7 +2018,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
{
// Wrap the match in a JSArray.
- Node* const result = array.ToJSArray(CAST(context));
+ Node* const result = array.ToJSArray(context);
Return(result);
}
}
@@ -2034,7 +2035,7 @@ TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) {
ThrowIfNotJSReceiver(context, maybe_receiver,
MessageTemplate::kIncompatibleMethodReceiver,
"RegExp.prototype.@@match");
- Node* const receiver = maybe_receiver;
+ TNode<JSReceiver> receiver = CAST(maybe_receiver);
// Convert {maybe_string} to a String.
TNode<String> const string = ToString_Inline(context, maybe_string);
@@ -2086,7 +2087,8 @@ void RegExpMatchAllAssembler::Generate(TNode<Context> context,
// 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
// 8. Perform ? Set(matcher, "lastIndex", lastIndex, true).
- FastStoreLastIndex(var_matcher.value(), FastLoadLastIndex(fast_regexp));
+ FastStoreLastIndex(CAST(var_matcher.value()),
+ FastLoadLastIndex(fast_regexp));
// 9. If flags contains "g", let global be true.
// 10. Else, let global be false.
@@ -2226,12 +2228,11 @@ TF_BUILTIN(RegExpMatchFast, RegExpBuiltinsAssembler) {
}
void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast(
- Node* const context, Node* const regexp, Node* const string) {
+ TNode<Context> context, TNode<JSRegExp> regexp, TNode<String> string) {
CSA_ASSERT(this, IsFastRegExp(context, regexp));
- CSA_ASSERT(this, IsString(string));
// Grab the initial value of last index.
- Node* const previous_last_index = FastLoadLastIndex(CAST(regexp));
+ TNode<Smi> previous_last_index = FastLoadLastIndex(regexp);
// Ensure last index is 0.
FastStoreLastIndex(regexp, SmiZero());
@@ -2239,7 +2240,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast(
// Call exec.
Label if_didnotmatch(this);
TNode<RegExpMatchInfo> match_indices = RegExpPrototypeExecBodyWithoutResult(
- CAST(context), CAST(regexp), CAST(string), &if_didnotmatch, true);
+ context, regexp, string, &if_didnotmatch, true);
// Successful match.
{
@@ -2839,16 +2840,14 @@ TF_BUILTIN(RegExpStringIteratorPrototypeNext, RegExpStringIteratorAssembler) {
GotoIfNot(IsEmptyString(match_str), &return_result);
// 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex")).
- TNode<Smi> this_index = CAST(FastLoadLastIndex(CAST(iterating_regexp)));
- CSA_ASSERT(this, TaggedIsSmi(this_index));
+ TNode<Smi> this_index = FastLoadLastIndex(CAST(iterating_regexp));
// 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode).
- TNode<Smi> next_index = CAST(AdvanceStringIndex(
- iterating_string, this_index, HasUnicodeFlag(flags), true));
- CSA_ASSERT(this, TaggedIsSmi(next_index));
+ TNode<Smi> next_index = AdvanceStringIndexFast(
+ iterating_string, this_index, HasUnicodeFlag(flags));
// 3. Perform ? Set(R, "lastIndex", nextIndex, true).
- FastStoreLastIndex(iterating_regexp, next_index);
+ FastStoreLastIndex(CAST(iterating_regexp), next_index);
// iii. Return ! CreateIterResultObject(match, false).
Goto(&return_result);
@@ -2866,8 +2865,8 @@ TF_BUILTIN(RegExpStringIteratorPrototypeNext, RegExpStringIteratorAssembler) {
TNode<Number> this_index = ToLength_Inline(context, last_index);
// 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode).
- TNode<Object> next_index = CAST(AdvanceStringIndex(
- iterating_string, this_index, HasUnicodeFlag(flags), false));
+ TNode<Number> next_index = AdvanceStringIndex(
+ iterating_string, this_index, HasUnicodeFlag(flags), false);
// 3. Perform ? Set(R, "lastIndex", nextIndex, true).
SlowStoreLastIndex(context, iterating_regexp, next_index);