summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-04-05 20:01:10 +0200
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-04-05 20:01:10 +0200
commitc3b63b831cd2c64700e875b28540212c7c881ac6 (patch)
treeedd98fcbd2004d3b562904f822bf6c3322fc7f52 /js
parentd432e068a21c815d5d5e7bcbc1cc8c6e77a7d1e0 (diff)
parentcc07da9cb4d6e7a53f8d953427ffc2bca2e0c2df (diff)
downloadUXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.gz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.lz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.xz
UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.zip
Merge branch 'master' into 816
Diffstat (limited to 'js')
-rw-r--r--js/public/LegacyIntTypes.h10
-rw-r--r--js/public/Value.h7
-rw-r--r--js/src/Makefile.in21
-rw-r--r--js/src/builtin/TestingFunctions.cpp4
-rw-r--r--js/src/ctypes/CTypes.cpp4
-rw-r--r--js/src/ctypes/libffi/testsuite/libffi.call/float2.c10
-rw-r--r--js/src/gc/Memory.cpp85
-rw-r--r--js/src/gc/Nursery.cpp1
-rw-r--r--js/src/gc/Nursery.h1
-rw-r--r--js/src/jit/AliasAnalysisShared.cpp3
-rw-r--r--js/src/jit/IonAnalysis.cpp21
-rw-r--r--js/src/jit/JitOptions.cpp2
-rw-r--r--js/src/jit/MIR.h7
-rw-r--r--js/src/jit/StupidAllocator.cpp1
-rw-r--r--js/src/jsapi-tests/testGCAllocator.cpp12
-rw-r--r--js/src/jsapi.cpp3
-rw-r--r--js/src/jsapi.h32
-rw-r--r--js/src/jsfun.cpp68
-rw-r--r--js/src/jsgc.cpp11
-rw-r--r--js/src/jsnativestack.cpp29
-rw-r--r--js/src/jsstr.cpp5
-rw-r--r--js/src/jstypes.h8
-rw-r--r--js/src/jswrapper.h2
-rw-r--r--js/src/moz.build8
-rw-r--r--js/src/old-configure.in4
-rw-r--r--js/src/proxy/OpaqueCrossCompartmentWrapper.cpp8
-rw-r--r--js/src/proxy/ScriptedProxyHandler.cpp4
-rw-r--r--js/src/vm/Interpreter.cpp14
-rw-r--r--js/src/vm/Interpreter.h3
-rw-r--r--js/src/vm/ObjectGroup.cpp1
-rw-r--r--js/src/vm/Time.cpp11
-rw-r--r--js/src/wasm/WasmSignalHandlers.cpp2
-rw-r--r--js/xpconnect/loader/mozJSSubScriptLoader.cpp1
-rw-r--r--js/xpconnect/src/Sandbox.cpp1
-rw-r--r--js/xpconnect/src/XPCJSContext.cpp4
-rw-r--r--js/xpconnect/src/XPCShellImpl.cpp13
-rw-r--r--js/xpconnect/src/nsScriptErrorWithStack.cpp1
-rw-r--r--js/xpconnect/wrappers/WaiveXrayWrapper.cpp31
-rw-r--r--js/xpconnect/wrappers/WaiveXrayWrapper.h2
-rw-r--r--js/xpconnect/wrappers/XrayWrapper.cpp14
-rw-r--r--js/xpconnect/wrappers/XrayWrapper.h2
41 files changed, 156 insertions, 315 deletions
diff --git a/js/public/LegacyIntTypes.h b/js/public/LegacyIntTypes.h
index 2c8498c89..cdfd98726 100644
--- a/js/public/LegacyIntTypes.h
+++ b/js/public/LegacyIntTypes.h
@@ -31,20 +31,10 @@ typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
-/*
- * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very
- * common header file) defines the types int8, int16, int32, and int64.
- * So we don't define these four types here to avoid conflicts in case
- * the code also includes sys/types.h.
- */
-#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H)
-#include <sys/inttypes.h>
-#else
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
-#endif /* AIX && HAVE_SYS_INTTYPES_H */
typedef uint8_t JSUint8;
typedef uint16_t JSUint16;
diff --git a/js/public/Value.h b/js/public/Value.h
index 01666ed4e..7c4f833e3 100644
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -567,8 +567,11 @@ class MOZ_NON_PARAM alignas(8) Value
}
bool isMagic(JSWhyMagic why) const {
- MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why);
- return isMagic();
+ if (!isMagic()) {
+ return false;
+ }
+ MOZ_RELEASE_ASSERT(data.s.payload.why == why);
+ return true;
}
JS::TraceKind traceKind() const {
diff --git a/js/src/Makefile.in b/js/src/Makefile.in
index b007954b1..20678c68c 100644
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -138,27 +138,6 @@ distclean::
CFLAGS += $(MOZ_ZLIB_CFLAGS)
-# Silence warnings on AIX/HP-UX from non-GNU compilers
-ifndef GNU_CC
-ifeq ($(OS_ARCH),AIX)
-# Suppress warnings from xlC
-# 1540-1281: offsetof() on null non-POD types
-# 1540-1608: anonymous unions using static data members
-CFLAGS += -qsuppress=1540-1281 -qsuppress=1540-1608
-CXXFLAGS += -qsuppress=1540-1281 -qsuppress=1540-1608
-endif
-endif
-ifeq ($(OS_ARCH),SunOS)
-ifeq ($(TARGET_CPU),sparc)
-
-ifdef GNU_CC
-CFLAGS += -mcpu=v9
-CXXFLAGS += -mcpu=v9
-endif # GNU_CC
-
-endif
-endif
-
$(LIBRARY_NAME).pc: js.pc
cp $^ $@
diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp
index 373b6c9ed..c896ce5d1 100644
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -240,11 +240,7 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp)
if (!JS_SetProperty(cx, info, "intl-api", value))
return false;
-#if defined(SOLARIS)
- value = BooleanValue(false);
-#else
value = BooleanValue(true);
-#endif
if (!JS_SetProperty(cx, info, "mapped-array-buffer", value))
return false;
diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp
index 0facd0009..d6adfac2c 100644
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -20,10 +20,6 @@
#include <float.h>
#endif
-#if defined(SOLARIS)
-#include <ieeefp.h>
-#endif
-
#ifdef HAVE_SSIZE_T
#include <sys/types.h>
#endif
diff --git a/js/src/ctypes/libffi/testsuite/libffi.call/float2.c b/js/src/ctypes/libffi/testsuite/libffi.call/float2.c
index a0b296cf4..dfdef0598 100644
--- a/js/src/ctypes/libffi/testsuite/libffi.call/float2.c
+++ b/js/src/ctypes/libffi/testsuite/libffi.call/float2.c
@@ -32,21 +32,11 @@ int main (void)
f = 3.14159;
-#if 1
- /* This is ifdef'd out for now. long double support under SunOS/gcc
- is pretty much non-existent. You'll get the odd bus error in library
- routines like printf(). */
printf ("%Lf\n", ldblit(f));
-#endif
ld = 666;
ffi_call(&cif, FFI_FN(ldblit), &ld, values);
-#if 1
- /* This is ifdef'd out for now. long double support under SunOS/gcc
- is pretty much non-existent. You'll get the odd bus error in library
- routines like printf(). */
printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
-#endif
/* These are not always the same!! Check for a reasonable delta */
if (ld - ldblit(f) < LDBL_EPSILON)
diff --git a/js/src/gc/Memory.cpp b/js/src/gc/Memory.cpp
index 26da75469..268e1e489 100644
--- a/js/src/gc/Memory.cpp
+++ b/js/src/gc/Memory.cpp
@@ -17,11 +17,6 @@
#include "jswin.h"
#include <psapi.h>
-#elif defined(SOLARIS)
-
-#include <sys/mman.h>
-#include <unistd.h>
-
#elif defined(XP_UNIX)
#include <algorithm>
@@ -408,86 +403,6 @@ DeallocateMappedContent(void* p, size_t length)
# endif
-#elif defined(SOLARIS)
-
-#ifndef MAP_NOSYNC
-# define MAP_NOSYNC 0
-#endif
-
-void
-InitMemorySubsystem()
-{
- if (pageSize == 0)
- pageSize = allocGranularity = size_t(sysconf(_SC_PAGESIZE));
-}
-
-void*
-MapAlignedPages(size_t size, size_t alignment)
-{
- MOZ_ASSERT(size >= alignment);
- MOZ_ASSERT(size >= allocGranularity);
- MOZ_ASSERT(size % alignment == 0);
- MOZ_ASSERT(size % pageSize == 0);
- MOZ_ASSERT_IF(alignment < allocGranularity, allocGranularity % alignment == 0);
- MOZ_ASSERT_IF(alignment > allocGranularity, alignment % allocGranularity == 0);
-
- int prot = PROT_READ | PROT_WRITE;
- int flags = MAP_PRIVATE | MAP_ANON | MAP_ALIGN | MAP_NOSYNC;
-
- void* p = mmap((caddr_t)alignment, size, prot, flags, -1, 0);
- if (p == MAP_FAILED)
- return nullptr;
- return p;
-}
-
-static void*
-MapAlignedPagesLastDitch(size_t size, size_t alignment)
-{
- return nullptr;
-}
-
-void
-UnmapPages(void* p, size_t size)
-{
- MOZ_ALWAYS_TRUE(0 == munmap((caddr_t)p, size));
-}
-
-bool
-MarkPagesUnused(void* p, size_t size)
-{
- MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
- return true;
-}
-
-bool
-MarkPagesInUse(void* p, size_t size)
-{
- if (!DecommitEnabled())
- return;
-
- MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
-}
-
-size_t
-GetPageFaultCount()
-{
- return 0;
-}
-
-void*
-AllocateMappedContent(int fd, size_t offset, size_t length, size_t alignment)
-{
- // Not implemented.
- return nullptr;
-}
-
-// Deallocate mapped memory for object.
-void
-DeallocateMappedContent(void* p, size_t length)
-{
- // Not implemented.
-}
-
#elif defined(XP_UNIX)
void
diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp
index ea4350fb8..93a0eb6a8 100644
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -210,6 +210,7 @@ js::Nursery::disable()
return;
updateNumChunks(0);
currentEnd_ = 0;
+ position_ = 0;
runtime()->gc.storeBuffer.disable();
}
diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h
index 0d215d997..a839a4979 100644
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -245,6 +245,7 @@ class Nursery
// Free space remaining, not counting chunk trailers.
MOZ_ALWAYS_INLINE size_t freeSpace() const {
+ MOZ_ASSERT(isEnabled());
MOZ_ASSERT(currentEnd_ - position_ <= NurseryChunkUsableSize);
return (currentEnd_ - position_) +
(numChunks() - currentChunk_ - 1) * NurseryChunkUsableSize;
diff --git a/js/src/jit/AliasAnalysisShared.cpp b/js/src/jit/AliasAnalysisShared.cpp
index ae28327ca..81c0fd067 100644
--- a/js/src/jit/AliasAnalysisShared.cpp
+++ b/js/src/jit/AliasAnalysisShared.cpp
@@ -102,7 +102,6 @@ GetObject(const MDefinition* ins)
case MDefinition::Op_SetDisjointTypedElements:
case MDefinition::Op_ArrayPopShift:
case MDefinition::Op_ArrayPush:
- case MDefinition::Op_ArraySlice:
case MDefinition::Op_LoadTypedArrayElementHole:
case MDefinition::Op_StoreTypedArrayElementHole:
case MDefinition::Op_LoadFixedSlot:
@@ -126,6 +125,7 @@ GetObject(const MDefinition* ins)
object = ins->getOperand(0);
break;
case MDefinition::Op_GetPropertyCache:
+ case MDefinition::Op_CallGetProperty:
case MDefinition::Op_LoadTypedArrayElementStatic:
case MDefinition::Op_StoreTypedArrayElementStatic:
case MDefinition::Op_GetDOMProperty:
@@ -148,6 +148,7 @@ GetObject(const MDefinition* ins)
case MDefinition::Op_WasmLoadGlobalVar:
case MDefinition::Op_WasmStoreGlobalVar:
case MDefinition::Op_ArrayJoin:
+ case MDefinition::Op_ArraySlice:
return nullptr;
default:
#ifdef DEBUG
diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp
index b163d5818..d255c32a8 100644
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3127,6 +3127,15 @@ ExtractMathSpace(MDefinition* ins)
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unknown TruncateKind");
}
+static bool MonotoneAdd(int32_t lhs, int32_t rhs) {
+ return (lhs >= 0 && rhs >= 0) || (lhs <= 0 && rhs <= 0);
+}
+
+static bool MonotoneSub(int32_t lhs, int32_t rhs) {
+ return (lhs >= 0 && rhs <= 0) || (lhs <= 0 && rhs >= 0);
+}
+
+
// Extract a linear sum from ins, if possible (otherwise giving the sum 'ins + 0').
SimpleLinearSum
jit::ExtractLinearSum(MDefinition* ins, MathSpace space)
@@ -3168,10 +3177,12 @@ jit::ExtractLinearSum(MDefinition* ins, MathSpace space)
// Check if this is of the form <SUM> + n or n + <SUM>.
if (ins->isAdd()) {
int32_t constant;
- if (space == MathSpace::Modulo)
+ if (space == MathSpace::Modulo) {
constant = lsum.constant + rsum.constant;
- else if (!SafeAdd(lsum.constant, rsum.constant, &constant))
+ } else if (!SafeAdd(lsum.constant, rsum.constant, &constant) ||
+ !MonotoneAdd(lsum.constant, rsum.constant)) {
return SimpleLinearSum(ins, 0);
+ }
return SimpleLinearSum(lsum.term ? lsum.term : rsum.term, constant);
}
@@ -3179,10 +3190,12 @@ jit::ExtractLinearSum(MDefinition* ins, MathSpace space)
// Check if this is of the form <SUM> - n.
if (lsum.term) {
int32_t constant;
- if (space == MathSpace::Modulo)
+ if (space == MathSpace::Modulo) {
constant = lsum.constant - rsum.constant;
- else if (!SafeSub(lsum.constant, rsum.constant, &constant))
+ } else if (!SafeSub(lsum.constant, rsum.constant, &constant) ||
+ !MonotoneSub(lsum.constant, rsum.constant)) {
return SimpleLinearSum(ins, 0);
+ }
return SimpleLinearSum(lsum.term, constant);
}
diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp
index eb5a6c1c2..b9a7c7b27 100644
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -222,7 +222,7 @@ DefaultJitOptions::DefaultJitOptions()
}
// Toggles whether unboxed plain objects can be created by the VM.
- SET_DEFAULT(disableUnboxedObjects, false);
+ SET_DEFAULT(disableUnboxedObjects, true);
// Test whether Atomics are allowed in asm.js code.
SET_DEFAULT(asmJSAtomicsEnable, false);
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index b2e84322f..fb0f22fc3 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -9910,10 +9910,6 @@ class MArraySlice
return unboxedType_;
}
- AliasSet getAliasSet() const override {
- return AliasSet::Store(AliasSet::BoxedOrUnboxedElements(unboxedType()) |
- AliasSet::ObjectFields);
- }
bool possiblyCalls() const override {
return true;
}
@@ -11837,7 +11833,8 @@ class MCallGetProperty
AliasSet getAliasSet() const override {
if (!idempotent_)
return AliasSet::Store(AliasSet::Any);
- return AliasSet::None();
+ return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
+ AliasSet::DynamicSlot);
}
bool possiblyCalls() const override {
return true;
diff --git a/js/src/jit/StupidAllocator.cpp b/js/src/jit/StupidAllocator.cpp
index 8e3ea6286..55431e8e0 100644
--- a/js/src/jit/StupidAllocator.cpp
+++ b/js/src/jit/StupidAllocator.cpp
@@ -407,7 +407,6 @@ StupidAllocator::allocateForDefinition(LInstruction* ins, LDefinition* def)
{
uint32_t vreg = def->virtualRegister();
- CodePosition from;
if ((def->output()->isRegister() && def->policy() == LDefinition::FIXED) ||
def->policy() == LDefinition::MUST_REUSE_INPUT)
{
diff --git a/js/src/jsapi-tests/testGCAllocator.cpp b/js/src/jsapi-tests/testGCAllocator.cpp
index 2c5c58a29..d203019ec 100644
--- a/js/src/jsapi-tests/testGCAllocator.cpp
+++ b/js/src/jsapi-tests/testGCAllocator.cpp
@@ -14,8 +14,6 @@
#if defined(XP_WIN)
#include "jswin.h"
#include <psapi.h>
-#elif defined(SOLARIS)
-// This test doesn't apply to Solaris.
#elif defined(XP_UNIX)
#include <algorithm>
#include <errno.h>
@@ -39,8 +37,6 @@ BEGIN_TEST(testGCAllocator)
# else // Various APIs are unavailable. This test is disabled.
return true;
# endif
-#elif defined(SOLARIS)
- return true;
#elif defined(XP_UNIX)
PageSize = size_t(sysconf(_SC_PAGESIZE));
#else
@@ -301,12 +297,6 @@ void* mapMemory(size_t length) { return nullptr; }
void unmapPages(void* p, size_t size) { }
# endif
-#elif defined(SOLARIS) // This test doesn't apply to Solaris.
-
-void* mapMemoryAt(void* desired, size_t length) { return nullptr; }
-void* mapMemory(size_t length) { return nullptr; }
-void unmapPages(void* p, size_t size) { }
-
#elif defined(XP_UNIX)
void*
@@ -377,7 +367,7 @@ unmapPages(void* p, size_t size)
MOZ_RELEASE_ASSERT(errno == ENOMEM);
}
-#else // !defined(XP_WIN) && !defined(SOLARIS) && !defined(XP_UNIX)
+#else // !defined(XP_WIN) && !defined(XP_UNIX)
#error "Memory mapping functions are not defined for your OS."
#endif
END_TEST(testGCAllocator)
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 9ee29ffe4..f78f94dc1 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -6434,6 +6434,9 @@ JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t v
}
jit::JitOptions.jumpThreshold = value;
break;
+ case JSJITCOMPILER_UNBOXED_OBJECTS:
+ jit::JitOptions.disableUnboxedObjects = !value;
+ break;
case JSJITCOMPILER_ASMJS_ATOMICS_ENABLE:
jit::JitOptions.asmJSAtomicsEnable = !!value;
break;
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index 799396a0a..1f726f2e5 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2154,6 +2154,13 @@ namespace JS {
extern JS_PUBLIC_API(bool)
OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp);
+// Implementation of
+// https://www.ecma-international.org/ecma-262/6.0/#sec-instanceofoperator
+// This is almost identical to JS_HasInstance, except the latter may call a
+// custom hasInstance class op instead of InstanceofOperator.
+extern JS_PUBLIC_API(bool)
+InstanceofOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp);
+
} // namespace JS
extern JS_PUBLIC_API(void*)
@@ -5776,19 +5783,20 @@ JS_SetParallelParsingEnabled(JSContext* cx, bool enabled);
extern JS_PUBLIC_API(void)
JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled);
-#define JIT_COMPILER_OPTIONS(Register) \
- Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
- Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
- Register(ION_GVN_ENABLE, "ion.gvn.enable") \
- Register(ION_FORCE_IC, "ion.forceinlineCaches") \
- Register(ION_ENABLE, "ion.enable") \
+#define JIT_COMPILER_OPTIONS(Register) \
+ Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
+ Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
+ Register(ION_GVN_ENABLE, "ion.gvn.enable") \
+ Register(ION_FORCE_IC, "ion.forceinlineCaches") \
+ Register(ION_ENABLE, "ion.enable") \
Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
- Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
- Register(BASELINE_ENABLE, "baseline.enable") \
- Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
- Register(JUMP_THRESHOLD, "jump-threshold") \
- Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \
- Register(WASM_TEST_MODE, "wasm.test-mode") \
+ Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
+ Register(BASELINE_ENABLE, "baseline.enable") \
+ Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
+ Register(JUMP_THRESHOLD, "jump-threshold") \
+ Register(UNBOXED_OBJECTS, "unboxed_objects") \
+ Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \
+ Register(WASM_TEST_MODE, "wasm.test-mode") \
Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets")
typedef enum JSJitCompilerOption {
diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp
index be11bf436..e624aa415 100644
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -288,6 +288,12 @@ CallerGetterImpl(JSContext* cx, const CallArgs& args)
return true;
}
+ if (JS_IsDeadWrapper(callerObj)) {
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+ JSMSG_DEAD_OBJECT);
+ return false;
+ }
+
JSFunction* callerFun = &callerObj->as<JSFunction>();
MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
@@ -314,54 +320,14 @@ CallerSetterImpl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsFunction(args.thisv()));
- // Beware! This function can be invoked on *any* function! It can't
- // assume it'll never be invoked on natives, strict mode functions, bound
- // functions, or anything else that ordinarily has immutable .caller
- // defined with [[ThrowTypeError]].
- RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>());
- if (!CallerRestrictions(cx, fun))
- return false;
-
- // Return |undefined| unless an error must be thrown.
- args.rval().setUndefined();
-
- // We can almost just return |undefined| here -- but if the caller function
- // was strict mode code, we still have to throw a TypeError. This requires
- // computing the caller, checking that no security boundaries are crossed,
- // and throwing a TypeError if the resulting caller is strict.
-
- NonBuiltinScriptFrameIter iter(cx);
- if (!AdvanceToActiveCallLinear(cx, iter, fun))
- return true;
-
- ++iter;
- while (!iter.done() && iter.isEvalFrame())
- ++iter;
-
- if (iter.done() || !iter.isFunctionFrame())
- return true;
-
- RootedObject caller(cx, iter.callee(cx));
- if (!cx->compartment()->wrap(cx, &caller)) {
- cx->clearPendingException();
- return true;
- }
-
- // If we don't have full access to the caller, or the caller is not strict,
- // return undefined. Otherwise throw a TypeError.
- JSObject* callerObj = CheckedUnwrap(caller);
- if (!callerObj)
- return true;
-
- JSFunction* callerFun = &callerObj->as<JSFunction>();
- MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
-
- if (callerFun->strict()) {
- JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
- JSMSG_CALLER_IS_STRICT);
- return false;
+ // We just have to return |undefined|, but first we call CallerGetterImpl
+ // because we need the same strict-mode and security checks.
+
+ if (!CallerGetterImpl(cx, args)) {
+ return false;
}
+ args.rval().setUndefined();
return true;
}
@@ -690,7 +656,7 @@ js::fun_symbolHasInstance(JSContext* cx, unsigned argc, Value* vp)
}
/*
- * ES6 (4-25-16) 7.3.19 OrdinaryHasInstance
+ * ES6 7.3.19 OrdinaryHasInstance
*/
bool
JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp)
@@ -707,7 +673,7 @@ JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool*
if (obj->is<JSFunction>() && obj->isBoundFunction()) {
/* Steps 2a-b. */
obj = obj->as<JSFunction>().getBoundFunctionTarget();
- return InstanceOfOperator(cx, obj, v, bp);
+ return InstanceofOperator(cx, obj, v, bp);
}
/* Step 3. */
@@ -716,12 +682,12 @@ JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool*
return true;
}
- /* Step 4. */
+ /* Step 4-5. */
RootedValue pval(cx);
if (!GetProperty(cx, obj, obj, cx->names().prototype, &pval))
return false;
- /* Step 5. */
+ /* Step 6. */
if (pval.isPrimitive()) {
/*
* Throw a runtime error if instanceof is called on a function that
@@ -732,7 +698,7 @@ JS::OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool*
return false;
}
- /* Step 6. */
+ /* Step 7. */
RootedObject pobj(cx, &pval.toObject());
bool isDelegate;
if (!IsDelegate(cx, pobj, v, &isDelegate))
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index 3d4dae9bb..8cee9ec09 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2310,22 +2310,27 @@ GCRuntime::updateCellPointers(MovingTracer* trc, Zone* zone, AllocKinds kinds, s
// 2) typed object type descriptor objects
// 3) all other objects
//
+// Also, there can be data races calling IsForwarded() on the new location of a
+// cell that is being updated in parallel on another thread. This can be avoided
+// by updating some kinds of cells in different phases. This is done for JSScripts
+// and LazyScripts, and JSScripts and Scopes.
+//
// Since we want to minimize the number of phases, we put everything else into
// the first phase and label it the 'misc' phase.
static const AllocKinds UpdatePhaseMisc {
AllocKind::SCRIPT,
- AllocKind::LAZY_SCRIPT,
AllocKind::BASE_SHAPE,
AllocKind::SHAPE,
AllocKind::ACCESSOR_SHAPE,
AllocKind::OBJECT_GROUP,
AllocKind::STRING,
- AllocKind::JITCODE,
- AllocKind::SCOPE
+ AllocKind::JITCODE
};
static const AllocKinds UpdatePhaseObjects {
+ AllocKind::LAZY_SCRIPT,
+ AllocKind::SCOPE,
AllocKind::FUNCTION,
AllocKind::FUNCTION_EXTENDED,
AllocKind::OBJECT0,
diff --git a/js/src/jsnativestack.cpp b/js/src/jsnativestack.cpp
index 166a5a4f7..98f8fc741 100644
--- a/js/src/jsnativestack.cpp
+++ b/js/src/jsnativestack.cpp
@@ -71,35 +71,6 @@ js::GetNativeStackBaseImpl()
# endif
}
-#elif defined(SOLARIS)
-
-#include <ucontext.h>
-
-JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);
-
-void*
-js::GetNativeStackBaseImpl()
-{
- stack_t st;
- stack_getbounds(&st);
- return static_cast<char*>(st.ss_sp) + st.ss_size;
-}
-
-#elif defined(AIX)
-
-#include <ucontext.h>
-
-JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);
-
-void*
-js::GetNativeStackBaseImpl()
-{
- ucontext_t context;
- getcontext(&context);
- return static_cast<char*>(context.uc_stack.ss_sp) +
- context.uc_stack.ss_size;
-}
-
#elif defined(XP_LINUX) && !defined(ANDROID) && defined(__GLIBC__)
void*
js::GetNativeStackBaseImpl()
diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp
index 4151d012b..e3b5708ca 100644
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3070,8 +3070,11 @@ js::ValueToSource(JSContext* cx, HandleValue v)
return ToString<CanGC>(cx, v);
}
-
+#if JS_HAS_TOSOURCE
return ObjectToSource(cx, obj);
+#else
+ return ToString<CanGC>(cx, v);
+#endif
}
JSString*
diff --git a/js/src/jstypes.h b/js/src/jstypes.h
index 75774e5b8..6cfb3d4ad 100644
--- a/js/src/jstypes.h
+++ b/js/src/jstypes.h
@@ -147,13 +147,7 @@
# define JS_64BIT
# endif
#elif defined(__GNUC__)
-/* Additional GCC defines are when running on Solaris, AIX, and HPUX */
-# if defined(__x86_64__) || defined(__sparcv9) || \
- defined(__64BIT__) || defined(__LP64__)
-# define JS_64BIT
-# endif
-#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Sun Studio C/C++ */
-# if defined(__x86_64) || defined(__sparcv9)
+# if defined(__x86_64__) || defined(__64BIT__)
# define JS_64BIT
# endif
#elif defined(__xlc__) || defined(__xlC__) /* IBM XL C/C++ */
diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h
index 3c73979f8..84ebe2732 100644
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -270,6 +270,8 @@ class JS_FRIEND_API(OpaqueCrossCompartmentWrapper) : public CrossCompartmentWrap
virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override;
virtual bool isArray(JSContext* cx, HandleObject obj,
JS::IsArrayAnswer* answer) const override;
+ virtual bool hasInstance(JSContext* cx, HandleObject wrapper,
+ MutableHandleValue v, bool* bp) const override;
virtual const char* className(JSContext* cx, HandleObject wrapper) const override;
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const override;
diff --git a/js/src/moz.build b/js/src/moz.build
index a3283b5d6..888741138 100644
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -722,14 +722,6 @@ if CONFIG['OS_ARCH'] == 'Linux':
'dl',
]
-if CONFIG['OS_ARCH'] == 'SunOS':
- OS_LIBS += [
- 'posix4',
- 'dl',
- 'nsl',
- 'socket',
- ]
-
OS_LIBS += CONFIG['REALTIME_LIBS']
CFLAGS += CONFIG['MOZ_ICU_CFLAGS']
diff --git a/js/src/old-configure.in b/js/src/old-configure.in
index 8abea5956..45108ee59 100644
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -206,10 +206,6 @@ case "$target" in
# -Zc:sizedDealloc- disables C++14 global sized deallocation (see bug 1160146)
CXXFLAGS="$CXXFLAGS -Zc:sizedDealloc-"
-
- # Disable C++11 thread-safe statics due to crashes on XP (bug 1204752)
- # See https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
- CXXFLAGS="$CXXFLAGS -Zc:threadSafeInit-"
;;
esac
AC_SUBST(MSVS_VERSION)
diff --git a/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp b/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
index ff3f4145c..02bf237ff 100644
--- a/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
+++ b/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
@@ -175,6 +175,14 @@ OpaqueCrossCompartmentWrapper::isArray(JSContext* cx, HandleObject obj,
return true;
}
+bool OpaqueCrossCompartmentWrapper::hasInstance(JSContext* cx,
+ HandleObject wrapper,
+ MutableHandleValue v,
+ bool* bp) const {
+ *bp = false;
+ return true;
+}
+
const char*
OpaqueCrossCompartmentWrapper::className(JSContext* cx,
HandleObject proxy) const
diff --git a/js/src/proxy/ScriptedProxyHandler.cpp b/js/src/proxy/ScriptedProxyHandler.cpp
index 776547337..0e25f470c 100644
--- a/js/src/proxy/ScriptedProxyHandler.cpp
+++ b/js/src/proxy/ScriptedProxyHandler.cpp
@@ -8,8 +8,6 @@
#include "jsapi.h"
-#include "vm/Interpreter.h" // For InstanceOfOperator
-
#include "jsobjinlines.h"
#include "vm/NativeObject-inl.h"
@@ -1230,7 +1228,7 @@ bool
ScriptedProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
bool* bp) const
{
- return InstanceOfOperator(cx, proxy, v, bp);
+ return InstanceofOperator(cx, proxy, v, bp);
}
bool
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index b747e4d7a..e6d6630c4 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -718,14 +718,14 @@ js::Execute(JSContext* cx, HandleScript script, JSObject& envChainArg, Value* rv
}
/*
- * ES6 (4-25-16) 12.10.4 InstanceofOperator
+ * ES6 12.9.4 InstanceofOperator
*/
extern bool
-js::InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
+JS::InstanceofOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
{
/* Step 1. is handled by caller. */
- /* Step 2. */
+ /* Step 2-3. */
RootedValue hasInstance(cx);
RootedId id(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().hasInstance));
if (!GetProperty(cx, obj, obj, id, &hasInstance))
@@ -735,7 +735,7 @@ js::InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
if (!IsCallable(hasInstance))
return ReportIsNotFunction(cx, hasInstance);
- /* Step 3. */
+ /* Step 4. */
RootedValue rval(cx);
if (!Call(cx, hasInstance, obj, v, &rval))
return false;
@@ -743,13 +743,13 @@ js::InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
return true;
}
- /* Step 4. */
+ /* Step 5. */
if (!obj->isCallable()) {
RootedValue val(cx, ObjectValue(*obj));
return ReportIsNotFunction(cx, val);
}
- /* Step 5. */
+ /* Step 6. */
return OrdinaryHasInstance(cx, obj, v, bp);
}
@@ -760,7 +760,7 @@ js::HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
RootedValue local(cx, v);
if (JSHasInstanceOp hasInstance = clasp->getHasInstance())
return hasInstance(cx, obj, &local, bp);
- return js::InstanceOfOperator(cx, obj, local, bp);
+ return JS::InstanceofOperator(cx, obj, local, bp);
}
static inline bool
diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h
index 330dbef5f..9fefd75cc 100644
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -323,9 +323,6 @@ extern JSType
TypeOfValue(const Value& v);
extern bool
-InstanceOfOperator(JSContext* cx, HandleObject obj, HandleValue v, bool* bp);
-
-extern bool
HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp);
// Unwind environment chain and iterator to match the scope corresponding to
diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp
index 1fbf8976b..46159a972 100644
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -495,7 +495,6 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp,
if (associated->is<JSFunction>()) {
// Canonicalize new functions to use the original one associated with its script.
- JSFunction* fun = &associated->as<JSFunction>();
associated = associated->as<JSFunction>().maybeCanonicalFunction();
// If we have previously cleared the 'new' script information for this
diff --git a/js/src/vm/Time.cpp b/js/src/vm/Time.cpp
index 69e2cc41d..87531c148 100644
--- a/js/src/vm/Time.cpp
+++ b/js/src/vm/Time.cpp
@@ -11,9 +11,6 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/MathAlgorithms.h"
-#ifdef SOLARIS
-#define _REENTRANT 1
-#endif
#include <string.h>
#include <time.h>
@@ -33,10 +30,6 @@
#ifdef XP_UNIX
-#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
-extern int gettimeofday(struct timeval* tv);
-#endif
-
#include <sys/time.h>
#endif /* XP_UNIX */
@@ -49,11 +42,7 @@ PRMJ_Now()
{
struct timeval tv;
-#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
- gettimeofday(&tv);
-#else
gettimeofday(&tv, 0);
-#endif /* _SVID_GETTOD */
return int64_t(tv.tv_sec) * PRMJ_USEC_PER_SEC + int64_t(tv.tv_usec);
}
diff --git a/js/src/wasm/WasmSignalHandlers.cpp b/js/src/wasm/WasmSignalHandlers.cpp
index 78d21369d..c4733cc96 100644
--- a/js/src/wasm/WasmSignalHandlers.cpp
+++ b/js/src/wasm/WasmSignalHandlers.cpp
@@ -130,7 +130,7 @@ class AutoSetHandlingSegFault
# define EPC_sig(p) ((p)->sc_pc)
# define RFP_sig(p) ((p)->sc_regs[30])
# endif
-#elif defined(__linux__) || defined(SOLARIS)
+#elif defined(__linux__)
# if defined(__linux__)
# define XMM_sig(p,i) ((p)->uc_mcontext.fpregs->_xmm[i])
# define EIP_sig(p) ((p)->uc_mcontext.gregs[REG_EIP])
diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
index 9c8908ea4..f23e5833a 100644
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -295,7 +295,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AsyncScriptLoader)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(AsyncScriptLoader)
diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp
index 120772ed2..a516cf73f 100644
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -66,7 +66,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SandboxPrivate)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SandboxPrivate)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
tmp->TraverseHostObjectURIs(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp
index 0243d80e3..bde949a96 100644
--- a/js/xpconnect/src/XPCJSContext.cpp
+++ b/js/xpconnect/src/XPCJSContext.cpp
@@ -1427,6 +1427,8 @@ ReloadPrefsCallback(const char* pref, void* data)
bool extraWarnings = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict");
+ bool unboxedObjects = Preferences::GetBool(JS_OPTIONS_DOT_STR "unboxed_objects");
+
sSharedMemoryEnabled = Preferences::GetBool(JS_OPTIONS_DOT_STR "shared_memory");
#ifdef DEBUG
@@ -1455,6 +1457,8 @@ ReloadPrefsCallback(const char* pref, void* data)
useBaselineEager ? 0 : -1);
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_WARMUP_TRIGGER,
useIonEager ? 0 : -1);
+ JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_UNBOXED_OBJECTS,
+ unboxedObjects);
}
XPCJSContext::~XPCJSContext()
diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp
index a6432856d..4ddc8deb3 100644
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -644,7 +644,6 @@ env_setProperty(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
ObjectOpResult& result)
{
/* XXX porting may be easy, but these don't seem to supply setenv by default */
-#if !defined SOLARIS
RootedString valstr(cx);
RootedString idstr(cx);
int rv;
@@ -663,7 +662,7 @@ env_setProperty(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
JSAutoByteString value(cx, valstr);
if (!value)
return false;
-#if defined XP_WIN || defined HPUX || defined OSF1 || defined SCO
+#if defined XP_WIN || defined SCO
{
char* waste = JS_smprintf("%s=%s", name.ptr(), value.ptr());
if (!waste) {
@@ -671,16 +670,7 @@ env_setProperty(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
return false;
}
rv = putenv(waste);
-#ifdef XP_WIN
- /*
- * HPUX9 at least still has the bad old non-copying putenv.
- *
- * Per mail from <s.shanmuganathan@digital.com>, OSF1 also has a putenv
- * that will crash if you pass it an auto char array (so it must place
- * its argument directly in the char* environ[] array).
- */
free(waste);
-#endif
}
#else
rv = setenv(name.ptr(), value.ptr(), 1);
@@ -696,7 +686,6 @@ env_setProperty(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
return false;
}
vp.setString(valstr);
-#endif /* !defined SOLARIS */
return result.succeed();
}
diff --git a/js/xpconnect/src/nsScriptErrorWithStack.cpp b/js/xpconnect/src/nsScriptErrorWithStack.cpp
index edc12fa76..50407da23 100644
--- a/js/xpconnect/src/nsScriptErrorWithStack.cpp
+++ b/js/xpconnect/src/nsScriptErrorWithStack.cpp
@@ -45,7 +45,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsScriptErrorWithStack)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsScriptErrorWithStack)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsScriptErrorWithStack)
diff --git a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
index 27c010d34..dca3daa58 100644
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
@@ -88,6 +88,37 @@ WaiveXrayWrapper::nativeCall(JSContext* cx, JS::IsAcceptableThis test,
}
bool
+WaiveXrayWrapper::hasInstance(JSContext* cx, HandleObject wrapper,
+ MutableHandleValue v, bool* bp) const {
+ if (v.isObject() && WrapperFactory::IsXrayWrapper(&v.toObject())) {
+ // If |v| is an XrayWrapper and in the same compartment as the value
+ // wrapped by |wrapper|, then the Xrays of |v| would be waived upon
+ // calling CrossCompartmentWrapper::hasInstance. This may trigger
+ // getters and proxy traps of unwrapped |v|. To prevent that from
+ // happening, we exit early.
+
+ // |wrapper| is the right operand of "instanceof", and must either be
+ // a function or an object with a @@hasInstance method. We are not going
+ // to call @@hasInstance, so only check whether it is a function.
+ // This check is here for consistency with usual "instanceof" behavior,
+ // which throws if the right operand is not a function. Without this
+ // check, the "instanceof" operator would return false and potentially
+ // hide errors in the code that uses the "instanceof" operator.
+ if (!JS::IsCallable(wrapper)) {
+ RootedValue wrapperv(cx, JS::ObjectValue(*wrapper));
+ js::ReportIsNotFunction(cx, wrapperv);
+ return false;
+ }
+
+ *bp = false;
+ return true;
+ }
+
+ // Both |wrapper| and |v| have no Xrays here.
+ return CrossCompartmentWrapper::hasInstance(cx, wrapper, v, bp);
+}
+
+bool
WaiveXrayWrapper::getPrototype(JSContext* cx, HandleObject wrapper, MutableHandleObject protop) const
{
return CrossCompartmentWrapper::getPrototype(cx, wrapper, protop) &&
diff --git a/js/xpconnect/wrappers/WaiveXrayWrapper.h b/js/xpconnect/wrappers/WaiveXrayWrapper.h
index b0b447796..0f9675c17 100644
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.h
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.h
@@ -36,6 +36,8 @@ class WaiveXrayWrapper : public js::CrossCompartmentWrapper {
JS::MutableHandle<JSObject*> objp) const override;
virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test,
JS::NativeImpl impl, const JS::CallArgs& args) const override;
+ virtual bool hasInstance(JSContext* cx, JS::HandleObject wrapper,
+ JS::MutableHandleValue v, bool* bp) const override;
virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id,
JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp
index 48a9fdc68..6e5a2f5e5 100644
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -2309,6 +2309,20 @@ XrayWrapper<Base, Traits>::getBuiltinClass(JSContext* cx, JS::HandleObject wrapp
}
template <typename Base, typename Traits>
+bool
+XrayWrapper<Base, Traits>::hasInstance(JSContext* cx,
+ JS::HandleObject wrapper,
+ JS::MutableHandleValue v,
+ bool* bp) const {
+ assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::GET);
+
+ // CrossCompartmentWrapper::hasInstance unwraps |wrapper|'s Xrays and enters
+ // its compartment. Any present XrayWrappers should be preserved, so the
+ // standard "instanceof" implementation is called without unwrapping first.
+ return JS::InstanceofOperator(cx, wrapper, v, bp);
+}
+
+template <typename Base, typename Traits>
const char*
XrayWrapper<Base, Traits>::className(JSContext* cx, HandleObject wrapper) const
{
diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h
index 5630982c2..038d82390 100644
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -482,6 +482,8 @@ class XrayWrapper : public Base {
JS::AutoIdVector& props) const override;
virtual bool getBuiltinClass(JSContext* cx, JS::HandleObject wapper, js::ESClass* cls) const override;
+ virtual bool hasInstance(JSContext* cx, JS::HandleObject wrapper,
+ JS::MutableHandleValue v, bool* bp) const override;
virtual const char* className(JSContext* cx, JS::HandleObject proxy) const override;
static const XrayWrapper singleton;