diff options
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/builtin/Array.js | 108 | ||||
-rw-r--r-- | js/src/builtin/String.js | 12 | ||||
-rw-r--r-- | js/src/builtin/SymbolObject.cpp | 29 | ||||
-rw-r--r-- | js/src/builtin/SymbolObject.h | 4 | ||||
-rw-r--r-- | js/src/jsarray.cpp | 7 | ||||
-rw-r--r-- | js/src/jsstr.cpp | 16 | ||||
-rw-r--r-- | js/src/jsstr.h | 4 | ||||
-rw-r--r-- | js/src/tests/ecma_6/Array/unscopables.js | 2 | ||||
-rw-r--r-- | js/src/vm/CommonPropertyNames.h | 2 | ||||
-rw-r--r-- | js/src/vm/SelfHosting.cpp | 6 |
10 files changed, 174 insertions, 16 deletions
diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js index 30e6fb35f..05fc41bc1 100644 --- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -1073,6 +1073,114 @@ function ArrayConcat(arg1) { return A; } +// https://tc39.github.io/proposal-flatMap/ +// January 4, 2019 +function ArrayFlatMap(mapperFunction/*, thisArg*/) { + // Step 1. + var O = ToObject(this); + + // Step 2. + var sourceLen = ToLength(O.length); + + // Step 3. + if (!IsCallable(mapperFunction)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapperFunction)); + + // Step 4. + var T = arguments.length > 1 ? arguments[1] : undefined; + + // Step 5. + var A = ArraySpeciesCreate(O, 0); + + // Step 6. + FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T); + + // Step 7. + return A; +} + +// https://tc39.github.io/proposal-flatMap/ +// January 4, 2019 +function ArrayFlat(/* depth */) { + // Step 1. + var O = ToObject(this); + + // Step 2. + var sourceLen = ToLength(O.length); + + // Step 3. + var depthNum = 1; + + // Step 4. + if (arguments.length > 0 && arguments[0] !== undefined) + depthNum = ToInteger(arguments[0]); + + // Step 5. + var A = ArraySpeciesCreate(O, 0); + + // Step 6. + FlattenIntoArray(A, O, sourceLen, 0, depthNum); + + // Step 7. + return A; +} + +// https://tc39.github.io/proposal-flatMap/ +// January 4, 2019 +function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunction, thisArg) { + // Step 1. + var targetIndex = start; + + // Steps 2-3. + for (var sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) { + // Steps 3.a-c. + if (sourceIndex in source) { + // Step 3.c.i. + var element = source[sourceIndex]; + + if (mapperFunction) { + // Step 3.c.ii.1. + assert(arguments.length === 7, "thisArg is present"); + + // Step 3.c.ii.2. + element = callContentFunction(mapperFunction, thisArg, element, sourceIndex, source); + } + + // Step 3.c.iii. + var shouldFlatten = false; + + // Step 3.c.iv. + if (depth > 0) { + // Step 3.c.iv.1. + shouldFlatten = IsArray(element); + } + + // Step 3.c.v. + if (shouldFlatten) { + // Step 3.c.v.1. + var elementLen = ToLength(element.length); + + // Step 3.c.v.2. + // Recursive call to walk the depth. + targetIndex = FlattenIntoArray(target, element, elementLen, targetIndex, depth - 1); + } else { + // Step 3.c.vi.1. + if (targetIndex >= MAX_NUMERIC_INDEX) + ThrowTypeError(JSMSG_TOO_LONG_ARRAY); + + // Step 3.c.vi.2. + _DefineDataProperty(target, targetIndex, element); + + // Step 3.c.vi.3. + targetIndex++; + } + } + } + + // Step 4. + return targetIndex; +} + function ArrayStaticConcat(arr, arg1) { if (arguments.length < 1) ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat'); diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js index e5b2ad552..f830b1aa2 100644 --- a/js/src/builtin/String.js +++ b/js/src/builtin/String.js @@ -828,16 +828,16 @@ function String_static_trim(string) { return callFunction(std_String_trim, string); } -function String_static_trimLeft(string) { +function String_static_trimStart(string) { if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimLeft'); - return callFunction(std_String_trimLeft, string); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimStart'); + return callFunction(std_String_trimStart, string); } -function String_static_trimRight(string) { +function String_static_trimEnd(string) { if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimRight'); - return callFunction(std_String_trimRight, string); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimEnd'); + return callFunction(std_String_trimEnd, string); } function String_static_toLocaleLowerCase(string) { diff --git a/js/src/builtin/SymbolObject.cpp b/js/src/builtin/SymbolObject.cpp index cf48402d6..ae38d5371 100644 --- a/js/src/builtin/SymbolObject.cpp +++ b/js/src/builtin/SymbolObject.cpp @@ -33,6 +33,7 @@ SymbolObject::create(JSContext* cx, JS::HandleSymbol symbol) } const JSPropertySpec SymbolObject::properties[] = { + JS_PSG("description", descriptionGetter, 0), JS_PS_END }; @@ -227,6 +228,34 @@ SymbolObject::toPrimitive(JSContext* cx, unsigned argc, Value* vp) return CallNonGenericMethod<IsSymbol, valueOf_impl>(cx, args); } +// ES2019 Stage 4 Draft / November 28, 2018 +// Symbol description accessor +// See: https://tc39.github.io/proposal-Symbol-description/ +bool +SymbolObject::descriptionGetter_impl(JSContext* cx, const CallArgs& args) +{ + // Get symbol object pointer. + HandleValue thisv = args.thisv(); + MOZ_ASSERT(IsSymbol(thisv)); + Rooted<Symbol*> sym(cx, thisv.isSymbol() + ? thisv.toSymbol() + : thisv.toObject().as<SymbolObject>().unbox()); + + // Return the symbol's description if present, otherwise return undefined. + if (JSString* str = sym->description()) + args.rval().setString(str); + else + args.rval().setUndefined(); + return true; +} + +bool +SymbolObject::descriptionGetter(JSContext* cx, unsigned argc, Value* vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + return CallNonGenericMethod<IsSymbol, descriptionGetter_impl>(cx, args); +} + JSObject* js::InitSymbolClass(JSContext* cx, HandleObject obj) { diff --git a/js/src/builtin/SymbolObject.h b/js/src/builtin/SymbolObject.h index 0f204b494..e10b42d53 100644 --- a/js/src/builtin/SymbolObject.h +++ b/js/src/builtin/SymbolObject.h @@ -52,6 +52,10 @@ class SymbolObject : public NativeObject static MOZ_MUST_USE bool valueOf(JSContext* cx, unsigned argc, Value* vp); static MOZ_MUST_USE bool toPrimitive(JSContext* cx, unsigned argc, Value* vp); + // Properties defined on Symbol.prototype. + static MOZ_MUST_USE bool descriptionGetter_impl(JSContext* cx, const CallArgs& args); + static MOZ_MUST_USE bool descriptionGetter(JSContext* cx, unsigned argc, Value *vp); + static const JSPropertySpec properties[]; static const JSFunctionSpec methods[]; static const JSFunctionSpec staticMethods[]; diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 7a67c0095..3b4c957dc 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -3169,6 +3169,11 @@ static const JSFunctionSpec array_methods[] = { /* ES7 additions */ JS_SELF_HOSTED_FN("includes", "ArrayIncludes", 2,0), + + /* ES2019 additions */ + JS_SELF_HOSTED_FN("flat", "ArrayFlat", 0,0), + JS_SELF_HOSTED_FN("flatMap", "ArrayFlatMap", 1,0), + JS_FS_END }; @@ -3333,6 +3338,8 @@ array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto) !DefineProperty(cx, unscopables, cx->names().fill, value) || !DefineProperty(cx, unscopables, cx->names().find, value) || !DefineProperty(cx, unscopables, cx->names().findIndex, value) || + !DefineProperty(cx, unscopables, cx->names().flat, value) || + !DefineProperty(cx, unscopables, cx->names().flatMap, value) || !DefineProperty(cx, unscopables, cx->names().includes, value) || !DefineProperty(cx, unscopables, cx->names().keys, value) || !DefineProperty(cx, unscopables, cx->names().values, value)) diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index e3b5708ca..7765b1197 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -1970,14 +1970,14 @@ js::str_trim(JSContext* cx, unsigned argc, Value* vp) } bool -js::str_trimLeft(JSContext* cx, unsigned argc, Value* vp) +js::str_trimStart(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return TrimString(cx, args, true, false); } bool -js::str_trimRight(JSContext* cx, unsigned argc, Value* vp) +js::str_trimEnd(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return TrimString(cx, args, false, true); @@ -2568,8 +2568,10 @@ static const JSFunctionSpec string_methods[] = { JS_FN("startsWith", str_startsWith, 1,0), JS_FN("endsWith", str_endsWith, 1,0), JS_FN("trim", str_trim, 0,0), - JS_FN("trimLeft", str_trimLeft, 0,0), - JS_FN("trimRight", str_trimRight, 0,0), + JS_FN("trimLeft", str_trimStart, 0,0), + JS_FN("trimStart", str_trimStart, 0,0), + JS_FN("trimRight", str_trimEnd, 0,0), + JS_FN("trimEnd", str_trimEnd, 0,0), JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,0), JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,0), JS_SELF_HOSTED_FN("localeCompare", "String_localeCompare", 1,0), @@ -2881,8 +2883,10 @@ static const JSFunctionSpec string_static_methods[] = { JS_SELF_HOSTED_FN("startsWith", "String_static_startsWith", 2,0), JS_SELF_HOSTED_FN("endsWith", "String_static_endsWith", 2,0), JS_SELF_HOSTED_FN("trim", "String_static_trim", 1,0), - JS_SELF_HOSTED_FN("trimLeft", "String_static_trimLeft", 1,0), - JS_SELF_HOSTED_FN("trimRight", "String_static_trimRight", 1,0), + JS_SELF_HOSTED_FN("trimLeft", "String_static_trimStart", 1,0), + JS_SELF_HOSTED_FN("trimStart", "String_static_trimStart", 1,0), + JS_SELF_HOSTED_FN("trimRight", "String_static_trimEnd", 1,0), + JS_SELF_HOSTED_FN("trimEnd", "String_static_trimEnd", 1,0), JS_SELF_HOSTED_FN("toLocaleLowerCase","String_static_toLocaleLowerCase",1,0), JS_SELF_HOSTED_FN("toLocaleUpperCase","String_static_toLocaleUpperCase",1,0), JS_SELF_HOSTED_FN("normalize", "String_static_normalize", 1,0), diff --git a/js/src/jsstr.h b/js/src/jsstr.h index 118118839..38fbfa85e 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -367,10 +367,10 @@ extern bool str_trim(JSContext* cx, unsigned argc, Value* vp); extern bool -str_trimLeft(JSContext* cx, unsigned argc, Value* vp); +str_trimStart(JSContext* cx, unsigned argc, Value* vp); extern bool -str_trimRight(JSContext* cx, unsigned argc, Value* vp); +str_trimEnd(JSContext* cx, unsigned argc, Value* vp); extern bool str_toLocaleLowerCase(JSContext* cx, unsigned argc, Value* vp); diff --git a/js/src/tests/ecma_6/Array/unscopables.js b/js/src/tests/ecma_6/Array/unscopables.js index 6685309a0..56b3aa520 100644 --- a/js/src/tests/ecma_6/Array/unscopables.js +++ b/js/src/tests/ecma_6/Array/unscopables.js @@ -26,6 +26,8 @@ assertDeepEq(keys, [ "fill", "find", "findIndex", + "flat", + "flatMap", "includes", "keys", "values" diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h index e971dc844..8a36df083 100644 --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -115,6 +115,8 @@ macro(firstDayOfWeek, firstDayOfWeek, "firstDayOfWeek") \ macro(fix, fix, "fix") \ macro(flags, flags, "flags") \ + macro(flat, flat, "flat") \ + macro(flatMap, flatMap, "flatMap") \ macro(float32, float32, "float32") \ macro(Float32x4, Float32x4, "Float32x4") \ macro(float64, float64, "float64") \ diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 328a960b6..ccd4cc8d7 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -2200,8 +2200,10 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_INLINABLE_FN("std_String_charAt", str_charAt, 1,0, StringCharAt), JS_FN("std_String_endsWith", str_endsWith, 1,0), JS_FN("std_String_trim", str_trim, 0,0), - JS_FN("std_String_trimLeft", str_trimLeft, 0,0), - JS_FN("std_String_trimRight", str_trimRight, 0,0), + JS_FN("std_String_trimLeft", str_trimStart, 0,0), + JS_FN("std_String_trimStart", str_trimStart, 0,0), + JS_FN("std_String_trimRight", str_trimEnd, 0,0), + JS_FN("std_String_trimEnd", str_trimEnd, 0,0), JS_FN("std_String_toLocaleLowerCase", str_toLocaleLowerCase, 0,0), JS_FN("std_String_toLocaleUpperCase", str_toLocaleUpperCase, 0,0), JS_FN("std_String_normalize", str_normalize, 0,0), |