Commit 0a127f30 authored by Choongwoo Han's avatar Choongwoo Han Committed by Commit Bot

Use ConvertToRelativeIndex

Replace conversions of relative indices in builtin-string-gen.cc with
ConvertToRelativeIndex which is defined in code-stub-assembler.cc.

Change-Id: I790d58d296ccb482d3f96a62ec64227b1c2ce2c0
Reviewed-on: https://chromium-review.googlesource.com/883701Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50880}
parent e19bc613
......@@ -124,42 +124,6 @@ Node* StringBuiltinsAssembler::PointerToStringDataAtIndex(
return IntPtrAdd(string_data, offset_in_bytes);
}
void StringBuiltinsAssembler::ConvertAndBoundsCheckStartArgument(
Node* context, Variable* var_start, Node* start, Node* string_length) {
TNode<Object> const start_int = ToInteger_Inline(
CAST(context), CAST(start), CodeStubAssembler::kTruncateMinusZero);
TNode<Smi> const zero = SmiConstant(0);
Label done(this);
Label if_issmi(this), if_isheapnumber(this, Label::kDeferred);
Branch(TaggedIsSmi(start_int), &if_issmi, &if_isheapnumber);
BIND(&if_issmi);
{
TNode<Smi> const start_int_smi = CAST(start_int);
var_start->Bind(Select(
SmiLessThan(start_int_smi, zero),
[&] { return SmiMax(SmiAdd(string_length, start_int_smi), zero); },
[&] { return start_int_smi; }, MachineRepresentation::kTagged));
Goto(&done);
}
BIND(&if_isheapnumber);
{
// If {start} is a heap number, it is definitely out of bounds. If it is
// negative, {start} = max({string_length} + {start}),0) = 0'. If it is
// positive, set {start} to {string_length} which ultimately results in
// returning an empty string.
TNode<HeapNumber> const start_int_hn = CAST(start_int);
TNode<Float64T> const float_zero = Float64Constant(0.);
TNode<Float64T> const start_float = LoadHeapNumberValue(start_int_hn);
var_start->Bind(SelectTaggedConstant<Smi>(
Float64LessThan(start_float, float_zero), zero, string_length));
Goto(&done);
}
BIND(&done);
}
void StringBuiltinsAssembler::GenerateStringEqual(Node* context, Node* left,
Node* right) {
VARIABLE(var_left, MachineRepresentation::kTagged, left);
......@@ -1666,8 +1630,8 @@ TF_BUILTIN(StringPrototypeSearch, StringMatchSearchAssembler) {
// ES6 section 21.1.3.18 String.prototype.slice ( start, end )
TF_BUILTIN(StringPrototypeSlice, StringBuiltinsAssembler) {
Label out(this);
VARIABLE(var_start, MachineRepresentation::kTagged);
VARIABLE(var_end, MachineRepresentation::kTagged);
TVARIABLE(Smi, var_start);
TVARIABLE(Smi, var_end);
const int kStart = 0;
const int kEnd = 1;
......@@ -1675,12 +1639,10 @@ TF_BUILTIN(StringPrototypeSlice, StringBuiltinsAssembler) {
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* const receiver = args.GetReceiver();
Node* const start = args.GetOptionalArgumentValue(kStart);
TNode<Object> start = args.GetOptionalArgumentValue(kStart);
TNode<Object> end = CAST(args.GetOptionalArgumentValue(kEnd));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Smi> const smi_zero = SmiConstant(0);
// 1. Let O be ? RequireObjectCoercible(this value).
RequireObjectCoercible(context, receiver, "String.prototype.slice");
......@@ -1691,53 +1653,23 @@ TF_BUILTIN(StringPrototypeSlice, StringBuiltinsAssembler) {
// 3. Let len be the number of elements in S.
TNode<Smi> const length = LoadStringLengthAsSmi(subject_string);
// Conversions and bounds-checks for {start}.
ConvertAndBoundsCheckStartArgument(context, &var_start, start, length);
// Convert {start} to a relative index.
var_start = ConvertToRelativeIndex(context, start, length);
// 5. If end is undefined, let intEnd be len;
var_end.Bind(length);
var_end = length;
GotoIf(IsUndefined(end), &out);
// else let intEnd be ? ToInteger(end).
Node* const end_int =
ToInteger_Inline(context, end, CodeStubAssembler::kTruncateMinusZero);
// 7. If intEnd < 0, let to be max(len + intEnd, 0);
// otherwise let to be min(intEnd, len).
Label if_issmi(this), if_isheapnumber(this, Label::kDeferred);
Branch(TaggedIsSmi(end_int), &if_issmi, &if_isheapnumber);
BIND(&if_issmi);
{
Node* const length_plus_end = SmiAdd(length, end_int);
var_end.Bind(Select(SmiLessThan(end_int, smi_zero),
[&] { return SmiMax(length_plus_end, smi_zero); },
[&] { return SmiMin(length, end_int); },
MachineRepresentation::kTagged));
Goto(&out);
}
BIND(&if_isheapnumber);
{
// If {end} is a heap number, it is definitely out of bounds. If it is
// negative, {int_end} = max({length} + {int_end}),0) = 0'. If it is
// positive, set {int_end} to {length} which ultimately results in
// returning an empty string.
Node* const float_zero = Float64Constant(0.);
Node* const end_float = LoadHeapNumberValue(end_int);
var_end.Bind(SelectTaggedConstant<Smi>(
Float64LessThan(end_float, float_zero), smi_zero, length));
Goto(&out);
}
// Convert {end} to a relative index.
var_end = ConvertToRelativeIndex(context, end, length);
Goto(&out);
Label return_emptystring(this);
BIND(&out);
{
GotoIf(SmiLessThanOrEqual(var_end.value(), var_start.value()),
&return_emptystring);
Node* const result =
SubString(context, subject_string, var_start.value(), var_end.value(),
SubStringFlags::FROM_TO_ARE_BOUNDED);
GotoIf(SmiLessThanOrEqual(var_end, var_start), &return_emptystring);
Node* const result = SubString(context, subject_string, var_start, var_end,
SubStringFlags::FROM_TO_ARE_BOUNDED);
args.PopAndReturn(result);
}
......@@ -1855,7 +1787,7 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) {
CodeStubArguments args(this, argc);
Node* const receiver = args.GetReceiver();
Node* const start = args.GetOptionalArgumentValue(kStartArg);
TNode<Object> start = args.GetOptionalArgumentValue(kStartArg);
TNode<Object> length = CAST(args.GetOptionalArgumentValue(kLengthArg));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
......@@ -1872,8 +1804,8 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) {
TNode<Smi> const string_length = LoadStringLengthAsSmi(string);
// Conversions and bounds-checks for {start}.
ConvertAndBoundsCheckStartArgument(context, &var_start, start, string_length);
// Convert {start} to a relative index.
var_start = ConvertToRelativeIndex(context, start, string_length);
// Conversions and bounds-checks for {length}.
Label if_issmi(this), if_isheapnumber(this, Label::kDeferred);
......
......@@ -1330,8 +1330,8 @@ TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
const char* method_name = "%TypedArray%.prototype.subarray";
Label offset_done(this);
VARIABLE(var_begin, MachineRepresentation::kTagged);
VARIABLE(var_end, MachineRepresentation::kTagged);
TVARIABLE(Smi, var_begin);
TVARIABLE(Smi, var_end);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
CodeStubArguments args(
......@@ -1355,24 +1355,23 @@ TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
// 8. If relativeBegin < 0, let beginIndex be max((srcLength + relativeBegin),
// 0); else let beginIndex be min(relativeBegin, srcLength).
TNode<Object> begin = args.GetOptionalArgumentValue(0, SmiConstant(0));
ConvertToRelativeIndex(context, &var_begin, begin, source_length);
var_begin = ConvertToRelativeIndex(context, begin, source_length);
TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
// 9. If end is undefined, let relativeEnd be srcLength;
var_end.Bind(source_length);
var_end = source_length;
GotoIf(IsUndefined(end), &offset_done);
// else, let relativeEnd be ? ToInteger(end).
// 10. If relativeEnd < 0, let endIndex be max((srcLength + relativeEnd), 0);
// else let endIndex be min(relativeEnd, srcLength).
ConvertToRelativeIndex(context, &var_end, end, source_length);
var_end = ConvertToRelativeIndex(context, end, source_length);
Goto(&offset_done);
BIND(&offset_done);
// 11. Let newLength be max(endIndex - beginIndex, 0).
TNode<Smi> new_length =
SmiMax(SmiSub(var_end.value(), var_begin.value()), SmiConstant(0));
TNode<Smi> new_length = SmiMax(SmiSub(var_end, var_begin), SmiConstant(0));
// 12. Let constructorName be the String value of O.[[TypedArrayName]].
// 13. Let elementSize be the Number value of the Element Size value specified
......@@ -1385,7 +1384,7 @@ TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
LoadObjectField<Number>(source, JSTypedArray::kByteOffsetOffset);
// 15. Let beginByteOffset be srcByteOffset + beginIndex × elementSize.
TNode<Number> offset = SmiMul(var_begin.value(), SmiFromWord(element_size));
TNode<Number> offset = SmiMul(var_begin, SmiFromWord(element_size));
TNode<Number> begin_byte_offset = CAST(NumberAdd(source_byte_offset, offset));
// 16. Let argumentsList be « buffer, beginByteOffset, newLength ».
......
......@@ -581,11 +581,13 @@ TNode<Object> CodeStubAssembler::NumberMin(SloppyTNode<Object> a,
return TNode<Object>::UncheckedCast(result.value());
}
void CodeStubAssembler::ConvertToRelativeIndex(Node* context,
Variable* var_result,
Node* index, Node* length) {
TNode<Object> const index_int =
ToInteger(context, index, CodeStubAssembler::kTruncateMinusZero);
TNode<Smi> CodeStubAssembler::ConvertToRelativeIndex(TNode<Context> context,
TNode<Object> index,
TNode<Smi> length) {
TVARIABLE(Smi, result);
TNode<Number> const index_int =
ToInteger_Inline(context, index, CodeStubAssembler::kTruncateMinusZero);
TNode<Smi> const zero = SmiConstant(0);
Label done(this);
......@@ -594,12 +596,12 @@ void CodeStubAssembler::ConvertToRelativeIndex(Node* context,
BIND(&if_issmi);
{
TNode<Smi> const start_int_smi = CAST(index_int);
var_result->Bind(
Select(SmiLessThan(start_int_smi, zero),
[&] { return SmiMax(SmiAdd(length, start_int_smi), zero); },
[&] { return SmiMin(start_int_smi, length); },
MachineRepresentation::kTagged));
TNode<Smi> const index_smi = CAST(index_int);
result =
Select<Smi>(SmiLessThan(index_smi, zero),
[&] { return SmiMax(SmiAdd(length, index_smi), zero); },
[&] { return SmiMin(index_smi, length); },
MachineRepresentation::kTagged);
Goto(&done);
}
......@@ -608,14 +610,15 @@ void CodeStubAssembler::ConvertToRelativeIndex(Node* context,
// If {index} is a heap number, it is definitely out of bounds. If it is
// negative, {index} = max({length} + {index}),0) = 0'. If it is positive,
// set {index} to {length}.
TNode<HeapNumber> const start_int_hn = CAST(index_int);
TNode<HeapNumber> const index_hn = CAST(index_int);
TNode<Float64T> const float_zero = Float64Constant(0.);
TNode<Float64T> const start_float = LoadHeapNumberValue(start_int_hn);
var_result->Bind(SelectTaggedConstant<Smi>(
Float64LessThan(start_float, float_zero), zero, length));
TNode<Float64T> const index_float = LoadHeapNumberValue(index_hn);
result = SelectTaggedConstant<Smi>(Float64LessThan(index_float, float_zero),
zero, length);
Goto(&done);
}
BIND(&done);
return result;
}
Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
......
......@@ -225,8 +225,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
// After converting an index to an integer, calculate a relative index: if
// index < 0, max(length + index, 0); else min(index, length)
void ConvertToRelativeIndex(Node* context, Variable* var_result, Node* index,
Node* length);
TNode<Smi> ConvertToRelativeIndex(TNode<Context> context, TNode<Object> index,
TNode<Smi> length);
// Tag a Word as a Smi value.
TNode<Smi> SmiTag(SloppyTNode<IntPtrT> value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment