Skip to content

Commit f54b1f2

Browse files
committedSep 6, 2018
[MERGE #5622 @rhuanjl] Implement Object.fromEntries
Merge pull request #5622 from rhuanjl:ObjectfromEntries This PR implements the stage 3 proposal Object.fromEntries. Proposal spec text is here: https://tc39.github.io/proposal-object-from-entries/ Notes: 1. Implementation done as a JsBuiltin - note this requires initialising the JsBuiltins for accessing the Object constructor - could this have negative effects? 2. This implementation passes the test262 tests for this feature. fixes: #5590
2 parents cfd1324 + c279dfd commit f54b1f2

21 files changed

+7987
-7249
lines changed
 

‎lib/Parser/rterrors.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ RT_ERROR_MSG(JSERR_ObjectIsNotInitialized, 5617, "%s: Object internal state is n
303303

304304
RT_ERROR_MSG(JSERR_GeneratorAlreadyExecuting, 5618, "%s: Cannot execute generator function because it is currently executing", "", kjstTypeError, 0)
305305
RT_ERROR_MSG(JSERR_LengthIsTooBig, 5619, "Length property would exceed maximum value in output from '%s'", "", kjstTypeError, 0)
306-
// 5620-5626 Unused
306+
RT_ERROR_MSG(JSERR_NonObjectFromIterable, 5620, "Iterable provided to %s must not return non-object or null value.", "", kjstTypeError, 0)
307+
// 5621-5626 Unused
307308
RT_ERROR_MSG(JSERR_NeedConstructor, 5627, "'%s' is not a constructor", "Constructor expected", kjstTypeError, 0)
308309

309310
RT_ERROR_MSG(VBSERR_CantDisplayDate, 32812, "", "The specified date is not available in the current locale's calendar", kjstRangeError, 0)

‎lib/Runtime/Base/JnDirectFields.h

+3
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ ENTRY(freeze)
156156
ENTRY(from)
157157
ENTRY(fromCharCode)
158158
ENTRY(fromCodePoint)
159+
ENTRY(fromEntries)
159160
ENTRY(function)
160161
ENTRY(Function)
161162
ENTRY(getDate)
@@ -611,6 +612,7 @@ ENTRY(InitInternalProperties)
611612
ENTRY(methodName)
612613
ENTRY(registerChakraLibraryFunction)
613614
ENTRY(registerFunction)
615+
ENTRY(staticMethod)
614616
ENTRY(toLength)
615617
ENTRY(toInteger)
616618
ENTRY(arraySpeciesCreate)
@@ -672,6 +674,7 @@ ENTRY(raiseNeedObject)
672674
ENTRY(raiseNeedObjectOfType)
673675
ENTRY(raiseNeedObjectOrString)
674676
ENTRY(raiseNotAConstructor)
677+
ENTRY(raiseNonObjectFromIterable)
675678
ENTRY(raiseObjectIsAlreadyInitialized)
676679
ENTRY(raiseObjectIsNonExtensible)
677680
ENTRY(raiseOptionValueOutOfRange_3)

‎lib/Runtime/ByteCode/ByteCodeCacheReleaseFileVersion.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
// NOTE: If there is a merge conflict the correct fix is to make a new GUID.
66
// This file was generated with tools\update_bytecode_version.ps1
77

8-
// {6CC5964E-CBF2-4053-99DA-987794182D7E}
8+
// {BAC3A947-4873-4DAF-AC60-915116FFE744}
99
const GUID byteCodeCacheReleaseFileVersion =
10-
{ 0x6CC5964E, 0xCBF2, 0x4053, { 0x99, 0xDA, 0x98, 0x77, 0x94, 0x18, 0x2D, 0x7E } };
10+
{ 0xBAC3A947, 0x4873, 0x4DAF, { 0xAC, 0x60, 0x91, 0x51, 0x16, 0xFF, 0xE7, 0x44 } };

‎lib/Runtime/Library/EngineInterfaceObjectBuiltIns.h

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ BuiltInRaiseException1(TypeError, This_NullOrUndefined)
5858
BuiltInRaiseException1(TypeError, NotAConstructor)
5959
BuiltInRaiseException1(TypeError, ObjectIsNonExtensible)
6060
BuiltInRaiseException1(TypeError, LengthIsTooBig)
61+
BuiltInRaiseException1(TypeError, NonObjectFromIterable)
6162
BuiltInRaiseException2(TypeError, NeedObjectOfType)
6263
BuiltInRaiseException1(RangeError, InvalidCurrencyCode)
6364
BuiltInRaiseException(TypeError, MissingCurrencyCode)

‎lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h

+1,093-1,093
Large diffs are not rendered by default.

‎lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h

+1,093-1,093
Large diffs are not rendered by default.

‎lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h

+1,099-1,099
Large diffs are not rendered by default.

‎lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h

+1,100-1,100
Large diffs are not rendered by default.

‎lib/Runtime/Library/JavascriptLibrary.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -3651,6 +3651,18 @@ namespace Js
36513651
propertyCount++;
36523652
}
36533653

3654+
if (scriptContext->GetConfig()->IsES7ValuesEntriesEnabled())
3655+
{
3656+
propertyCount += 2;
3657+
}
3658+
3659+
#ifdef ENABLE_JS_BUILTINS
3660+
if (scriptContext->IsJsBuiltInEnabled())
3661+
{
3662+
propertyCount++;
3663+
}
3664+
#endif
3665+
36543666
typeHandler->Convert(objectConstructor, mode, propertyCount);
36553667

36563668
library->AddMember(objectConstructor, PropertyIds::length, TaggedInt::ToVarUnchecked(1), PropertyConfigurable);
@@ -3707,6 +3719,13 @@ namespace Js
37073719
library->AddFunctionToLibraryObject(objectConstructor, PropertyIds::entries, &JavascriptObject::EntryInfo::Entries, 1));
37083720
}
37093721

