Skip to content

Commit

Permalink
array.prototype.flat AND array.prototype.flatMap
Browse files Browse the repository at this point in the history
  • Loading branch information
rhuanjl committed Aug 4, 2018
1 parent 7691f9a commit 7fd4d71
Show file tree
Hide file tree
Showing 17 changed files with 23,836 additions and 22,201 deletions.
3 changes: 2 additions & 1 deletion lib/Parser/rterrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ RT_ERROR_MSG(JSERROR_SetPrototypeOf, 5616, "Failed to set prototype", "Failed to
RT_ERROR_MSG(JSERR_ObjectIsNotInitialized, 5617, "%s: Object internal state is not initialized", "Object internal state is not initialized", kjstTypeError, 0)

RT_ERROR_MSG(JSERR_GeneratorAlreadyExecuting, 5618, "%s: Cannot execute generator function because it is currently executing", "", kjstTypeError, 0)
// 5619-5626 Unused
RT_ERROR_MSG(JSERR_LengthIsTooBig, 5619, "Length property would exceed maximum value in output from '%s'", "", kjstTypeError, 0)
// 5620-5626 Unused
RT_ERROR_MSG(JSERR_NeedConstructor, 5627, "'%s' is not a constructor", "Constructor expected", kjstTypeError, 0)

RT_ERROR_MSG(VBSERR_CantDisplayDate, 32812, "", "The specified date is not available in the current locale's calendar", kjstRangeError, 0)
Expand Down
4 changes: 4 additions & 0 deletions lib/Runtime/Base/JnDirectFields.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ ENTRY(every)
ENTRY(exec)
ENTRY2(false_, _u("false")) // "false" cannot be an identifier in C++ so using "false_" instead
ENTRY(flags)
ENTRY(flat)
ENTRY(flatMap)
ENTRY(fill)
ENTRY(filter)
ENTRY(finally)
Expand Down Expand Up @@ -190,6 +192,7 @@ ENTRY(Intl)
ENTRY(invokeJit)
ENTRY(is)
ENTRY(isArray)
ENTRY(isCallable)
ENTRY(isConcatSpreadable)
ENTRY(isExtensible)
ENTRY(isFinite)
Expand Down Expand Up @@ -657,6 +660,7 @@ ENTRY(builtInRegexMatch)
ENTRY(builtInCallInstanceFunction)
ENTRY(raiseInvalidCurrencyCode)
ENTRY(raiseInvalidDate)
ENTRY(raiseLengthIsTooBig)
ENTRY(raiseLocaleNotWellFormed)
ENTRY(raiseMissingCurrencyCode)
ENTRY(raiseNeedObject)
Expand Down
1 change: 1 addition & 0 deletions lib/Runtime/Library/EngineInterfaceObjectBuiltIns.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ BuiltInRaiseException1(RangeError, LocaleNotWellFormed)
BuiltInRaiseException1(TypeError, This_NullOrUndefined)
BuiltInRaiseException1(TypeError, NotAConstructor)
BuiltInRaiseException1(TypeError, ObjectIsNonExtensible)
BuiltInRaiseException1(TypeError, LengthIsTooBig)
BuiltInRaiseException2(TypeError, NeedObjectOfType)
BuiltInRaiseException1(RangeError, InvalidCurrencyCode)
BuiltInRaiseException(TypeError, MissingCurrencyCode)
Expand Down
10,906 changes: 5,453 additions & 5,453 deletions lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h

Large diffs are not rendered by default.

10,904 changes: 5,452 additions & 5,452 deletions lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h

Large diffs are not rendered by default.

9,546 changes: 4,773 additions & 4,773 deletions lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h

Large diffs are not rendered by default.

9,544 changes: 4,772 additions & 4,772 deletions lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions lib/Runtime/Library/JavascriptLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1663,8 +1663,8 @@ namespace Js
}

