Skip to content

Commit

Permalink
implement Array.prototype.filter in javascript
Browse files Browse the repository at this point in the history
  • Loading branch information
sigatrev committed May 15, 2018
1 parent 0730b1f commit c648792
Show file tree
Hide file tree
Showing 18 changed files with 5,614 additions and 4,814 deletions.
5 changes: 5 additions & 0 deletions RegenAllByteCodeNoBuild.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ setlocal
call GenByteCode.cmd
call GenByteCode.cmd -nojit
popd

pushd %_reporoot%\lib\Runtime\Library\JsBuiltIn
call GenByteCode.cmd
call GenByteCode.cmd -nojit
popd
endlocal
3 changes: 3 additions & 0 deletions lib/Runtime/Base/JnDirectFields.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,8 @@ ENTRY(registerChakraLibraryFunction)
ENTRY(registerFunction)
ENTRY(toLength)
ENTRY(toInteger)
ENTRY(arraySpeciesCreate)
ENTRY(arrayCreateDataPropertyOrThrow)

// EngineInterfaceObject built-ins
ENTRY(builtInGlobalObjectEntryIsFinite)
Expand Down Expand Up @@ -666,6 +668,7 @@ ENTRY(raiseObjectIsNonExtensible)
ENTRY(raiseOptionValueOutOfRange_3)
ENTRY(raiseOptionValueOutOfRange)
ENTRY(raiseThis_NullOrUndefined)
ENTRY(raiseFunctionArgument_NeedFunction)

// Promise (ChakraFull)
ENTRY(Promise)
Expand Down
4 changes: 2 additions & 2 deletions lib/Runtime/ByteCode/ByteCodeCacheReleaseFileVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
//-------------------------------------------------------------------------------------------------------
// NOTE: If there is a merge conflict the correct fix is to make a new GUID.

// {9F2ABB67-7351-401E-911C-9919B54F761C}
// {9B3A48D4-C8EF-46CF-A473-14CB0DA3244F}
const GUID byteCodeCacheReleaseFileVersion =
{ 0x9F2ABB67, 0x7351, 0x401E, { 0x91, 0x1C, 0x99, 0x19, 0xB5, 0x4F, 0x76, 0x1C } };
{ 0x9B3A48D4, 0xC8EF, 0x46CF, { 0xA4, 0x73, 0x14, 0xCB, 0x0D, 0xA3, 0x24, 0x4F } };
2 changes: 1 addition & 1 deletion lib/Runtime/Library/EngineInterfaceObjectBuiltIns.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ GlobalBuiltIn(JavascriptArray, EntryPush)
GlobalBuiltIn(JavascriptArray, EntryJoin)
GlobalBuiltIn(JavascriptArray, EntryMap)
GlobalBuiltIn(JavascriptArray, EntryReduce)
GlobalBuiltIn(JavascriptArray, EntryFilter)
GlobalBuiltIn(JavascriptArray, EntrySlice)
GlobalBuiltIn(JavascriptArray, EntryConcat)

Expand Down Expand Up @@ -63,3 +62,4 @@ BuiltInRaiseException2(TypeError, NeedObjectOfType)
BuiltInRaiseException1(RangeError, InvalidCurrencyCode)
BuiltInRaiseException(TypeError, MissingCurrencyCode)
BuiltInRaiseException(RangeError, InvalidDate)
BuiltInRaiseException1(TypeError, FunctionArgument_NeedFunction)
1,596 changes: 798 additions & 798 deletions lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h

Large diffs are not rendered by default.

1,610 changes: 805 additions & 805 deletions lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h

Large diffs are not rendered by default.

1,618 changes: 809 additions & 809 deletions lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h

Large diffs are not rendered by default.

1,602 changes: 801 additions & 801 deletions lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions lib/Runtime/Library/JavascriptArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3032,6 +3032,20 @@ namespace Js
}
}

void JavascriptArray::CreateDataPropertyOrThrow(RecyclableObject * obj, BigIndex index, Var item, ScriptContext * scriptContext)
{
JS_REENTRANCY_LOCK(jsReentLock, scriptContext->GetThreadContext());
JavascriptArray * arr = JavascriptOperators::TryFromVar<JavascriptArray>(obj);
if (arr != nullptr)
{
arr->GenericDirectSetItemAt(index, item);
}
else
{
JS_REENTRANT(jsReentLock, ThrowErrorOnFailure(SetArrayLikeObjects(obj, index, item), scriptContext, index));
}
}

