diff --git a/src/builtins/builtins-regexp-gen.cc b/src/builtins/builtins-regexp-gen.cc index d1fb9e82f1..a675c483f4 100644 --- a/src/builtins/builtins-regexp-gen.cc +++ b/src/builtins/builtins-regexp-gen.cc @@ -306,9 +306,16 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, Node* const smi_string_length = LoadStringLength(string); - // Bail out to runtime for invalid {last_index} values. - GotoIfNot(TaggedIsSmi(last_index), &runtime); - GotoIf(SmiAboveOrEqual(last_index, smi_string_length), &runtime); + // At this point, last_index is definitely a canonicalized non-negative + // number, which implies that any non-Smi last_index is greater than + // the maximal string length. If lastIndex > string.length then the matcher + // must fail. + + Label if_failure(this); + CSA_ASSERT(this, IsNumberNormalized(last_index)); + CSA_ASSERT(this, IsNumberPositive(last_index)); + GotoIfNot(TaggedIsSmi(last_index), &if_failure); // Outside Smi range. + GotoIf(SmiGreaterThan(last_index, smi_string_length), &if_failure); // Load the irregexp code object and offsets into the subject string. Both // depend on whether the string is one- or two-byte. @@ -358,8 +365,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, GotoIf(TaggedIsSmi(code), &runtime); CSA_ASSERT(this, HasInstanceType(code, CODE_TYPE)); - Label if_success(this), if_failure(this), - if_exception(this, Label::kDeferred); + Label if_success(this), if_exception(this, Label::kDeferred); { IncrementCounter(isolate()->counters()->regexp_entry_native(), 1); diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc index 26d5cb08d4..ae83a15f42 100644 --- a/src/code-stub-assembler.cc +++ b/src/code-stub-assembler.cc @@ -3362,6 +3362,18 @@ Node* CodeStubAssembler::IsNumberNormalized(Node* number) { return var_result.value(); } +Node* CodeStubAssembler::IsNumberPositive(Node* number) { + CSA_ASSERT(this, IsNumber(number)); + Node* const float_zero = Float64Constant(0.); + return Select(TaggedIsSmi(number), + [=] { return TaggedIsPositiveSmi(number); }, + [=] { + Node* v = LoadHeapNumberValue(number); + return Float64GreaterThanOrEqual(v, float_zero); + }, + MachineRepresentation::kWord32); +} + Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index, ParameterMode parameter_mode) { if (parameter_mode == SMI_PARAMETERS) CSA_ASSERT(this, TaggedIsSmi(index)); diff --git a/src/code-stub-assembler.h b/src/code-stub-assembler.h index e4b9080f11..7573fcf4c8 100644 --- a/src/code-stub-assembler.h +++ b/src/code-stub-assembler.h @@ -791,6 +791,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { // True iff |number| is either a Smi, or a HeapNumber whose value is not // within Smi range. Node* IsNumberNormalized(Node* number); + Node* IsNumberPositive(Node* number); // ElementsKind helpers: Node* IsFastElementsKind(Node* elements_kind);