Commit a2b5e64c authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[builtins] Remove BuiltinDescriptor.

Now TFJ builtins can use their own descriptors so there's no need to
keep the hacky BuiltinDescriptor around.

Bug: v8:7754
Change-Id: Ia7f23a21fb979370fd2149fef13186b83a3d5d30
Reviewed-on: https://chromium-review.googlesource.com/1104428
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53806}
parent 733b7c82
This diff is collapsed.
......@@ -329,12 +329,12 @@ TF_BUILTIN(AsyncGeneratorPrototypeNext, AsyncGeneratorBuiltinsAssembler) {
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* generator = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kNext,
......@@ -347,12 +347,12 @@ TF_BUILTIN(AsyncGeneratorPrototypeReturn, AsyncGeneratorBuiltinsAssembler) {
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* generator = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kReturn,
......@@ -365,12 +365,12 @@ TF_BUILTIN(AsyncGeneratorPrototypeThrow, AsyncGeneratorBuiltinsAssembler) {
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* generator = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kThrow,
......
......@@ -745,20 +745,20 @@ TNode<Object> CollectionsBuiltinsAssembler::AllocateTable(
}
TF_BUILTIN(MapConstructor, CollectionsBuiltinsAssembler) {
TNode<Object> new_target = CAST(Parameter(BuiltinDescriptor::kNewTarget));
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
GenerateConstructor(kMap, isolate()->factory()->Map_string(), new_target,
argc, context);
}
TF_BUILTIN(SetConstructor, CollectionsBuiltinsAssembler) {
TNode<Object> new_target = CAST(Parameter(BuiltinDescriptor::kNewTarget));
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
GenerateConstructor(kSet, isolate()->factory()->Set_string(), new_target,
argc, context);
......@@ -1538,8 +1538,8 @@ TF_BUILTIN(MapPrototypeGetSize, CollectionsBuiltinsAssembler) {
TF_BUILTIN(MapPrototypeForEach, CollectionsBuiltinsAssembler) {
const char* const kMethodName = "Map.prototype.forEach";
Node* const argc = Parameter(BuiltinDescriptor::kArgumentsCount);
Node* const context = Parameter(BuiltinDescriptor::kContext);
Node* const argc = Parameter(Descriptor::kJSActualArgumentsCount);
Node* const context = Parameter(Descriptor::kContext);
CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
Node* const receiver = args.GetReceiver();
Node* const callback = args.GetOptionalArgumentValue(0);
......@@ -1769,8 +1769,8 @@ TF_BUILTIN(SetPrototypeGetSize, CollectionsBuiltinsAssembler) {
TF_BUILTIN(SetPrototypeForEach, CollectionsBuiltinsAssembler) {
const char* const kMethodName = "Set.prototype.forEach";
Node* const argc = Parameter(BuiltinDescriptor::kArgumentsCount);
Node* const context = Parameter(BuiltinDescriptor::kContext);
Node* const argc = Parameter(Descriptor::kJSActualArgumentsCount);
Node* const context = Parameter(Descriptor::kContext);
CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
Node* const receiver = args.GetReceiver();
Node* const callback = args.GetOptionalArgumentValue(0);
......@@ -2236,20 +2236,20 @@ TNode<IntPtrT> WeakCollectionsBuiltinsAssembler::ValueIndexFromKeyIndex(
}
TF_BUILTIN(WeakMapConstructor, WeakCollectionsBuiltinsAssembler) {
TNode<Object> new_target = CAST(Parameter(BuiltinDescriptor::kNewTarget));
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
GenerateConstructor(kWeakMap, isolate()->factory()->WeakMap_string(),
new_target, argc, context);
}
TF_BUILTIN(WeakSetConstructor, WeakCollectionsBuiltinsAssembler) {
TNode<Object> new_target = CAST(Parameter(BuiltinDescriptor::kNewTarget));
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
GenerateConstructor(kWeakSet, isolate()->factory()->WeakSet_string(),
new_target, argc, context);
......
......@@ -16,9 +16,9 @@ TF_BUILTIN(FastConsoleAssert, CodeStubAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
Node* context = Parameter(Descriptor::kContext);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
GotoIf(Word32Equal(argc, Int32Constant(0)), &runtime);
CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
......
......@@ -631,10 +631,10 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral(
TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) {
int const kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* context = Parameter(Descriptor::kContext);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
VARIABLE(var_result, MachineRepresentation::kTagged);
Label if_subclass(this, Label::kDeferred), if_notsubclass(this),
......@@ -683,9 +683,9 @@ TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) {
// ES #sec-number-constructor
TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) {
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
// 1. If no arguments were passed to this function invocation, let n be +0.
......@@ -705,7 +705,7 @@ TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) {
{
// 3. If NewTarget is undefined, return n.
Node* n_value = var_n.value();
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
Label return_n(this), constructnumber(this, Label::kDeferred);
Branch(IsUndefined(new_target), &return_n, &constructnumber);
......@@ -730,12 +730,12 @@ TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) {
// https://tc39.github.io/ecma262/#sec-string-constructor
TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) {
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
......
This diff is collapsed.
......@@ -7,21 +7,24 @@
#include "src/builtins/builtins.h"
#include "src/interface-descriptors.h"
#include "src/objects/shared-function-info.h"
namespace v8 {
namespace internal {
// Define interface descriptors for builtins with JS linkage.
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR(Name, Argc, ...) \
struct Builtin_##Name##_InterfaceDescriptor { \
enum ParameterIndices { \
kReceiver, \
##__VA_ARGS__, \
kNewTarget, \
kActualArgumentsCount, \
kContext, \
kParameterCount, \
}; \
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR(Name, Argc, ...) \
struct Builtin_##Name##_InterfaceDescriptor { \
enum ParameterIndices { \
kJSTarget = -1, \
##__VA_ARGS__, \
kJSNewTarget, \
kJSActualArgumentsCount, \
kContext, \
kParameterCount, \
}; \
static_assert((Argc) == static_cast<uint16_t>(kParameterCount - 4), \
"Inconsistent set of arguments"); \
};
// Define interface descriptors for builtins with StubCall linkage.
......
......@@ -17,9 +17,9 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
Node* context = Parameter(Descriptor::kContext);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
......
......@@ -125,12 +125,12 @@ TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) {
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* receiver = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
GeneratorPrototypeResume(&args, receiver, value, context,
JSGeneratorObject::kNext,
......@@ -142,12 +142,12 @@ TF_BUILTIN(GeneratorPrototypeReturn, GeneratorBuiltinsAssembler) {
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* receiver = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
GeneratorPrototypeResume(&args, receiver, value, context,
JSGeneratorObject::kReturn,
......@@ -159,12 +159,12 @@ TF_BUILTIN(GeneratorPrototypeThrow, GeneratorBuiltinsAssembler) {
const int kExceptionArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* receiver = args.GetReceiver();
Node* exception = args.GetOptionalArgumentValue(kExceptionArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
GeneratorPrototypeResume(&args, receiver, exception, context,
JSGeneratorObject::kThrow,
......
......@@ -176,10 +176,10 @@ TF_BUILTIN(ReturnReceiver, CodeStubAssembler) {
TF_BUILTIN(DebugBreakTrampoline, CodeStubAssembler) {
Label tailcall_to_shared(this);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Object> new_target = CAST(Parameter(BuiltinDescriptor::kNewTarget));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
TNode<Int32T> arg_count =
UncheckedCast<Int32T>(Parameter(BuiltinDescriptor::kArgumentsCount));
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<JSFunction> function = CAST(LoadFromFrame(
StandardFrameConstants::kFunctionOffset, MachineType::TaggedPointer()));
......
......@@ -503,8 +503,8 @@ TF_BUILTIN(MathTrunc, MathBuiltinsAssembler) {
TF_BUILTIN(MathMax, MathBuiltinsAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
Node* context = Parameter(Descriptor::kContext);
Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
MathMaxMin(context, argc, &CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY);
}
......@@ -512,8 +512,8 @@ TF_BUILTIN(MathMax, MathBuiltinsAssembler) {
TF_BUILTIN(MathMin, MathBuiltinsAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
Node* context = Parameter(Descriptor::kContext);
Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
MathMaxMin(context, argc, &CodeStubAssembler::Float64Min, V8_INFINITY);
}
......
......@@ -485,10 +485,10 @@ TF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) {
// ES #sec-object.assign
TF_BUILTIN(ObjectAssign, ObjectBuiltinsAssembler) {
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> target = args.GetOptionalArgumentValue(0);
// 1. Let to be ? ToObject(target).
......@@ -1194,12 +1194,12 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) {
int const kPropertiesArg = 1;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* prototype = args.GetOptionalArgumentValue(kPrototypeArg);
Node* properties = args.GetOptionalArgumentValue(kPropertiesArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
Label call_runtime(this, Label::kDeferred), prototype_valid(this),
no_properties(this);
......@@ -1407,9 +1407,9 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) {
// ES6 section 19.1.2.7 Object.getOwnPropertyDescriptor ( O, P )
TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) {
Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
Node* context = Parameter(BuiltinDescriptor::kContext);
CSA_ASSERT(this, IsUndefined(Parameter(BuiltinDescriptor::kNewTarget)));
Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);
Node* context = Parameter(Descriptor::kContext);
CSA_ASSERT(this, IsUndefined(Parameter(Descriptor::kJSNewTarget)));
CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
Node* object = args.GetOptionalArgumentValue(0);
......
......@@ -791,7 +791,7 @@ TF_BUILTIN(PromiseConstructorLazyDeoptContinuation, PromiseBuiltinsAssembler) {
// ES6 #sec-promise-executor
TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
Node* const executor = Parameter(Descriptor::kExecutor);
Node* const new_target = Parameter(Descriptor::kNewTarget);
Node* const new_target = Parameter(Descriptor::kJSNewTarget);
Node* const context = Parameter(Descriptor::kContext);
Isolate* isolate = this->isolate();
......
......@@ -150,7 +150,7 @@ TF_BUILTIN(ProxyConstructor, ProxiesCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
// 1. If NewTarget is undefined, throw a TypeError exception.
Node* new_target = Parameter(Descriptor::kNewTarget);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
Label throwtypeerror(this, Label::kDeferred), createproxy(this);
Branch(IsUndefined(new_target), &throwtypeerror, &createproxy);
......
......@@ -1298,7 +1298,7 @@ TF_BUILTIN(RegExpPrototypeFlagsGetter, RegExpBuiltinsAssembler) {
TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) {
Node* const pattern = Parameter(Descriptor::kPattern);
Node* const flags = Parameter(Descriptor::kFlags);
Node* const new_target = Parameter(Descriptor::kNewTarget);
Node* const new_target = Parameter(Descriptor::kJSNewTarget);
Node* const context = Parameter(Descriptor::kContext);
Isolate* isolate = this->isolate();
......@@ -2638,13 +2638,13 @@ TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) {
const int kLimitArg = 1;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* const maybe_receiver = args.GetReceiver();
Node* const maybe_string = args.GetOptionalArgumentValue(kStringArg);
Node* const maybe_limit = args.GetOptionalArgumentValue(kLimitArg);
Node* const context = Parameter(BuiltinDescriptor::kContext);
Node* const context = Parameter(Descriptor::kContext);
// Ensure {maybe_receiver} is a JSReceiver.
ThrowIfNotJSReceiver(context, maybe_receiver,
......@@ -3048,13 +3048,13 @@ TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) {
const int kReplaceValueArg = 1;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* const maybe_receiver = args.GetReceiver();
Node* const maybe_string = args.GetOptionalArgumentValue(kStringArg);
Node* const replace_value = args.GetOptionalArgumentValue(kReplaceValueArg);
Node* const context = Parameter(BuiltinDescriptor::kContext);
Node* const context = Parameter(Descriptor::kContext);
// RegExpPrototypeReplace is a bit of a beast - a summary of dispatch logic:
//
......
......@@ -628,8 +628,8 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
TNode<Int32T> argc =
UncheckedCast<Int32T>(Parameter(BuiltinDescriptor::kArgumentsCount));
Node* context = Parameter(BuiltinDescriptor::kContext);
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount));
Node* context = Parameter(Descriptor::kContext);
CodeStubArguments arguments(this, ChangeInt32ToIntPtr(argc));
TNode<Smi> smi_argc = SmiTag(arguments.GetLength(INTPTR_PARAMETERS));
......@@ -787,9 +787,10 @@ TF_BUILTIN(StringPrototypeConcat, CodeStubAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
CodeStubArguments arguments(
this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));
this,
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
Node* receiver = arguments.GetReceiver();
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
// Check that {receiver} is coercible to Object and convert it to a String.
receiver = ToThisString(context, receiver, "String.prototype.concat");
......@@ -990,22 +991,18 @@ TF_BUILTIN(StringIndexOf, StringBuiltinsAssembler) {
// ES6 String.prototype.includes(searchString [, position])
// #sec-string.prototype.includes
TF_BUILTIN(StringPrototypeIncludes, StringIncludesIndexOfAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Generate(kIncludes, argc, context);
}
// ES6 String.prototype.indexOf(searchString [, position])
// #sec-string.prototype.indexof
TF_BUILTIN(StringPrototypeIndexOf, StringIncludesIndexOfAssembler) {
// TODO(ishell): use constants from Descriptor once the JSFunction linkage
// arguments are reordered.
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Generate(kIndexOf, argc, context);
}
......@@ -1738,16 +1735,16 @@ class StringPadAssembler : public StringBuiltinsAssembler {
TF_BUILTIN(StringPrototypePadEnd, StringPadAssembler) {
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Generate(kEnd, "String.prototype.padEnd", argc, context);
}
TF_BUILTIN(StringPrototypePadStart, StringPadAssembler) {
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Generate(kStart, "String.prototype.padStart", argc, context);
}
......@@ -1769,12 +1766,12 @@ TF_BUILTIN(StringPrototypeSlice, StringBuiltinsAssembler) {
const int kStart = 0;
const int kEnd = 1;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* const receiver = args.GetReceiver();
TNode<Object> start = args.GetOptionalArgumentValue(kStart);
TNode<Object> end = args.GetOptionalArgumentValue(kEnd);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
// 1. Let O be ? RequireObjectCoercible(this value).
RequireObjectCoercible(context, receiver, "String.prototype.slice");
......@@ -1893,13 +1890,13 @@ TF_BUILTIN(StringPrototypeSplit, StringBuiltinsAssembler) {
const int kLimitArg = 1;
Node* const argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* const receiver = args.GetReceiver();
Node* const separator = args.GetOptionalArgumentValue(kSeparatorArg);
Node* const limit = args.GetOptionalArgumentValue(kLimitArg);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Smi> smi_zero = SmiConstant(0);
......@@ -1995,13 +1992,13 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) {
const int kLengthArg = 1;
Node* const argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* const receiver = args.GetReceiver();
TNode<Object> start = args.GetOptionalArgumentValue(kStartArg);
TNode<Object> length = args.GetOptionalArgumentValue(kLengthArg);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Label out(this);
......@@ -2151,13 +2148,13 @@ TF_BUILTIN(StringPrototypeSubstring, StringBuiltinsAssembler) {
const int kEndArg = 1;
Node* const argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
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(BuiltinDescriptor::kContext);
Node* const context = Parameter(Descriptor::kContext);
Label out(this);
......@@ -2203,8 +2200,8 @@ TF_BUILTIN(StringPrototypeSubstring, StringBuiltinsAssembler) {
// ES6 #sec-string.prototype.trim
TF_BUILTIN(StringPrototypeTrim, StringTrimAssembler) {
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Generate(String::kTrim, "String.prototype.trim", argc, context);
}
......@@ -2212,8 +2209,8 @@ TF_BUILTIN(StringPrototypeTrim, StringTrimAssembler) {
// https://github.com/tc39/proposal-string-left-right-trim
TF_BUILTIN(StringPrototypeTrimStart, StringTrimAssembler) {
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Generate(String::kTrimStart, "String.prototype.trimLeft", argc, context);
}
......@@ -2221,8 +2218,8 @@ TF_BUILTIN(StringPrototypeTrimStart, StringTrimAssembler) {
// https://github.com/tc39/proposal-string-left-right-trim
TF_BUILTIN(StringPrototypeTrimEnd, StringTrimAssembler) {
TNode<IntPtrT> argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Generate(String::kTrimEnd, "String.prototype.trimRight", argc, context);
}
......
......@@ -757,12 +757,12 @@ TF_BUILTIN(TypedArrayConstructorLazyDeoptContinuation,
// ES #sec-typedarray-constructors
TF_BUILTIN(TypedArrayConstructor, TypedArrayBuiltinsAssembler) {
Node* context = Parameter(BuiltinDescriptor::kContext);
Node* context = Parameter(Descriptor::kContext);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* arg1 = args.GetOptionalArgumentValue(0);
Node* arg2 = args.GetOptionalArgumentValue(1);
......@@ -1201,9 +1201,10 @@ void TypedArrayBuiltinsAssembler::DispatchTypedArrayByElementsKind(
// ES #sec-get-%typedarray%.prototype.set
TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
CodeStubArguments args(
this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));
this,
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
Label if_source_is_typed_array(this), if_source_is_fast_jsarray(this),
if_offset_is_out_of_bounds(this, Label::kDeferred),
......@@ -1291,9 +1292,10 @@ TF_BUILTIN(TypedArrayPrototypeSlice, TypedArrayBuiltinsAssembler) {
if_typed_array_is_neutered(this, Label::kDeferred),
if_bigint_mixed_types(this, Label::kDeferred);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
CodeStubArguments args(
this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));
this,
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
TNode<Object> receiver = args.GetReceiver();
TNode<JSTypedArray> source =
......@@ -1415,9 +1417,10 @@ TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
TVARIABLE(Smi, var_begin);
TVARIABLE(Smi, var_end);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
CodeStubArguments args(
this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));
this,
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
// 1. Let O be the this value.
// 3. If O does not have a [[TypedArrayName]] internal slot, throw a TypeError
......@@ -1571,11 +1574,11 @@ TF_BUILTIN(TypedArrayPrototypeKeys, TypedArrayBuiltinsAssembler) {
// ES6 #sec-%typedarray%.of
TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
// 1. Let len be the actual number of arguments passed to this function.
TNode<IntPtrT> length = ChangeInt32ToIntPtr(
UncheckedCast<Int32T>(Parameter(BuiltinDescriptor::kArgumentsCount)));
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)));
// 2. Let items be the List of arguments passed to this function.
CodeStubArguments args(this, length, nullptr, INTPTR_PARAMETERS,
CodeStubArguments::ReceiverMode::kHasReceiver);
......@@ -1713,7 +1716,7 @@ TF_BUILTIN(IterableToList, TypedArrayBuiltinsAssembler) {
// ES6 #sec-%typedarray%.from
TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Label check_iterator(this), from_array_like(this), fast_path(this),
slow_path(this), create_typed_array(this),
......@@ -1723,7 +1726,8 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
if_neutered(this, Label::kDeferred);
CodeStubArguments args(
this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));
this,
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
TNode<Object> source = args.GetOptionalArgumentValue(0);
// 5. If thisArg is present, let T be thisArg; else let T be undefined.
......@@ -1895,9 +1899,10 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
TF_BUILTIN(TypedArrayPrototypeFilter, TypedArrayBuiltinsAssembler) {
const char* method_name = "%TypedArray%.prototype.filter";
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
CodeStubArguments args(
this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));
this,
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
Label if_callback_not_callable(this, Label::kDeferred),
detached(this, Label::kDeferred);
......
......@@ -38,11 +38,6 @@ class CodeAssemblerState;
Node* Parameter(Descriptor::ParameterIndices index) { \
return CodeAssembler::Parameter(static_cast<int>(index)); \
} \
/* TODO(ishell): Remove this way of accessing parameters once the */ \
/* JSFunction linkage arguments are reordered. */ \
Node* Parameter(BuiltinDescriptor::ParameterIndices index) { \
return CodeAssembler::Parameter(static_cast<int>(index)); \
} \
}; \
void Builtins::Generate_##Name(compiler::CodeAssemblerState* state) { \
Name##Assembler assembler(state); \
......
......@@ -159,7 +159,7 @@ Callable Builtins::CallableFor(Isolate* isolate, Name name) {
default:
Builtins::Kind kind = Builtins::KindOf(name);
if (kind == TFJ || kind == CPP) {
return Callable(code, BuiltinDescriptor{});
return Callable(code, JSTrampolineDescriptor{});
}
UNREACHABLE();
}
......
......@@ -434,12 +434,12 @@ Callable CodeFactory::InternalArraySingleArgumentConstructor(
// static
Callable CodeFactory::ArrayPop(Isolate* isolate) {
return Callable(BUILTIN_CODE(isolate, ArrayPop), BuiltinDescriptor{});
return Callable(BUILTIN_CODE(isolate, ArrayPop), JSTrampolineDescriptor{});
}
// static
Callable CodeFactory::ArrayShift(Isolate* isolate) {
return Callable(BUILTIN_CODE(isolate, ArrayShift), BuiltinDescriptor{});
return Callable(BUILTIN_CODE(isolate, ArrayShift), JSTrampolineDescriptor{});
}
// static
......@@ -456,13 +456,13 @@ Callable CodeFactory::CloneFastJSArray(Isolate* isolate) {
// static
Callable CodeFactory::ArrayPush(Isolate* isolate) {
return Callable(BUILTIN_CODE(isolate, ArrayPush), BuiltinDescriptor{});
return Callable(BUILTIN_CODE(isolate, ArrayPush), JSTrampolineDescriptor{});
}
// static
Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) {
return Callable(BUILTIN_CODE(isolate, FunctionPrototypeBind),
BuiltinDescriptor{});
JSTrampolineDescriptor{});
}
} // namespace internal
......
......@@ -138,15 +138,15 @@ struct IteratorRecord {
EXPAND(CSA_ASSERT_GET_FIRST_STR(__VA_ARGS__)), __FILE__, \
__LINE__, CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__))
#define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected) \
(csa)->Assert( \
[&]() -> compiler::Node* { \
compiler::Node* const argc = \
(csa)->Parameter(Descriptor::kActualArgumentsCount); \
return (csa)->Op(argc, (csa)->Int32Constant(expected)); \
}, \
"argc " #op " " #expected, __FILE__, __LINE__, \
SmiFromInt32((csa)->Parameter(Descriptor::kActualArgumentsCount)), \
#define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected) \
(csa)->Assert( \
[&]() -> compiler::Node* { \
compiler::Node* const argc = \
(csa)->Parameter(Descriptor::kJSActualArgumentsCount); \
return (csa)->Op(argc, (csa)->Int32Constant(expected)); \
}, \
"argc " #op " " #expected, __FILE__, __LINE__, \
SmiFromInt32((csa)->Parameter(Descriptor::kJSActualArgumentsCount)), \
"argc")
#define CSA_ASSERT_JS_ARGC_EQ(csa, expected) \
......
......@@ -492,34 +492,6 @@ void ConstructStubDescriptor::InitializePlatformIndependent(
machine_types);
}
void BuiltinDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kTarget, kNewTarget, kArgumentsCount
MachineType machine_types[] = {
MachineType::AnyTagged(), MachineType::AnyTagged(), MachineType::Int32()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void BuiltinDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {TargetRegister(), NewTargetRegister(),
ArgumentsCountRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
const Register BuiltinDescriptor::ArgumentsCountRegister() {
return kJavaScriptCallArgCountRegister;
}
const Register BuiltinDescriptor::NewTargetRegister() {
return kJavaScriptCallNewTargetRegister;
}
const Register BuiltinDescriptor::TargetRegister() {
return kJSFunctionRegister;
}
void ArrayNoArgumentConstructorDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kFunction, kAllocationSite, kActualArgumentsCount, kFunctionParameter
......
......@@ -50,7 +50,6 @@ class PlatformInterfaceDescriptor;
V(JSTrampoline) \
V(AbortJS) \
V(AllocateHeapNumber) \
V(Builtin) \
V(ArrayConstructor) \
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
......@@ -321,20 +320,6 @@ constexpr int kMaxBuiltinRegisterParams = 5;
\
public:
#define DECLARE_DESCRIPTOR_WITH_STACK_ARGS(name, base) \
DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
protected: \
void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
override { \
data->InitializePlatformIndependent(0, kParameterCount, nullptr); \
} \
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
override { \
data->InitializePlatformSpecific(0, nullptr); \
} \
\
public:
#define DEFINE_PARAMETERS(...) \
enum ParameterIndices { \
__dummy = -1, /* to be able to pass zero arguments */ \
......@@ -355,40 +340,6 @@ constexpr int kMaxBuiltinRegisterParams = 5;
kContext = kParameterCount /* implicit parameter */ \
};
#define DECLARE_BUILTIN_DESCRIPTOR(name) \
DECLARE_DESCRIPTOR_WITH_BASE(name, BuiltinDescriptor) \
protected: \
void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
override { \
MachineType machine_types[] = {MachineType::AnyTagged(), \
MachineType::AnyTagged(), \
MachineType::Int32()}; \
data->InitializePlatformIndependent(arraysize(machine_types), \
kStackParameterCount, machine_types); \
} \
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
override { \
Register registers[] = {TargetRegister(), NewTargetRegister(), \
ArgumentsCountRegister()}; \
data->InitializePlatformSpecific(arraysize(registers), registers); \
} \
\
public:
#define DEFINE_BUILTIN_PARAMETERS(...) \
enum ParameterIndices { \
kReceiver, \
kBeforeFirstStackParameter = kReceiver, \
__VA_ARGS__, \
kAfterLastStackParameter, \
kNewTarget = kAfterLastStackParameter, \
kArgumentsCount, \
kContext, /* implicit parameter */ \
kParameterCount = kContext, \
kArity = kAfterLastStackParameter - kBeforeFirstStackParameter - 1, \
kStackParameterCount = kArity + 1 \
};
class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
......@@ -696,17 +647,6 @@ class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
};
class BuiltinDescriptor : public CallInterfaceDescriptor {
public:
// TODO(ishell): Where is kFunction??
DEFINE_PARAMETERS(kNewTarget, kArgumentsCount)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(BuiltinDescriptor,
CallInterfaceDescriptor)
static const Register ArgumentsCountRegister();
static const Register NewTargetRegister();
static const Register TargetRegister();
};
class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_JS_PARAMETERS(kAllocationSite)
......
......@@ -272,7 +272,8 @@ class DeclarationVisitor : public FileVisitor {
assert(builtin->parameter_names().size() >= 2);
new_contents_stream << ", "
<< (builtin->parameter_names().size() - 2);
// And the receiver is implicitly declared.
// And the receiver is explicitly declared.
new_contents_stream << ", kReceiver";
firstParameterIndex = 2;
}
}
......
......@@ -252,7 +252,6 @@ void ImplementationVisitor::Visit(TorqueBuiltinDeclaration* decl,
GenerateIndent();
source_out() << "TNode<Context> " << val->GetValueForDeclaration()
<< " = UncheckedCast<Context>(Parameter("
<< (builtin->IsVarArgsJavaScript() ? "Builtin" : "")
<< "Descriptor::kContext));" << std::endl;
GenerateIndent();
source_out() << "USE(" << val->GetValueForDeclaration() << ");" << std::endl;
......@@ -265,7 +264,7 @@ void ImplementationVisitor::Visit(TorqueBuiltinDeclaration* decl,
std::string arguments_name = arguments->GetValueForDeclaration();
GenerateIndent();
source_out()
<< "Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);"
<< "Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);"
<< std::endl;
GenerateIndent();
source_out() << "CodeStubArguments arguments_impl(this, "
......
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