BOOL JavascriptArray::SetArrayLikeObjects(RecyclableObject* pDestObj, uint32 idxDest, Var aItem)
{
return pDestObj->SetItem(idxDest, aItem, Js::PropertyOperation_ThrowIfNotExtensible);
Expand Down
4 changes: 3 additions & 1 deletion lib/Runtime/Library/JavascriptArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -862,9 +862,11 @@ namespace Js
static bool PromoteToBigIndex(BigIndex lhs, BigIndex rhs);
static bool PromoteToBigIndex(BigIndex lhs, uint32 rhs);
static JavascriptArray* ConcatFloatArgs(JavascriptNativeFloatArray* pDestArray, TypeId* remoteTypeIds, Js::Arguments& args, ScriptContext* scriptContext);
private:

template<typename T=uint32>
static RecyclableObject* ArraySpeciesCreate(Var pThisArray, T length, ScriptContext* scriptContext, bool *pIsIntArray = nullptr, bool *pIsFloatArray = nullptr, bool *pIsBuiltinArrayCtor = nullptr);
static void CreateDataPropertyOrThrow(RecyclableObject * obj, BigIndex index, Var item, ScriptContext * scriptContext);
private:
template <typename T, typename R> static R ConvertToIndex(T idxDest, ScriptContext* scriptContext) { Throw::InternalError(); return 0; }
static BOOL SetArrayLikeObjects(RecyclableObject* pDestObj, uint32 idxDest, Var aItem);
static BOOL SetArrayLikeObjects(RecyclableObject* pDestObj, BigIndex idxDest, Var aItem);
Expand Down
34 changes: 13 additions & 21 deletions lib/Runtime/Library/JavascriptLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,6 @@ namespace Js
}

/* No inlining Array_Every */ library->AddFunctionToLibraryObject(arrayPrototype, PropertyIds::every, &JavascriptArray::EntryInfo::Every, 1);
/* No inlining Array_Filter */ library->AddFunctionToLibraryObject(arrayPrototype, PropertyIds::filter, &JavascriptArray::EntryInfo::Filter, 1);

/* No inlining Array_ForEach */
library->AddMember(arrayPrototype, PropertyIds::forEach, library->EnsureArrayPrototypeForEachFunction());
Expand All @@ -1725,18 +1724,13 @@ namespace Js
/* No inlining Array_FindIndex */ library->AddFunctionToLibraryObject(arrayPrototype, PropertyIds::findIndex, &JavascriptArray::EntryInfo::FindIndex, 1);
}

#ifndef ENABLE_JS_BUILTINS
/* No inlining Array_Entries */
library->AddMember(arrayPrototype, PropertyIds::entries, library->EnsureArrayPrototypeEntriesFunction());

/* No inlining Array_Keys */
library->AddMember(arrayPrototype, PropertyIds::keys, library->EnsureArrayPrototypeKeysFunction());

JavascriptFunction *values = library->EnsureArrayPrototypeValuesFunction();
/* No inlining Array_Values */ library->AddMember(arrayPrototype, PropertyIds::values, values);
/* No inlining Array_SymbolIterator */ library->AddMember(arrayPrototype, PropertyIds::_symbolIterator, values);
#else
if (!scriptContext->IsJsBuiltInEnabled())
#ifdef ENABLE_JS_BUILTINS
if (scriptContext->IsJsBuiltInEnabled())
{
library->EnsureBuiltInEngineIsReady();
}
else
#endif
{
/* No inlining Array_Entries */
library->AddMember(arrayPrototype, PropertyIds::entries, library->EnsureArrayPrototypeEntriesFunction());
Expand All @@ -1747,13 +1741,9 @@ namespace Js
JavascriptFunction *values = library->EnsureArrayPrototypeValuesFunction();
/* No inlining Array_Values */ library->AddMember(arrayPrototype, PropertyIds::values, values);
/* No inlining Array_SymbolIterator */ library->AddMember(arrayPrototype, PropertyIds::_symbolIterator, values);
}
else
{
library->EnsureBuiltInEngineIsReady();
}

