Commit 15e207b3 authored by Mathias Bynens's avatar Mathias Bynens Committed by Commit Bot

[builtins] Refactor the StringConstructor builtin

This patch removes the StringConstructor_ConstructStub builtin,
merging its functionality into the refactored StringConstructor
TurboFan builtin.

This brings us closer to our goal of deprecating the `construct_stub`
field in `SharedFunctionInfo`.

Bug: v8:7503
Change-Id: Ie98520c652f49dda91eff2fc51263611f29e0ebe
Reviewed-on: https://chromium-review.googlesource.com/942882
Commit-Queue: Mathias Bynens <mathias@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51660}
parent 896fc89c
......@@ -1937,7 +1937,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
isolate->initial_object_prototype(), Builtins::kStringConstructor);
string_fun->shared()->set_builtin_function_id(kStringConstructor);
string_fun->shared()->SetConstructStub(
*BUILTIN_CODE(isolate, StringConstructor_ConstructStub));
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
string_fun->shared()->DontAdaptArguments();
string_fun->shared()->set_length(1);
InstallWithIntrinsicDefaultProto(isolate, string_fun,
......
......@@ -732,79 +732,62 @@ TF_BUILTIN(NumberConstructor_ConstructStub, ConstructorBuiltinsAssembler) {
args.PopAndReturn(result);
}
Node* ConstructorBuiltinsAssembler::EmitConstructString(Node* argc,
CodeStubArguments& args,
Node* context,
bool convert_symbol) {
VARIABLE(var_result, MachineRepresentation::kTagged);
Label return_empty_string(this), to_string(this),
check_symbol(this, Label::kDeferred), done(this);
GotoIf(IntPtrEqual(IntPtrConstant(0), argc), &return_empty_string);
Node* argument = args.AtIndex(0);
// https://tc39.github.io/ecma262/#sec-string-constructor
TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) {
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
GotoIf(TaggedIsSmi(argument), &to_string);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
Node* instance_type = LoadInstanceType(argument);
// 1. If no arguments were passed to this function invocation, let s be "".
VARIABLE(var_s, MachineRepresentation::kTagged, EmptyStringConstant());
Label if_sloaded(this, &var_s);
GotoIf(WordEqual(argc, IntPtrConstant(0)), &if_sloaded);
Label* non_string = convert_symbol ? &check_symbol : &to_string;
GotoIfNot(IsStringInstanceType(instance_type), non_string);
{
var_result.Bind(argument);
Goto(&done);
}
// 2. Else,
// a. If NewTarget is undefined [...]
Node* value = args.AtIndex(0);
Label if_tostring(this, &var_s);
GotoIfNot(IsUndefined(new_target), &if_tostring);
if (convert_symbol) {
BIND(&check_symbol);
GotoIfNot(IsSymbolInstanceType(instance_type), &to_string);
// 2a. [...] and Type(value) is Symbol, return SymbolDescriptiveString(value).
GotoIf(TaggedIsSmi(value), &if_tostring);
GotoIfNot(IsSymbol(value), &if_tostring);
{
var_result.Bind(
CallRuntime(Runtime::kSymbolDescriptiveString, context, argument));
Goto(&done);
}
Node* result =
CallRuntime(Runtime::kSymbolDescriptiveString, context, value);
args.PopAndReturn(result);
}
BIND(&to_string);
// 2b. Let s be ? ToString(value).
BIND(&if_tostring);
{
var_result.Bind(ToString(context, argument));
Goto(&done);
var_s.Bind(CallBuiltin(Builtins::kToString, context, value));
Goto(&if_sloaded);
}
BIND(&return_empty_string);
// 3. If NewTarget is undefined, return s.
BIND(&if_sloaded);
{
var_result.Bind(EmptyStringConstant());
Goto(&done);
}
BIND(&done);
return var_result.value();
}
TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) {
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
args.PopAndReturn(EmitConstructString(argc, args, context, true));
}
TF_BUILTIN(StringConstructor_ConstructStub, ConstructorBuiltinsAssembler) {
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* s_value = var_s.value();
Label return_s(this), constructstring(this, Label::kDeferred);
Branch(IsUndefined(new_target), &return_s, &constructstring);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
BIND(&return_s);
{ args.PopAndReturn(s_value); }
Node* string = EmitConstructString(argc, args, context, false);
Node* result = EmitFastNewObject(context, target, new_target);
StoreObjectField(result, JSValue::kValueOffset, string);
BIND(&constructstring);
{
Node* result =
CallBuiltin(Builtins::kFastNewObject, context, target, new_target);
StoreObjectField(result, JSValue::kValueOffset, s_value);
args.PopAndReturn(result);
}
}
}
} // namespace internal
......
......@@ -36,9 +36,6 @@ class ConstructorBuiltinsAssembler : public CodeStubAssembler {
Node* EmitFastNewObject(Node* context, Node* target, Node* new_target,
Label* call_runtime);
Node* EmitConstructString(Node* argc, CodeStubArguments& args, Node* context,
bool convert_symbol);
private:
Node* NotHasBoilerplate(Node* literal_site);
Node* LoadAllocationSiteBoilerplate(Node* allocation_site);
......
......@@ -968,9 +968,9 @@ namespace internal {
CPP(AtomicsWake) \
\
/* String */ \
/* ES #sec-string-constructor */ \
TFJ(StringConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(StringConstructor_ConstructStub, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES #sec-string.fromcodepoint */ \
CPP(StringFromCodePoint) \
/* ES6 #sec-string.fromcharcode */ \
TFJ(StringFromCharCode, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
......
......@@ -262,10 +262,9 @@ bool Builtins::IsLazy(int index) {
case kInterpreterEnterBytecodeAdvance:
case kInterpreterEnterBytecodeDispatch:
case kInterpreterEntryTrampoline:
case kPromiseConstructorLazyDeoptContinuation: // crbug/v8/6786.
case kPromiseConstructorLazyDeoptContinuation: // https://crbug/v8/6786.
case kProxyConstructor_ConstructStub: // https://crbug.com/v8/6787.
case kNumberConstructor_ConstructStub: // https://crbug.com/v8/6787.
case kStringConstructor_ConstructStub: // https://crbug.com/v8/6787.
case kTypedArrayConstructor_ConstructStub: // https://crbug.com/v8/6787.
case kProxyConstructor: // https://crbug.com/v8/6787.
case kRecordWrite: // https://crbug.com/chromium/765301.
......
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