aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/builtins-string-gen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/builtins-string-gen.cc')
-rw-r--r--deps/v8/src/builtins/builtins-string-gen.cc315
1 files changed, 28 insertions, 287 deletions
diff --git a/deps/v8/src/builtins/builtins-string-gen.cc b/deps/v8/src/builtins/builtins-string-gen.cc
index e2db979452..74b2db0542 100644
--- a/deps/v8/src/builtins/builtins-string-gen.cc
+++ b/deps/v8/src/builtins/builtins-string-gen.cc
@@ -107,10 +107,13 @@ Node* StringBuiltinsAssembler::CallSearchStringRaw(Node* const subject_ptr,
MachineType type_ptr = MachineType::Pointer();
MachineType type_intptr = MachineType::IntPtr();
- Node* const result = CallCFunction6(
- type_intptr, type_ptr, type_ptr, type_intptr, type_ptr, type_intptr,
- type_intptr, function_addr, isolate_ptr, subject_ptr, subject_length,
- search_ptr, search_length, start_position);
+ Node* const result = CallCFunction(
+ function_addr, type_intptr, std::make_pair(type_ptr, isolate_ptr),
+ std::make_pair(type_ptr, subject_ptr),
+ std::make_pair(type_intptr, subject_length),
+ std::make_pair(type_ptr, search_ptr),
+ std::make_pair(type_intptr, search_length),
+ std::make_pair(type_intptr, start_position));
return result;
}
@@ -321,7 +324,7 @@ TF_BUILTIN(SubString, StringBuiltinsAssembler) {
}
void StringBuiltinsAssembler::GenerateStringAt(
- char const* method_name, TNode<Context> context, Node* receiver,
+ char const* method_name, TNode<Context> context, TNode<Object> receiver,
TNode<Object> maybe_position, TNode<Object> default_return,
const StringAtAccessor& accessor) {
// Check that {receiver} is coercible to Object and convert it to a String.
@@ -707,7 +710,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
// ES6 #sec-string.prototype.charat
TF_BUILTIN(StringPrototypeCharAt, StringBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
- Node* receiver = Parameter(Descriptor::kReceiver);
+ TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<Object> maybe_position = CAST(Parameter(Descriptor::kPosition));
GenerateStringAt("String.prototype.charAt", context, receiver, maybe_position,
@@ -722,7 +725,7 @@ TF_BUILTIN(StringPrototypeCharAt, StringBuiltinsAssembler) {
// ES6 #sec-string.prototype.charcodeat
TF_BUILTIN(StringPrototypeCharCodeAt, StringBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
- Node* receiver = Parameter(Descriptor::kReceiver);
+ TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<Object> maybe_position = CAST(Parameter(Descriptor::kPosition));
GenerateStringAt("String.prototype.charCodeAt", context, receiver,
@@ -737,7 +740,7 @@ TF_BUILTIN(StringPrototypeCharCodeAt, StringBuiltinsAssembler) {
// ES6 #sec-string.prototype.codepointat
TF_BUILTIN(StringPrototypeCodePointAt, StringBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
- Node* receiver = Parameter(Descriptor::kReceiver);
+ TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<Object> maybe_position = CAST(Parameter(Descriptor::kPosition));
GenerateStringAt("String.prototype.codePointAt", context, receiver,
@@ -760,8 +763,8 @@ TF_BUILTIN(StringPrototypeConcat, CodeStubAssembler) {
CodeStubArguments arguments(
this,
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
- Node* receiver = arguments.GetReceiver();
- Node* context = Parameter(Descriptor::kContext);
+ TNode<Object> receiver = arguments.GetReceiver();
+ TNode<Context> context = CAST(Parameter(Descriptor::kContext));
// Check that {receiver} is coercible to Object and convert it to a String.
receiver = ToThisString(context, receiver, "String.prototype.concat");
@@ -867,9 +870,10 @@ void StringBuiltinsAssembler::StringIndexOf(
Node* const memchr =
ExternalConstant(ExternalReference::libc_memchr_function());
Node* const result_address =
- CallCFunction3(MachineType::Pointer(), MachineType::Pointer(),
- MachineType::IntPtr(), MachineType::UintPtr(), memchr,
- string_addr, search_byte, search_length);
+ CallCFunction(memchr, MachineType::Pointer(),
+ std::make_pair(MachineType::Pointer(), string_addr),
+ std::make_pair(MachineType::IntPtr(), search_byte),
+ std::make_pair(MachineType::UintPtr(), search_length));
GotoIf(WordEqual(result_address, int_zero), &return_minus_1);
Node* const result_index =
IntPtrAdd(IntPtrSub(result_address, string_addr), start_position);
@@ -1160,121 +1164,6 @@ compiler::Node* StringBuiltinsAssembler::GetSubstitution(
return var_result.value();
}
-// ES6 #sec-string.prototype.repeat
-TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
- Label invalid_count(this), invalid_string_length(this),
- return_emptystring(this);
-
- TNode<Context> context = CAST(Parameter(Descriptor::kContext));
- Node* const receiver = Parameter(Descriptor::kReceiver);
- TNode<Object> count = CAST(Parameter(Descriptor::kCount));
- Node* const string =
- ToThisString(context, receiver, "String.prototype.repeat");
-
- VARIABLE(
- var_count, MachineRepresentation::kTagged,
- ToInteger_Inline(context, count, CodeStubAssembler::kTruncateMinusZero));
-
- // Verifies a valid count and takes a fast path when the result will be an
- // empty string.
- {
- Label if_count_isheapnumber(this, Label::kDeferred);
-
- GotoIfNot(TaggedIsSmi(var_count.value()), &if_count_isheapnumber);
- {
- // If count is a SMI, throw a RangeError if less than 0 or greater than
- // the maximum string length.
- TNode<Smi> smi_count = CAST(var_count.value());
- GotoIf(SmiLessThan(smi_count, SmiConstant(0)), &invalid_count);
- GotoIf(SmiEqual(smi_count, SmiConstant(0)), &return_emptystring);
- GotoIf(Word32Equal(LoadStringLengthAsWord32(string), Int32Constant(0)),
- &return_emptystring);
- GotoIf(SmiGreaterThan(smi_count, SmiConstant(String::kMaxLength)),
- &invalid_string_length);
- Return(CallBuiltin(Builtins::kStringRepeat, context, string, smi_count));
- }
-
- // If count is a Heap Number...
- // 1) If count is Infinity, throw a RangeError exception
- // 2) If receiver is an empty string, return an empty string
- // 3) Otherwise, throw RangeError exception
- BIND(&if_count_isheapnumber);
- {
- CSA_ASSERT(this, IsNumberNormalized(var_count.value()));
- Node* const number_value = LoadHeapNumberValue(var_count.value());
- GotoIf(Float64Equal(number_value, Float64Constant(V8_INFINITY)),
- &invalid_count);
- GotoIf(Float64LessThan(number_value, Float64Constant(0.0)),
- &invalid_count);
- Branch(Word32Equal(LoadStringLengthAsWord32(string), Int32Constant(0)),
- &return_emptystring, &invalid_string_length);
- }
- }
-
- BIND(&return_emptystring);
- Return(EmptyStringConstant());
-
- BIND(&invalid_count);
- {
- ThrowRangeError(context, MessageTemplate::kInvalidCountValue,
- var_count.value());
- }
-
- BIND(&invalid_string_length);
- {
- CallRuntime(Runtime::kThrowInvalidStringLength, context);
- Unreachable();
- }
-}
-
-// Helper with less checks
-TF_BUILTIN(StringRepeat, StringBuiltinsAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const string = Parameter(Descriptor::kString);
- TNode<Smi> const count = CAST(Parameter(Descriptor::kCount));
-
- CSA_ASSERT(this, IsString(string));
- CSA_ASSERT(this, Word32BinaryNot(IsEmptyString(string)));
- CSA_ASSERT(this, TaggedIsPositiveSmi(count));
-
- // The string is repeated with the following algorithm:
- // let n = count;
- // let power_of_two_repeats = string;
- // let result = "";
- // while (true) {
- // if (n & 1) result += s;
- // n >>= 1;
- // if (n === 0) return result;
- // power_of_two_repeats += power_of_two_repeats;
- // }
- VARIABLE(var_result, MachineRepresentation::kTagged, EmptyStringConstant());
- VARIABLE(var_temp, MachineRepresentation::kTagged, string);
- TVARIABLE(Smi, var_count, count);
-
- Label loop(this, {&var_count, &var_result, &var_temp}), return_result(this);
- Goto(&loop);
- BIND(&loop);
- {
- {
- Label next(this);
- GotoIfNot(SmiToInt32(SmiAnd(var_count.value(), SmiConstant(1))), &next);
- var_result.Bind(CallBuiltin(Builtins::kStringAdd_CheckNone, context,
- var_result.value(), var_temp.value()));
- Goto(&next);
- BIND(&next);
- }
-
- var_count = SmiShr(var_count.value(), 1);
- GotoIf(SmiEqual(var_count.value(), SmiConstant(0)), &return_result);
- var_temp.Bind(CallBuiltin(Builtins::kStringAdd_CheckNone, context,
- var_temp.value(), var_temp.value()));
- Goto(&loop);
- }
-
- BIND(&return_result);
- Return(var_result.value());
-}
-
// ES6 #sec-string.prototype.replace
TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
Label out(this);
@@ -1570,8 +1459,9 @@ class StringPadAssembler : public StringBuiltinsAssembler {
void Generate(Variant variant, const char* method_name, TNode<IntPtrT> argc,
TNode<Context> context) {
CodeStubArguments arguments(this, argc);
- Node* const receiver = arguments.GetReceiver();
- Node* const receiver_string = ToThisString(context, receiver, method_name);
+ TNode<Object> receiver = arguments.GetReceiver();
+ TNode<String> receiver_string =
+ ToThisString(context, receiver, method_name);
TNode<Smi> const string_length = LoadStringLengthAsSmi(receiver_string);
TVARIABLE(String, var_fill_string, StringConstant(" "));
@@ -1939,7 +1829,7 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) {
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
- Node* const receiver = args.GetReceiver();
+ TNode<Object> receiver = args.GetReceiver();
TNode<Object> start = args.GetOptionalArgumentValue(kStartArg);
TNode<Object> length = args.GetOptionalArgumentValue(kLengthArg);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
@@ -2095,10 +1985,10 @@ TF_BUILTIN(StringPrototypeSubstring, StringBuiltinsAssembler) {
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
- Node* const receiver = args.GetReceiver();
- Node* const start = args.GetOptionalArgumentValue(kStartArg);
- Node* const end = args.GetOptionalArgumentValue(kEndArg);
- Node* const context = Parameter(Descriptor::kContext);
+ TNode<Object> receiver = args.GetReceiver();
+ TNode<Object> start = args.GetOptionalArgumentValue(kStartArg);
+ TNode<Object> end = args.GetOptionalArgumentValue(kEndArg);
+ TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Label out(this);
@@ -2174,7 +2064,7 @@ void StringTrimAssembler::Generate(String::TrimMode mode,
Label return_emptystring(this), if_runtime(this);
CodeStubArguments arguments(this, argc);
- Node* const receiver = arguments.GetReceiver();
+ TNode<Object> receiver = arguments.GetReceiver();
// Check that {receiver} is coercible to Object and convert it to a String.
TNode<String> const string = ToThisString(context, receiver, method_name);
@@ -2332,8 +2222,8 @@ TF_BUILTIN(StringPrototypeValueOf, CodeStubAssembler) {
}
TF_BUILTIN(StringPrototypeIterator, CodeStubAssembler) {
- Node* context = Parameter(Descriptor::kContext);
- Node* receiver = Parameter(Descriptor::kReceiver);
+ TNode<Context> context = CAST(Parameter(Descriptor::kContext));
+ TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
Node* string =
ToThisString(context, receiver, "String.prototype[Symbol.iterator]");
@@ -2548,154 +2438,5 @@ TF_BUILTIN(StringToList, StringBuiltinsAssembler) {
Return(StringToList(context, string));
}
-// -----------------------------------------------------------------------------
-// ES6 section B.2.3 Additional Properties of the String.prototype object
-
-class StringHtmlAssembler : public StringBuiltinsAssembler {
- public:
- explicit StringHtmlAssembler(compiler::CodeAssemblerState* state)
- : StringBuiltinsAssembler(state) {}
-
- protected:
- void Generate(Node* const context, Node* const receiver,
- const char* method_name, const char* tag_name) {
- Node* const string = ToThisString(context, receiver, method_name);
- std::string open_tag = "<" + std::string(tag_name) + ">";
- std::string close_tag = "</" + std::string(tag_name) + ">";
-
- Node* strings[] = {StringConstant(open_tag.c_str()), string,
- StringConstant(close_tag.c_str())};
- Return(ConcatStrings(context, strings, arraysize(strings)));
- }
-
- void GenerateWithAttribute(Node* const context, Node* const receiver,
- const char* method_name, const char* tag_name,
- const char* attr, Node* const value) {
- Node* const string = ToThisString(context, receiver, method_name);
- TNode<String> value_string =
- EscapeQuotes(CAST(context), ToString_Inline(context, value));
- std::string open_tag_attr =
- "<" + std::string(tag_name) + " " + std::string(attr) + "=\"";
- std::string close_tag = "</" + std::string(tag_name) + ">";
-
- Node* strings[] = {StringConstant(open_tag_attr.c_str()), value_string,
- StringConstant("\">"), string,
- StringConstant(close_tag.c_str())};
- Return(ConcatStrings(context, strings, arraysize(strings)));
- }
-
- Node* ConcatStrings(Node* const context, Node** strings, int len) {
- VARIABLE(var_result, MachineRepresentation::kTagged, strings[0]);
- for (int i = 1; i < len; i++) {
- var_result.Bind(CallStub(CodeFactory::StringAdd(isolate()), context,
- var_result.value(), strings[i]));
- }
- return var_result.value();
- }
-
- TNode<String> EscapeQuotes(TNode<Context> context, TNode<String> string) {
- return CAST(CallRuntime(Runtime::kStringEscapeQuotes, context, string));
- }
-};
-
-// ES6 #sec-string.prototype.anchor
-TF_BUILTIN(StringPrototypeAnchor, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Node* const value = Parameter(Descriptor::kValue);
- GenerateWithAttribute(context, receiver, "String.prototype.anchor", "a",
- "name", value);
-}
-
-// ES6 #sec-string.prototype.big
-TF_BUILTIN(StringPrototypeBig, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.big", "big");
-}
-
-// ES6 #sec-string.prototype.blink
-TF_BUILTIN(StringPrototypeBlink, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.blink", "blink");
-}
-
-// ES6 #sec-string.prototype.bold
-TF_BUILTIN(StringPrototypeBold, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.bold", "b");
-}
-
-// ES6 #sec-string.prototype.fontcolor
-TF_BUILTIN(StringPrototypeFontcolor, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Node* const value = Parameter(Descriptor::kValue);
- GenerateWithAttribute(context, receiver, "String.prototype.fontcolor", "font",
- "color", value);
-}
-
-// ES6 #sec-string.prototype.fontsize
-TF_BUILTIN(StringPrototypeFontsize, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Node* const value = Parameter(Descriptor::kValue);
- GenerateWithAttribute(context, receiver, "String.prototype.fontsize", "font",
- "size", value);
-}
-
-// ES6 #sec-string.prototype.fixed
-TF_BUILTIN(StringPrototypeFixed, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.fixed", "tt");
-}
-
-// ES6 #sec-string.prototype.italics
-TF_BUILTIN(StringPrototypeItalics, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.italics", "i");
-}
-
-// ES6 #sec-string.prototype.link
-TF_BUILTIN(StringPrototypeLink, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Node* const value = Parameter(Descriptor::kValue);
- GenerateWithAttribute(context, receiver, "String.prototype.link", "a", "href",
- value);
-}
-
-// ES6 #sec-string.prototype.small
-TF_BUILTIN(StringPrototypeSmall, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.small", "small");
-}
-
-// ES6 #sec-string.prototype.strike
-TF_BUILTIN(StringPrototypeStrike, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.strike", "strike");
-}
-
-// ES6 #sec-string.prototype.sub
-TF_BUILTIN(StringPrototypeSub, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.sub", "sub");
-}
-
-// ES6 #sec-string.prototype.sup
-TF_BUILTIN(StringPrototypeSup, StringHtmlAssembler) {
- Node* const context = Parameter(Descriptor::kContext);
- Node* const receiver = Parameter(Descriptor::kReceiver);
- Generate(context, receiver, "String.prototype.sup", "sup");
-}
-
} // namespace internal
} // namespace v8