Commit a5336471 authored by Caitlin Potter's avatar Caitlin Potter Committed by Commit Bot

[builtins] Implement Object.fromEntries

Adds the Object.fromEntries() method behind
--harmony-object-from-entries.


Includes an initial implementation of the new experimental builtin
Object.fromEntries implemented by Daniel Clifford, and
has been modified by Caitlin Potter to support a fast case to skip
the iterator protocol when it can be done unobservably in common cases.

There are some incidental changes: A number of CSA macros have been
updated to use TNodes, and some Context arguments have been
re-arranged to be implicit in Torque.


There are also a number of mjsunit tests written mirroring and
expanding on the test262 tests.

BUG=v8:8021

Change-Id: I1c12bee8a2f98c6297b77d5d723910a5e3b630cc
Co-authored-by: 's avatarDaniel Clifford <danno@chromium.org>
Co-authored-by: 's avatarCaitlin Potter <caitp@igalia.com>
Reviewed-on: https://chromium-review.googlesource.com/c/1337585
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57667}
parent b84766b3
...@@ -925,9 +925,11 @@ torque_files = [ ...@@ -925,9 +925,11 @@ torque_files = [
"src/builtins/array-splice.tq", "src/builtins/array-splice.tq",
"src/builtins/array-unshift.tq", "src/builtins/array-unshift.tq",
"src/builtins/collections.tq", "src/builtins/collections.tq",
"src/builtins/typed-array.tq",
"src/builtins/data-view.tq", "src/builtins/data-view.tq",
"src/builtins/object.tq",
"src/builtins/object-fromentries.tq",
"src/builtins/iterator.tq", "src/builtins/iterator.tq",
"src/builtins/typed-array.tq",
"test/torque/test-torque.tq", "test/torque/test-torque.tq",
"third_party/v8/builtins/array-sort.tq", "third_party/v8/builtins/array-sort.tq",
] ]
...@@ -937,6 +939,7 @@ torque_namespaces = [ ...@@ -937,6 +939,7 @@ torque_namespaces = [
"array", "array",
"collections", "collections",
"iterator", "iterator",
"object",
"typed-array", "typed-array",
"data-view", "data-view",
"test", "test",
......
...@@ -4903,6 +4903,12 @@ void Genesis::InitializeGlobal_harmony_intl_segmenter() { ...@@ -4903,6 +4903,12 @@ void Genesis::InitializeGlobal_harmony_intl_segmenter() {
#endif // V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT
void Genesis::InitializeGlobal_harmony_object_from_entries() {
if (!FLAG_harmony_object_from_entries) return;
SimpleInstallFunction(isolate(), isolate()->object_function(), "fromEntries",
Builtins::kObjectFromEntries, 1, false);
}
Handle<JSFunction> Genesis::CreateArrayBuffer( Handle<JSFunction> Genesis::CreateArrayBuffer(
Handle<String> name, ArrayBufferKind array_buffer_kind) { Handle<String> name, ArrayBufferKind array_buffer_kind) {
// Create the %ArrayBufferPrototype% // Create the %ArrayBufferPrototype%
......
...@@ -41,10 +41,20 @@ type JSArgumentsObjectWithLength extends JSObject ...@@ -41,10 +41,20 @@ type JSArgumentsObjectWithLength extends JSObject
generates 'TNode<JSArgumentsObjectWithLength>'; generates 'TNode<JSArgumentsObjectWithLength>';
type JSArray extends JSArgumentsObjectWithLength type JSArray extends JSArgumentsObjectWithLength
generates 'TNode<JSArray>'; generates 'TNode<JSArray>';
// A HeapObject with a JSArray map, and either fast packed elements, or fast
// holey elements when the global NoElementsProtector is not invalidated.
transient type FastJSArray extends JSArray transient type FastJSArray extends JSArray
generates 'TNode<JSArray>'; generates 'TNode<JSArray>';
// A FastJSArray when the global ArraySpeciesProtector is not invalidated.
transient type FastJSArrayForCopy extends FastJSArray transient type FastJSArrayForCopy extends FastJSArray
generates 'TNode<JSArray>'; generates 'TNode<JSArray>';
// A FastJSArray when the global ArrayIteratorProtector is not invalidated.
transient type FastJSArrayWithNoCustomIteration extends FastJSArray
generates 'TNode<JSArray>';
type JSFunction extends JSObject generates 'TNode<JSFunction>'; type JSFunction extends JSObject generates 'TNode<JSFunction>';
type JSBoundFunction extends JSObject generates 'TNode<JSBoundFunction>'; type JSBoundFunction extends JSObject generates 'TNode<JSBoundFunction>';
type Callable = JSFunction | JSBoundFunction | JSProxy; type Callable = JSFunction | JSBoundFunction | JSProxy;
...@@ -67,6 +77,8 @@ const ARRAY_JOIN_STACK_INDEX: constexpr NativeContextSlot ...@@ -67,6 +77,8 @@ const ARRAY_JOIN_STACK_INDEX: constexpr NativeContextSlot
generates 'Context::ARRAY_JOIN_STACK_INDEX'; generates 'Context::ARRAY_JOIN_STACK_INDEX';
const OBJECT_FUNCTION_INDEX: constexpr NativeContextSlot const OBJECT_FUNCTION_INDEX: constexpr NativeContextSlot
generates 'Context::OBJECT_FUNCTION_INDEX'; generates 'Context::OBJECT_FUNCTION_INDEX';
const ITERATOR_RESULT_MAP_INDEX: constexpr NativeContextSlot
generates 'Context::ITERATOR_RESULT_MAP_INDEX';
extern operator '[]' macro LoadContextElement( extern operator '[]' macro LoadContextElement(
NativeContext, NativeContextSlot): Object; NativeContext, NativeContextSlot): Object;
extern operator '[]=' macro StoreContextElement( extern operator '[]=' macro StoreContextElement(
...@@ -843,6 +855,8 @@ extern macro RawCastObjectToJSArgumentsObjectWithLength(Object): ...@@ -843,6 +855,8 @@ extern macro RawCastObjectToJSArgumentsObjectWithLength(Object):
JSArgumentsObjectWithLength; JSArgumentsObjectWithLength;
extern macro RawCastObjectToFastJSArray(Object): FastJSArray; extern macro RawCastObjectToFastJSArray(Object): FastJSArray;
extern macro RawCastObjectToFastJSArrayForCopy(Object): FastJSArrayForCopy; extern macro RawCastObjectToFastJSArrayForCopy(Object): FastJSArrayForCopy;
extern macro RawCastObjectToFastJSArrayWithNoCustomIteration(Object):
FastJSArrayWithNoCustomIteration;
macro BranchIfJSArgumentsObjectWithLength(implicit context: Context)(o: Object): macro BranchIfJSArgumentsObjectWithLength(implicit context: Context)(o: Object):
never never
...@@ -911,6 +925,21 @@ Cast<FastJSArrayForCopy>(implicit context: Context)(o: Object): ...@@ -911,6 +925,21 @@ Cast<FastJSArrayForCopy>(implicit context: Context)(o: Object):
} }
} }
UnsafeCast<FastJSArrayWithNoCustomIteration>(implicit context: Context)(
o: Object): FastJSArrayWithNoCustomIteration {
assert(BranchIfFastJSArrayWithNoCustomIteration(o));
return RawCastObjectToFastJSArrayWithNoCustomIteration(o);
}
Cast<FastJSArrayWithNoCustomIteration>(implicit context: Context)(o: Object):
FastJSArrayWithNoCustomIteration labels CastError {
if (BranchIfFastJSArrayWithNoCustomIteration(o)) {
return UnsafeCast<FastJSArrayWithNoCustomIteration>(o);
} else {
goto CastError;
}
}
UnsafeCast<JSFunction>(implicit context: Context)(o: Object): JSFunction { UnsafeCast<JSFunction>(implicit context: Context)(o: Object): JSFunction {
assert(IsJSFunction(Cast<HeapObject>(o) otherwise unreachable)); assert(IsJSFunction(Cast<HeapObject>(o) otherwise unreachable));
return RawCastObjectToJSFunction(o); return RawCastObjectToJSFunction(o);
...@@ -951,6 +980,9 @@ extern macro BranchIfFastJSArray(Object, Context): never ...@@ -951,6 +980,9 @@ extern macro BranchIfFastJSArray(Object, Context): never
labels Taken, NotTaken; labels Taken, NotTaken;
extern macro BranchIfFastJSArrayForCopy(Object, Context): never extern macro BranchIfFastJSArrayForCopy(Object, Context): never
labels Taken, NotTaken; labels Taken, NotTaken;
extern macro BranchIfFastJSArrayWithNoCustomIteration(
implicit context: Context)(Object): never labels Taken,
NotTaken;
extern macro BranchIfNotFastJSArray(Object, Context): never extern macro BranchIfNotFastJSArray(Object, Context): never
labels Taken, NotTaken; labels Taken, NotTaken;
macro BranchIfNotFastJSArrayForCopy(implicit context: Context)(o: Object): never macro BranchIfNotFastJSArrayForCopy(implicit context: Context)(o: Object): never
...@@ -1078,7 +1110,7 @@ extern macro CopyFixedArrayElements( ...@@ -1078,7 +1110,7 @@ extern macro CopyFixedArrayElements(
extern macro AllocateJSArray(constexpr ElementsKind, Map, intptr, Smi): JSArray; extern macro AllocateJSArray(constexpr ElementsKind, Map, intptr, Smi): JSArray;
extern macro AllocateJSArray(constexpr ElementsKind, Map, Smi, Smi): JSArray; extern macro AllocateJSArray(constexpr ElementsKind, Map, Smi, Smi): JSArray;
extern macro AllocateJSObjectFromMap(Map): HeapObject; extern macro AllocateJSObjectFromMap(Map): JSObject;
extern operator '[]=' macro StoreFixedDoubleArrayElementSmi( extern operator '[]=' macro StoreFixedDoubleArrayElementSmi(
FixedDoubleArray, Smi, float64): void; FixedDoubleArray, Smi, float64): void;
...@@ -1195,9 +1227,22 @@ extern macro IsNumber(Object): bool; ...@@ -1195,9 +1227,22 @@ extern macro IsNumber(Object): bool;
extern macro IsExtensibleMap(Map): bool; extern macro IsExtensibleMap(Map): bool;
extern macro IsCustomElementsReceiverInstanceType(int32): bool; extern macro IsCustomElementsReceiverInstanceType(int32): bool;
extern macro IsFastJSArray(Object, Context): bool; extern macro IsFastJSArray(Object, Context): bool;
extern macro IsFastJSArrayWithNoCustomIteration(implicit context: Context)(
Object): bool;
extern macro Typeof(Object): Object; extern macro Typeof(Object): Object;
extern macro LoadTargetFromFrame(): JSFunction; extern macro LoadTargetFromFrame(): JSFunction;
macro IsJSReceiver(o: Object): bool {
typeswitch (o) {
case (JSReceiver): {
return true;
}
case (Object): {
return false;
}
}
}
// Return true iff number is NaN. // Return true iff number is NaN.
macro NumberIsNaN(number: Number): bool { macro NumberIsNaN(number: Number): bool {
typeswitch (number) { typeswitch (number) {
......
...@@ -173,7 +173,7 @@ void BaseCollectionsAssembler::AddConstructorEntries( ...@@ -173,7 +173,7 @@ void BaseCollectionsAssembler::AddConstructorEntries(
Variant variant, TNode<Context> context, TNode<Context> native_context, Variant variant, TNode<Context> context, TNode<Context> native_context,
TNode<Object> collection, TNode<Object> initial_entries) { TNode<Object> collection, TNode<Object> initial_entries) {
TVARIABLE(BoolT, use_fast_loop, TVARIABLE(BoolT, use_fast_loop,
IsFastJSArrayWithNoCustomIteration(initial_entries, context)); IsFastJSArrayWithNoCustomIteration(context, initial_entries));
TNode<IntPtrT> at_least_space_for = TNode<IntPtrT> at_least_space_for =
EstimatedInitialSize(initial_entries, use_fast_loop.value()); EstimatedInitialSize(initial_entries, use_fast_loop.value());
Label allocate_table(this, &use_fast_loop), exit(this), fast_loop(this), Label allocate_table(this, &use_fast_loop), exit(this), fast_loop(this),
...@@ -193,8 +193,8 @@ void BaseCollectionsAssembler::AddConstructorEntries( ...@@ -193,8 +193,8 @@ void BaseCollectionsAssembler::AddConstructorEntries(
TNode<JSArray> initial_entries_jsarray = TNode<JSArray> initial_entries_jsarray =
UncheckedCast<JSArray>(initial_entries); UncheckedCast<JSArray>(initial_entries);
#if DEBUG #if DEBUG
CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(initial_entries_jsarray, CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(
context)); context, initial_entries_jsarray));
TNode<Map> original_initial_entries_map = LoadMap(initial_entries_jsarray); TNode<Map> original_initial_entries_map = LoadMap(initial_entries_jsarray);
#endif #endif
...@@ -243,7 +243,7 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromFastJSArray( ...@@ -243,7 +243,7 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromFastJSArray(
CSA_ASSERT( CSA_ASSERT(
this, this,
WordEqual(GetAddFunction(variant, native_context, collection), add_func)); WordEqual(GetAddFunction(variant, native_context, collection), add_func));
CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(fast_jsarray, context)); CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(context, fast_jsarray));
TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(fast_jsarray)); TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(fast_jsarray));
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(length, IntPtrConstant(0))); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(length, IntPtrConstant(0)));
CSA_ASSERT( CSA_ASSERT(
......
...@@ -256,7 +256,7 @@ TF_BUILTIN(IterableToListMayPreserveHoles, IteratorBuiltinsAssembler) { ...@@ -256,7 +256,7 @@ TF_BUILTIN(IterableToListMayPreserveHoles, IteratorBuiltinsAssembler) {
Label slow_path(this); Label slow_path(this);
GotoIfNot(IsFastJSArrayWithNoCustomIteration(iterable, context), &slow_path); GotoIfNot(IsFastJSArrayWithNoCustomIteration(context, iterable), &slow_path);
// The fast path will copy holes to the new array. // The fast path will copy holes to the new array.
TailCallBuiltin(Builtins::kCloneFastJSArray, context, iterable); TailCallBuiltin(Builtins::kCloneFastJSArray, context, iterable);
...@@ -270,7 +270,7 @@ void IteratorBuiltinsAssembler::FastIterableToList( ...@@ -270,7 +270,7 @@ void IteratorBuiltinsAssembler::FastIterableToList(
TVariable<Object>* var_result, Label* slow) { TVariable<Object>* var_result, Label* slow) {
Label done(this), check_string(this), check_map(this), check_set(this); Label done(this), check_string(this), check_map(this), check_set(this);
GotoIfNot(IsFastJSArrayWithNoCustomIteration(iterable, context), GotoIfNot(IsFastJSArrayWithNoCustomIteration(context, iterable),
&check_string); &check_string);
// Fast path for fast JSArray. // Fast path for fast JSArray.
......
// 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.
#ifndef V8_BUILTINS_BUILTINS_OBJECT_GEN_H_
#define V8_BUILTINS_BUILTINS_OBJECT_GEN_H_
#include "src/code-stub-assembler.h"
namespace v8 {
namespace internal {} // namespace internal
} // namespace v8
#endif // V8_BUILTINS_BUILTINS_OBJECT_GEN_H_
// 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.
namespace object {
transitioning macro ObjectFromEntriesFastCase(implicit context: Context)(
iterable: Object): JSObject labels IfSlow {
typeswitch (iterable) {
case (array: FastJSArrayWithNoCustomIteration): {
const elements: FixedArray =
Cast<FixedArray>(array.elements) otherwise IfSlow;
const length: Smi = array.length;
const result: JSObject = AllocateEmptyJSObject();
for (let k: Smi = 0; k < length; ++k) {
const value: Object = array::LoadElementOrUndefined(elements, k);
const pair: KeyValuePair =
collections::LoadKeyValuePairNoSideEffects(value)
otherwise IfSlow;
// Bail out if ToPropertyKey will attempt to load and call
// Symbol.toPrimitive, toString, and valueOf, which could
// invalidate assumptions about the iterable.
if (IsJSReceiver(pair.key)) goto IfSlow;
CreateDataProperty(result, pair.key, pair.value);
}
return result;
}
case (Object): {
goto IfSlow;
}
}
}
transitioning javascript builtin
ObjectFromEntries(implicit context: Context)(receiver: Object): Object {
const iterable: Object = receiver;
try {
if (IsNullOrUndefined(iterable)) goto Throw;
return ObjectFromEntriesFastCase(iterable) otherwise IfSlow;
}
label IfSlow {
const result: JSObject = AllocateEmptyJSObject();
const fastIteratorResultMap: Map =
Cast<Map>(LoadNativeContext(context)[ITERATOR_RESULT_MAP_INDEX])
otherwise unreachable;
let i: iterator::IteratorRecord = iterator::GetIterator(iterable);
try {
assert(!IsNullOrUndefined(i.object));
while (true) {
const step: Object = iterator::IteratorStep(i, fastIteratorResultMap)
otherwise return result;
const iteratorValue: Object =
iterator::IteratorValue(step, fastIteratorResultMap);
const pair: KeyValuePair =
collections::LoadKeyValuePair(iteratorValue);
CreateDataProperty(result, pair.key, pair.value);
}
return result;
} catch (e) deferred {
iterator::IteratorCloseOnException(i, e);
}
}
label Throw deferred {
ThrowTypeError(context, kNotIterable);
}
}
} // namespace object
// 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.
namespace object {
macro AllocateEmptyJSObject(implicit context: Context)(): JSObject {
const objectFunction: JSFunction = GetObjectFunction();
const map: Map = Cast<Map>(objectFunction.prototype_or_initial_map)
otherwise unreachable;
return AllocateJSObjectFromMap(map);
}
}
...@@ -1056,22 +1056,29 @@ TNode<BoolT> CodeStubAssembler::IsFastJSArray(SloppyTNode<Object> object, ...@@ -1056,22 +1056,29 @@ TNode<BoolT> CodeStubAssembler::IsFastJSArray(SloppyTNode<Object> object,
return var_result.value(); return var_result.value();
} }
TNode<BoolT> CodeStubAssembler::IsFastJSArrayWithNoCustomIteration( void CodeStubAssembler::BranchIfFastJSArrayWithNoCustomIteration(
TNode<Object> object, TNode<Context> context) { TNode<Context> context, TNode<Object> object, Label* if_true,
Label if_false(this, Label::kDeferred), if_fast(this), exit(this); Label* if_false) {
TVARIABLE(BoolT, var_result); Label if_fast(this);
BranchIfFastJSArray(object, context, &if_fast, &if_false, true); BranchIfFastJSArray(object, context, &if_fast, if_false, true);
BIND(&if_fast); BIND(&if_fast);
{ {
// Check that the Array.prototype hasn't been modified in a way that would // Check that the Array.prototype hasn't been modified in a way that would
// affect iteration. // affect iteration.
Node* protector_cell = LoadRoot(RootIndex::kArrayIteratorProtector); Node* protector_cell = LoadRoot(RootIndex::kArrayIteratorProtector);
DCHECK(isolate()->heap()->array_iterator_protector()->IsPropertyCell()); DCHECK(isolate()->heap()->array_iterator_protector()->IsPropertyCell());
var_result = Branch(
WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
SmiConstant(Isolate::kProtectorValid)); SmiConstant(Isolate::kProtectorValid)),
Goto(&exit); if_true, if_false);
} }
}
TNode<BoolT> CodeStubAssembler::IsFastJSArrayWithNoCustomIteration(
TNode<Context> context, TNode<Object> object) {
Label if_false(this, Label::kDeferred), exit(this);
TVARIABLE(BoolT, var_result, Int32TrueConstant());
BranchIfFastJSArrayWithNoCustomIteration(context, object, &exit, &if_false);
BIND(&if_false); BIND(&if_false);
{ {
var_result = Int32FalseConstant(); var_result = Int32FalseConstant();
......
...@@ -416,6 +416,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -416,6 +416,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return TNode<JSArray>::UncheckedCast(p_o); return TNode<JSArray>::UncheckedCast(p_o);
} }
TNode<JSArray> RawCastObjectToFastJSArrayWithNoCustomIteration(
TNode<Object> p_o) {
return TNode<JSArray>::UncheckedCast(p_o);
}
TNode<JSFunction> RawCastObjectToJSFunction(TNode<Object> p_o) { TNode<JSFunction> RawCastObjectToJSFunction(TNode<Object> p_o) {
return TNode<JSFunction>::UncheckedCast(p_o); return TNode<JSFunction>::UncheckedCast(p_o);
} }
...@@ -807,6 +812,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -807,6 +812,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
} }
void BranchIfFastJSArrayForCopy(Node* object, Node* context, Label* if_true, void BranchIfFastJSArrayForCopy(Node* object, Node* context, Label* if_true,
Label* if_false); Label* if_false);
void BranchIfFastJSArrayWithNoCustomIteration(TNode<Context> context,
TNode<Object> object,
Label* if_true,
Label* if_false);
// Branches to {if_true} when --force-slow-path flag has been passed. // Branches to {if_true} when --force-slow-path flag has been passed.
// It's used for testing to ensure that slow path implementation behave // It's used for testing to ensure that slow path implementation behave
...@@ -2022,8 +2031,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2022,8 +2031,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type);
TNode<BoolT> IsFastJSArray(SloppyTNode<Object> object, TNode<BoolT> IsFastJSArray(SloppyTNode<Object> object,
SloppyTNode<Context> context); SloppyTNode<Context> context);
TNode<BoolT> IsFastJSArrayWithNoCustomIteration(TNode<Object> object, TNode<BoolT> IsFastJSArrayWithNoCustomIteration(TNode<Context> context,
TNode<Context> context); TNode<Object> object);
TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object); TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object);
TNode<BoolT> IsFeedbackVector(SloppyTNode<HeapObject> object); TNode<BoolT> IsFeedbackVector(SloppyTNode<HeapObject> object);
TNode<BoolT> IsContext(SloppyTNode<HeapObject> object); TNode<BoolT> IsContext(SloppyTNode<HeapObject> object);
......
...@@ -199,7 +199,8 @@ DEFINE_IMPLICATION(harmony_private_methods, harmony_private_fields) ...@@ -199,7 +199,8 @@ DEFINE_IMPLICATION(harmony_private_methods, harmony_private_fields)
V(harmony_await_optimization, "harmony await taking 1 tick") \ V(harmony_await_optimization, "harmony await taking 1 tick") \
V(harmony_private_methods, "harmony private methods in class literals") \ V(harmony_private_methods, "harmony private methods in class literals") \
V(harmony_regexp_sequence, "RegExp Unicode sequence properties") \ V(harmony_regexp_sequence, "RegExp Unicode sequence properties") \
V(harmony_weak_refs, "harmony weak references") V(harmony_weak_refs, "harmony weak references") \
V(harmony_object_from_entries, "harmony Object.fromEntries()")
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#define HARMONY_INPROGRESS(V) \ #define HARMONY_INPROGRESS(V) \
......
This diff is collapsed.
...@@ -57,10 +57,10 @@ FEATURE_FLAGS = { ...@@ -57,10 +57,10 @@ FEATURE_FLAGS = {
'globalThis': '--harmony-global', 'globalThis': '--harmony-global',
'well-formed-json-stringify': '--harmony-json-stringify', 'well-formed-json-stringify': '--harmony-json-stringify',
'export-star-as-namespace-from-module': '--harmony-namespace-exports', 'export-star-as-namespace-from-module': '--harmony-namespace-exports',
'Object.fromEntries': '--harmony-object-from-entries',
} }
SKIPPED_FEATURES = set(['Object.fromEntries', SKIPPED_FEATURES = set(['class-fields-private',
'class-fields-private',
'class-static-fields-private', 'class-static-fields-private',
'class-methods-private', 'class-methods-private',
'class-static-methods-private']) 'class-static-methods-private'])
......
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