[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: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#60248}
This commit is contained in:
parent
d68cdcae8f
commit
4b9b23521e
2
BUILD.gn
2
BUILD.gn
@ -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));
|
||||
|
@ -321,7 +321,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 +707,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 +722,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 +737,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 +760,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");
|
||||
@ -1166,7 +1166,7 @@ TF_BUILTIN(StringPrototypeRepeat, StringBuiltinsAssembler) {
|
||||
return_emptystring(this);
|
||||
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
Node* const receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
TNode<Object> count = CAST(Parameter(Descriptor::kCount));
|
||||
Node* const string =
|
||||
ToThisString(context, receiver, "String.prototype.repeat");
|
||||
@ -1570,8 +1570,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 +1940,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 +2096,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 +2175,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 +2333,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 +2549,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
|
||||
|
@ -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);
|
||||
|
||||
|
125
src/builtins/string-html.tq
Normal file
125
src/builtins/string-html.tq
Normal file
@ -0,0 +1,125 @@
|
||||
// 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:
|
||||
|
Loading…
Reference in New Issue
Block a user