[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: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#51660}
This commit is contained in:
parent
896fc89cce
commit
15e207b300
@ -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);
|
||||
|
||||
GotoIf(TaggedIsSmi(argument), &to_string);
|
||||
|
||||
Node* instance_type = LoadInstanceType(argument);
|
||||
|
||||
Label* non_string = convert_symbol ? &check_symbol : &to_string;
|
||||
GotoIfNot(IsStringInstanceType(instance_type), non_string);
|
||||
{
|
||||
var_result.Bind(argument);
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
if (convert_symbol) {
|
||||
BIND(&check_symbol);
|
||||
GotoIfNot(IsSymbolInstanceType(instance_type), &to_string);
|
||||
{
|
||||
var_result.Bind(
|
||||
CallRuntime(Runtime::kSymbolDescriptiveString, context, argument));
|
||||
Goto(&done);
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&to_string);
|
||||
{
|
||||
var_result.Bind(ToString(context, argument));
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
BIND(&return_empty_string);
|
||||
{
|
||||
var_result.Bind(EmptyStringConstant());
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
BIND(&done);
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
args.PopAndReturn(EmitConstructString(argc, args, context, true));
|
||||
}
|
||||
|
||||
TF_BUILTIN(StringConstructor_ConstructStub, ConstructorBuiltinsAssembler) {
|
||||
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
|
||||
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
|
||||
MachineType::TaggedPointer());
|
||||
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
|
||||
Node* context = Parameter(BuiltinDescriptor::kContext);
|
||||
|
||||
Node* argc =
|
||||
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
|
||||
CodeStubArguments args(this, argc);
|
||||
// 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);
|
||||
|
||||
Node* string = EmitConstructString(argc, args, context, false);
|
||||
Node* result = EmitFastNewObject(context, target, new_target);
|
||||
StoreObjectField(result, JSValue::kValueOffset, string);
|
||||
args.PopAndReturn(result);
|
||||
// 2. Else,
|
||||
// a. If NewTarget is undefined [...]
|
||||
Node* value = args.AtIndex(0);
|
||||
Label if_tostring(this, &var_s);
|
||||
GotoIfNot(IsUndefined(new_target), &if_tostring);
|
||||
|
||||
// 2a. [...] and Type(value) is Symbol, return SymbolDescriptiveString(value).
|
||||
GotoIf(TaggedIsSmi(value), &if_tostring);
|
||||
GotoIfNot(IsSymbol(value), &if_tostring);
|
||||
{
|
||||
Node* result =
|
||||
CallRuntime(Runtime::kSymbolDescriptiveString, context, value);
|
||||
args.PopAndReturn(result);
|
||||
}
|
||||
|
||||
// 2b. Let s be ? ToString(value).
|
||||
BIND(&if_tostring);
|
||||
{
|
||||
var_s.Bind(CallBuiltin(Builtins::kToString, context, value));
|
||||
Goto(&if_sloaded);
|
||||
}
|
||||
|
||||
// 3. If NewTarget is undefined, return s.
|
||||
BIND(&if_sloaded);
|
||||
{
|
||||
Node* s_value = var_s.value();
|
||||
Label return_s(this), constructstring(this, Label::kDeferred);
|
||||
Branch(IsUndefined(new_target), &return_s, &constructstring);
|
||||
|
||||
BIND(&return_s);
|
||||
{ args.PopAndReturn(s_value); }
|
||||
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user