Commit dffba1ee authored by Mathias Bynens's avatar Mathias Bynens Committed by Commit Bot

Port Array.of to Torque

Spec: https://tc39.github.io/ecma262/#sec-array.of

Note that the `IsConstructor` abstract operation [1] is implemented
as a `typeswitch`.

[1] https://tc39.github.io/ecma262/#sec-isconstructor

Bug: v8:8321
Change-Id: I17af918c1d928faf8a630b35432876baa96da217
Reviewed-on: https://chromium-review.googlesource.com/c/1296464Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Mathias Bynens <mathias@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56935}
parent 97fee020
......@@ -916,6 +916,7 @@ torque_files = [
"src/builtins/array-foreach.tq",
"src/builtins/array-join.tq",
"src/builtins/array-lastindexof.tq",
"src/builtins/array-of.tq",
"src/builtins/array-reverse.tq",
"src/builtins/array-slice.tq",
"src/builtins/array-splice.tq",
......
// Copyright 2018 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.
module array {
// https://tc39.github.io/ecma262/#sec-array.of
javascript builtin ArrayOf(implicit context: Context)(
receiver: Object, ...arguments): Object {
// 1. Let len be the actual number of arguments passed to this function.
const len: Smi = Convert<Smi>(arguments.length);
// 2. Let items be the List of arguments passed to this function.
const items: constexpr Arguments = arguments;
// 3. Let C be the this value.
const c: Object = receiver;
let a: JSReceiver;
// 4. If IsConstructor(C) is true, then
typeswitch (c) {
case (c: Constructor): {
// a. Let A be ? Construct(C, « len »).
a = Construct(c, len);
}
case (Object): {
// a. Let A be ? ArrayCreate(len).
a = ArrayCreate(len);
}
}
// 6. Let k be 0.
let k: Smi = 0;
// 7. Repeat, while k < len
while (k < len) {
// a. Let kValue be items[k].
let kValue: Object = items[Convert<intptr>(k)];
// b. Let Pk be ! ToString(k).
// c. Perform ? CreateDataPropertyOrThrow(A, Pk, kValue).
CreateDataProperty(a, k, kValue);
// d. Increase k by 1.
k++;
}
// 8. Perform ? Set(A, "length", len, true).
SetProperty(a, kLengthString, len);
// 9. Return A.
return a;
}
}
......@@ -25,6 +25,7 @@ type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
type AbstractCode extends HeapObject generates 'TNode<AbstractCode>';
type Code extends AbstractCode generates 'TNode<Code>';
type JSReceiver extends HeapObject generates 'TNode<JSReceiver>';
type Constructor extends JSReceiver generates 'TNode<JSReceiver>';
type Context extends HeapObject generates 'TNode<Context>';
type NativeContext extends Context generates 'TNode<Context>';
type String extends HeapObject generates 'TNode<String>';
......@@ -264,10 +265,18 @@ extern macro ThrowTypeError(Context, constexpr MessageTemplate, Object): never;
extern macro ThrowTypeError(
Context, constexpr MessageTemplate, Object, Object, Object): never;
extern macro ArraySpeciesCreate(Context, Object, Number): JSReceiver;
extern macro ArrayCreate(implicit context: Context)(Number): JSArray;
extern macro InternalArrayCreate(Context, Number): JSArray;
extern macro EnsureArrayPushable(Map): ElementsKind
labels Bailout;
extern macro EnsureArrayLengthWritable(Map) labels Bailout;
// TODO: Reduce duplication once varargs are supported in macros.
extern macro Construct(implicit context: Context)(
Constructor, Object): JSReceiver;
extern macro Construct(implicit context: Context)(
Constructor, Object, Object): JSReceiver;
extern macro Construct(implicit context: Context)(
Constructor, Object, Object, Object): JSReceiver;
extern builtin ToObject(Context, Object): JSReceiver;
extern macro ToObject_Inline(Context, Object): JSReceiver;
......@@ -455,6 +464,8 @@ extern macro HeapObjectToFixedDoubleArray(HeapObject): FixedDoubleArray
labels CastError;
extern macro HeapObjectToString(HeapObject): String
labels CastError;
extern macro HeapObjectToConstructor(HeapObject): Constructor
labels CastError;
extern macro HeapObjectToHeapNumber(HeapObject): HeapNumber
labels CastError;
extern macro HeapObjectToSloppyArgumentsElements(HeapObject):
......@@ -497,6 +508,10 @@ CastHeapObject<String>(o: HeapObject): String
labels CastError {
return HeapObjectToString(o) otherwise CastError;
}
CastHeapObject<Constructor>(o: HeapObject): Constructor
labels CastError {
return HeapObjectToConstructor(o) otherwise CastError;
}
macro Cast<A: type>(o: HeapObject): A
labels CastError {
......
......@@ -2140,49 +2140,6 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) {
args.PopAndReturn(array.value());
}
// ES #sec-array.of
TF_BUILTIN(ArrayOf, ArrayPopulatorAssembler) {
TNode<Int32T> argc =
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<Smi> length = SmiFromInt32(argc);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
CodeStubArguments args(this, length, nullptr, ParameterMode::SMI_PARAMETERS);
TNode<Object> receiver = args.GetReceiver();
TVARIABLE(Object, array);
Label is_constructor(this), is_not_constructor(this), fill_array(this);
GotoIf(TaggedIsSmi(receiver), &is_not_constructor);
Branch(IsConstructor(CAST(receiver)), &is_constructor, &is_not_constructor);
BIND(&is_constructor);
{
array = Construct(context, CAST(receiver), length);
Goto(&fill_array);
}
BIND(&is_not_constructor);
{
array = ArrayCreate(context, length);
Goto(&fill_array);
}
BIND(&fill_array);
// TODO(delphick): Avoid using CreateDataProperty on the fast path.
BuildFastLoop(SmiConstant(0), length,
[&](Node* index) {
CallRuntime(
Runtime::kCreateDataProperty, context,
static_cast<Node*>(array.value()), index,
args.AtIndex(index, ParameterMode::SMI_PARAMETERS));
},
1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
GenerateSetLength(context, array.value(), length);
args.PopAndReturn(array.value());
}
// ES #sec-get-%typedarray%.prototype.find
TF_BUILTIN(TypedArrayPrototypeFind, ArrayBuiltinsAssembler) {
TNode<IntPtrT> argc =
......
......@@ -294,8 +294,6 @@ namespace internal {
CPP(ArrayPrototypeFill) \
/* ES6 #sec-array.from */ \
TFJ(ArrayFrom, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.of */ \
TFJ(ArrayOf, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES7 #sec-array.prototype.includes */ \
TFS(ArrayIncludesSmiOrObject, kElements, kSearchElement, kLength, \
kFromIndex) \
......
......@@ -341,6 +341,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
return CAST(heap_object);
}
TNode<JSReceiver> HeapObjectToConstructor(TNode<HeapObject> heap_object,
Label* fail) {
GotoIfNot(IsConstructor(heap_object), fail);
return CAST(heap_object);
}
TNode<HeapNumber> UnsafeCastNumberToHeapNumber(TNode<Number> p_n) {
return CAST(p_n);
}
......
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