3722+
#ifdef ENABLE_JS_BUILTINS
3723+
if (scriptContext->IsJsBuiltInEnabled())
3724+
{
3725+
library->EnsureBuiltInEngineIsReady();
3726+
}
3727+
#endif
3728+
37103729
objectConstructor->SetHasNoEnumerableProperties(true);
37113730

37123731
return true;

‎lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js

+32
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ArrayFlat: { className: "Array", methodName: "flat", argumentsCount: 0, forceInline: true /*optional*/ },
1818
ArrayFlatMap: { className: "Array", methodName: "flatMap", argumentsCount: 1, forceInline: true /*optional*/ },
1919
ArrayForEach: { className: "Array", methodName: "forEach", argumentsCount: 1, forceInline: true /*optional*/ },
20+
ObjectFromEntries: { className: "Object", staticMethod: true, methodName: "fromEntries", argumentsCount: 1, forceInline: true /*optional*/ },
2021
};
2122

2223
var setPrototype = platform.builtInSetPrototype;
@@ -39,10 +40,13 @@
3940
__chakraLibrary.ArrayIterator.prototype = CreateObject(iteratorPrototype);
4041
__chakraLibrary.raiseNeedObjectOfType = platform.raiseNeedObjectOfType;
4142
__chakraLibrary.raiseThis_NullOrUndefined = platform.raiseThis_NullOrUndefined;
43+
__chakraLibrary.raiseNeedObject = platform.raiseNeedObject;
44+
__chakraLibrary.raiseNonObjectFromIterable = platform.raiseNonObjectFromIterable;
4245
__chakraLibrary.raiseLengthIsTooBig = platform.raiseLengthIsTooBig;
4346
__chakraLibrary.raiseFunctionArgument_NeedFunction = platform.raiseFunctionArgument_NeedFunction;
4447
__chakraLibrary.callInstanceFunc = platform.builtInCallInstanceFunction;
4548
__chakraLibrary.functionBind = platform.builtInJavascriptFunctionEntryBind;
49+
__chakraLibrary.objectDefineProperty = _objectDefineProperty;
4650

4751
_objectDefineProperty(__chakraLibrary.ArrayIterator.prototype, 'next',
4852
// Object's getter and setter can get overriden on the prototype, in that case while setting the value attributes, we will end up with TypeError
@@ -440,4 +444,32 @@
440444

441445
return undefined;
442446
});
447+
448+
platform.registerFunction(FunctionsEnum.ObjectFromEntries, function (iterable) {
449+
// #sec-object.fromentries
450+
"use strict";
451+
if (iterable === null || iterable === undefined) {
452+
__chakraLibrary.raiseNeedObject("Object.fromEntries");
453+
}
454+
455+
const o = {};
456+
const propDescriptor = {
457+
enumerable : true,
458+
configurable : true,
459+
writable : true,
460+
value : undefined
461+
};
462+
463+
let key;
464+
for (const entry of iterable) {
465+
if (typeof entry !== "object" || entry === null) {
466+
__chakraLibrary.raiseNonObjectFromIterable("Object.fromEntries");
467+
}
468+
469+
key = entry[0];
470+
propDescriptor.value = entry[1];
471+
__chakraLibrary.objectDefineProperty(o, key, propDescriptor);
472+
}
473+
return o;
474+
});
443475
});

0 commit comments

Comments
 (0)
Please sign in to comment.