summaryrefslogtreecommitdiffstats
path: root/js/src
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-06-08 07:48:28 +0000
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-06-08 07:48:28 +0000
commitba9e648ce2705ad1c4679325a9326c47263e2a3e (patch)
tree724cf5101a1b5923c235dc767b355a7b0e906eb7 /js/src
parentc8300fbd6ae08925736c32f8b02c980ce1531f3f (diff)
parent19c0f5e9ff625c6a67e5e0a08f0a800782168492 (diff)
downloadUXP-ba9e648ce2705ad1c4679325a9326c47263e2a3e.tar
UXP-ba9e648ce2705ad1c4679325a9326c47263e2a3e.tar.gz
UXP-ba9e648ce2705ad1c4679325a9326c47263e2a3e.tar.lz
UXP-ba9e648ce2705ad1c4679325a9326c47263e2a3e.tar.xz
UXP-ba9e648ce2705ad1c4679325a9326c47263e2a3e.zip
Merge branch 'master' into remove-unboxed
Diffstat (limited to 'js/src')
-rw-r--r--js/src/builtin/Array.js108
-rw-r--r--js/src/builtin/String.js12
-rw-r--r--js/src/builtin/SymbolObject.cpp29
-rw-r--r--js/src/builtin/SymbolObject.h4
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp28
-rw-r--r--js/src/frontend/BytecodeEmitter.h10
-rw-r--r--js/src/jit/IonCaches.cpp1
-rw-r--r--js/src/jit/Recover.cpp1
-rw-r--r--js/src/jit/arm/Assembler-arm.cpp7
-rw-r--r--js/src/jit/arm/MacroAssembler-arm.cpp5
-rw-r--r--js/src/jsarray.cpp7
-rw-r--r--js/src/jsstr.cpp16
-rw-r--r--js/src/jsstr.h4
-rw-r--r--js/src/jstypes.h2
-rw-r--r--js/src/tests/ecma_6/Array/unscopables.js2
-rw-r--r--js/src/vm/CommonPropertyNames.h2
-rw-r--r--js/src/vm/SelfHosting.cpp6
17 files changed, 211 insertions, 33 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/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp
index b3dd6d777..c524184d6 100644
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -2260,12 +2260,14 @@ BytecodeEmitter::locationOfNameBoundInFunctionScope(JSAtom* name, EmitterScope*
bool
BytecodeEmitter::emitCheck(ptrdiff_t delta, ptrdiff_t* offset)
{
- *offset = code().length();
+ size_t oldLength = code().length();
+ *offset = ptrdiff_t(oldLength);
- // Start it off moderately large to avoid repeated resizings early on.
- // ~98% of cases fit within 1024 bytes.
- if (code().capacity() == 0 && !code().reserve(1024))
- return false;
+ size_t newLength = oldLength + size_t(delta);
+ if (MOZ_UNLIKELY(newLength > MaxBytecodeLength)) {
+ ReportAllocationOverflow(cx);
+ return false;
+ }
if (!code().growBy(delta)) {
ReportOutOfMemory(cx);
@@ -10697,17 +10699,19 @@ BytecodeEmitter::emitTreeInBranch(ParseNode* pn)
static bool
AllocSrcNote(ExclusiveContext* cx, SrcNotesVector& notes, unsigned* index)
{
- // Start it off moderately large to avoid repeated resizings early on.
- // ~99% of cases fit within 256 bytes.
- if (notes.capacity() == 0 && !notes.reserve(256))
- return false;
+ size_t oldLength = notes.length();
+ if (MOZ_UNLIKELY(oldLength + 1 > MaxSrcNotesLength)) {
+ ReportAllocationOverflow(cx);
+ return false;
+ }
+
if (!notes.growBy(1)) {
ReportOutOfMemory(cx);
return false;
}
- *index = notes.length() - 1;
+ *index = oldLength;
return true;
}
@@ -10833,6 +10837,10 @@ BytecodeEmitter::setSrcNoteOffset(unsigned index, unsigned which, ptrdiff_t offs
/* Maybe this offset was already set to a four-byte value. */
if (!(*sn & SN_4BYTE_OFFSET_FLAG)) {
/* Insert three dummy bytes that will be overwritten shortly. */
+ if (MOZ_UNLIKELY(notes.length() + 3 > MaxSrcNotesLength)) {
+ ReportAllocationOverflow(cx);
+ return false;
+ }
jssrcnote dummy = 0;
if (!(sn = notes.insert(sn, dummy)) ||
!(sn = notes.insert(sn, dummy)) ||
diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h
index 32668a34c..814fa11d4 100644
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -109,10 +109,12 @@ struct CGYieldOffsetList {
void finish(YieldOffsetArray& array, uint32_t prologueLength);
};
-// Use zero inline elements because these go on the stack and affect how many
-// nested functions are possible.
-typedef Vector<jsbytecode, 0> BytecodeVector;
-typedef Vector<jssrcnote, 0> SrcNotesVector;
+static size_t MaxBytecodeLength = INT32_MAX;
+static size_t MaxSrcNotesLength = INT32_MAX;
+
+// Have a few inline elements to avoid heap allocation for tiny sequences.
+typedef Vector<jsbytecode, 256> BytecodeVector;
+typedef Vector<jssrcnote, 64> SrcNotesVector;
// Linked list of jump instructions that need to be patched. The linked list is
// stored in the bytes of the incomplete bytecode that will be patched, so no
diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp
index 0a53f178f..81cf9d9bb 100644
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -31,6 +31,7 @@
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/Shape-inl.h"
+#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp
index 13bf9224b..6fd71f377 100644
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -30,6 +30,7 @@
#include "vm/Interpreter-inl.h"
#include "vm/NativeObject-inl.h"
+#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp
index 2830f0695..1e20da1c8 100644
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -2401,7 +2401,12 @@ Assembler::as_b(Label* l, Condition c)
if (oom())
return BufferOffset();
- as_b(BufferOffset(l).diffB<BOffImm>(ret), c, ret);
+ BOffImm off = BufferOffset(l).diffB<BOffImm>(ret);
+ if (off.isInvalid()) {
+ m_buffer.fail_bail();
+ return BufferOffset();
+ }
+ as_b(off, c, ret);
#ifdef JS_DISASM_ARM
spewBranch(m_buffer.getInstOrNull(ret), l);
#endif
diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp
index d40578514..a4161ab00 100644
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -5012,7 +5012,10 @@ void
MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset)
{
BufferOffset inst(callerOffset - 4);
- as_bl(BufferOffset(calleeOffset).diffB<BOffImm>(inst), Always, inst);
+ BOffImm off = BufferOffset(calleeOffset).diffB<BOffImm>(inst);
+ MOZ_RELEASE_ASSERT(!off.isInvalid(),
+ "Failed to insert necessary far jump islands");
+ as_bl(off, Always, inst);
}
CodeOffset
diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp
index fa5ef2ab3..a8bd3f028 100644
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -3146,6 +3146,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
};
@@ -3310,6 +3315,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/jstypes.h b/js/src/jstypes.h
index 6cfb3d4ad..04ffbe00d 100644
--- a/js/src/jstypes.h
+++ b/js/src/jstypes.h
@@ -147,7 +147,7 @@
# define JS_64BIT
# endif
#elif defined(__GNUC__)
-# if defined(__x86_64__) || defined(__64BIT__)
+# if defined(__x86_64__) || defined(__LP64__)
# define JS_64BIT
# endif
#elif defined(__xlc__) || defined(__xlC__) /* IBM XL C/C++ */
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),