bool JavascriptLibrary::InitializeArrayPrototype(DynamicObject* arrayPrototype, DeferredTypeHandlerBase * typeHandler, DeferredInitializeMode mode)
{
typeHandler->Convert(arrayPrototype, mode, 24);
{
typeHandler->Convert(arrayPrototype, mode, 26);
// Note: Any new function addition/deletion/modification should also be updated in JavascriptLibrary::ProfilerRegisterArray
// so that the update is in sync with profiler

Expand Down Expand Up @@ -4624,7 +4624,7 @@ namespace Js
bool JavascriptLibrary::InitializeChakraLibraryObject(DynamicObject * chakraLibraryObject, DeferredTypeHandlerBase * typeHandler, DeferredInitializeMode mode)
{
JavascriptLibrary* library = chakraLibraryObject->GetLibrary();
typeHandler->Convert(chakraLibraryObject, mode, 8);
typeHandler->Convert(chakraLibraryObject, mode, 9);

library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::toLength, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_ToLengthFunction, 1);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::toInteger, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_ToIntegerFunction, 1);
Expand All @@ -4634,6 +4634,7 @@ namespace Js
library->AddMember(chakraLibraryObject, PropertyIds::Object, library->objectConstructor);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::arraySpeciesCreate, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_ArraySpeciesCreate, 2);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::arrayCreateDataPropertyOrThrow, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_ArrayCreateDataPropertyOrThrow, 3);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::isCallable, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_IsCallableFunction, 1);

return true;
}
Expand Down
157 changes: 156 additions & 1 deletion lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
ArrayEntries: { className: "Array", methodName: "entries", argumentsCount: 0, forceInline: true /*optional*/ },
ArrayIndexOf: { className: "Array", methodName: "indexOf", argumentsCount: 1, forceInline: true /*optional*/ },
ArrayFilter: { className: "Array", methodName: "filter", argumentsCount: 1, forceInline: true /*optional*/ },
ArrayFlat: { className: "Array", methodName: "flat", argumentsCount: 0, forceInline: true /*optional*/ },
ArrayFlatMap: { className: "Array", methodName: "flatMap", argumentsCount: 1, forceInline: true /*optional*/ },
};

var setPrototype = platform.builtInSetPrototype;
Expand All @@ -36,6 +38,7 @@
__chakraLibrary.ArrayIterator.prototype = CreateObject(iteratorPrototype);
__chakraLibrary.raiseNeedObjectOfType = platform.raiseNeedObjectOfType;
__chakraLibrary.raiseThis_NullOrUndefined = platform.raiseThis_NullOrUndefined;
__chakraLibrary.raiseLengthIsTooBig = platform.raiseLengthIsTooBig;
__chakraLibrary.raiseFunctionArgument_NeedFunction = platform.raiseFunctionArgument_NeedFunction;
__chakraLibrary.callInstanceFunc = platform.builtInCallInstanceFunction;
__chakraLibrary.functionBind = platform.builtInJavascriptFunctionEntryBind;
Expand Down Expand Up @@ -238,5 +241,157 @@

return a;
});


platform.registerChakraLibraryFunction("FlattenIntoArray", function(target, source, sourceLen, start, depth)
{
"use strict";
//1. Let targetIndex be start.
let targetIndex = start;
//2. Let sourceIndex be 0.
let sourceIndex = 0;
//3. Repeat, while sourceIndex < sourceLen
let element;
while (sourceIndex < sourceLen) {
// a. Let P be ! ToString(sourceIndex).
// b. Let exists be ? HasProperty(source, P).
if (sourceIndex in source) {
// c. If exists is true, then
// i. Let element be ? Get(source, P).
// ii. If mapperFunction is present - skipped see separate function
// iii. Let shouldFlatten be false.
// iv. If depth > 0, then
// 1. Set shouldFlatten to ? IsArray(element).
if (depth > 0 && __chakraLibrary.isArray(source[sourceIndex])) {
// v. If shouldFlatten is true, then
// 1. Let elementLen be ? ToLength(? Get(element, "length")).
// 2. Set targetIndex to ? FlattenIntoArray(target, element, elementLen, targetIndex, depth - 1).
element = source[sourceIndex];
targetIndex = __chakraLibrary.FlattenIntoArray(target, element, element.length |0, targetIndex, depth - 1);
} else {
// vi. Else,
// 1. If targetIndex >= 2^53-1, throw a TypeError exception.
if (targetIndex >= 9007199254740991 /* 2^53 -1 */) {
__chakraLibrary.raiseLengthIsTooBig("Array.prototype.flat");
}
// 2. Perform ? CreateDataPropertyOrThrow(target, ! ToString(targetIndex), element).
__chakraLibrary.arrayCreateDataPropertyOrThrow(target, targetIndex, source[sourceIndex]);
// 3. Increase targetIndex by 1.
++targetIndex;
}
}
// d. Increase sourceIndex by 1.
++sourceIndex;
}
//4. Return targetIndex.
return targetIndex;
});

