Commit 390c430e authored by Z Nguyen-Huu's avatar Z Nguyen-Huu Committed by Commit Bot

[builtins] Port the String constructor to Torque

Bug: v8:8996
Change-Id: Ie21bf5b695370a89a2f1023cc14db8b7ff1a141e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1744641
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63170}
parent 79786f4c
......@@ -739,66 +739,5 @@ TF_BUILTIN(GenericLazyDeoptContinuation, ConstructorBuiltinsAssembler) {
Return(result);
}
// https://tc39.github.io/ecma262/#sec-string-constructor
TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* argc =
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
// 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);
// 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);
{
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
Node* result =
CallBuiltin(Builtins::kFastNewObject, context, target, new_target);
StoreObjectField(result, JSPrimitiveWrapper::kValueOffset, s_value);
args.PopAndReturn(result);
}
}
}
} // namespace internal
} // namespace v8
......@@ -924,8 +924,6 @@ namespace internal {
CPP(AtomicsWake) \
\
/* String */ \
/* ES #sec-string-constructor */ \
TFJ(StringConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES #sec-string.fromcodepoint */ \
CPP(StringFromCodePoint) \
/* ES6 #sec-string.fromcharcode */ \
......
......@@ -137,4 +137,46 @@ namespace string {
}
return string;
}
extern transitioning runtime
SymbolDescriptiveString(implicit context: Context)(Object): Object;
// ES #sec-string-constructor
// https://tc39.github.io/ecma262/#sec-string-constructor
transitioning javascript builtin StringConstructor(
js-implicit context: Context, receiver: Object, newTarget: Object,
target: JSFunction)(...arguments): Object {
const length: intptr = Convert<intptr>(arguments.length);
let s: String;
// 1. If no arguments were passed to this function invocation, let s be "".
if (length == 0) {
s = EmptyStringConstant();
} else {
// 2. Else,
// 2. a. If NewTarget is undefined and Type(value) is Symbol, return
// SymbolDescriptiveString(value).
if (newTarget == Undefined) {
typeswitch (arguments[0]) {
case (value: Symbol): {
return SymbolDescriptiveString(value);
}
case (Object): {
}
}
}
// 2. b. Let s be ? ToString(value).
s = ToString_Inline(context, arguments[0]);
}
// 3. If NewTarget is undefined, return s.
if (newTarget == Undefined) {
return s;
}
// 4. Return ! StringCreate(s, ? GetPrototypeFromConstructor(NewTarget,
// "%String.prototype%")).
const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget));
const obj =
UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map));
obj.value = s;
return obj;
}
}
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