#endif
/* No inlining Array_Filter */ library->AddFunctionToLibraryObject(arrayPrototype, PropertyIds::filter, &JavascriptArray::EntryInfo::Filter, 1);
}

if (scriptContext->GetConfig()->IsES6UnscopablesEnabled())
{
Expand Down Expand Up @@ -4632,14 +4622,16 @@ namespace Js
bool JavascriptLibrary::InitializeChakraLibraryObject(DynamicObject * chakraLibraryObject, DeferredTypeHandlerBase * typeHandler, DeferredInitializeMode mode)
{
JavascriptLibrary* library = chakraLibraryObject->GetLibrary();
typeHandler->Convert(chakraLibraryObject, mode, 6);
typeHandler->Convert(chakraLibraryObject, mode, 8);

library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::toLength, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_ToLengthFunction, 1);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::toInteger, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_ToIntegerFunction, 1);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::toInteger, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_ToIntegerFunction, 1);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::GetLength, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_GetLength, 1);
library->AddFunctionToLibraryObject(chakraLibraryObject, PropertyIds::InitInternalProperties, &JsBuiltInEngineInterfaceExtensionObject::EntryInfo::JsBuiltIn_Internal_InitInternalProperties, 1);
library->AddMember(chakraLibraryObject, PropertyIds::isArray, library->isArrayFunction);
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);

return true;
}
Expand Down
62 changes: 62 additions & 0 deletions lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
ArrayKeys: { className: "Array", methodName: "keys", argumentsCount: 0, forceInline: true /*optional*/ },
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*/ },
};

var setPrototype = platform.builtInSetPrototype;
Expand All @@ -35,6 +36,9 @@
__chakraLibrary.ArrayIterator.prototype = CreateObject(iteratorPrototype);
__chakraLibrary.raiseNeedObjectOfType = platform.raiseNeedObjectOfType;
__chakraLibrary.raiseThis_NullOrUndefined = platform.raiseThis_NullOrUndefined;
__chakraLibrary.raiseFunctionArgument_NeedFunction = platform.raiseFunctionArgument_NeedFunction;
__chakraLibrary.callInstanceFunc = platform.builtInCallInstanceFunction;
__chakraLibrary.functionBind = platform.builtInJavascriptFunctionEntryBind;

_objectDefineProperty(__chakraLibrary.ArrayIterator.prototype, 'next',
// 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
Expand Down Expand Up @@ -177,4 +181,62 @@

return -1;
});

platform.registerFunction(FunctionsEnum.ArrayFilter, function (callbackfn, thisArg) {
// ECMAScript 2017 #sec-array.prototype.filter
"use strict";

if (this === null || this === undefined) {
__chakraLibrary.raiseThis_NullOrUndefined("Array.prototype.filter");
}

let o;
let len
if (__chakraLibrary.isArray(this)) {
o = this;
len = o.length;
} else {
o = __chakraLibrary.Object(this);
len = __chakraLibrary.GetLength(o);
}

if (typeof callbackfn != "function") {
__chakraLibrary.raiseFunctionArgument_NeedFunction("Array.prototype.filter");
}

let a = __chakraLibrary.arraySpeciesCreate(o, 0);
let k = 0;
let to = 0;

if (thisArg === undefined) {
// fast path.
while (k < len) {
if (k in o) {
let kValue = o[k];
if (callbackfn(kValue, k, o)) {
__chakraLibrary.arrayCreateDataPropertyOrThrow(a, to, kValue);
to++;
}
}
k++;
}
} else {
// slow path.
// safe equivalent of calling "callbackfn.bind(thisArg)"
let boundCallback = __chakraLibrary.callInstanceFunc(__chakraLibrary.functionBind, callbackfn, thisArg);
while (k < len) {
if (k in o) {
let kValue = o[k];
if (boundCallback(kValue, k, o)) {
__chakraLibrary.arrayCreateDataPropertyOrThrow(a, to, kValue);
to++;
}
}
k++;
}
}

return a;
});

});
Loading

0 comments on commit c648792

Please sign in to comment.