platform.registerChakraLibraryFunction("FlattenIntoArrayMapped", function(target, source, sourceLen, start, mapperFunction) {
"use strict";
//1. Let targetIndex be start.
let targetIndex = start;
//2. Let sourceIndex be 0.
let sourceIndex = 0;
//3. Repeat, while sourceIndex < sourceLen

let element;
while (sourceIndex < sourceLen) {
// a. Let P be ! ToString(sourceIndex).
// b. Let exists be ? HasProperty(source, P).
if (sourceIndex in source) {
// c. If exists is true, then
// i. Let element be ? Get(source, P).
// ii. If mapperFunction is present, then
// 1. Assert: thisArg is present.
// 2. Set element to ? Call(mapperFunction, thisArg , element, sourceIndex, source).
element = mapperFunction(source[sourceIndex], sourceIndex, source);
// iii. Let shouldFlatten be false.
// iv. If depth > 0, then
// 1. Set shouldFlatten to ? IsArray(element).
// v. If shouldFlatten is true, then
// 1. Let elementLen be ? ToLength(? Get(element, "length")).
// 2. Set targetIndex to ? FlattenIntoArray(target, element, elementLen, targetIndex, depth - 1).
if (__chakraLibrary.isArray(element)) {
targetIndex = __chakraLibrary.FlattenIntoArray(target, element, element.length |0, targetIndex, 0);
} else {
// vi. Else,
// 1. If targetIndex >= 253-1, throw a TypeError exception.
if (targetIndex >= 9007199254740991 /* 2^53 -1 */) {
__chakraLibrary.raiseLengthIsTooBig("Array.prototype.flatMap");
}
// 2. Perform ? CreateDataPropertyOrThrow(target, ! ToString(targetIndex), element).
__chakraLibrary.arrayCreateDataPropertyOrThrow(target, targetIndex, element);
// 3. Increase targetIndex by 1.
++targetIndex;
}
}
// d. Increase sourceIndex by 1.
++sourceIndex;
}
//4. Return targetIndex.
return targetIndex;
});

platform.registerFunction(FunctionsEnum.ArrayFlat, function (depth) {
"use strict";
// this version excludes the mapper function
//1. Let O be ? ToObject(this value).
//2. Let sourceLen be ? ToLength(? Get(O, "length")).
let o, sourceLen;

if (__chakraLibrary.isArray(this)) {
o = this;
sourceLen = o.length;
} else {
if (this === null || this === undefined) {
__chakraLibrary.raiseThis_NullOrUndefined("Array.prototype.flat");
}
o = __chakraLibrary.Object(this);
sourceLen = __chakraLibrary.GetLength(o);
}
//3. Let depthNum be 1.
//4. If depth is not undefined, then
//5. Set depthNum to ? ToInteger(depth).
const depthNum = depth !== undefined ? __chakraLibrary.toInteger(depth) : 1;
//6. Let A be ? ArraySpeciesCreate(O, 0).
const A = __chakraLibrary.arraySpeciesCreate(o, 0);
//7. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum).
__chakraLibrary.FlattenIntoArray(A, o, sourceLen, 0, depthNum);
//8. Return A.
return A;
});

platform.registerFunction(FunctionsEnum.ArrayFlatMap, function (mapperFunction, thisArg) {
"use strict";
//1. Let O be ? ToObject(this value).
//2. Let sourceLen be ? ToLength(? Get(O, "length")).
let o, sourceLen;
if (__chakraLibrary.isArray(this)) {
o = this;
sourceLen = o.length;
} else {
if (this === null || this === undefined) {
__chakraLibrary.raiseThis_NullOrUndefined("Array.prototype.flatMap");
}
o = __chakraLibrary.Object(this);
sourceLen = __chakraLibrary.GetLength(o);
}
//3. If IsCallable(mapperFunction) is false throw a TypeError exception
if (!__chakraLibrary.isCallable(mapperFunction)) {
__chakraLibrary.raiseFunctionArgument_NeedFunction("Array.prototype.flatMap");
}
//4. If thisArg is present, let T be thisArg; else let T be undefined
//5. Let A be ? ArraySpeciesCreate(O, 0).
const A = __chakraLibrary.arraySpeciesCreate(o, 0);
//6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum).
if (!thisArg) {
__chakraLibrary.FlattenIntoArrayMapped(A, o, sourceLen, 0, mapperFunction);
} else {
const func = __chakraLibrary.callInstanceFunc(__chakraLibrary.functionBind, mapperFunction, thisArg);
__chakraLibrary.FlattenIntoArrayMapped(A, o, sourceLen, 0, func);
}
//7. Return A.
return A;
});

});
Loading

0 comments on commit 7fd4d71

Please sign in to comment.