Commit 4b9b2352 authored by peterwmwong's avatar peterwmwong Committed by Commit Bot

[builtins] Port String.prototype HTML functions to Torque

Consolidates all the work into a single TFS builtin (CreateHTML)
called by all these functions. Reduces the builtin size by
about half.

Change-Id: I92b2c7889f72db4c8c79d7ef0ce0e61036ab619e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1522727
Commit-Queue: Peter Wong <peter.wm.wong@gmail.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60248}
parent d68cdcae
......@@ -938,6 +938,7 @@ torque_files = [
"src/builtins/object-fromentries.tq",
"src/builtins/iterator.tq",
"src/builtins/string-endswith.tq",
"src/builtins/string-html.tq",
"src/builtins/string-startswith.tq",
"src/builtins/typed-array.tq",
"src/builtins/typed-array-createtypedarray.tq",
......@@ -980,6 +981,7 @@ torque_namespaces = [
"iterator",
"object",
"string",
"string-html",
"test",
"typed-array",
"typed-array-createtypedarray",
......
......@@ -1943,13 +1943,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
// Install the String.prototype methods.
SimpleInstallFunction(isolate_, prototype, "anchor",
Builtins::kStringPrototypeAnchor, 1, true);
Builtins::kStringPrototypeAnchor, 1, false);
SimpleInstallFunction(isolate_, prototype, "big",
Builtins::kStringPrototypeBig, 0, true);
Builtins::kStringPrototypeBig, 0, false);
SimpleInstallFunction(isolate_, prototype, "blink",
Builtins::kStringPrototypeBlink, 0, true);
Builtins::kStringPrototypeBlink, 0, false);
SimpleInstallFunction(isolate_, prototype, "bold",
Builtins::kStringPrototypeBold, 0, true);
Builtins::kStringPrototypeBold, 0, false);
SimpleInstallFunction(isolate_, prototype, "charAt",
Builtins::kStringPrototypeCharAt, 1, true);
SimpleInstallFunction(isolate_, prototype, "charCodeAt",
......@@ -1961,21 +1961,21 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleInstallFunction(isolate_, prototype, "endsWith",
Builtins::kStringPrototypeEndsWith, 1, false);
SimpleInstallFunction(isolate_, prototype, "fontcolor",
Builtins::kStringPrototypeFontcolor, 1, true);
Builtins::kStringPrototypeFontcolor, 1, false);
SimpleInstallFunction(isolate_, prototype, "fontsize",
Builtins::kStringPrototypeFontsize, 1, true);
Builtins::kStringPrototypeFontsize, 1, false);
SimpleInstallFunction(isolate_, prototype, "fixed",
Builtins::kStringPrototypeFixed, 0, true);
Builtins::kStringPrototypeFixed, 0, false);
SimpleInstallFunction(isolate_, prototype, "includes",
Builtins::kStringPrototypeIncludes, 1, false);
SimpleInstallFunction(isolate_, prototype, "indexOf",
Builtins::kStringPrototypeIndexOf, 1, false);
SimpleInstallFunction(isolate_, prototype, "italics",
Builtins::kStringPrototypeItalics, 0, true);
Builtins::kStringPrototypeItalics, 0, false);
SimpleInstallFunction(isolate_, prototype, "lastIndexOf",
Builtins::kStringPrototypeLastIndexOf, 1, false);
SimpleInstallFunction(isolate_, prototype, "link",
Builtins::kStringPrototypeLink, 1, true);
Builtins::kStringPrototypeLink, 1, false);
#ifdef V8_INTL_SUPPORT
SimpleInstallFunction(isolate_, prototype, "localeCompare",
Builtins::kStringPrototypeLocaleCompare, 1, false);
......@@ -2005,19 +2005,19 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleInstallFunction(isolate_, prototype, "slice",
Builtins::kStringPrototypeSlice, 2, false);
SimpleInstallFunction(isolate_, prototype, "small",
Builtins::kStringPrototypeSmall, 0, true);
Builtins::kStringPrototypeSmall, 0, false);
SimpleInstallFunction(isolate_, prototype, "split",
Builtins::kStringPrototypeSplit, 2, false);
SimpleInstallFunction(isolate_, prototype, "strike",
Builtins::kStringPrototypeStrike, 0, true);
Builtins::kStringPrototypeStrike, 0, false);
SimpleInstallFunction(isolate_, prototype, "sub",
Builtins::kStringPrototypeSub, 0, true);
Builtins::kStringPrototypeSub, 0, false);
SimpleInstallFunction(isolate_, prototype, "substr",
Builtins::kStringPrototypeSubstr, 2, false);
SimpleInstallFunction(isolate_, prototype, "substring",
Builtins::kStringPrototypeSubstring, 2, false);
SimpleInstallFunction(isolate_, prototype, "sup",
Builtins::kStringPrototypeSup, 0, true);
Builtins::kStringPrototypeSup, 0, false);
SimpleInstallFunction(isolate_, prototype, "startsWith",
Builtins::kStringPrototypeStartsWith, 1, false);
SimpleInstallFunction(isolate_, prototype, "toString",
......
......@@ -821,6 +821,7 @@ extern macro ToSmiIndex(implicit context: Context)(Object): PositiveSmi
extern macro ToSmiLength(implicit context: Context)(Object): PositiveSmi
labels IfRangeError;
extern macro ToString_Inline(Context, Object): String;
extern macro ToThisString(implicit context: Context)(Object, String): String;
extern transitioning macro GetProperty(implicit context: Context)(
Object, Object): Object;
extern transitioning builtin SetProperty(implicit context: Context)(
......@@ -1092,6 +1093,13 @@ extern operator '.length' macro GetArgumentsLength(constexpr Arguments): intptr;
extern operator '[]' macro GetArgumentValue(
constexpr Arguments, intptr): Object;
extern builtin StringAdd_CheckNone(implicit context: Context)(
String, String): String;
operator '+' macro StringAdd(implicit context: Context)(
a: String, b: String): String {
return StringAdd_CheckNone(a, b);
}
extern macro TaggedIsSmi(Object): bool;
extern macro TaggedIsNotSmi(Object): bool;
extern macro TaggedIsPositiveSmi(Object): bool;
......
......@@ -997,14 +997,6 @@ namespace internal {
CPP(StringFromCodePoint) \
/* ES6 #sec-string.fromcharcode */ \
TFJ(StringFromCharCode, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.anchor */ \
TFJ(StringPrototypeAnchor, 1, kReceiver, kValue) \
/* ES6 #sec-string.prototype.big */ \
TFJ(StringPrototypeBig, 0, kReceiver) \
/* ES6 #sec-string.prototype.blink */ \
TFJ(StringPrototypeBlink, 0, kReceiver) \
/* ES6 #sec-string.prototype.bold */ \
TFJ(StringPrototypeBold, 0, kReceiver) \
/* ES6 #sec-string.prototype.charat */ \
TFJ(StringPrototypeCharAt, 1, kReceiver, kPosition) \
/* ES6 #sec-string.prototype.charcodeat */ \
......@@ -1013,23 +1005,13 @@ namespace internal {
TFJ(StringPrototypeCodePointAt, 1, kReceiver, kPosition) \
/* ES6 #sec-string.prototype.concat */ \
TFJ(StringPrototypeConcat, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.fontcolor */ \
TFJ(StringPrototypeFontcolor, 1, kReceiver, kValue) \
/* ES6 #sec-string.prototype.fontsize */ \
TFJ(StringPrototypeFontsize, 1, kReceiver, kValue) \
/* ES6 #sec-string.prototype.fixed */ \
TFJ(StringPrototypeFixed, 0, kReceiver) \
/* ES6 #sec-string.prototype.includes */ \
TFJ(StringPrototypeIncludes, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.indexof */ \
TFJ(StringPrototypeIndexOf, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.italics */ \
TFJ(StringPrototypeItalics, 0, kReceiver) \
/* ES6 #sec-string.prototype.lastindexof */ \
CPP(StringPrototypeLastIndexOf) \
/* ES6 #sec-string.prototype.link */ \
TFJ(StringPrototypeLink, 1, kReceiver, kValue) \
/* ES6 #sec-string.prototype.match */ \
TFJ(StringPrototypeMatch, 1, kReceiver, kRegexp) \
/* ES #sec-string.prototype.matchAll */ \
......@@ -1049,21 +1031,13 @@ namespace internal {
TFJ(StringPrototypeSearch, 1, kReceiver, kRegexp) \
/* ES6 #sec-string.prototype.slice */ \
TFJ(StringPrototypeSlice, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.small */ \
TFJ(StringPrototypeSmall, 0, kReceiver) \
/* ES6 #sec-string.prototype.split */ \
TFJ(StringPrototypeSplit, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.strike */ \
TFJ(StringPrototypeStrike, 0, kReceiver) \
/* ES6 #sec-string.prototype.sub */ \
TFJ(StringPrototypeSub, 0, kReceiver) \
/* ES6 #sec-string.prototype.substr */ \
TFJ(StringPrototypeSubstr, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.substring */ \
TFJ(StringPrototypeSubstring, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.sup */ \
TFJ(StringPrototypeSup, 0, kReceiver) \
/* ES6 #sec-string.prototype.tostring */ \
TFJ(StringPrototypeToString, 0, kReceiver) \
TFJ(StringPrototypeTrim, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
......
......@@ -131,10 +131,10 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
}
TF_BUILTIN(StringPrototypeToLowerCaseIntl, IntlBuiltinsAssembler) {
Node* const maybe_string = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
TNode<Object> maybe_string = CAST(Parameter(Descriptor::kReceiver));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* const string =
TNode<String> string =
ToThisString(context, maybe_string, "String.prototype.toLowerCase");
Return(CallBuiltin(Builtins::kStringToLowerCaseIntl, context, string));
......
This diff is collapsed.
......@@ -68,7 +68,7 @@ class StringBuiltinsAssembler : public CodeStubAssembler {
StringAtAccessor;
void GenerateStringAt(const char* method_name, TNode<Context> context,
Node* receiver, TNode<Object> maybe_position,
TNode<Object> receiver, TNode<Object> maybe_position,
TNode<Object> default_return,
const StringAtAccessor& accessor);
......
// 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.
namespace string_html {
extern runtime StringEscapeQuotes(Context, String): String;
// https://tc39.github.io/ecma262/#sec-createhtml
builtin CreateHTML(implicit context: Context)(
receiver: Object, methodName: String, tagName: String, attr: String,
attrValue: Object): String {
const tagContents: String = ToThisString(receiver, methodName);
let result = '<' + tagName;
if (attr != kEmptyString) {
const attrStringValue: String =
StringEscapeQuotes(context, ToString_Inline(context, attrValue));
result = result + ' ' + attr + '=\"' + attrStringValue + '\"';
}
return result + '>' + tagContents + '</' + tagName + '>';
}
// https://tc39.github.io/ecma262/#sec-string.prototype.anchor
javascript builtin StringPrototypeAnchor(
context: Context, receiver: Object, ...arguments): String {
return CreateHTML(
receiver, 'String.prototype.anchor', 'a', 'name', arguments[0]);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.big
javascript builtin
StringPrototypeBig(context: Context, receiver: Object, ...arguments): String {
return CreateHTML(
receiver, 'String.prototype.big', 'big', kEmptyString, kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.blink
javascript builtin
StringPrototypeBlink(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.blink', 'blink', kEmptyString,
kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.bold
javascript builtin
StringPrototypeBold(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.bold', 'b', kEmptyString, kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.fontcolor
javascript builtin
StringPrototypeFontcolor(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.fontcolor', 'font', 'color', arguments[0]);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.fontsize
javascript builtin
StringPrototypeFontsize(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.fontsize', 'font', 'size', arguments[0]);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.fixed
javascript builtin
StringPrototypeFixed(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.fixed', 'tt', kEmptyString, kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.italics
javascript builtin
StringPrototypeItalics(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.italics', 'i', kEmptyString, kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.link
javascript builtin
StringPrototypeLink(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.link', 'a', 'href', arguments[0]);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.small
javascript builtin
StringPrototypeSmall(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.small', 'small', kEmptyString,
kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.strike
javascript builtin
StringPrototypeStrike(context: Context, receiver: Object, ...arguments):
String {
return CreateHTML(
receiver, 'String.prototype.strike', 'strike', kEmptyString,
kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.sub
javascript builtin
StringPrototypeSub(context: Context, receiver: Object, ...arguments): String {
return CreateHTML(
receiver, 'String.prototype.sub', 'sub', kEmptyString, kEmptyString);
}
// https://tc39.github.io/ecma262/#sec-string.prototype.sup
javascript builtin
StringPrototypeSup(context: Context, receiver: Object, ...arguments): String {
return CreateHTML(
receiver, 'String.prototype.sup', 'sup', kEmptyString, kEmptyString);
}
}
......@@ -5554,8 +5554,9 @@ TNode<Number> CodeStubAssembler::ChangeUintPtrToTagged(TNode<UintPtrT> value) {
return var_result.value();
}
TNode<String> CodeStubAssembler::ToThisString(Node* context, Node* value,
char const* method_name) {
TNode<String> CodeStubAssembler::ToThisString(TNode<Context> context,
TNode<Object> value,
TNode<String> method_name) {
VARIABLE(var_value, MachineRepresentation::kTagged, value);
// Check if the {value} is a Smi or a HeapObject.
......@@ -5565,7 +5566,7 @@ TNode<String> CodeStubAssembler::ToThisString(Node* context, Node* value,
BIND(&if_valueisnotsmi);
{
// Load the instance type of the {value}.
Node* value_instance_type = LoadInstanceType(value);
Node* value_instance_type = LoadInstanceType(CAST(value));
// Check if the {value} is already String.
Label if_valueisnotstring(this, Label::kDeferred);
......
......@@ -2030,8 +2030,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// Type conversions.
// Throws a TypeError for {method_name} if {value} is not coercible to Object,
// or returns the {value} converted to a String otherwise.
TNode<String> ToThisString(Node* context, Node* value,
char const* method_name);
TNode<String> ToThisString(TNode<Context> context, TNode<Object> value,
TNode<String> method_name);
TNode<String> ToThisString(TNode<Context> context, TNode<Object> value,
char const* method_name) {
return ToThisString(context, value, StringConstant(method_name));
}
// Throws a TypeError for {method_name} if {value} is neither of the given
// {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or
// returns the {value} (or wrapped value) otherwise.
......
......@@ -949,6 +949,7 @@ static bool TransitivelyCalledBuiltinHasNoSideEffect(Builtins::Name caller,
case Builtins::kFlattenIntoArray:
case Builtins::kGetProperty:
case Builtins::kHasProperty:
case Builtins::kCreateHTML:
case Builtins::kNonNumberToNumber:
case Builtins::kNonPrimitiveToPrimitive_Number:
case Builtins::kNumberToString:
......
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